diff --git a/src/main/java/envoy/client/Client.java b/src/main/java/envoy/client/Client.java index 5b9a2b8..4c775e1 100644 --- a/src/main/java/envoy/client/Client.java +++ b/src/main/java/envoy/client/Client.java @@ -36,14 +36,14 @@ public class Client { this.config = config; sender = getUser(username); - logger.info("ID: " + sender.getID()); + logger.info("ID: " + sender.getID()); } private R post(String uri, T body, Class responseBodyClass) { - javax.ws.rs.client.Client client = ClientBuilder.newClient(); - WebTarget target = client.target(uri); - Response response = target.request().post(Entity.entity(body, "application/xml")); - R responseBody = response.readEntity(responseBodyClass); + javax.ws.rs.client.Client client = ClientBuilder.newClient(); + WebTarget target = client.target(uri); + Response response = target.request().post(Entity.entity(body, "application/xml")); + R responseBody = response.readEntity(responseBodyClass); response.close(); client.close(); @@ -133,7 +133,9 @@ public class Client { * Updating UserStatus of all users in LocalDB. (Server sends all users with * their updated UserStatus to the client.)
* - * @param userId + * @param userId the id of the {@link Client} who sends the {@link Sync} + * @param sync the {@link Sync} to send + * @return a sync * @since Envoy v0.1-alpha */ public Sync sendSync(long userId, Sync sync) { @@ -168,16 +170,16 @@ public class Client { public User getRecipient() { return recipient; } /** - * Sets the recipient. + * Sets the recipient. + * * @param recipient - the recipient to set * @since Envoy v0.1-alpha */ public void setRecipient(User recipient) { this.recipient = recipient; } - /** + /** * @return true, if a recipient is selected * @since Envoy v0.1-alpha */ public boolean hasRecipient() { return recipient != null; } } - diff --git a/src/main/java/envoy/client/Config.java b/src/main/java/envoy/client/Config.java index 545df2f..116a341 100644 --- a/src/main/java/envoy/client/Config.java +++ b/src/main/java/envoy/client/Config.java @@ -114,7 +114,7 @@ public class Config { * Changes the default local database. * Exclusively intended for development purposes. * - * @param the file containing the local database + * @param localDB the file containing the local database * @since Envoy v0.1-alpha **/ public void setLocalDB(File localDB) { this.localDB = localDB; } diff --git a/src/main/java/envoy/client/LocalDB.java b/src/main/java/envoy/client/LocalDB.java index 3929315..d952bef 100644 --- a/src/main/java/envoy/client/LocalDB.java +++ b/src/main/java/envoy/client/LocalDB.java @@ -1,300 +1,295 @@ -package envoy.client; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.time.Instant; -import java.util.ArrayList; -import java.util.List; -import java.util.logging.Logger; - -import javax.xml.datatype.DatatypeConfigurationException; -import javax.xml.datatype.DatatypeFactory; - -import envoy.client.event.EventBus; -import envoy.client.event.MessageCreationEvent; -import envoy.exception.EnvoyException; -import envoy.schema.Message; -import envoy.schema.Message.Metadata.MessageState; -import envoy.schema.ObjectFactory; -import envoy.schema.Sync; -import envoy.schema.User; - -/** - * Project: envoy-client
- * File: LocalDB.java
- * Created: 27.10.2019
- * - * @author Kai S. K. Engelbart - * @author Maximilian Käfer - * @since Envoy v0.1-alpha - */ -public class LocalDB { - - private File localDB; - private User sender; - private List chats = new ArrayList<>(); - private ObjectFactory objectFactory = new ObjectFactory(); - private DatatypeFactory datatypeFactory; - - private Sync unreadMessagesSync = objectFactory.createSync(); - private Sync sync = objectFactory.createSync(); - private Sync readMessages = objectFactory.createSync(); - - private static final Logger logger = Logger.getLogger(LocalDB.class.getSimpleName()); - - /** - * Constructs an empty local database. - * - * @param sender the user that is logged in with this client - * @since Envoy v0.1-alpha - */ - public LocalDB(User sender) { - this.sender = sender; - try { - datatypeFactory = DatatypeFactory.newInstance(); - } catch (DatatypeConfigurationException e) { - e.printStackTrace(); - } - } - - /** - * Initializes the local database and fills it with values - * if the user has already sent or received messages. - * - * @param localDBDir the directory where we wish to save/load the database from. - * @throws EnvoyException if the directory selected is not an actual directory. - * @since Envoy v0.1-alpha - */ - public void initializeDBFile(File localDBDir) throws EnvoyException { - if (localDBDir.exists() && !localDBDir.isDirectory()) - throw new EnvoyException(String.format("LocalDBDir '%s' is not a directory!", localDBDir.getAbsolutePath())); - localDB = new File(localDBDir, sender.getID() + ".db"); - if (localDB.exists()) loadFromLocalDB(); - } - - /** - * Saves the database into a file for future use. - * - * @throws IOException if something went wrong during saving - * @since Envoy v0.1-alpha - */ - public void saveToLocalDB() { - try { - localDB.getParentFile().mkdirs(); - localDB.createNewFile(); - } catch (IOException e) { - e.printStackTrace(); - logger.warning("unable to save the messages"); - } - try (ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(localDB))) { - out.writeObject(chats); - } catch (IOException ex) { - ex.printStackTrace(); - logger.warning("unable to save the messages"); - } - } - - /** - * Loads all chats saved by Envoy for the client user. - * - * @throws EnvoyException if something fails while loading. - * @since Envoy v0.1-alpha - */ - @SuppressWarnings("unchecked") - private void loadFromLocalDB() throws EnvoyException { - try (ObjectInputStream in = new ObjectInputStream(new FileInputStream(localDB))) { - Object obj = in.readObject(); - if (obj instanceof ArrayList) chats = (ArrayList) obj; - } catch (ClassNotFoundException | IOException e) { - throw new EnvoyException(e); - } - } - - /** - * Creates a {@link Message} object serializable to XML. - * - * @param textContent The content (text) of the message - * @param recipient The recipient of the message - * @return prepared {@link Message} object - * @since Envoy v0.1-alpha - */ - public Message createMessage(String textContent, User recipient) { - Message.Metadata metaData = objectFactory.createMessageMetadata(); - metaData.setSender(sender.getID()); - metaData.setRecipient(recipient.getID()); - metaData.setState(MessageState.WAITING); - metaData.setDate(datatypeFactory.newXMLGregorianCalendar(Instant.now().toString())); - - Message.Content content = objectFactory.createMessageContent(); - content.setType("text"); - content.setText(textContent); - - Message message = objectFactory.createMessage(); - message.setMetadata(metaData); - message.getContent().add(content); - - return message; - } - - /** - * Creates a {@link Sync} object filled with the changes that occurred to the - * local database since the last synchronization. - * - * @param userId the ID of the user that is synchronized by this client - * @return {@link Sync} object filled with the current changes - */ - public Sync fillSync(long userId) { - addWaitingMessagesToSync(); - - sync.getMessages().addAll(readMessages.getMessages()); - readMessages.getMessages().clear(); - - logger.info(String.format("Filled sync with %d messages.", sync.getMessages().size())); - return sync; - } - - /** - * Applies the changes carried by a {@link Sync} object to the local database - * - * @param returnSync the {@link Sync} object to apply - */ - public void applySync(Sync returnSync) { - for (int i = 0; i < returnSync.getMessages().size(); i++) { - - // The message has an ID - if (returnSync.getMessages().get(i).getMetadata().getMessageId() != 0) { - - // Messages are processes differently corresponding to their state - switch (returnSync.getMessages().get(i).getMetadata().getState()) { - case SENT: - // Update previously waiting and now sent messages that were assigned an ID by - // the server - sync.getMessages().get(i).getMetadata().setMessageId(returnSync.getMessages().get(i).getMetadata().getMessageId()); - sync.getMessages().get(i).getMetadata().setState(returnSync.getMessages().get(i).getMetadata().getState()); - break; - case RECEIVED: - if (returnSync.getMessages().get(i).getMetadata().getSender() != 0) { - // these are the unread Messages from the server - unreadMessagesSync.getMessages().add(returnSync.getMessages().get(i)); - - // Create and dispatch message creation event - EventBus.getInstance().dispatch(new MessageCreationEvent(returnSync.getMessages().get(i))); - } else { - // Update Messages in localDB to state RECEIVED - for (Chat chat : getChats()) - if (chat.getRecipient().getID() == returnSync.getMessages().get(i).getMetadata().getRecipient()) - for (int j = 0; j < chat.getModel().getSize(); j++) - if (chat.getModel().get(j).getMetadata().getMessageId() == returnSync.getMessages() - .get(i) - .getMetadata() - .getMessageId()) - chat.getModel().get(j).getMetadata().setState(returnSync.getMessages().get(i).getMetadata().getState()); - } - break; - case READ: - // Update local Messages to state READ - logger.info("Message with ID: " + returnSync.getMessages().get(i).getMetadata().getMessageId() - + "was initialized to be set to READ in localDB."); - for (Chat chat : getChats()) - if (chat.getRecipient().getID() == returnSync.getMessages().get(i).getMetadata().getRecipient()) { - logger.info("Chat with: " + chat.getRecipient().getID() + "was selected."); - for (int k = 0; k < chat.getModel().getSize(); k++) - if (chat.getModel().get(k).getMetadata().getMessageId() == returnSync.getMessages() - .get(i) - .getMetadata() - .getMessageId()) { - logger.info("Message with ID: " + chat.getModel().get(k).getMetadata().getMessageId() + "was selected."); - chat.getModel().get(k).getMetadata().setState(returnSync.getMessages().get(i).getMetadata().getState()); - logger.info("Message State is now: " + chat.getModel().get(k).getMetadata().getState()); - } - } - break; - } - } - } - - // Updating UserStatus of all users in LocalDB - for (User user : returnSync.getUsers()) - for (Chat chat : getChats()) - if (user.getID() == chat.getRecipient().getID()) { - chat.getRecipient().setStatus(user.getStatus()); - logger.info(chat.getRecipient().getStatus().toString()); - } - - sync.getMessages().clear(); - sync.getUsers().clear(); - } - - /** - * Adds the unread messages returned from the server in the latest sync to the - * right chats in the LocalDB. - * - * @param localDB - * @since Envoy v0.1-alpha - */ - public void addUnreadMessagesToLocalDB() { - for (Message message : unreadMessagesSync.getMessages()) - for (Chat chat : getChats()) - if (message.getMetadata().getSender() == chat.getRecipient().getID()) { - chat.appendMessage(message); - break; - } - } - - /** - * Changes all messages with state {@code RECEIVED} of a specific chat to state - * {@code READ}. - *
- * Adds these messages to the {@code readMessages} {@link Sync} object. - * - * @param currentChat - * @since Envoy v0.1-alpha - */ - public void setMessagesToRead(Chat currentChat) { - for (int i = currentChat.getModel().size() - 1; i >= 0; --i) - if (currentChat.getModel().get(i).getMetadata().getRecipient() != currentChat.getRecipient().getID()) - if (currentChat.getModel().get(i).getMetadata().getState() == MessageState.RECEIVED) { - currentChat.getModel().get(i).getMetadata().setState(MessageState.READ); - readMessages.getMessages().add(currentChat.getModel().get(i)); - } else break; - } - - /** - * Adds all messages with state {@code WAITING} from the {@link LocalDB} to the - * {@link Sync} object. - * - * @since Envoy v0.1-alpha - */ - private void addWaitingMessagesToSync() { - for (Chat chat : getChats()) - for (int i = 0; i < chat.getModel().size(); i++) - if (chat.getModel().get(i).getMetadata().getState() == MessageState.WAITING) { - logger.info("Got Waiting Message"); - sync.getMessages().add(chat.getModel().get(i)); - } - } - - /** - * Clears the {@code unreadMessagesSync} {@link Sync} object. - * - * @since Envoy v0.1-alpha - */ - public void clearUnreadMessagesSync() { unreadMessagesSync.getMessages().clear(); } - - /** - * @return all saved {@link Chat} objects that list the client user as the - * sender - * @since Envoy v0.1-alpha - **/ - public List getChats() { return chats; } - - /** - * @return the {@link User} who initialized the local database - * @since Envoy v0.1-alpha - */ - public User getUser() { return sender; } -} \ No newline at end of file +package envoy.client; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.time.Instant; +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Logger; + +import javax.xml.datatype.DatatypeConfigurationException; +import javax.xml.datatype.DatatypeFactory; + +import envoy.client.event.EventBus; +import envoy.client.event.MessageCreationEvent; +import envoy.exception.EnvoyException; +import envoy.schema.Message; +import envoy.schema.Message.Metadata.MessageState; +import envoy.schema.ObjectFactory; +import envoy.schema.Sync; +import envoy.schema.User; + +/** + * Project: envoy-client
+ * File: LocalDB.java
+ * Created: 27.10.2019
+ * + * @author Kai S. K. Engelbart + * @author Maximilian Käfer + * @since Envoy v0.1-alpha + */ +public class LocalDB { + + private File localDB; + private User sender; + private List chats = new ArrayList<>(); + private ObjectFactory objectFactory = new ObjectFactory(); + private DatatypeFactory datatypeFactory; + + private Sync unreadMessagesSync = objectFactory.createSync(); + private Sync sync = objectFactory.createSync(); + private Sync readMessages = objectFactory.createSync(); + + private static final Logger logger = Logger.getLogger(LocalDB.class.getSimpleName()); + + /** + * Constructs an empty local database. + * + * @param sender the user that is logged in with this client + * @since Envoy v0.1-alpha + */ + public LocalDB(User sender) { + this.sender = sender; + try { + datatypeFactory = DatatypeFactory.newInstance(); + } catch (DatatypeConfigurationException e) { + e.printStackTrace(); + } + } + + /** + * Initializes the local database and fills it with values + * if the user has already sent or received messages. + * + * @param localDBDir the directory where we wish to save/load the database from. + * @throws EnvoyException if the directory selected is not an actual directory. + * @since Envoy v0.1-alpha + */ + public void initializeDBFile(File localDBDir) throws EnvoyException { + if (localDBDir.exists() && !localDBDir.isDirectory()) + throw new EnvoyException(String.format("LocalDBDir '%s' is not a directory!", localDBDir.getAbsolutePath())); + localDB = new File(localDBDir, sender.getID() + ".db"); + if (localDB.exists()) loadFromLocalDB(); + } + + /** + * Saves the database into a file for future use. + * + * @throws IOException if something went wrong during saving + * @since Envoy v0.1-alpha + */ + public void saveToLocalDB() throws IOException { + localDB.getParentFile().mkdirs(); + localDB.createNewFile(); + try (ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(localDB))) { + out.writeObject(chats); + } catch (IOException ex) { + throw ex; + } + } + + /** + * Loads all chats saved by Envoy for the client user. + * + * @throws EnvoyException if something fails while loading. + * @since Envoy v0.1-alpha + */ + @SuppressWarnings("unchecked") + private void loadFromLocalDB() throws EnvoyException { + try (ObjectInputStream in = new ObjectInputStream(new FileInputStream(localDB))) { + Object obj = in.readObject(); + if (obj instanceof ArrayList) chats = (ArrayList) obj; + } catch (ClassNotFoundException | IOException e) { + throw new EnvoyException(e); + } + } + + /** + * Creates a {@link Message} object serializable to XML. + * + * @param textContent The content (text) of the message + * @param recipient The recipient of the message + * @return prepared {@link Message} object + * @since Envoy v0.1-alpha + */ + public Message createMessage(String textContent, User recipient) { + Message.Metadata metaData = objectFactory.createMessageMetadata(); + metaData.setSender(sender.getID()); + metaData.setRecipient(recipient.getID()); + metaData.setState(MessageState.WAITING); + metaData.setDate(datatypeFactory.newXMLGregorianCalendar(Instant.now().toString())); + + Message.Content content = objectFactory.createMessageContent(); + content.setType("text"); + content.setText(textContent); + + Message message = objectFactory.createMessage(); + message.setMetadata(metaData); + message.getContent().add(content); + + return message; + } + + /** + * Creates a {@link Sync} object filled with the changes that occurred to the + * local database since the last synchronization. + * + * @param userId the ID of the user that is synchronized by this client + * @return {@link Sync} object filled with the current changes + * @since Envoy v0.1-alpha + */ + public Sync fillSync(long userId) { + addWaitingMessagesToSync(); + + sync.getMessages().addAll(readMessages.getMessages()); + readMessages.getMessages().clear(); + + logger.finest(String.format("Filled sync with %d messages.", sync.getMessages().size())); + return sync; + } + + /** + * Applies the changes carried by a {@link Sync} object to the local database + * + * @param returnSync the {@link Sync} object to apply + * @since Envoy v0.1-alpha + */ + public void applySync(Sync returnSync) { + for (int i = 0; i < returnSync.getMessages().size(); i++) { + + // The message has an ID + if (returnSync.getMessages().get(i).getMetadata().getMessageId() != 0) { + + // Messages are processes differently corresponding to their state + switch (returnSync.getMessages().get(i).getMetadata().getState()) { + case SENT: + // Update previously waiting and now sent messages that were assigned an ID by + // the server + sync.getMessages().get(i).getMetadata().setMessageId(returnSync.getMessages().get(i).getMetadata().getMessageId()); + sync.getMessages().get(i).getMetadata().setState(returnSync.getMessages().get(i).getMetadata().getState()); + break; + case RECEIVED: + if (returnSync.getMessages().get(i).getMetadata().getSender() != 0) { + // these are the unread Messages from the server + unreadMessagesSync.getMessages().add(returnSync.getMessages().get(i)); + + // Create and dispatch message creation event + EventBus.getInstance().dispatch(new MessageCreationEvent(returnSync.getMessages().get(i))); + } else { + // Update Messages in localDB to state RECEIVED + for (Chat chat : getChats()) + if (chat.getRecipient().getID() == returnSync.getMessages().get(i).getMetadata().getRecipient()) + for (int j = 0; j < chat.getModel().getSize(); j++) + if (chat.getModel().get(j).getMetadata().getMessageId() == returnSync.getMessages() + .get(i) + .getMetadata() + .getMessageId()) + chat.getModel().get(j).getMetadata().setState(returnSync.getMessages().get(i).getMetadata().getState()); + } + break; + case READ: + // Update local Messages to state READ + logger.info("Message with ID: " + returnSync.getMessages().get(i).getMetadata().getMessageId() + + "was initialized to be set to READ in localDB."); + for (Chat chat : getChats()) + if (chat.getRecipient().getID() == returnSync.getMessages().get(i).getMetadata().getRecipient()) { + logger.info("Chat with: " + chat.getRecipient().getID() + "was selected."); + for (int k = 0; k < chat.getModel().getSize(); k++) + if (chat.getModel().get(k).getMetadata().getMessageId() == returnSync.getMessages() + .get(i) + .getMetadata() + .getMessageId()) { + logger.info("Message with ID: " + chat.getModel().get(k).getMetadata().getMessageId() + "was selected."); + chat.getModel().get(k).getMetadata().setState(returnSync.getMessages().get(i).getMetadata().getState()); + logger.info("Message State is now: " + chat.getModel().get(k).getMetadata().getState()); + } + } + break; + } + } + } + + // Updating UserStatus of all users in LocalDB + for (User user : returnSync.getUsers()) + for (Chat chat : getChats()) + if (user.getID() == chat.getRecipient().getID()) { + chat.getRecipient().setStatus(user.getStatus()); + logger.info(chat.getRecipient().getStatus().toString()); + } + + sync.getMessages().clear(); + sync.getUsers().clear(); + } + + /** + * Adds the unread messages returned from the server in the latest sync to the + * right chats in the LocalDB. + * + * @since Envoy v0.1-alpha + */ + public void addUnreadMessagesToLocalDB() { + for (Message message : unreadMessagesSync.getMessages()) + for (Chat chat : getChats()) + if (message.getMetadata().getSender() == chat.getRecipient().getID()) { + chat.appendMessage(message); + break; + } + } + + /** + * Changes all messages with state {@code RECEIVED} of a specific chat to state + * {@code READ}. + *
+ * Adds these messages to the {@code readMessages} {@link Sync} object. + * + * @param currentChat the {@link Chat} that was just opened + * @since Envoy v0.1-alpha + */ + public void setMessagesToRead(Chat currentChat) { + for (int i = currentChat.getModel().size() - 1; i >= 0; --i) + if (currentChat.getModel().get(i).getMetadata().getRecipient() != currentChat.getRecipient().getID()) + if (currentChat.getModel().get(i).getMetadata().getState() == MessageState.RECEIVED) { + currentChat.getModel().get(i).getMetadata().setState(MessageState.READ); + readMessages.getMessages().add(currentChat.getModel().get(i)); + } else break; + } + + /** + * Adds all messages with state {@code WAITING} from the {@link LocalDB} to the + * {@link Sync} object. + * + * @since Envoy v0.1-alpha + */ + private void addWaitingMessagesToSync() { + for (Chat chat : getChats()) + for (int i = 0; i < chat.getModel().size(); i++) + if (chat.getModel().get(i).getMetadata().getState() == MessageState.WAITING) { + logger.info("Got Waiting Message"); + sync.getMessages().add(chat.getModel().get(i)); + } + } + + /** + * Clears the {@code unreadMessagesSync} {@link Sync} object. + * + * @since Envoy v0.1-alpha + */ + public void clearUnreadMessagesSync() { unreadMessagesSync.getMessages().clear(); } + + /** + * @return all saved {@link Chat} objects that list the client user as the + * sender + * @since Envoy v0.1-alpha + **/ + public List getChats() { return chats; } + + /** + * @return the {@link User} who initialized the local database + * @since Envoy v0.1-alpha + */ + public User getUser() { return sender; } +} diff --git a/src/main/java/envoy/client/ui/ChatWindow.java b/src/main/java/envoy/client/ui/ChatWindow.java index e6e6872..b43bb65 100644 --- a/src/main/java/envoy/client/ui/ChatWindow.java +++ b/src/main/java/envoy/client/ui/ChatWindow.java @@ -1,342 +1,349 @@ -package envoy.client.ui; - -import java.awt.Color; -import java.awt.ComponentOrientation; -import java.awt.Font; -import java.awt.GridBagConstraints; -import java.awt.GridBagLayout; -import java.awt.Insets; -import java.awt.event.KeyAdapter; -import java.awt.event.KeyEvent; -import java.awt.event.WindowAdapter; -import java.awt.event.WindowEvent; -import java.util.logging.Logger; - -import javax.swing.DefaultListModel; -import javax.swing.JButton; -import javax.swing.JFrame; -import javax.swing.JList; -import javax.swing.JOptionPane; -import javax.swing.JPanel; -import javax.swing.JScrollPane; -import javax.swing.JTextArea; -import javax.swing.JTextPane; -import javax.swing.ListSelectionModel; -import javax.swing.SwingUtilities; -import javax.swing.Timer; -import javax.swing.border.EmptyBorder; - -import envoy.client.Chat; -import envoy.client.Client; -import envoy.client.Config; -import envoy.client.LocalDB; -import envoy.schema.Message; -import envoy.schema.Sync; -import envoy.schema.User; - -/** - * Project: envoy-client
- * File: ChatWindow.java
- * Created: 28 Sep 2019
- * - * @author Kai S. K. Engelbart - * @author Maximilian Käfer - * @author Leon Hofmeister - * @since Envoy v0.1-alpha - */ -public class ChatWindow extends JFrame { - - private static final long serialVersionUID = 6865098428255463649L; - - private JPanel contentPane = new JPanel(); - - private Client client; - private LocalDB localDB; - - private JList userList = new JList<>(); - private Chat currentChat; - - private JTextArea messageEnterTextArea; - - private static final Logger logger = Logger.getLogger(ChatWindow.class.getSimpleName()); - - public ChatWindow(Client client, LocalDB localDB) { - this.client = client; - this.localDB = localDB; - - setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - setBounds(100, 100, 600, 800); - setTitle("Envoy"); - setLocationRelativeTo(null); - - // Save chats when window closes - addWindowListener(new WindowAdapter() { - - @Override - public void windowClosing(WindowEvent e) { localDB.saveToLocalDB(); } - }); - - contentPane.setBackground(new Color(0, 0, 0)); - contentPane.setForeground(Color.white); - contentPane.setBorder(new EmptyBorder(0, 5, 0, 0)); - setContentPane(contentPane); - GridBagLayout gbl_contentPane = new GridBagLayout(); - gbl_contentPane.columnWidths = new int[] { 1, 1, 1 }; - gbl_contentPane.rowHeights = new int[] { 1, 1, 1 }; - gbl_contentPane.columnWeights = new double[] { 0.3, 1.0, 0.1 }; - gbl_contentPane.rowWeights = new double[] { 0.05, 1.0, 0.07 }; - contentPane.setLayout(gbl_contentPane); - - JList messageList = new JList<>(); - messageList.setCellRenderer(new MessageListRenderer()); - - messageList.setFocusTraversalKeysEnabled(false); - messageList.setSelectionForeground(new Color(255, 255, 255)); - messageList.setSelectionBackground(new Color(102, 0, 153)); - messageList.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT); - messageList.setForeground(new Color(255, 255, 255)); - messageList.setBackground(new Color(51, 51, 51)); - - DefaultListModel messageListModel = new DefaultListModel<>(); - messageList.setModel(messageListModel); - messageList.setFont(new Font("Arial", Font.PLAIN, 17)); - messageList.setFixedCellHeight(60); - messageList.setBorder(new EmptyBorder(5, 5, 5, 5)); - - JScrollPane scrollPane = new JScrollPane(); - scrollPane.setForeground(new Color(0, 0, 0)); - scrollPane.setBackground(new Color(51, 51, 51)); - scrollPane.setViewportView(messageList); - scrollPane.setBorder(null); - - GridBagConstraints gbc_scrollPane = new GridBagConstraints(); - gbc_scrollPane.fill = GridBagConstraints.BOTH; - gbc_scrollPane.gridwidth = 2; - gbc_scrollPane.gridx = 1; - gbc_scrollPane.gridy = 1; - - gbc_scrollPane.insets = new Insets(0, 10, 10, 10); - - contentPane.add(scrollPane, gbc_scrollPane); - - // Message enter field - messageEnterTextArea = new JTextArea(); - messageEnterTextArea.addKeyListener(new KeyAdapter() { - - @Override - public void keyReleased(KeyEvent e) { - if (e.getKeyCode() == KeyEvent.VK_ENTER - && ((SettingsScreen.enterToSend && e.getModifiersEx() == 0) || (e.getModifiersEx() == KeyEvent.CTRL_DOWN_MASK))) { - - postMessage(messageList); - } - } - }); - // Checks for changed Message - messageEnterTextArea.setWrapStyleWord(true); - messageEnterTextArea.setCaretColor(new Color(255, 255, 255)); - messageEnterTextArea.setForeground(new Color(255, 255, 255)); - messageEnterTextArea.setBackground(new Color(51, 51, 51)); - messageEnterTextArea.setLineWrap(true); - messageEnterTextArea.setBorder(null); - messageEnterTextArea.setFont(new Font("Arial", Font.PLAIN, 17)); - messageEnterTextArea.setBorder(new EmptyBorder(5, 5, 5, 5)); - - GridBagConstraints gbc_messageEnterTextfield = new GridBagConstraints(); - gbc_messageEnterTextfield.fill = GridBagConstraints.BOTH; - gbc_messageEnterTextfield.gridx = 1; - gbc_messageEnterTextfield.gridy = 2; - - gbc_messageEnterTextfield.insets = new Insets(10, 10, 10, 10); - - contentPane.add(messageEnterTextArea, gbc_messageEnterTextfield); - - // Post Button - JButton postButton = new JButton("Post"); - postButton.setForeground(new Color(255, 255, 255)); - postButton.setBackground(new Color(102, 51, 153)); - postButton.setBorderPainted(false); - - GridBagConstraints gbc_moveSelectionPostButton = new GridBagConstraints(); - - gbc_moveSelectionPostButton.fill = GridBagConstraints.BOTH; - gbc_moveSelectionPostButton.gridx = 2; - gbc_moveSelectionPostButton.gridy = 2; - - gbc_moveSelectionPostButton.insets = new Insets(10, 10, 10, 10); - - postButton.addActionListener((evt) -> { postMessage(messageList); }); - contentPane.add(postButton, gbc_moveSelectionPostButton); - - // Settings Button - JButton settingsButton = new JButton("Settings"); - settingsButton.setForeground(new Color(255, 255, 255)); - settingsButton.setBackground(new Color(102, 51, 153)); - settingsButton.setBorderPainted(false); - - GridBagConstraints gbc_moveSelectionSettingsButton = new GridBagConstraints(); - - gbc_moveSelectionSettingsButton.fill = GridBagConstraints.BOTH; - gbc_moveSelectionSettingsButton.gridx = 2; - gbc_moveSelectionSettingsButton.gridy = 0; - - gbc_moveSelectionSettingsButton.insets = new Insets(10, 10, 10, 10); - - settingsButton.addActionListener((evt) -> { - try { - SettingsScreen.open(localDB.getUser().getName()); - } catch (Exception e) { - SettingsScreen.open(); - logger.warning("An error occured while opening the settings screen: " + e); - e.printStackTrace(); - } - }); - contentPane.add(settingsButton, gbc_moveSelectionSettingsButton); - - // Partner name display - JTextPane textPane = new JTextPane(); - textPane.setBackground(new Color(0, 0, 0)); - textPane.setForeground(new Color(255, 255, 255)); - - textPane.setFont(new Font("Arial", Font.PLAIN, 20)); - - GridBagConstraints gbc_partnerName = new GridBagConstraints(); - gbc_partnerName.fill = GridBagConstraints.HORIZONTAL; - gbc_partnerName.gridx = 1; - gbc_partnerName.gridy = 0; - - gbc_partnerName.insets = new Insets(0, 10, 0, 10); - contentPane.add(textPane, gbc_partnerName); - - userList.setCellRenderer(new UserListRenderer()); - userList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); - userList.addListSelectionListener((listSelectionEvent) -> { - if (!listSelectionEvent.getValueIsAdjusting()) { - @SuppressWarnings("unchecked") - final JList selectedUserList = (JList) listSelectionEvent.getSource(); - final User user = selectedUserList.getSelectedValue(); - client.setRecipient(user); - - currentChat = localDB.getChats().stream().filter(chat -> chat.getRecipient().getID() == user.getID()).findFirst().get(); - - // Set all unread messages in the chat to read - readCurrentChat(); - - client.setRecipient(user); - - textPane.setText(currentChat.getRecipient().getName()); - - messageList.setModel(currentChat.getModel()); - contentPane.revalidate(); - } - }); - - userList.setSelectionForeground(new Color(255, 255, 255)); - userList.setSelectionBackground(new Color(102, 0, 153)); - userList.setForeground(new Color(255, 255, 255)); - userList.setBackground(new Color(51, 51, 51)); - userList.setFont(new Font("Arial", Font.PLAIN, 17)); - userList.setBorder(new EmptyBorder(5, 5, 5, 5)); - - GridBagConstraints gbc_userList = new GridBagConstraints(); - gbc_userList.fill = GridBagConstraints.VERTICAL; - gbc_userList.gridx = 0; - gbc_userList.gridy = 1; - gbc_userList.anchor = GridBagConstraints.PAGE_START; - gbc_userList.insets = new Insets(0, 0, 10, 0); - - contentPane.add(userList, gbc_userList); - contentPane.revalidate(); - - loadUsersAndChats(); - startSyncThread(Config.getInstance().getSyncTimeout()); - - contentPane.revalidate(); - } - - private void postMessage(JList messageList) { - if (!client.hasRecipient()) { - JOptionPane.showMessageDialog(this, "Please select a recipient!", "Cannot send message", JOptionPane.INFORMATION_MESSAGE); - return; - } - - if (!messageEnterTextArea.getText().isEmpty()) try { - - // Create and send message object - final Message message = localDB.createMessage(messageEnterTextArea.getText(), currentChat.getRecipient()); - currentChat.appendMessage(message); - messageList.setModel(currentChat.getModel()); - - // Clear text field - messageEnterTextArea.setText(""); - contentPane.revalidate(); - } catch (Exception e) { - JOptionPane.showMessageDialog(this, - "An exception occured while sending a message. See the log for more details.", - "Exception occured", - JOptionPane.ERROR_MESSAGE); - e.printStackTrace(); - } - } - - /** - * Initializes the elements of the user list by downloading them from the - * server. - * - * @since Envoy v0.1-alpha - */ - private void loadUsersAndChats() { - new Thread(() -> { - Sync users = client.getUsersListXml(); - DefaultListModel userListModel = new DefaultListModel<>(); - users.getUsers().forEach(user -> { - userListModel.addElement(user); - - // Check if user exists in local DB - if (localDB.getChats().stream().filter(c -> c.getRecipient().getID() == user.getID()).count() == 0) - localDB.getChats().add(new Chat(user)); - }); - SwingUtilities.invokeLater(() -> userList.setModel(userListModel)); - }).start(); - } - - /** - * Updates the data model and the UI repeatedly after a certain amount of - * time. - * - * @param timeout the amount of time that passes between two requests sent to - * the server - * @since Envoy v0.1-alpha - */ - private void startSyncThread(int timeout) { - new Timer(timeout, (evt) -> { - new Thread(() -> { - - // Synchronize - localDB.applySync(client.sendSync(client.getSender().getID(), localDB.fillSync(client.getSender().getID()))); - - // Process unread messages - localDB.addUnreadMessagesToLocalDB(); - localDB.clearUnreadMessagesSync(); - - // Mark unread messages as read when they are in the current chat - readCurrentChat(); - - // Update UI - SwingUtilities.invokeLater(() -> { updateUserStates(); contentPane.revalidate(); contentPane.repaint(); }); - }).start(); - }).start(); - } - - private void updateUserStates() { - for (int i = 0; i < userList.getModel().getSize(); i++) - for (int j = 0; j < localDB.getChats().size(); j++) - if (userList.getModel().getElementAt(i).getID() == localDB.getChats().get(j).getRecipient().getID()) - userList.getModel().getElementAt(i).setStatus(localDB.getChats().get(j).getRecipient().getStatus()); - } - - /** - * Marks messages in the current chat as {@code READ}. - */ - private void readCurrentChat() { if (currentChat != null) { localDB.setMessagesToRead(currentChat); } } -} +package envoy.client.ui; + +import java.awt.Color; +import java.awt.ComponentOrientation; +import java.awt.Font; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.io.IOException; +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.swing.DefaultListModel; +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JList; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTextArea; +import javax.swing.JTextPane; +import javax.swing.ListSelectionModel; +import javax.swing.SwingUtilities; +import javax.swing.Timer; +import javax.swing.border.EmptyBorder; + +import envoy.client.Chat; +import envoy.client.Client; +import envoy.client.Config; +import envoy.client.LocalDB; +import envoy.schema.Message; +import envoy.schema.Sync; +import envoy.schema.User; + +/** + * Project: envoy-client
+ * File: ChatWindow.java
+ * Created: 28 Sep 2019
+ * + * @author Kai S. K. Engelbart + * @author Maximilian Käfer + * @author Leon Hofmeister + * @since Envoy v0.1-alpha + */ +public class ChatWindow extends JFrame { + + private static final long serialVersionUID = 6865098428255463649L; + + private JPanel contentPane = new JPanel(); + + private Client client; + private LocalDB localDB; + + private JList userList = new JList<>(); + private Chat currentChat; + + private JTextArea messageEnterTextArea; + + private static final Logger logger = Logger.getLogger(ChatWindow.class.getSimpleName()); + + public ChatWindow(Client client, LocalDB localDB) { + this.client = client; + this.localDB = localDB; + + setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + setBounds(100, 100, 600, 800); + setTitle("Envoy"); + setLocationRelativeTo(null); + + // Save chats when window closes + addWindowListener(new WindowAdapter() { + + @Override + public void windowClosing(WindowEvent evt) { + try { + localDB.saveToLocalDB(); + } catch (IOException e1) { + e1.printStackTrace(); + logger.log(Level.WARNING, "Unable to save the messages", e1); + } + } + }); + + contentPane.setBackground(new Color(0, 0, 0)); + contentPane.setForeground(Color.white); + contentPane.setBorder(new EmptyBorder(0, 5, 0, 0)); + setContentPane(contentPane); + GridBagLayout gbl_contentPane = new GridBagLayout(); + gbl_contentPane.columnWidths = new int[] { 1, 1, 1 }; + gbl_contentPane.rowHeights = new int[] { 1, 1, 1 }; + gbl_contentPane.columnWeights = new double[] { 0.3, 1.0, 0.1 }; + gbl_contentPane.rowWeights = new double[] { 0.05, 1.0, 0.07 }; + contentPane.setLayout(gbl_contentPane); + + JList messageList = new JList<>(); + messageList.setCellRenderer(new MessageListRenderer()); + + messageList.setFocusTraversalKeysEnabled(false); + messageList.setSelectionForeground(new Color(255, 255, 255)); + messageList.setSelectionBackground(new Color(102, 0, 153)); + messageList.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT); + messageList.setForeground(new Color(255, 255, 255)); + messageList.setBackground(new Color(51, 51, 51)); + + DefaultListModel messageListModel = new DefaultListModel<>(); + messageList.setModel(messageListModel); + messageList.setFont(new Font("Arial", Font.PLAIN, 17)); + messageList.setFixedCellHeight(60); + messageList.setBorder(new EmptyBorder(5, 5, 5, 5)); + + JScrollPane scrollPane = new JScrollPane(); + scrollPane.setForeground(new Color(0, 0, 0)); + scrollPane.setBackground(new Color(51, 51, 51)); + scrollPane.setViewportView(messageList); + scrollPane.setBorder(null); + + GridBagConstraints gbc_scrollPane = new GridBagConstraints(); + gbc_scrollPane.fill = GridBagConstraints.BOTH; + gbc_scrollPane.gridwidth = 2; + gbc_scrollPane.gridx = 1; + gbc_scrollPane.gridy = 1; + + gbc_scrollPane.insets = new Insets(0, 10, 10, 10); + + contentPane.add(scrollPane, gbc_scrollPane); + + // Message enter field + messageEnterTextArea = new JTextArea(); + messageEnterTextArea.addKeyListener(new KeyAdapter() { + + @Override + public void keyReleased(KeyEvent e) { + if (e.getKeyCode() == KeyEvent.VK_ENTER + && ((SettingsScreen.enterToSend && e.getModifiersEx() == 0) || (e.getModifiersEx() == KeyEvent.CTRL_DOWN_MASK))) + postMessage(messageList); + } + }); + // Checks for changed Message + messageEnterTextArea.setWrapStyleWord(true); + messageEnterTextArea.setCaretColor(new Color(255, 255, 255)); + messageEnterTextArea.setForeground(new Color(255, 255, 255)); + messageEnterTextArea.setBackground(new Color(51, 51, 51)); + messageEnterTextArea.setLineWrap(true); + messageEnterTextArea.setBorder(null); + messageEnterTextArea.setFont(new Font("Arial", Font.PLAIN, 17)); + messageEnterTextArea.setBorder(new EmptyBorder(5, 5, 5, 5)); + + GridBagConstraints gbc_messageEnterTextfield = new GridBagConstraints(); + gbc_messageEnterTextfield.fill = GridBagConstraints.BOTH; + gbc_messageEnterTextfield.gridx = 1; + gbc_messageEnterTextfield.gridy = 2; + + gbc_messageEnterTextfield.insets = new Insets(10, 10, 10, 10); + + contentPane.add(messageEnterTextArea, gbc_messageEnterTextfield); + + // Post Button + JButton postButton = new JButton("Post"); + postButton.setForeground(new Color(255, 255, 255)); + postButton.setBackground(new Color(102, 51, 153)); + postButton.setBorderPainted(false); + + GridBagConstraints gbc_moveSelectionPostButton = new GridBagConstraints(); + + gbc_moveSelectionPostButton.fill = GridBagConstraints.BOTH; + gbc_moveSelectionPostButton.gridx = 2; + gbc_moveSelectionPostButton.gridy = 2; + + gbc_moveSelectionPostButton.insets = new Insets(10, 10, 10, 10); + + postButton.addActionListener((evt) -> { postMessage(messageList); }); + contentPane.add(postButton, gbc_moveSelectionPostButton); + + // Settings Button + JButton settingsButton = new JButton("Settings"); + settingsButton.setForeground(new Color(255, 255, 255)); + settingsButton.setBackground(new Color(102, 51, 153)); + settingsButton.setBorderPainted(false); + + GridBagConstraints gbc_moveSelectionSettingsButton = new GridBagConstraints(); + + gbc_moveSelectionSettingsButton.fill = GridBagConstraints.BOTH; + gbc_moveSelectionSettingsButton.gridx = 2; + gbc_moveSelectionSettingsButton.gridy = 0; + + gbc_moveSelectionSettingsButton.insets = new Insets(10, 10, 10, 10); + + settingsButton.addActionListener((evt) -> { + try { + SettingsScreen.open(localDB.getUser().getName()); + } catch (Exception e) { + SettingsScreen.open(); + logger.log(Level.WARNING, "An error occured while opening the settings screen", e); + e.printStackTrace(); + } + }); + contentPane.add(settingsButton, gbc_moveSelectionSettingsButton); + + // Partner name display + JTextPane textPane = new JTextPane(); + textPane.setBackground(new Color(0, 0, 0)); + textPane.setForeground(new Color(255, 255, 255)); + + textPane.setFont(new Font("Arial", Font.PLAIN, 20)); + + GridBagConstraints gbc_partnerName = new GridBagConstraints(); + gbc_partnerName.fill = GridBagConstraints.HORIZONTAL; + gbc_partnerName.gridx = 1; + gbc_partnerName.gridy = 0; + + gbc_partnerName.insets = new Insets(0, 10, 0, 10); + contentPane.add(textPane, gbc_partnerName); + + userList.setCellRenderer(new UserListRenderer()); + userList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + userList.addListSelectionListener((listSelectionEvent) -> { + if (!listSelectionEvent.getValueIsAdjusting()) { + @SuppressWarnings("unchecked") + final JList selectedUserList = (JList) listSelectionEvent.getSource(); + final User user = selectedUserList.getSelectedValue(); + client.setRecipient(user); + + currentChat = localDB.getChats().stream().filter(chat -> chat.getRecipient().getID() == user.getID()).findFirst().get(); + + // Set all unread messages in the chat to read + readCurrentChat(); + + client.setRecipient(user); + + textPane.setText(currentChat.getRecipient().getName()); + + messageList.setModel(currentChat.getModel()); + contentPane.revalidate(); + } + }); + + userList.setSelectionForeground(new Color(255, 255, 255)); + userList.setSelectionBackground(new Color(102, 0, 153)); + userList.setForeground(new Color(255, 255, 255)); + userList.setBackground(new Color(51, 51, 51)); + userList.setFont(new Font("Arial", Font.PLAIN, 17)); + userList.setBorder(new EmptyBorder(5, 5, 5, 5)); + + GridBagConstraints gbc_userList = new GridBagConstraints(); + gbc_userList.fill = GridBagConstraints.VERTICAL; + gbc_userList.gridx = 0; + gbc_userList.gridy = 1; + gbc_userList.anchor = GridBagConstraints.PAGE_START; + gbc_userList.insets = new Insets(0, 0, 10, 0); + + contentPane.add(userList, gbc_userList); + contentPane.revalidate(); + + loadUsersAndChats(); + startSyncThread(Config.getInstance().getSyncTimeout()); + + contentPane.revalidate(); + } + + private void postMessage(JList messageList) { + if (!client.hasRecipient()) { + JOptionPane.showMessageDialog(this, "Please select a recipient!", "Cannot send message", JOptionPane.INFORMATION_MESSAGE); + return; + } + + if (!messageEnterTextArea.getText().isEmpty()) try { + + // Create and send message object + final Message message = localDB.createMessage(messageEnterTextArea.getText(), currentChat.getRecipient()); + currentChat.appendMessage(message); + messageList.setModel(currentChat.getModel()); + + // Clear text field + messageEnterTextArea.setText(""); + contentPane.revalidate(); + } catch (Exception e) { + JOptionPane.showMessageDialog(this, + "An exception occured while sending a message. See the log for more details.", + "Exception occured", + JOptionPane.ERROR_MESSAGE); + e.printStackTrace(); + } + } + + /** + * Initializes the elements of the user list by downloading them from the + * server. + * + * @since Envoy v0.1-alpha + */ + private void loadUsersAndChats() { + new Thread(() -> { + Sync users = client.getUsersListXml(); + DefaultListModel userListModel = new DefaultListModel<>(); + users.getUsers().forEach(user -> { + userListModel.addElement(user); + + // Check if user exists in local DB + if (localDB.getChats().stream().filter(c -> c.getRecipient().getID() == user.getID()).count() == 0) + localDB.getChats().add(new Chat(user)); + }); + SwingUtilities.invokeLater(() -> userList.setModel(userListModel)); + }).start(); + } + + /** + * Updates the data model and the UI repeatedly after a certain amount of + * time. + * + * @param timeout the amount of time that passes between two requests sent to + * the server + * @since Envoy v0.1-alpha + */ + private void startSyncThread(int timeout) { + new Timer(timeout, (evt) -> { + new Thread(() -> { + + // Synchronize + localDB.applySync(client.sendSync(client.getSender().getID(), localDB.fillSync(client.getSender().getID()))); + + // Process unread messages + localDB.addUnreadMessagesToLocalDB(); + localDB.clearUnreadMessagesSync(); + + // Mark unread messages as read when they are in the current chat + readCurrentChat(); + + // Update UI + SwingUtilities.invokeLater(() -> { updateUserStates(); contentPane.revalidate(); contentPane.repaint(); }); + }).start(); + }).start(); + } + + private void updateUserStates() { + for (int i = 0; i < userList.getModel().getSize(); i++) + for (int j = 0; j < localDB.getChats().size(); j++) + if (userList.getModel().getElementAt(i).getID() == localDB.getChats().get(j).getRecipient().getID()) + userList.getModel().getElementAt(i).setStatus(localDB.getChats().get(j).getRecipient().getStatus()); + } + + /** + * Marks messages in the current chat as {@code READ}. + */ + private void readCurrentChat() { if (currentChat != null) { localDB.setMessagesToRead(currentChat); } } +} diff --git a/src/main/java/envoy/client/ui/MessageListRenderer.java b/src/main/java/envoy/client/ui/MessageListRenderer.java index 9053c6c..3e6eb23 100644 --- a/src/main/java/envoy/client/ui/MessageListRenderer.java +++ b/src/main/java/envoy/client/ui/MessageListRenderer.java @@ -1,54 +1,49 @@ -package envoy.client.ui; - -import java.awt.Component; -import java.text.SimpleDateFormat; - -import javax.swing.JLabel; -import javax.swing.JList; -import javax.swing.ListCellRenderer; - -import envoy.schema.Message; - -/** - * Defines how a message is displayed.
- *
- * - * Project: envoy-client
- * File: UserListRenderer.java
- * Created: 19 Oct 2019
- * - * @author Kai S. K. Engelbart - * @author Maximilian Käfer - * @since Envoy v0.1-alpha - */ -public class MessageListRenderer extends JLabel implements ListCellRenderer { - - private static final long serialVersionUID = 5164417379767181198L; - - @Override - public Component getListCellRendererComponent(JList list, Message value, int index, - boolean isSelected, boolean cellHasFocus) { - if (isSelected) { - setBackground(list.getSelectionBackground()); - setForeground(list.getSelectionForeground()); - } else { - setBackground(list.getBackground()); - setForeground(list.getForeground()); - } - - setOpaque(true); - - final String text = value.getContent().get(0).getText(); - final String state = value.getMetadata().getState().toString(); - final String date = value.getMetadata().getDate() == null ? "" - : new SimpleDateFormat("dd.MM.yyyy HH:mm ") - .format(value.getMetadata().getDate().toGregorianCalendar().getTime()); - - setText(String.format( - "

%s

%s :%s", - date, - text, - state)); - return this; - } +package envoy.client.ui; + +import java.awt.Component; +import java.text.SimpleDateFormat; + +import javax.swing.JLabel; +import javax.swing.JList; +import javax.swing.ListCellRenderer; + +import envoy.schema.Message; + +/** + * Defines how a message is displayed.
+ *
+ * + * Project: envoy-client
+ * File: UserListRenderer.java
+ * Created: 19 Oct 2019
+ * + * @author Kai S. K. Engelbart + * @author Maximilian Käfer + * @since Envoy v0.1-alpha + */ +public class MessageListRenderer extends JLabel implements ListCellRenderer { + + private static final long serialVersionUID = 5164417379767181198L; + + @Override + public Component getListCellRendererComponent(JList list, Message value, int index, boolean isSelected, boolean cellHasFocus) { + if (isSelected) { + setBackground(list.getSelectionBackground()); + setForeground(list.getSelectionForeground()); + } else { + setBackground(list.getBackground()); + setForeground(list.getForeground()); + } + + setOpaque(true); + + final String text = value.getContent().get(0).getText(); + final String state = value.getMetadata().getState().toString(); + final String date = value.getMetadata().getDate() == null ? "" + : new SimpleDateFormat("dd.MM.yyyy HH:mm ").format(value.getMetadata().getDate().toGregorianCalendar().getTime()); + + setText(String + .format("

%s

%s :%s", date, text, state)); + return this; + } } \ No newline at end of file diff --git a/src/main/java/envoy/client/ui/SettingsScreen.java b/src/main/java/envoy/client/ui/SettingsScreen.java index 7d5de28..08aa9cb 100644 --- a/src/main/java/envoy/client/ui/SettingsScreen.java +++ b/src/main/java/envoy/client/ui/SettingsScreen.java @@ -41,7 +41,6 @@ public class SettingsScreen extends JDialog { * It personalises the screen more. * * @param username The name of the User - * @param Email The Email that is associated with that Account * @since Envoy v0.1-alpha */ public static void open(String username) {// , String Email) {AUSKLAMMERN, WENN ANMELDUNG PER @@ -101,7 +100,6 @@ public class SettingsScreen extends JDialog { * It personalises the screen more. * * @param Username The name of the User - * @param Email The Email that is associated with that Account * @since Envoy v0.1-alpha */ public SettingsScreen(String Username) {// , String Email, String hashedPwd) {AUSKLAMMERN, WENN ANMELDUNG PER EMAIL @@ -145,10 +143,10 @@ public class SettingsScreen extends JDialog { public static boolean isEnterToSend() { return enterToSend; } /** - * @param enterToSend
- * toggles whether a message should be sent via - *
- * buttonpress "enter" or "ctrl"+"enter" + * @param enterForSend
+ * toggles whether a message should be sent via + *
+ * buttonpress "enter" or "ctrl"+"enter" * @since Envoy v0.1-alpha */ public static void setEnterToSend(boolean enterForSend) { enterToSend = enterForSend; } diff --git a/src/main/java/envoy/client/ui/Startup.java b/src/main/java/envoy/client/ui/Startup.java index 473e912..f672f94 100644 --- a/src/main/java/envoy/client/ui/Startup.java +++ b/src/main/java/envoy/client/ui/Startup.java @@ -26,11 +26,11 @@ import envoy.exception.EnvoyException; */ public class Startup { - private static final Logger logger = Logger.getLogger(Client.class.getSimpleName()); - + private static final Logger logger = Logger.getLogger(Startup.class.getSimpleName()); + public static void main(String[] args) { logger.setLevel(Level.ALL); - + Config config = Config.getInstance(); // Load the configuration from client.properties first @@ -44,30 +44,29 @@ public class Startup { } // Override configuration values with command line arguments - if (args.length > 0) - config.load(args); + if (args.length > 0) config.load(args); if (!config.isInitialized()) { - logger.warning("Server or port are not defined. Exiting..."); - JOptionPane.showMessageDialog(null, "Error loading configuration values.", "Configuration error", - JOptionPane.ERROR_MESSAGE); + logger.severe("Server or port are not defined. Exiting..."); + JOptionPane.showMessageDialog(null, "Error loading configuration values.", "Configuration error", JOptionPane.ERROR_MESSAGE); System.exit(1); } String userName = JOptionPane.showInputDialog("Please enter your username"); if (userName == null || userName.isEmpty()) { - logger.warning("User name is not set or empty. Exiting..."); + logger.severe("User name is not set or empty. Exiting..."); System.exit(1); } - Client client = new Client(config, userName); - LocalDB localDB = new LocalDB(client.getSender()); + Client client = new Client(config, userName); + LocalDB localDB = new LocalDB(client.getSender()); try { localDB.initializeDBFile(config.getLocalDB()); } catch (EnvoyException e) { e.printStackTrace(); JOptionPane.showMessageDialog(null, "Error while loading local database: " + e.toString() + "\nChats will not be stored locally.", - "Local DB error", JOptionPane.WARNING_MESSAGE); + "Local DB error", + JOptionPane.WARNING_MESSAGE); } EventQueue.invokeLater(() -> { diff --git a/src/main/java/envoy/client/ui/UserListRenderer.java b/src/main/java/envoy/client/ui/UserListRenderer.java index 40bb2ad..e794b1f 100644 --- a/src/main/java/envoy/client/ui/UserListRenderer.java +++ b/src/main/java/envoy/client/ui/UserListRenderer.java @@ -1,65 +1,56 @@ -package envoy.client.ui; - -import java.awt.Component; - -import javax.swing.JLabel; -import javax.swing.JList; -import javax.swing.ListCellRenderer; - -import envoy.schema.User; -import envoy.schema.User.UserStatus; - -/** - * Defines how the {@code UserList} is displayed. - * - * Project: envoy-client
- * File: UserListRenderer.java
- * Created: 12 Oct 2019
- * - * @author Kai S. K. Engelbart - * @author Maximilian Käfer - * @since Envoy v0.1-alpha - */ -public class UserListRenderer extends JLabel implements ListCellRenderer { - - private static final long serialVersionUID = 5164417379767181198L; - - @Override - public Component getListCellRendererComponent(JList list, User value, int index, boolean isSelected, - boolean cellHasFocus) { - if (isSelected) { - setBackground(list.getSelectionBackground()); - setForeground(list.getSelectionForeground()); - } else { - setBackground(list.getBackground()); - setForeground(list.getForeground()); - } - - // Enable background rendering - setOpaque(true); - - - final String name = value.getName(); - final UserStatus status = value.getStatus(); - - switch (status) { - case ONLINE: - setText(String.format( - "

%s

%s", - status, - name)); - break; - - case OFFLINE: - setText(String.format( - "

%s

%s", - status, - name)); - break; - } - - - - return this; - } +package envoy.client.ui; + +import java.awt.Component; + +import javax.swing.JLabel; +import javax.swing.JList; +import javax.swing.ListCellRenderer; + +import envoy.schema.User; +import envoy.schema.User.UserStatus; + +/** + * Defines how the {@code UserList} is displayed. + * + * Project: envoy-client
+ * File: UserListRenderer.java
+ * Created: 12 Oct 2019
+ * + * @author Kai S. K. Engelbart + * @author Maximilian Käfer + * @since Envoy v0.1-alpha + */ +public class UserListRenderer extends JLabel implements ListCellRenderer { + + private static final long serialVersionUID = 5164417379767181198L; + + @SuppressWarnings("incomplete-switch") + @Override + public Component getListCellRendererComponent(JList list, User value, int index, boolean isSelected, boolean cellHasFocus) { + if (isSelected) { + setBackground(list.getSelectionBackground()); + setForeground(list.getSelectionForeground()); + } else { + setBackground(list.getBackground()); + setForeground(list.getForeground()); + } + + // Enable background rendering + setOpaque(true); + + final String name = value.getName(); + final UserStatus status = value.getStatus(); + + switch (status) { + case ONLINE: + setText(String + .format("

%s

%s", status, name)); + break; + case OFFLINE: + setText(String + .format("

%s

%s", status, name)); + break; + } + return this; + } } \ No newline at end of file