diff --git a/.classpath b/.classpath
index 1a0c560..a5d9509 100644
--- a/.classpath
+++ b/.classpath
@@ -28,11 +28,5 @@
-
-
-
-
-
-
diff --git a/pom.xml b/pom.xml
index 01fa149..0b5487d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -28,11 +28,16 @@
com.github.informatik-ag-ngl
envoy-common
- e5c67b8
+ develop-SNAPSHOT
envoy-client
+
+
+ src/main/resources
+
+
\ No newline at end of file
diff --git a/src/main/java/envoy/client/Chat.java b/src/main/java/envoy/client/Chat.java
index ef762c4..a00e46d 100644
--- a/src/main/java/envoy/client/Chat.java
+++ b/src/main/java/envoy/client/Chat.java
@@ -2,9 +2,9 @@ package envoy.client;
import java.io.Serializable;
-import javax.swing.DefaultListModel;
-
+import envoy.client.ui.list.ComponentListModel;
import envoy.data.Message;
+import envoy.data.Message.MessageStatus;
import envoy.data.User;
/**
@@ -25,7 +25,7 @@ public class Chat implements Serializable {
private static final long serialVersionUID = -7751248474547242056L;
private User recipient;
- private DefaultListModel model = new DefaultListModel<>();
+ private ComponentListModel model = new ComponentListModel<>();
/**
* Provides the list of messages that the recipient receives.
@@ -37,22 +37,34 @@ public class Chat implements Serializable {
public Chat(User recipient) { this.recipient = recipient; }
/**
- * @return the recipient of a message
+ * Appends a message to the bottom of this chat
+ *
+ * @param message the message to append
* @since Envoy v0.1-alpha
*/
- public User getRecipient() { return recipient; }
+ public void appendMessage(Message message) { model.add(message); }
/**
- * Adds the received message at the current Point in the current chat
- *
- * @param message the message to add in said chat
- * @since Envoy v0.1-alpha
+ * Sets the status of all chat messages to {@code READ} starting from the bottom
+ * and stopping once a read message is found.
+ *
+ * @since Envoy v0.3-alpha
*/
- public void appendMessage(Message message) { model.addElement(message); }
+ public void read() {
+ for (int i = model.size() - 1; i >= 0; --i)
+ if (model.get(i).getStatus() == MessageStatus.READ) break;
+ else model.get(i).setStatus(MessageStatus.READ);
+ }
/**
* @return all messages in the current chat
* @since Envoy v0.1-alpha
*/
- public DefaultListModel getModel() { return model; }
+ public ComponentListModel getModel() { return model; }
+
+ /**
+ * @return the recipient of a message
+ * @since Envoy v0.1-alpha
+ */
+ public User getRecipient() { return recipient; }
}
\ No newline at end of file
diff --git a/src/main/java/envoy/client/Client.java b/src/main/java/envoy/client/Client.java
index 4885a92..935669f 100644
--- a/src/main/java/envoy/client/Client.java
+++ b/src/main/java/envoy/client/Client.java
@@ -11,6 +11,7 @@ import javax.naming.TimeLimitExceededException;
import envoy.client.util.EnvoyLog;
import envoy.data.*;
+import envoy.event.IdGeneratorRequest;
import envoy.util.SerializationUtils;
/**
@@ -45,11 +46,13 @@ public class Client implements Closeable {
* an exception is thrown.
*
* @param credentials the login credentials of the user
+ * @param localDB the local database used to persist the current
+ * {@link IdGenerator}
* @throws Exception if the online mode could not be entered or the request
* failed for some other reason
* @since Envoy v0.2-alpha
*/
- public void onlineInit(LoginCredentials credentials) throws Exception {
+ public void onlineInit(LoginCredentials credentials, LocalDB localDB) throws Exception {
// Establish TCP connection
logger.info(String.format("Attempting connection to server %s:%d...", config.getServer(), config.getPort()));
socket = new Socket(config.getServer(), config.getPort());
@@ -84,21 +87,38 @@ public class Client implements Closeable {
// Register processors for message and status handling
receiver.registerProcessor(Message.class, new ReceivedMessageProcessor());
+ // TODO: Status handling
+
+ // Process message ID generation
+ receiver.registerProcessor(IdGenerator.class, localDB::setIdGenerator);
+
+ // Request a generator if none is present
+ if (!localDB.hasIdGenerator() || !localDB.getIdGenerator().hasNext()) requestIdGenerator();
}
/**
* Sends a message to the server.
- *
+ *
* @param message the message to send
* @throws IOException if the message does not reach the server
* @since Envoy v0.3-alpha
*/
public void sendMessage(Message message) throws IOException {
- checkOnline();
- SerializationUtils.writeBytesWithLength(message, socket.getOutputStream());
+ writeObject(message);
message.nextStatus();
}
+ /**
+ * Requests a new {@link IdGenerator} from the server.
+ *
+ * @throws IOException if the request does not reach the server
+ * @since Envoy v0.3-alpha
+ */
+ public void requestIdGenerator() throws IOException {
+ logger.info("Requesting new id generator...");
+ writeObject(new IdGeneratorRequest());
+ }
+
/**
* @return a {@code Map} of all users on the server with their
* user names as keys
@@ -114,6 +134,11 @@ public class Client implements Closeable {
@Override
public void close() throws IOException { if (online) socket.close(); }
+ private void writeObject(Object obj) throws IOException {
+ checkOnline();
+ SerializationUtils.writeBytesWithLength(obj, socket.getOutputStream());
+ }
+
private void checkOnline() { if (!online) throw new IllegalStateException("Client is not online"); }
/**
diff --git a/src/main/java/envoy/client/Config.java b/src/main/java/envoy/client/Config.java
index 9a2c08b..fc93a08 100644
--- a/src/main/java/envoy/client/Config.java
+++ b/src/main/java/envoy/client/Config.java
@@ -31,7 +31,6 @@ public class Config {
items.put("server", new ConfigItem<>("server", "s", (input) -> input, null));
items.put("port", new ConfigItem<>("port", "p", (input) -> Integer.parseInt(input), null));
items.put("localDB", new ConfigItem<>("localDB", "db", (input) -> new File(input), new File("localDB")));
- items.put("syncTimeout", new ConfigItem<>("syncTimeout", "st", (input) -> Integer.parseInt(input), 1000));
items.put("homeDirectory",
new ConfigItem<>("homeDirectory", "h", (input) -> new File(input), new File(System.getProperty("user.home"), ".envoy")));
items.put("fileLevelBarrier", new ConfigItem<>("fileLevelBarrier", "fb", (input) -> Level.parse(input), Level.CONFIG));
@@ -112,7 +111,7 @@ public class Config {
* @return the port at which the Envoy server is located on the host
* @since Envoy v0.1-alpha
*/
- public int getPort() { return (int) items.get("port").get(); }
+ public Integer getPort() { return (Integer) items.get("port").get(); }
/**
* @return the local database specific to the client user
@@ -120,12 +119,6 @@ public class Config {
*/
public File getLocalDB() { return (File) items.get("localDB").get(); }
- /**
- * @return the current time (milliseconds) that is waited between Syncs
- * @since Envoy v0.1-alpha
- */
- public int getSyncTimeout() { return (int) items.get("syncTimeout").get(); }
-
/**
* @return the directory in which all local files are saves
* @since Envoy v0.2-alpha
diff --git a/src/main/java/envoy/client/LocalDB.java b/src/main/java/envoy/client/LocalDB.java
index 2c40e65..7511d41 100644
--- a/src/main/java/envoy/client/LocalDB.java
+++ b/src/main/java/envoy/client/LocalDB.java
@@ -4,10 +4,15 @@ import java.io.File;
import java.io.IOException;
import java.util.*;
+import envoy.data.IdGenerator;
import envoy.data.User;
import envoy.util.SerializationUtils;
/**
+ * Stored information about the current {@link User} and their {@link Chat}s.
+ * For message ID generation a {@link IdGenerator} is stored as well.
+ * These object are persisted inside a folder of the local file system.
+ *
* Project: envoy-client
* File: LocalDB.java
* Created: 27.10.2019
@@ -18,10 +23,11 @@ import envoy.util.SerializationUtils;
*/
public class LocalDB {
- private File localDBDir, localDBFile, usersFile;
+ private File localDBDir, localDBFile, usersFile, idGeneratorFile;
private User user;
private Map users = new HashMap<>();
private List chats = new ArrayList<>();
+ private IdGenerator idGenerator;
/**
* Constructs an empty local database. To serialize any chats to the file
@@ -37,7 +43,8 @@ public class LocalDB {
// Initialize local database directory
if (localDBDir.exists() && !localDBDir.isDirectory())
throw new IOException(String.format("LocalDBDir '%s' is not a directory!", localDBDir.getAbsolutePath()));
- usersFile = new File(localDBDir, "users.db");
+ usersFile = new File(localDBDir, "users.db");
+ idGeneratorFile = new File(localDBDir, "id_generator.db");
}
/**
@@ -53,7 +60,8 @@ public class LocalDB {
/**
* Stores all users to the local database. If the client user is specified, the
- * chats related to this user are stored as well.
+ * chats related to this user are stored as well. The message id generator will
+ * also be saved if present.
*
* @throws IOException if something went wrong during saving
* @since Envoy v0.1-alpha
@@ -63,12 +71,15 @@ public class LocalDB {
SerializationUtils.write(usersFile, users);
// Save chats
- SerializationUtils.write(localDBFile, chats);
+ if (user != null) SerializationUtils.write(localDBFile, chats);
+
+ // Save id generator
+ if (hasIdGenerator()) SerializationUtils.write(idGeneratorFile, idGenerator);
}
/**
* Loads all users that are stored in the local database.
- *
+ *
* @throws IOException if the loading process failed
* @throws ClassNotFoundException if the loading process failed
* @since Envoy v0.2-alpha
@@ -77,13 +88,25 @@ public class LocalDB {
/**
* Loads all chats saved by Envoy for the client user.
- *
+ *
* @throws IOException if the loading process failed
* @throws ClassNotFoundException if the loading process failed
* @since Envoy v0.1-alpha
*/
public void loadChats() throws ClassNotFoundException, IOException { chats = SerializationUtils.read(localDBFile, ArrayList.class); }
+ /**
+ * Loads the message ID generator that is stored in the local database. If the
+ * file is not found, the exception is ignored.
+ *
+ * @since Envoy v0.3-alpha
+ */
+ public void loadIdGenerator() {
+ try {
+ idGenerator = SerializationUtils.read(idGeneratorFile, IdGenerator.class);
+ } catch (ClassNotFoundException | IOException e) {}
+ }
+
/**
* @return a {@code Map} of all users stored locally with their
* user names as keys
@@ -119,4 +142,22 @@ public class LocalDB {
* @since Envoy v0.2-alpha
*/
public void setUser(User user) { this.user = user; }
+
+ /**
+ * @return the message ID generator
+ * @since Envoy v0.3-alpha
+ */
+ public IdGenerator getIdGenerator() { return idGenerator; }
+
+ /**
+ * @param idGenerator the message ID generator to set
+ * @since Envoy v0.3-alpha
+ */
+ public void setIdGenerator(IdGenerator idGenerator) { this.idGenerator = idGenerator; }
+
+ /**
+ * @return {@code true} if an {@link IdGenerator} is present
+ * @since Envoy v0.3-alpha
+ */
+ public boolean hasIdGenerator() { return idGenerator != null; }
}
\ No newline at end of file
diff --git a/src/main/java/envoy/client/Settings.java b/src/main/java/envoy/client/Settings.java
index ef451d0..02b6c88 100644
--- a/src/main/java/envoy/client/Settings.java
+++ b/src/main/java/envoy/client/Settings.java
@@ -135,7 +135,7 @@ public class Settings {
* {@code Control} key.
* @since Envoy v0.2-alpha
*/
- public boolean isEnterToSend() { return (boolean) items.get("enterToSend").get(); }
+ public Boolean isEnterToSend() { return (Boolean) items.get("enterToSend").get(); }
/**
* Changes the keystrokes performed by the user to send a message.
@@ -152,7 +152,7 @@ public class Settings {
* @return the current on close mode.
* @since Envoy v0.3-alpha
*/
- public boolean getCurrentOnCloseMode() { return (boolean) items.get("onCloseMode").get(); }
+ public Boolean getCurrentOnCloseMode() { return (Boolean) items.get("onCloseMode").get(); }
/**
* Sets the current on close mode.
diff --git a/src/main/java/envoy/client/ui/ChatWindow.java b/src/main/java/envoy/client/ui/ChatWindow.java
index 4f8b0dc..ab9e968 100644
--- a/src/main/java/envoy/client/ui/ChatWindow.java
+++ b/src/main/java/envoy/client/ui/ChatWindow.java
@@ -10,7 +10,9 @@ import javax.swing.*;
import javax.swing.border.EmptyBorder;
import envoy.client.*;
+import envoy.client.event.MessageCreationEvent;
import envoy.client.event.ThemeChangeEvent;
+import envoy.client.ui.list.ComponentList;
import envoy.client.ui.settings.SettingsScreen;
import envoy.client.util.EnvoyLog;
import envoy.data.Message;
@@ -30,27 +32,29 @@ import envoy.event.EventBus;
*/
public class ChatWindow extends JFrame {
- private static final long serialVersionUID = 6865098428255463649L;
-
// User specific objects
private Client client;
private LocalDB localDB;
// GUI components
- private JPanel contentPane = new JPanel();
- private PrimaryTextArea messageEnterTextArea = new PrimaryTextArea(space);
- private JList userList = new JList<>();
- private Chat currentChat;
- private JList messageList = new JList<>();
- private PrimaryScrollPane scrollPane = new PrimaryScrollPane();
- private JTextPane textPane = new JTextPane();
- private PrimaryButton postButton = new PrimaryButton("Post");
- private PrimaryButton settingsButton = new PrimaryButton("Settings");
-
- private static int space = 4;
+ private JPanel contentPane = new JPanel();
+ private PrimaryTextArea messageEnterTextArea = new PrimaryTextArea(space);
+ private JList userList = new JList<>();
+ private Chat currentChat;
+ private ComponentList messageList = new ComponentList<>(new MessageListRenderer());
+ private PrimaryScrollPane scrollPane = new PrimaryScrollPane();
+ private JTextPane textPane = new JTextPane();
+ private PrimaryButton postButton = new PrimaryButton("Post");
+ private PrimaryButton settingsButton = new PrimaryButton("Settings");
private static final Logger logger = EnvoyLog.getLogger(ChatWindow.class.getSimpleName());
+ // GUI component spacing
+ private final static int space = 4;
+ private static final Insets insets = new Insets(space, space, space, space);
+
+ private static final long serialVersionUID = 6865098428255463649L;
+
/**
* Initializes a {@link JFrame} with UI elements used to send and read messages
* to different users.
@@ -73,14 +77,11 @@ public class ChatWindow extends JFrame {
gbl_contentPane.rowWeights = new double[] { 0.05, 1.0, 0.07 };
contentPane.setLayout(gbl_contentPane);
- messageList.setCellRenderer(new MessageListRenderer());
- messageList.setFocusTraversalKeysEnabled(false);
- messageList.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
+ // TODO: messageList.setFocusTraversalKeysEnabled(false);
+ // messageList.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
- DefaultListModel messageListModel = new DefaultListModel<>();
- messageList.setModel(messageListModel);
- messageList.setFont(new Font("Arial", Font.PLAIN, 17));
- messageList.setFixedCellHeight(60);
+ // messageList.setFont(new Font("Arial", Font.PLAIN, 17));
+ // messageList.setFixedCellHeight(60);
messageList.setBorder(new EmptyBorder(space, space, space, space));
scrollPane.setViewportView(messageList);
@@ -91,7 +92,7 @@ public class ChatWindow extends JFrame {
gbc_scrollPane.gridx = 1;
gbc_scrollPane.gridy = 1;
- gbc_scrollPane.insets = new Insets(space, space, space, space);
+ gbc_scrollPane.insets = insets;
contentPane.add(scrollPane, gbc_scrollPane);
// Message enter field
@@ -100,8 +101,8 @@ public class ChatWindow extends JFrame {
@Override
public void keyReleased(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ENTER
- && ((Settings.getInstance().isEnterToSend() && e.getModifiersEx() == 0) || (e.getModifiersEx() == KeyEvent.CTRL_DOWN_MASK)))
- postMessage(messageList);
+ && (Settings.getInstance().isEnterToSend() && e.getModifiersEx() == 0 || e.getModifiersEx() == KeyEvent.CTRL_DOWN_MASK))
+ postMessage();
}
});
@@ -110,7 +111,7 @@ public class ChatWindow extends JFrame {
gbc_messageEnterTextfield.gridx = 1;
gbc_messageEnterTextfield.gridy = 2;
- gbc_messageEnterTextfield.insets = new Insets(space, space, space, space);
+ gbc_messageEnterTextfield.insets = insets;
contentPane.add(messageEnterTextArea, gbc_messageEnterTextfield);
@@ -121,9 +122,9 @@ public class ChatWindow extends JFrame {
gbc_moveSelectionPostButton.gridx = 2;
gbc_moveSelectionPostButton.gridy = 2;
- gbc_moveSelectionPostButton.insets = new Insets(space, space, space, space);
+ gbc_moveSelectionPostButton.insets = insets;
- postButton.addActionListener((evt) -> { postMessage(messageList); });
+ postButton.addActionListener((evt) -> { postMessage(); });
contentPane.add(postButton, gbc_moveSelectionPostButton);
// Settings Button
@@ -133,7 +134,7 @@ public class ChatWindow extends JFrame {
gbc_moveSelectionSettingsButton.gridx = 2;
gbc_moveSelectionSettingsButton.gridy = 0;
- gbc_moveSelectionSettingsButton.insets = new Insets(space, space, space, space);
+ gbc_moveSelectionSettingsButton.insets = insets;
settingsButton.addActionListener((evt) -> {
try {
@@ -154,7 +155,7 @@ public class ChatWindow extends JFrame {
gbc_partnerName.gridx = 1;
gbc_partnerName.gridy = 0;
- gbc_partnerName.insets = new Insets(space, space, space, space);
+ gbc_partnerName.insets = insets;
contentPane.add(textPane, gbc_partnerName);
userList.setCellRenderer(new UserListRenderer());
@@ -165,17 +166,22 @@ public class ChatWindow extends JFrame {
final JList selectedUserList = (JList) listSelectionEvent.getSource();
final User user = selectedUserList.getSelectedValue();
+ // Select current chat
currentChat = localDB.getChats().stream().filter(chat -> chat.getRecipient().getId() == user.getId()).findFirst().get();
- // Set all unread messages in the chat to read
- readCurrentChat();
+ // Read current Chat
+ currentChat.read();
+ // Set recipient in client and chat title
client.setRecipient(user);
textPane.setText(currentChat.getRecipient().getName());
+ // Update model and scroll down
messageList.setModel(currentChat.getModel());
scrollPane.setChatOpened(true);
- contentPane.revalidate();
+
+ revalidate();
+ repaint();
}
});
@@ -187,20 +193,29 @@ public class ChatWindow extends JFrame {
gbc_userList.gridx = 0;
gbc_userList.gridy = 1;
gbc_userList.anchor = GridBagConstraints.PAGE_START;
- gbc_userList.insets = new Insets(space, space, space, space);
+ gbc_userList.insets = insets;
applyTheme(Settings.getInstance().getThemes().get(Settings.getInstance().getCurrentTheme()));
contentPane.add(userList, gbc_userList);
contentPane.revalidate();
+ // Listen to theme changes
EventBus.getInstance().register(ThemeChangeEvent.class, (evt) -> applyTheme((Theme) evt.get()));
- contentPane.revalidate();
+ // Listen to received messages
+ EventBus.getInstance().register(MessageCreationEvent.class, (evt) -> {
+ Message message = ((MessageCreationEvent) evt).get();
+ localDB.getChats().stream().filter(c -> c.getRecipient().getId() == message.getSenderId()).findFirst().get().appendMessage(message);
+ revalidate();
+ repaint();
+ });
+
+ revalidate();
}
/**
- * Used to immediately reload the ChatWindow when settings were changed.
+ * Used to immediately reload the {@link ChatWindow} when settings were changed.
*
* @param theme the theme to change colors into
* @since Envoy v0.2-alpha
@@ -210,8 +225,8 @@ public class ChatWindow extends JFrame {
contentPane.setBackground(theme.getBackgroundColor());
contentPane.setForeground(theme.getUserNameColor());
// messageList
- messageList.setSelectionForeground(theme.getUserNameColor());
- messageList.setSelectionBackground(theme.getSelectionColor());
+ // messageList.setSelectionForeground(theme.getUserNameColor());
+ // messageList.setSelectionBackground(theme.getSelectionColor());
messageList.setForeground(theme.getMessageColorChat());
messageList.setBackground(theme.getCellColor());
// scrollPane
@@ -238,7 +253,7 @@ public class ChatWindow extends JFrame {
userList.setBackground(theme.getCellColor());
}
- private void postMessage(JList messageList) {
+ private void postMessage() {
if (!client.hasRecipient()) {
JOptionPane.showMessageDialog(this, "Please select a recipient!", "Cannot send message", JOptionPane.INFORMATION_MESSAGE);
return;
@@ -247,24 +262,32 @@ public class ChatWindow extends JFrame {
if (!messageEnterTextArea.getText().isEmpty()) try {
// Create message
- final Message message = new MessageBuilder(localDB.getUser().getId(), currentChat.getRecipient().getId())
+ final Message message = new MessageBuilder(localDB.getUser().getId(), currentChat.getRecipient().getId(), localDB.getIdGenerator())
.setText(messageEnterTextArea.getText())
.build();
// Send message
+ // TODO: Store offline messages
client.sendMessage(message);
// Add message to LocalDB and update UI
currentChat.appendMessage(message);
- messageList.setModel(currentChat.getModel());
+ // messageList.setModel(currentChat.getModel());
// Clear text field
messageEnterTextArea.setText("");
- contentPane.revalidate();
+
+ // Update UI
+ revalidate();
+ repaint();
+
+ // Request a new id generator if all ids were used
+ if (!localDB.getIdGenerator().hasNext()) client.requestIdGenerator();
+
} catch (Exception e) {
JOptionPane.showMessageDialog(this,
- "An exception occured while sending a message. See the log for more details.",
- "Exception occured",
+ "Error sending message:\n" + e.toString(),
+ "Message sending error",
JOptionPane.ERROR_MESSAGE);
e.printStackTrace();
}
@@ -291,64 +314,13 @@ public class ChatWindow extends JFrame {
}
/**
- * 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
- try {
- // localDB.applySync(client.sendSync(client.getSender().getId(),
- // localDB.fillSync(client.getSender().getId())));
- } catch (Exception e) {
- logger.log(Level.SEVERE, "Could not perform sync", e);
- }
-
- // TODO: 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) {
- // TODO: localDB.setMessagesToRead(currentChat);
- }
- }
-
- /**
- * Sets the {@link Client} used by this {@link ChatWindow}. If the client is
- * online, the sync thread is started.
+ * Sets the {@link Client} used by this {@link ChatWindow}.
*
* @param client the {@link Client} used to send and receive messages
* @since Envoy v0.2-alpha
*/
public void setClient(Client client) {
this.client = client;
- if (client.isOnline() && localDB != null) startSyncThread(Config.getInstance().getSyncTimeout());
}
/**
@@ -361,6 +333,5 @@ public class ChatWindow extends JFrame {
public void setLocalDB(LocalDB localDB) {
this.localDB = localDB;
loadUsersAndChats();
- if (client != null && client.isOnline()) startSyncThread(Config.getInstance().getSyncTimeout());
}
}
diff --git a/src/main/java/envoy/client/ui/MessageListRenderer.java b/src/main/java/envoy/client/ui/MessageListRenderer.java
index ed62854..c038e39 100644
--- a/src/main/java/envoy/client/ui/MessageListRenderer.java
+++ b/src/main/java/envoy/client/ui/MessageListRenderer.java
@@ -1,13 +1,13 @@
package envoy.client.ui;
-import java.awt.Component;
+import java.awt.Dimension;
import java.text.SimpleDateFormat;
-import javax.swing.JLabel;
-import javax.swing.JList;
-import javax.swing.ListCellRenderer;
+import javax.swing.*;
import envoy.client.Settings;
+import envoy.client.ui.list.ComponentList;
+import envoy.client.ui.list.ComponentListCellRenderer;
import envoy.data.Message;
/**
@@ -21,22 +21,22 @@ import envoy.data.Message;
* @author Maximilian Käfer
* @since Envoy v0.1-alpha
*/
-public class MessageListRenderer extends JLabel implements ListCellRenderer {
-
- private static final long serialVersionUID = 5164417379767181198L;
+public class MessageListRenderer implements ComponentListCellRenderer {
@Override
- public Component getListCellRendererComponent(JList extends Message> list, Message value, int index, boolean isSelected, boolean cellHasFocus) {
+ public JComponent getListCellComponent(ComponentList extends Message> list, Message value, boolean isSelected) {
+ final JPanel panel = new JPanel();
if (isSelected) {
- setBackground(list.getSelectionBackground());
- setForeground(list.getSelectionForeground());
+ panel.setBackground(Color.DARK_GRAY);
+ panel.setForeground(Color.RED);
+ // TODO: Selection
+ // setBackground(list.getSelectionBackground());
+ // setForeground(list.getSelectionForeground());
} else {
- setBackground(list.getBackground());
- setForeground(list.getForeground());
+ panel.setBackground(list.getBackground());
+ panel.setForeground(list.getForeground());
}
- setOpaque(true);
-
// TODO: Handle message attachments
final String text = value.getText();
@@ -49,12 +49,22 @@ public class MessageListRenderer extends JLabel implements ListCellRenderer%s
%s :%s