Implemented ComponentList rendering and integration of message list
This commit is contained in:
parent
0c1c3f6fce
commit
063f5798dc
@ -12,7 +12,6 @@ import javax.swing.border.EmptyBorder;
|
|||||||
import envoy.client.*;
|
import envoy.client.*;
|
||||||
import envoy.client.event.ThemeChangeEvent;
|
import envoy.client.event.ThemeChangeEvent;
|
||||||
import envoy.client.ui.list.ComponentList;
|
import envoy.client.ui.list.ComponentList;
|
||||||
import envoy.client.ui.list.ComponentListModel;
|
|
||||||
import envoy.client.ui.settings.SettingsScreen;
|
import envoy.client.ui.settings.SettingsScreen;
|
||||||
import envoy.client.util.EnvoyLog;
|
import envoy.client.util.EnvoyLog;
|
||||||
import envoy.data.Message;
|
import envoy.data.Message;
|
||||||
@ -32,27 +31,29 @@ import envoy.event.EventBus;
|
|||||||
*/
|
*/
|
||||||
public class ChatWindow extends JFrame {
|
public class ChatWindow extends JFrame {
|
||||||
|
|
||||||
private static final long serialVersionUID = 6865098428255463649L;
|
|
||||||
|
|
||||||
// User specific objects
|
// User specific objects
|
||||||
private Client client;
|
private Client client;
|
||||||
private LocalDB localDB;
|
private LocalDB localDB;
|
||||||
|
|
||||||
// GUI components
|
// GUI components
|
||||||
private JPanel contentPane = new JPanel();
|
private JPanel contentPane = new JPanel();
|
||||||
private PrimaryTextArea messageEnterTextArea = new PrimaryTextArea(space);
|
private PrimaryTextArea messageEnterTextArea = new PrimaryTextArea(space);
|
||||||
private JList<User> userList = new JList<>();
|
private JList<User> userList = new JList<>();
|
||||||
private Chat currentChat;
|
private Chat currentChat;
|
||||||
private ComponentList<Message> messageList;
|
private ComponentList<Message> messageList = new ComponentList<>(new MessageListRenderer());
|
||||||
private PrimaryScrollPane scrollPane = new PrimaryScrollPane();
|
private PrimaryScrollPane scrollPane = new PrimaryScrollPane();
|
||||||
private JTextPane textPane = new JTextPane();
|
private JTextPane textPane = new JTextPane();
|
||||||
private PrimaryButton postButton = new PrimaryButton("Post");
|
private PrimaryButton postButton = new PrimaryButton("Post");
|
||||||
private PrimaryButton settingsButton = new PrimaryButton("Settings");
|
private PrimaryButton settingsButton = new PrimaryButton("Settings");
|
||||||
|
|
||||||
private static int space = 4;
|
|
||||||
|
|
||||||
private static final Logger logger = EnvoyLog.getLogger(ChatWindow.class.getSimpleName());
|
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
|
* Initializes a {@link JFrame} with UI elements used to send and read messages
|
||||||
* to different users.
|
* to different users.
|
||||||
@ -75,7 +76,6 @@ public class ChatWindow extends JFrame {
|
|||||||
gbl_contentPane.rowWeights = new double[] { 0.05, 1.0, 0.07 };
|
gbl_contentPane.rowWeights = new double[] { 0.05, 1.0, 0.07 };
|
||||||
contentPane.setLayout(gbl_contentPane);
|
contentPane.setLayout(gbl_contentPane);
|
||||||
|
|
||||||
messageList = new ComponentList<>(new ComponentListModel<>(), new MessageListRenderer());
|
|
||||||
// TODO: messageList.setFocusTraversalKeysEnabled(false);
|
// TODO: messageList.setFocusTraversalKeysEnabled(false);
|
||||||
// messageList.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
|
// messageList.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
|
||||||
|
|
||||||
@ -91,7 +91,7 @@ public class ChatWindow extends JFrame {
|
|||||||
gbc_scrollPane.gridx = 1;
|
gbc_scrollPane.gridx = 1;
|
||||||
gbc_scrollPane.gridy = 1;
|
gbc_scrollPane.gridy = 1;
|
||||||
|
|
||||||
gbc_scrollPane.insets = new Insets(space, space, space, space);
|
gbc_scrollPane.insets = insets;
|
||||||
contentPane.add(scrollPane, gbc_scrollPane);
|
contentPane.add(scrollPane, gbc_scrollPane);
|
||||||
|
|
||||||
// Message enter field
|
// Message enter field
|
||||||
@ -100,7 +100,7 @@ public class ChatWindow extends JFrame {
|
|||||||
@Override
|
@Override
|
||||||
public void keyReleased(KeyEvent e) {
|
public void keyReleased(KeyEvent e) {
|
||||||
if (e.getKeyCode() == KeyEvent.VK_ENTER
|
if (e.getKeyCode() == KeyEvent.VK_ENTER
|
||||||
&& ((Settings.getInstance().isEnterToSend() && e.getModifiersEx() == 0) || (e.getModifiersEx() == KeyEvent.CTRL_DOWN_MASK)))
|
&& (Settings.getInstance().isEnterToSend() && e.getModifiersEx() == 0 || e.getModifiersEx() == KeyEvent.CTRL_DOWN_MASK))
|
||||||
postMessage();
|
postMessage();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -110,7 +110,7 @@ public class ChatWindow extends JFrame {
|
|||||||
gbc_messageEnterTextfield.gridx = 1;
|
gbc_messageEnterTextfield.gridx = 1;
|
||||||
gbc_messageEnterTextfield.gridy = 2;
|
gbc_messageEnterTextfield.gridy = 2;
|
||||||
|
|
||||||
gbc_messageEnterTextfield.insets = new Insets(space, space, space, space);
|
gbc_messageEnterTextfield.insets = insets;
|
||||||
|
|
||||||
contentPane.add(messageEnterTextArea, gbc_messageEnterTextfield);
|
contentPane.add(messageEnterTextArea, gbc_messageEnterTextfield);
|
||||||
|
|
||||||
@ -121,7 +121,7 @@ public class ChatWindow extends JFrame {
|
|||||||
gbc_moveSelectionPostButton.gridx = 2;
|
gbc_moveSelectionPostButton.gridx = 2;
|
||||||
gbc_moveSelectionPostButton.gridy = 2;
|
gbc_moveSelectionPostButton.gridy = 2;
|
||||||
|
|
||||||
gbc_moveSelectionPostButton.insets = new Insets(space, space, space, space);
|
gbc_moveSelectionPostButton.insets = insets;
|
||||||
|
|
||||||
postButton.addActionListener((evt) -> { postMessage(); });
|
postButton.addActionListener((evt) -> { postMessage(); });
|
||||||
contentPane.add(postButton, gbc_moveSelectionPostButton);
|
contentPane.add(postButton, gbc_moveSelectionPostButton);
|
||||||
@ -133,7 +133,7 @@ public class ChatWindow extends JFrame {
|
|||||||
gbc_moveSelectionSettingsButton.gridx = 2;
|
gbc_moveSelectionSettingsButton.gridx = 2;
|
||||||
gbc_moveSelectionSettingsButton.gridy = 0;
|
gbc_moveSelectionSettingsButton.gridy = 0;
|
||||||
|
|
||||||
gbc_moveSelectionSettingsButton.insets = new Insets(space, space, space, space);
|
gbc_moveSelectionSettingsButton.insets = insets;
|
||||||
|
|
||||||
settingsButton.addActionListener((evt) -> {
|
settingsButton.addActionListener((evt) -> {
|
||||||
try {
|
try {
|
||||||
@ -154,7 +154,7 @@ public class ChatWindow extends JFrame {
|
|||||||
gbc_partnerName.gridx = 1;
|
gbc_partnerName.gridx = 1;
|
||||||
gbc_partnerName.gridy = 0;
|
gbc_partnerName.gridy = 0;
|
||||||
|
|
||||||
gbc_partnerName.insets = new Insets(space, space, space, space);
|
gbc_partnerName.insets = insets;
|
||||||
contentPane.add(textPane, gbc_partnerName);
|
contentPane.add(textPane, gbc_partnerName);
|
||||||
|
|
||||||
userList.setCellRenderer(new UserListRenderer());
|
userList.setCellRenderer(new UserListRenderer());
|
||||||
@ -187,7 +187,7 @@ public class ChatWindow extends JFrame {
|
|||||||
gbc_userList.gridx = 0;
|
gbc_userList.gridx = 0;
|
||||||
gbc_userList.gridy = 1;
|
gbc_userList.gridy = 1;
|
||||||
gbc_userList.anchor = GridBagConstraints.PAGE_START;
|
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()));
|
applyTheme(Settings.getInstance().getThemes().get(Settings.getInstance().getCurrentTheme()));
|
||||||
|
|
||||||
@ -252,15 +252,18 @@ public class ChatWindow extends JFrame {
|
|||||||
.build();
|
.build();
|
||||||
|
|
||||||
// Send message
|
// Send message
|
||||||
|
// TODO: Store offline messages
|
||||||
client.sendMessage(message);
|
client.sendMessage(message);
|
||||||
|
|
||||||
// Add message to LocalDB and update UI
|
// Add message to LocalDB and update UI
|
||||||
currentChat.appendMessage(message);
|
currentChat.appendMessage(message);
|
||||||
messageList.setModel(currentChat.getModel());
|
// messageList.setModel(currentChat.getModel());
|
||||||
|
|
||||||
// Clear text field
|
// Clear text field
|
||||||
messageEnterTextArea.setText("");
|
messageEnterTextArea.setText("");
|
||||||
contentPane.revalidate();
|
|
||||||
|
revalidate();
|
||||||
|
repaint();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
JOptionPane.showMessageDialog(this,
|
JOptionPane.showMessageDialog(this,
|
||||||
"An exception occured while sending a message. See the log for more details.",
|
"An exception occured while sending a message. See the log for more details.",
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
package envoy.client.ui;
|
package envoy.client.ui;
|
||||||
|
|
||||||
import java.awt.Component;
|
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
|
|
||||||
|
import javax.swing.JComponent;
|
||||||
import javax.swing.JLabel;
|
import javax.swing.JLabel;
|
||||||
|
import javax.swing.border.EmptyBorder;
|
||||||
|
|
||||||
import envoy.client.Settings;
|
import envoy.client.Settings;
|
||||||
import envoy.client.ui.list.ComponentList;
|
import envoy.client.ui.list.ComponentList;
|
||||||
@ -21,23 +22,22 @@ import envoy.data.Message;
|
|||||||
* @author Maximilian Käfer
|
* @author Maximilian Käfer
|
||||||
* @since Envoy v0.1-alpha
|
* @since Envoy v0.1-alpha
|
||||||
*/
|
*/
|
||||||
public class MessageListRenderer extends JLabel implements ComponentListCellRenderer<Message> {
|
public class MessageListRenderer implements ComponentListCellRenderer<Message> {
|
||||||
|
|
||||||
private static final long serialVersionUID = 5164417379767181198L;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Component getListCellComponent(ComponentList<? extends Message> list, Message value, boolean isSelected) {
|
public JComponent getListCellComponent(ComponentList<? extends Message> list, Message value, boolean isSelected) {
|
||||||
|
final JLabel label = new JLabel();
|
||||||
if (isSelected) {
|
if (isSelected) {
|
||||||
setBackground(Color.DARK_GRAY);
|
label.setBackground(Color.DARK_GRAY);
|
||||||
setForeground(Color.RED);
|
label.setForeground(Color.RED);
|
||||||
// setBackground(list.getSelectionBackground());
|
// setBackground(list.getSelectionBackground());
|
||||||
// setForeground(list.getSelectionForeground());
|
// setForeground(list.getSelectionForeground());
|
||||||
} else {
|
} else {
|
||||||
setBackground(list.getBackground());
|
label.setBackground(list.getBackground());
|
||||||
setForeground(list.getForeground());
|
label.setForeground(list.getForeground());
|
||||||
}
|
}
|
||||||
|
|
||||||
setOpaque(true);
|
label.setOpaque(true);
|
||||||
|
|
||||||
// TODO: Handle message attachments
|
// TODO: Handle message attachments
|
||||||
|
|
||||||
@ -51,12 +51,16 @@ public class MessageListRenderer extends JLabel implements ComponentListCellRend
|
|||||||
// Getting the DateColor in the Chat of the current theme
|
// Getting the DateColor in the Chat of the current theme
|
||||||
String dateColor = Settings.getInstance().getThemes().get(Settings.getInstance().getCurrentTheme()).getDateColorChat().toHex();
|
String dateColor = Settings.getInstance().getThemes().get(Settings.getInstance().getCurrentTheme()).getDateColorChat().toHex();
|
||||||
|
|
||||||
setText(String.format("<html><p style=\"color:%s\"><b><small>%s</b></small><br><p style=\"color:%s\">%s :%s</html>",
|
label.setText(String.format("<html><p style=\"color:%s\"><b><small>%s</b></small><br><p style=\"color:%s\">%s :%s</html>",
|
||||||
dateColor,
|
dateColor,
|
||||||
date,
|
date,
|
||||||
textColor,
|
textColor,
|
||||||
text,
|
text,
|
||||||
state));
|
state));
|
||||||
return this;
|
|
||||||
|
// Define some space to the components above and below
|
||||||
|
label.setBorder(new EmptyBorder(0, 0, 15, 0));
|
||||||
|
|
||||||
|
return label;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -7,28 +7,34 @@ import javax.swing.JPanel;
|
|||||||
* Project: <strong>envoy-client</strong><br>
|
* Project: <strong>envoy-client</strong><br>
|
||||||
* File: <strong>ComponentList.java</strong><br>
|
* File: <strong>ComponentList.java</strong><br>
|
||||||
* Created: <strong>25.01.2020</strong><br>
|
* Created: <strong>25.01.2020</strong><br>
|
||||||
*
|
*
|
||||||
* @author Kai S. K. Engelbart
|
* @author Kai S. K. Engelbart
|
||||||
* @since Envoy v0.3-alpha
|
* @since Envoy v0.3-alpha
|
||||||
*/
|
*/
|
||||||
public class ComponentList<E> extends JPanel {
|
public class ComponentList<E> extends JPanel {
|
||||||
|
|
||||||
private ComponentListModel<E> model;
|
private ComponentListModel<E> model;
|
||||||
private ComponentListCellRenderer<E> renderer;
|
private ComponentListCellRenderer<E> renderer;
|
||||||
|
|
||||||
private static final long serialVersionUID = 1759644503942876737L;
|
private static final long serialVersionUID = 1759644503942876737L;
|
||||||
|
|
||||||
public ComponentList(ComponentListModel<E> model, ComponentListCellRenderer<E> renderer) {
|
public ComponentList(ComponentListCellRenderer<E> renderer) {
|
||||||
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
|
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
|
||||||
this.model = model;
|
this.renderer = renderer;
|
||||||
this.renderer = renderer;
|
}
|
||||||
|
|
||||||
|
public ComponentList(ComponentListModel<E> model, ComponentListCellRenderer<E> renderer) {
|
||||||
|
this(renderer);
|
||||||
|
this.model = model;
|
||||||
setModel(model);
|
setModel(model);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setModel(ComponentListModel<E> model) {
|
public void setModel(ComponentListModel<E> model) {
|
||||||
// Remove old model
|
// Remove old model
|
||||||
this.model.clear();
|
if (this.model != null) {
|
||||||
this.model.setComponentList(null);
|
this.model.clear();
|
||||||
|
this.model.setComponentList(null);
|
||||||
|
}
|
||||||
|
|
||||||
// Synchronize with new model
|
// Synchronize with new model
|
||||||
this.model = model;
|
this.model = model;
|
||||||
@ -40,9 +46,10 @@ public class ComponentList<E> extends JPanel {
|
|||||||
add(renderer.getListCellComponent(this, elem, false));
|
add(renderer.getListCellComponent(this, elem, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void synchronizeModel() {
|
void synchronizeModel() {
|
||||||
removeAll();
|
removeAll();
|
||||||
for (E elem : model)
|
if (model != null)
|
||||||
add(renderer.getListCellComponent(this, elem, false));
|
for (E elem : model)
|
||||||
|
add(renderer.getListCellComponent(this, elem, false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
package envoy.client.ui.list;
|
package envoy.client.ui.list;
|
||||||
|
|
||||||
import java.awt.Component;
|
import javax.swing.JComponent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Project: <strong>envoy-client</strong><br>
|
* Project: <strong>envoy-client</strong><br>
|
||||||
* File: <strong>ComponentListCellRenderer.java</strong><br>
|
* File: <strong>ComponentListCellRenderer.java</strong><br>
|
||||||
* Created: <strong>25.01.2020</strong><br>
|
* Created: <strong>25.01.2020</strong><br>
|
||||||
*
|
*
|
||||||
* @author Kai S. K. Engelbart
|
* @author Kai S. K. Engelbart
|
||||||
* @since Envoy v0.3-alpha
|
* @since Envoy v0.3-alpha
|
||||||
*/
|
*/
|
||||||
public interface ComponentListCellRenderer<E> {
|
public interface ComponentListCellRenderer<E> {
|
||||||
|
|
||||||
Component getListCellComponent(ComponentList<? extends E> list, E value, boolean isSelected);
|
JComponent getListCellComponent(ComponentList<? extends E> list, E value, boolean isSelected);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package envoy.client.ui.list;
|
package envoy.client.ui.list;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -8,19 +9,21 @@ import java.util.List;
|
|||||||
* Project: <strong>envoy-client</strong><br>
|
* Project: <strong>envoy-client</strong><br>
|
||||||
* File: <strong>ComponentListModel.java</strong><br>
|
* File: <strong>ComponentListModel.java</strong><br>
|
||||||
* Created: <strong>25.01.2020</strong><br>
|
* Created: <strong>25.01.2020</strong><br>
|
||||||
*
|
*
|
||||||
* @author Kai S. K. Engelbart
|
* @author Kai S. K. Engelbart
|
||||||
* @since Envoy v0.3-alpha
|
* @since Envoy v0.3-alpha
|
||||||
*/
|
*/
|
||||||
public final class ComponentListModel<E> implements Iterable<E> {
|
public final class ComponentListModel<E> implements Iterable<E>, Serializable {
|
||||||
|
|
||||||
private List<E> elements = new ArrayList<>();
|
private List<E> elements = new ArrayList<>();
|
||||||
private ComponentList<E> componentList;
|
transient private ComponentList<E> componentList;
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 4815005915255497331L;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds an element to this model and notifies the associated
|
* Adds an element to this model and notifies the associated
|
||||||
* {@link ComponentList} to add the corresponding component.
|
* {@link ComponentList} to add the corresponding component.
|
||||||
*
|
*
|
||||||
* @param e the element to add
|
* @param e the element to add
|
||||||
* @return {@code true}
|
* @return {@code true}
|
||||||
* @see java.util.List#add(java.lang.Object)
|
* @see java.util.List#add(java.lang.Object)
|
||||||
@ -33,7 +36,7 @@ public final class ComponentListModel<E> implements Iterable<E> {
|
|||||||
/**
|
/**
|
||||||
* Removes all elements from this model and clears the associated
|
* Removes all elements from this model and clears the associated
|
||||||
* {@link ComponentList}.
|
* {@link ComponentList}.
|
||||||
*
|
*
|
||||||
* @see java.util.List#clear()
|
* @see java.util.List#clear()
|
||||||
* @since Envoy v0.3-alpha
|
* @since Envoy v0.3-alpha
|
||||||
*/
|
*/
|
||||||
@ -52,7 +55,7 @@ public final class ComponentListModel<E> implements Iterable<E> {
|
|||||||
/**
|
/**
|
||||||
* Removes the element at a specific index from this model and the corresponding
|
* Removes the element at a specific index from this model and the corresponding
|
||||||
* component from the {@link ComponentList}.
|
* component from the {@link ComponentList}.
|
||||||
*
|
*
|
||||||
* @param index
|
* @param index
|
||||||
* @return the removed element
|
* @return the removed element
|
||||||
* @see java.util.List#remove(int)
|
* @see java.util.List#remove(int)
|
||||||
@ -66,6 +69,7 @@ public final class ComponentListModel<E> implements Iterable<E> {
|
|||||||
* @return
|
* @return
|
||||||
* @see java.util.List#iterator()
|
* @see java.util.List#iterator()
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public Iterator<E> iterator() {
|
public Iterator<E> iterator() {
|
||||||
return new Iterator<E>() {
|
return new Iterator<E>() {
|
||||||
|
|
||||||
@ -81,6 +85,6 @@ public final class ComponentListModel<E> implements Iterable<E> {
|
|||||||
|
|
||||||
void setComponentList(ComponentList<E> componentList) {
|
void setComponentList(ComponentList<E> componentList) {
|
||||||
this.componentList = componentList;
|
this.componentList = componentList;
|
||||||
if (componentList != null) elements.forEach(componentList::add);
|
if (componentList != null) componentList.synchronizeModel();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user