diff --git a/client/src/main/java/ch/zhaw/pm2/multichat/client/ChatWindowController.java b/client/src/main/java/ch/zhaw/pm2/multichat/client/ChatWindowController.java index f0ae66c..b94ce1e 100644 --- a/client/src/main/java/ch/zhaw/pm2/multichat/client/ChatWindowController.java +++ b/client/src/main/java/ch/zhaw/pm2/multichat/client/ChatWindowController.java @@ -6,6 +6,7 @@ import ch.zhaw.pm2.multichat.protocol.NetworkHandler; import javafx.application.Platform; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; +import javafx.collections.ListChangeListener; import javafx.event.EventHandler; import javafx.fxml.FXML; import javafx.scene.control.Button; @@ -41,14 +42,14 @@ public class ChatWindowController { public void initialize() { serverAddressField.setText(NetworkHandler.DEFAULT_ADDRESS.getCanonicalHostName()); serverPortField.setText(String.valueOf(NetworkHandler.DEFAULT_PORT)); - } + this.messages = new ClientMessageList(); - public void chatWindowController(ClientMessageList messages,ClientConnectionHandler connectionHandler) { - this.connectionHandler = connectionHandler; - this.messages = messages; - - //register changelistener - startChangeListener(); + messages.getChangedProperty().addListener(new ChangeListener() { + @Override + public void changed(ObservableValue observable, Boolean oldValue, Boolean newValue) { + setMessageField(messages.getMessages()); + } + }); } private void applicationClose() { @@ -67,23 +68,22 @@ public class ChatWindowController { private void connect() { try { messages.clear(); // clear message list - redrawMessageList(); startConnectionHandler(); connectionHandler.connect(); } catch(ChatProtocolException | IOException e) { - addError(e.getMessage()); + messages.addMessage(null,null, e.getMessage(), Message.MessageType.ERROR); } } private void disconnect() { if (connectionHandler == null) { - addError("No connection handler"); + messages.addMessage(null,null,"No connection handler", Message.MessageType.ERROR); return; } try { connectionHandler.disconnect(); } catch (ChatProtocolException e) { - addError(e.getMessage()); + messages.addMessage(null,null, e.getMessage(), Message.MessageType.ERROR); } } @@ -92,29 +92,33 @@ public class ChatWindowController { String messageString = messageField.getText().strip(); try { if (connectionHandler == null) { - addError("No connection handler"); + messages.addMessage(null,null,"No connection handler", Message.MessageType.ERROR); } else if (!connectionHandler.message(messageString)) { - addError("Not a valid message format."); + messages.addMessage(null,null,"Not a valid message format.", Message.MessageType.ERROR); } else { messageField.clear(); } } catch (ChatProtocolException e) { - addError(e.getMessage()); + messages.addMessage(null,null, e.getMessage(), Message.MessageType.ERROR); } } + //TODO: TEST @FXML private void applyFilter( ) { - this.redrawMessageList(); + messages.getFilteredMessages(filterValue.getText().strip()); } private void startConnectionHandler() throws IOException { String userName = userNameField.getText(); String serverAddress = serverAddressField.getText(); int serverPort = Integer.parseInt(serverPortField.getText()); - connectionHandler.openConnection(serverAddress,serverPort,userName); + connectionHandler = new ClientConnectionHandler(messages,serverAddress,serverPort,userName); new Thread(connectionHandler).start(); + //register changelistener + startChangeListener(); + // register window close handler rootPane.getScene().getWindow().addEventHandler(WindowEvent.WINDOW_CLOSE_REQUEST, windowCloseHandler); } @@ -175,6 +179,15 @@ public class ChatWindowController { }); } + public void setMessageField(String message) { + Platform.runLater(new Runnable() { + @Override + public void run() { + messageField.setText(message); + } + }); + } + public void setUserName(String userName) { Platform.runLater(new Runnable() { @Override @@ -202,21 +215,7 @@ public class ChatWindowController { }); } - public void addMessage(String sender, String receiver, String message) { - messages.addMessage(new Message(Message.MessageType.MESSAGE, sender, receiver, message)); - this.redrawMessageList(); - } - - public void addInfo(String message) { - messages.addMessage(new Message(Message.MessageType.INFO, null, null, message)); - this.redrawMessageList(); - } - - public void addError(String message) { - messages.addMessage(new Message(Message.MessageType.ERROR, null, null, message)); - this.redrawMessageList(); - } - + //TODO: MAKE ChangeListener private void redrawMessageList() { this.messageArea.clear(); Platform.runLater(() -> this.messageArea.setText(messages.getFilteredMessages(filterValue.getText().strip()))); diff --git a/client/src/main/java/ch/zhaw/pm2/multichat/client/ClientConnectionHandler.java b/client/src/main/java/ch/zhaw/pm2/multichat/client/ClientConnectionHandler.java index bef80ba..1281e70 100644 --- a/client/src/main/java/ch/zhaw/pm2/multichat/client/ClientConnectionHandler.java +++ b/client/src/main/java/ch/zhaw/pm2/multichat/client/ClientConnectionHandler.java @@ -15,6 +15,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import static ch.zhaw.pm2.multichat.client.ClientConnectionHandler.State.*; +import static ch.zhaw.pm2.multichat.client.Message.MessageType.*; public class ClientConnectionHandler implements Runnable { private NetworkHandler.NetworkConnection connection; @@ -40,18 +41,13 @@ public class ClientConnectionHandler implements Runnable { NEW, CONFIRM_CONNECT, CONNECTED, CONFIRM_DISCONNECT, DISCONNECTED; } - public ClientConnectionHandler(ClientMessageList messageList) { + public ClientConnectionHandler(ClientMessageList messageList,String serverAddress,int serverPort,String userName) throws IOException { this.stateObjectProperty = new SimpleObjectProperty<>(NEW); - connection = null; - userName = new SimpleStringProperty(USER_NONE); - serverPort = new SimpleIntegerProperty(); - serverAddress = new SimpleStringProperty(); + this.userName = new SimpleStringProperty((userName == null || userName.isBlank())? USER_NONE : userName); + this.serverPort = new SimpleIntegerProperty(); + this.serverAddress = new SimpleStringProperty(); this.messageList = messageList; - } - - public void openConnection(String serverAddress, int serverPort, String userName) throws IOException{ - connection = NetworkHandler.openConnection(serverAddress,serverPort); - this.userName.set((userName == null || userName.isBlank())? USER_NONE : userName); + this.connection = NetworkHandler.openConnection(serverAddress,serverPort); } public ObjectProperty getStateObjectProperty() { @@ -115,6 +111,7 @@ public class ClientConnectionHandler implements Runnable { System.out.println("Closed Connection Handler to Server"); } + private void processData(String data) { try { // parse data content @@ -147,15 +144,13 @@ public class ClientConnectionHandler implements Runnable { } else if (type.equals(DATA_TYPE_CONFIRM)) { if (stateObjectProperty.get() == CONFIRM_CONNECT) { this.userName.set(reciever); - controller.addInfo(payload);//TODO: Make Changelistener - messageList.addMessage(ClientMessageList.MessageType.INFO,sender,reciever,payload); - + this.serverAddress.set(connection.getRemoteHost()); + this.serverPort.set(connection.getRemotePort()); + messageList.addMessage(sender,reciever,payload,INFO); System.out.println("CONFIRM: " + payload); this.setState(CONNECTED); } else if (stateObjectProperty.get() == CONFIRM_DISCONNECT) { - controller.addInfo(payload);//TODO: Make Changelistener - messageList.addMessage(ClientMessageList.MessageType.INFO,sender,reciever,payload); - + messageList.addMessage(sender,reciever,payload,INFO); System.out.println("CONFIRM: " + payload); this.setState(DISCONNECTED); } else { @@ -166,9 +161,7 @@ public class ClientConnectionHandler implements Runnable { System.out.println("DISCONNECT: Already in disconnected: " + payload); return; } - controller.addInfo(payload); - messageList.addMessage(ClientMessageList.MessageType.INFO,sender,reciever,payload); - + messageList.addMessage(sender,reciever,payload,INFO); System.out.println("DISCONNECT: " + payload); this.setState(DISCONNECTED); } else if (type.equals(DATA_TYPE_MESSAGE)) { @@ -176,14 +169,10 @@ public class ClientConnectionHandler implements Runnable { System.out.println("MESSAGE: Illegal state " + stateObjectProperty.get() + " for message: " + payload); return; } - controller.addMessage(sender, reciever, payload); - messageList.addMessage(ClientMessageList.MessageType.MESSAGE,sender,reciever,payload); - + messageList.addMessage(sender,reciever,payload,MESSAGE); System.out.println("MESSAGE: From " + sender + " to " + reciever + ": "+ payload); } else if (type.equals(DATA_TYPE_ERROR)) { - controller.addError(payload); - messageList.addMessage(ClientMessageList.MessageType.ERROR,sender,reciever,payload); - + messageList.addMessage(sender,reciever,payload,ERROR); System.out.println("ERROR: " + payload); } else { System.out.println("Unknown data type received: " + type); @@ -227,11 +216,8 @@ public class ClientConnectionHandler implements Runnable { this.setState(CONFIRM_DISCONNECT); } - public void message(String receiver, String message) throws ChatProtocolException { - if (stateObjectProperty.get() != CONNECTED) throw new ChatProtocolException("Illegal state for message: " + stateObjectProperty.get()); - this.sendData(userName.get(), receiver, DATA_TYPE_MESSAGE,message); public boolean message(String messageString) throws ChatProtocolException { - if (state != CONNECTED) throw new ChatProtocolException("Illegal state for message: " + state); + if (stateObjectProperty.get() != CONNECTED) throw new ChatProtocolException("Illegal state for message: " + stateObjectProperty.get()); Matcher matcher = messagePattern.matcher(messageString); if (matcher.find()) { @@ -241,7 +227,7 @@ public class ClientConnectionHandler implements Runnable { return false; } if (receiver == null || receiver.isBlank()) receiver = ClientConnectionHandler.USER_ALL; - this.sendData(userName, receiver, DATA_TYPE_MESSAGE,message); + this.sendData(userName.get(), receiver, DATA_TYPE_MESSAGE,message); return true; } else { return false; diff --git a/client/src/main/java/ch/zhaw/pm2/multichat/client/ClientMessageList.java b/client/src/main/java/ch/zhaw/pm2/multichat/client/ClientMessageList.java index a811406..d07981c 100644 --- a/client/src/main/java/ch/zhaw/pm2/multichat/client/ClientMessageList.java +++ b/client/src/main/java/ch/zhaw/pm2/multichat/client/ClientMessageList.java @@ -1,14 +1,34 @@ package ch.zhaw.pm2.multichat.client; +import javafx.beans.property.SimpleBooleanProperty; +import javafx.beans.property.SimpleListProperty; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; + import java.util.ArrayList; import java.util.List; +import static ch.zhaw.pm2.multichat.client.ClientConnectionHandler.USER_NONE; + public class ClientMessageList { - private List messages = new ArrayList<>(); + private List messages; + private SimpleBooleanProperty changed; + public ClientMessageList() { + messages = new ArrayList<>(); + changed = new SimpleBooleanProperty(true); + } - public void addMessage(Message message) { - messages.add(message); + public SimpleBooleanProperty getChangedProperty() { + return changed; + } + + public void addMessage(String sender, String receiver, String message, Message.MessageType type) { + if(sender == null) { + sender = USER_NONE; + } + messages.add(new Message(type, sender, receiver, message)); + changed.set(!changed.get()); } public String getFilteredMessages(String filter) { @@ -28,8 +48,21 @@ public class ClientMessageList { return result.toString(); } + public String getMessages() { + StringBuilder result = new StringBuilder(); + for(Message message : messages) { + switch (message.getType()) { + case MESSAGE -> result.append(String.format("[%s -> %s] %s\n", message.getSender(), message.getReceiver(), message.getText())); + case ERROR -> result.append(String.format("[ERROR] %s\n", message.getText())); + case INFO -> result.append(String.format("[INFO] %s\n", message.getText())); + default -> result.append(String.format("[ERROR] %s\n", "Unexpected message type: " + message.getType())); + } + } + return result.toString(); + } + public void clear() { - messages = new ArrayList<>(); + messages = new SimpleListProperty<>(); } } diff --git a/client/src/main/java/ch/zhaw/pm2/multichat/client/ClientUI.java b/client/src/main/java/ch/zhaw/pm2/multichat/client/ClientUI.java index a8b58a6..7dfa44a 100644 --- a/client/src/main/java/ch/zhaw/pm2/multichat/client/ClientUI.java +++ b/client/src/main/java/ch/zhaw/pm2/multichat/client/ClientUI.java @@ -18,18 +18,8 @@ public class ClientUI extends Application { try { FXMLLoader loader = new FXMLLoader(getClass().getResource("ChatWindow.fxml")); - // set up Controller - - ChatWindowController controller = loader.getController(); - ClientMessageList messageList = new ClientMessageList(controller); - ClientConnectionHandler connectionHandler = new ClientConnectionHandler(messageList); - controller.chatWindowController(messageList,connectionHandler); - Pane rootPane = loader.load(); - ChatWindowController chatWindowController = loader.getController(); - chatWindowController.setMessages(clientMessageList); - // fill in scene and stage setup Scene scene = new Scene(rootPane); //scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());