Merge pull request #120 from informatik-ag-ngl/f/enhanced_component_list
Revised the rendering and selection mechanism in ComponentList
This commit is contained in:
commit
4bdc4e0a16
@ -4,7 +4,7 @@ import java.io.IOException;
|
|||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
import envoy.client.net.WriteProxy;
|
import envoy.client.net.WriteProxy;
|
||||||
import envoy.client.ui.list.ComponentListModel;
|
import envoy.client.ui.list.Model;
|
||||||
import envoy.data.Message;
|
import envoy.data.Message;
|
||||||
import envoy.data.Message.MessageStatus;
|
import envoy.data.Message.MessageStatus;
|
||||||
import envoy.data.User;
|
import envoy.data.User;
|
||||||
@ -28,7 +28,7 @@ public class Chat implements Serializable {
|
|||||||
private static final long serialVersionUID = -7751248474547242056L;
|
private static final long serialVersionUID = -7751248474547242056L;
|
||||||
|
|
||||||
private final User recipient;
|
private final User recipient;
|
||||||
private final ComponentListModel<Message> model = new ComponentListModel<>();
|
private final Model<Message> model = new Model<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides the list of messages that the recipient receives.<br>
|
* Provides the list of messages that the recipient receives.<br>
|
||||||
@ -80,7 +80,7 @@ public class Chat implements Serializable {
|
|||||||
* @return all messages in the current chat
|
* @return all messages in the current chat
|
||||||
* @since Envoy v0.1-alpha
|
* @since Envoy v0.1-alpha
|
||||||
*/
|
*/
|
||||||
public ComponentListModel<Message> getModel() { return model; }
|
public Model<Message> getModel() { return model; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the recipient of a message
|
* @return the recipient of a message
|
||||||
|
@ -112,13 +112,19 @@ public class Settings {
|
|||||||
* @param theme the {@link Theme} to add
|
* @param theme the {@link Theme} to add
|
||||||
* @since Envoy v0.2-alpha
|
* @since Envoy v0.2-alpha
|
||||||
*/
|
*/
|
||||||
public void addNewThemeToMap(Theme theme) { settings.getThemes().put(theme.getThemeName(), theme); }
|
public void addNewThemeToMap(Theme theme) { getThemes().put(theme.getThemeName(), theme); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the name of the currently active {@link Theme}
|
* @return the name of the currently active {@link Theme}
|
||||||
* @since Envoy v0.2-alpha
|
* @since Envoy v0.2-alpha
|
||||||
*/
|
*/
|
||||||
public String getCurrentTheme() { return (String) items.get("currentTheme").get(); }
|
public String getCurrentThemeName() { return (String) items.get("currentTheme").get(); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the currently active {@link Theme}
|
||||||
|
* @since Envoy v0.1-beta
|
||||||
|
*/
|
||||||
|
public Theme getCurrentTheme() { return getTheme(getCurrentThemeName()); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the name of the current {@link Theme}.
|
* Sets the name of the current {@link Theme}.
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package envoy.client.ui.renderer;
|
package envoy.client.ui;
|
||||||
|
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
@ -8,45 +8,36 @@ import javax.swing.*;
|
|||||||
|
|
||||||
import envoy.client.data.Settings;
|
import envoy.client.data.Settings;
|
||||||
import envoy.client.event.SendEvent;
|
import envoy.client.event.SendEvent;
|
||||||
import envoy.client.ui.Color;
|
|
||||||
import envoy.client.ui.list.ComponentList;
|
import envoy.client.ui.list.ComponentList;
|
||||||
import envoy.client.ui.list.ComponentListCellRenderer;
|
|
||||||
import envoy.client.ui.primary.PrimaryButton;
|
import envoy.client.ui.primary.PrimaryButton;
|
||||||
import envoy.data.User;
|
import envoy.data.User;
|
||||||
import envoy.event.ContactOperationEvent;
|
import envoy.event.ContactOperationEvent;
|
||||||
import envoy.event.EventBus;
|
import envoy.event.EventBus;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines how a contact is displayed.<br>
|
* Project: <strong>envoy-client</strong>
|
||||||
* <br>
|
* File: <strong>ContactSearchComponent.java</strong>
|
||||||
* Project: <strong>envoy-client</strong><br>
|
* Created: <strong>21.03.2020</strong>
|
||||||
* File: <strong>ContactsSearchRenderer.java</strong><br>
|
|
||||||
* Created: <strong>08.02.2020</strong><br>
|
|
||||||
*
|
*
|
||||||
* @author Maximilian Käfer
|
|
||||||
* @author Kai S. K. Engelbart
|
* @author Kai S. K. Engelbart
|
||||||
* @since Envoy v0.3-alpha
|
* @since Envoy v0.1-beta
|
||||||
*/
|
*/
|
||||||
public class ContactsSearchRenderer implements ComponentListCellRenderer<User> {
|
public class ContactSearchComponent extends JComponent {
|
||||||
|
|
||||||
@Override
|
private static final long serialVersionUID = 3166795412575239455L;
|
||||||
public JComponent getListCellComponent(ComponentList<? extends User> list, User user, boolean isSelected) {
|
|
||||||
final JPanel panel = new JPanel();
|
public ContactSearchComponent(ComponentList<? extends User> list, User user) {
|
||||||
panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
|
setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
|
||||||
if (isSelected) {
|
|
||||||
panel.setBackground(Color.DARK_GRAY);
|
setBackground(list.getBackground());
|
||||||
panel.setForeground(Color.RED);
|
setForeground(list.getForeground());
|
||||||
} else {
|
|
||||||
panel.setBackground(list.getBackground());
|
|
||||||
panel.setForeground(list.getForeground());
|
|
||||||
}
|
|
||||||
|
|
||||||
JLabel display = new JLabel(user.getName());
|
JLabel display = new JLabel(user.getName());
|
||||||
display.setForeground(Settings.getInstance().getThemes().get(Settings.getInstance().getCurrentTheme()).getMessageTextColor());
|
display.setForeground(Settings.getInstance().getCurrentTheme().getMessageTextColor());
|
||||||
display.setAlignmentX(Component.LEFT_ALIGNMENT);
|
display.setAlignmentX(Component.LEFT_ALIGNMENT);
|
||||||
display.setAlignmentY(Component.CENTER_ALIGNMENT);
|
display.setAlignmentY(Component.CENTER_ALIGNMENT);
|
||||||
display.setFont(new Font("Arial", Font.PLAIN, 16));
|
display.setFont(new Font("Arial", Font.PLAIN, 16));
|
||||||
panel.add(display);
|
add(display);
|
||||||
|
|
||||||
PrimaryButton add = new PrimaryButton("+");
|
PrimaryButton add = new PrimaryButton("+");
|
||||||
add.setFont(new Font("Arial", Font.PLAIN, 19));
|
add.setFont(new Font("Arial", Font.PLAIN, 19));
|
||||||
@ -63,17 +54,15 @@ public class ContactsSearchRenderer implements ComponentListCellRenderer<User> {
|
|||||||
EventBus.getInstance().dispatch(new SendEvent(contactsOperationEvent));
|
EventBus.getInstance().dispatch(new SendEvent(contactsOperationEvent));
|
||||||
});
|
});
|
||||||
|
|
||||||
panel.add(add);
|
add(add);
|
||||||
|
|
||||||
// Define some space to the messages below
|
// Define some space to the messages below
|
||||||
panel.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(0, 0, 15, 0), BorderFactory.createEtchedBorder()));
|
setBorder(BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(0, 0, 15, 0), BorderFactory.createEtchedBorder()));
|
||||||
|
|
||||||
// Define a maximum height of 50px
|
// Define a maximum height of 50px
|
||||||
Dimension size = new Dimension(435, 50);
|
Dimension size = new Dimension(435, 50);
|
||||||
panel.setMaximumSize(size);
|
setMaximumSize(size);
|
||||||
panel.setMinimumSize(size);
|
setMinimumSize(size);
|
||||||
panel.setPreferredSize(size);
|
setPreferredSize(size);
|
||||||
|
|
||||||
return panel;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -50,7 +50,6 @@ public class ContextMenu extends JPopupMenu {
|
|||||||
|
|
||||||
private ButtonGroup radioButtonGroup = new ButtonGroup();
|
private ButtonGroup radioButtonGroup = new ButtonGroup();
|
||||||
private boolean built = false;
|
private boolean built = false;
|
||||||
private boolean visible = false;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param parent the component which will call this
|
* @param parent the component which will call this
|
||||||
@ -110,8 +109,10 @@ public class ContextMenu extends JPopupMenu {
|
|||||||
if (mnemonics.containsKey(text)) item.setMnemonic(mnemonics.get(text));
|
if (mnemonics.containsKey(text)) item.setMnemonic(mnemonics.get(text));
|
||||||
add(item);
|
add(item);
|
||||||
});
|
});
|
||||||
|
if (getInvoker() != null) {
|
||||||
getInvoker().addMouseListener(getShowingListener());
|
getInvoker().addMouseListener(getShowingListener());
|
||||||
built = true;
|
built = true;
|
||||||
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,10 +139,8 @@ public class ContextMenu extends JPopupMenu {
|
|||||||
if (!built) build();
|
if (!built) build();
|
||||||
if (e.isPopupTrigger()) {
|
if (e.isPopupTrigger()) {
|
||||||
// hides the menu if already visible
|
// hides the menu if already visible
|
||||||
visible = !visible;
|
if (!isVisible()) show(e.getComponent(), e.getX(), e.getY());
|
||||||
if (visible) show(e.getComponent(), e.getX(), e.getY());
|
|
||||||
else setVisible(false);
|
else setVisible(false);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package envoy.client.ui.renderer;
|
package envoy.client.ui;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -8,26 +8,21 @@ import java.util.EnumMap;
|
|||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
|
|
||||||
import envoy.client.data.Settings;
|
import envoy.client.data.Settings;
|
||||||
import envoy.client.ui.Color;
|
|
||||||
import envoy.client.ui.IconUtil;
|
|
||||||
import envoy.client.ui.list.ComponentList;
|
import envoy.client.ui.list.ComponentList;
|
||||||
import envoy.client.ui.list.ComponentListCellRenderer;
|
|
||||||
import envoy.data.Message;
|
import envoy.data.Message;
|
||||||
import envoy.data.Message.MessageStatus;
|
import envoy.data.Message.MessageStatus;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines how a message is displayed.<br>
|
* Project: <strong>envoy-client</strong>
|
||||||
* <br>
|
* File: <strong>MessageComponent.java</strong>
|
||||||
* Project: <strong>envoy-client</strong><br>
|
* Created: <strong>21.03.2020</strong>
|
||||||
* File: <strong>MessageListRenderer.java</strong><br>
|
|
||||||
* Created: <strong>19 Oct 2019</strong><br>
|
|
||||||
*
|
*
|
||||||
* @author Kai S. K. Engelbart
|
* @author Kai S. K. Engelbart
|
||||||
* @author Maximilian Käfer
|
* @since Envoy v0.1-beta
|
||||||
* @author Leon Hofmeister
|
|
||||||
* @since Envoy v0.1-alpha
|
|
||||||
*/
|
*/
|
||||||
public class MessageListRenderer implements ComponentListCellRenderer<Message> {
|
public class MessageComponent extends JPanel {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 103920706139926996L;
|
||||||
|
|
||||||
private static EnumMap<MessageStatus, ImageIcon> statusIcons;
|
private static EnumMap<MessageStatus, ImageIcon> statusIcons;
|
||||||
private static ImageIcon forwardIcon;
|
private static ImageIcon forwardIcon;
|
||||||
@ -41,27 +36,13 @@ public class MessageListRenderer implements ComponentListCellRenderer<Message> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final long senderId;
|
public MessageComponent(ComponentList<? extends Message> list, Message message, long senderId) {
|
||||||
|
this(list.getMaximumSize().width, message, senderId);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
public MessageComponent(int width, Message message, long senderId) {
|
||||||
* Initializes a message list renderer. Messages with the given sender ID will
|
final var theme = Settings.getInstance().getCurrentTheme();
|
||||||
* be aligned on the right side, while all other messages will be aligned on
|
final int padding = (int) (width * 0.35);
|
||||||
* the left side
|
|
||||||
*
|
|
||||||
* @param senderId the sender ID of the messages to align on the right side
|
|
||||||
* @since Envoy v0.1-beta
|
|
||||||
*/
|
|
||||||
public MessageListRenderer(long senderId) { this.senderId = senderId; }
|
|
||||||
|
|
||||||
// TODO: Handle message attachments
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JPanel getListCellComponent(ComponentList<? extends Message> list, Message message, boolean isSelected) {
|
|
||||||
final var theme = Settings.getInstance().getThemes().get(Settings.getInstance().getCurrentTheme());
|
|
||||||
|
|
||||||
// Panel
|
|
||||||
final var panel = new JPanel();
|
|
||||||
final int padding = (int) (list.getWidth() * 0.35);
|
|
||||||
|
|
||||||
GridBagLayout gbl_panel = new GridBagLayout();
|
GridBagLayout gbl_panel = new GridBagLayout();
|
||||||
gbl_panel.columnWidths = new int[] { 1, 1 };
|
gbl_panel.columnWidths = new int[] { 1, 1 };
|
||||||
@ -69,8 +50,8 @@ public class MessageListRenderer implements ComponentListCellRenderer<Message> {
|
|||||||
gbl_panel.columnWeights = new double[] { 1, 1 };
|
gbl_panel.columnWeights = new double[] { 1, 1 };
|
||||||
gbl_panel.rowWeights = new double[] { 1, 1 };
|
gbl_panel.rowWeights = new double[] { 1, 1 };
|
||||||
|
|
||||||
panel.setLayout(gbl_panel);
|
setLayout(gbl_panel);
|
||||||
panel.setBackground(isSelected ? theme.getSelectionColor() : theme.getCellColor());
|
setBackground(theme.getCellColor());
|
||||||
|
|
||||||
// Date Label - The Label that displays the creation date of a message
|
// Date Label - The Label that displays the creation date of a message
|
||||||
var dateLabel = new JLabel(new SimpleDateFormat("dd.MM.yyyy HH:mm").format(message.getCreationDate()));
|
var dateLabel = new JLabel(new SimpleDateFormat("dd.MM.yyyy HH:mm").format(message.getCreationDate()));
|
||||||
@ -83,7 +64,7 @@ public class MessageListRenderer implements ComponentListCellRenderer<Message> {
|
|||||||
gbc_dateLabel.fill = GridBagConstraints.BOTH;
|
gbc_dateLabel.fill = GridBagConstraints.BOTH;
|
||||||
gbc_dateLabel.gridx = 0;
|
gbc_dateLabel.gridx = 0;
|
||||||
gbc_dateLabel.gridy = 0;
|
gbc_dateLabel.gridy = 0;
|
||||||
panel.add(dateLabel, gbc_dateLabel);
|
add(dateLabel, gbc_dateLabel);
|
||||||
|
|
||||||
// Message area - The JTextArea that displays the text content of a message.
|
// Message area - The JTextArea that displays the text content of a message.
|
||||||
var messageTextArea = new JTextArea(message.getText());
|
var messageTextArea = new JTextArea(message.getText());
|
||||||
@ -95,13 +76,13 @@ public class MessageListRenderer implements ComponentListCellRenderer<Message> {
|
|||||||
messageTextArea.setEditable(false);
|
messageTextArea.setEditable(false);
|
||||||
var font = new Font("Arial", Font.PLAIN, 14);
|
var font = new Font("Arial", Font.PLAIN, 14);
|
||||||
messageTextArea.setFont(font);
|
messageTextArea.setFont(font);
|
||||||
messageTextArea.setSize(list.getMaximumSize().width - padding - 16, 10);
|
messageTextArea.setSize(width - padding - 16, 10);
|
||||||
|
|
||||||
var gbc_messageTextArea = new GridBagConstraints();
|
var gbc_messageTextArea = new GridBagConstraints();
|
||||||
gbc_messageTextArea.fill = GridBagConstraints.HORIZONTAL;
|
gbc_messageTextArea.fill = GridBagConstraints.HORIZONTAL;
|
||||||
gbc_messageTextArea.gridx = 0;
|
gbc_messageTextArea.gridx = 0;
|
||||||
gbc_messageTextArea.gridy = 1;
|
gbc_messageTextArea.gridy = 1;
|
||||||
panel.add(messageTextArea, gbc_messageTextArea);
|
add(messageTextArea, gbc_messageTextArea);
|
||||||
|
|
||||||
// Status Label - displays the status of the message
|
// Status Label - displays the status of the message
|
||||||
var statusLabel = new JLabel(statusIcons.get(message.getStatus()));
|
var statusLabel = new JLabel(statusIcons.get(message.getStatus()));
|
||||||
@ -109,32 +90,31 @@ public class MessageListRenderer implements ComponentListCellRenderer<Message> {
|
|||||||
var gbc_statusLabel = new GridBagConstraints();
|
var gbc_statusLabel = new GridBagConstraints();
|
||||||
gbc_statusLabel.gridx = 1;
|
gbc_statusLabel.gridx = 1;
|
||||||
gbc_statusLabel.gridy = 1;
|
gbc_statusLabel.gridy = 1;
|
||||||
panel.add(statusLabel, gbc_statusLabel);
|
add(statusLabel, gbc_statusLabel);
|
||||||
|
|
||||||
// Forwarding
|
// Forwarding
|
||||||
if (message.isForwarded()) {
|
if (message.isForwarded()) {
|
||||||
var forwardLabel = new JLabel("Forwarded", forwardIcon, SwingConstants.CENTER);
|
var forwardLabel = new JLabel("Forwarded", forwardIcon, SwingConstants.CENTER);
|
||||||
forwardLabel.setBackground(panel.getBackground());
|
forwardLabel.setBackground(getBackground());
|
||||||
forwardLabel.setForeground(Color.lightGray);
|
forwardLabel.setForeground(Color.lightGray);
|
||||||
|
|
||||||
var gbc_forwardLabel = new GridBagConstraints();
|
var gbc_forwardLabel = new GridBagConstraints();
|
||||||
gbc_forwardLabel.fill = GridBagConstraints.BOTH;
|
gbc_forwardLabel.fill = GridBagConstraints.BOTH;
|
||||||
gbc_forwardLabel.gridx = 1;
|
gbc_forwardLabel.gridx = 1;
|
||||||
gbc_forwardLabel.gridy = 0;
|
gbc_forwardLabel.gridy = 0;
|
||||||
panel.add(forwardLabel, gbc_forwardLabel);
|
add(forwardLabel, gbc_forwardLabel);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Define an etched border and some space to the messages below
|
// Define an etched border and some space to the messages below
|
||||||
var ours = senderId == message.getSenderId();
|
var ours = senderId == message.getSenderId();
|
||||||
panel.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(0, ours ? padding : 0, 10, ours ? 0 : padding),
|
setBorder(BorderFactory.createCompoundBorder(
|
||||||
|
BorderFactory.createEmptyBorder(0, ours ? padding : 10, 10, ours ? 0 : padding),
|
||||||
BorderFactory.createEtchedBorder()));
|
BorderFactory.createEtchedBorder()));
|
||||||
|
|
||||||
var size = new Dimension(list.getMaximumSize().width - 50, panel.getPreferredSize().height);
|
var size = new Dimension(width - 50, getPreferredSize().height);
|
||||||
|
|
||||||
panel.setPreferredSize(size);
|
setPreferredSize(size);
|
||||||
panel.setMinimumSize(size);
|
setMinimumSize(size);
|
||||||
panel.setMaximumSize(size);
|
setMaximumSize(size);
|
||||||
|
|
||||||
return panel;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
62
src/main/java/envoy/client/ui/UserComponent.java
Normal file
62
src/main/java/envoy/client/ui/UserComponent.java
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
package envoy.client.ui;
|
||||||
|
|
||||||
|
import java.awt.BorderLayout;
|
||||||
|
import java.awt.Dimension;
|
||||||
|
|
||||||
|
import javax.swing.JComponent;
|
||||||
|
import javax.swing.JLabel;
|
||||||
|
|
||||||
|
import envoy.client.data.Settings;
|
||||||
|
import envoy.client.ui.list.ComponentList;
|
||||||
|
import envoy.data.User;
|
||||||
|
import envoy.data.User.UserStatus;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Project: <strong>envoy-client</strong>
|
||||||
|
* File: <strong>UserComponent.java</strong>
|
||||||
|
* Created: <strong>21.03.2020</strong>
|
||||||
|
*
|
||||||
|
* @author Kai S. K. Engelbart
|
||||||
|
* @since Envoy v0.1-beta
|
||||||
|
*/
|
||||||
|
public class UserComponent extends JComponent {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 8450602172939729585L;
|
||||||
|
|
||||||
|
public UserComponent(ComponentList<? extends User> list, User user) {
|
||||||
|
final Theme theme = Settings.getInstance().getCurrentTheme();
|
||||||
|
|
||||||
|
setLayout(new BorderLayout());
|
||||||
|
|
||||||
|
// Panel background
|
||||||
|
setBackground(theme.getCellColor());
|
||||||
|
setOpaque(true);
|
||||||
|
setPreferredSize(new Dimension(100, 35));
|
||||||
|
|
||||||
|
// TODO add profile picture support in BorderLayout.West
|
||||||
|
|
||||||
|
JLabel username = new JLabel(user.getName());
|
||||||
|
username.setForeground(theme.getUserNameColor());
|
||||||
|
add(username, BorderLayout.CENTER);
|
||||||
|
|
||||||
|
final UserStatus status = user.getStatus();
|
||||||
|
JLabel statusLabel = new JLabel(status.toString());
|
||||||
|
Color foreground;
|
||||||
|
switch (status) {
|
||||||
|
case AWAY:
|
||||||
|
foreground = Color.yellow;
|
||||||
|
break;
|
||||||
|
case BUSY:
|
||||||
|
foreground = Color.blue;
|
||||||
|
break;
|
||||||
|
case ONLINE:
|
||||||
|
foreground = Color.green;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
foreground = Color.lightGray;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
statusLabel.setForeground(foreground);
|
||||||
|
add(statusLabel, BorderLayout.NORTH);
|
||||||
|
}
|
||||||
|
}
|
@ -22,16 +22,13 @@ import envoy.client.event.MessageCreationEvent;
|
|||||||
import envoy.client.event.ThemeChangeEvent;
|
import envoy.client.event.ThemeChangeEvent;
|
||||||
import envoy.client.net.Client;
|
import envoy.client.net.Client;
|
||||||
import envoy.client.net.WriteProxy;
|
import envoy.client.net.WriteProxy;
|
||||||
import envoy.client.ui.ContextMenu;
|
import envoy.client.ui.*;
|
||||||
import envoy.client.ui.Theme;
|
|
||||||
import envoy.client.ui.list.ComponentList;
|
import envoy.client.ui.list.ComponentList;
|
||||||
import envoy.client.ui.list.ComponentList.SelectionMode;
|
import envoy.client.ui.list.ComponentList.SelectionMode;
|
||||||
import envoy.client.ui.list.ComponentListModel;
|
import envoy.client.ui.list.Model;
|
||||||
import envoy.client.ui.primary.PrimaryButton;
|
import envoy.client.ui.primary.PrimaryButton;
|
||||||
import envoy.client.ui.primary.PrimaryScrollPane;
|
import envoy.client.ui.primary.PrimaryScrollPane;
|
||||||
import envoy.client.ui.primary.PrimaryTextArea;
|
import envoy.client.ui.primary.PrimaryTextArea;
|
||||||
import envoy.client.ui.renderer.ContactsSearchRenderer;
|
|
||||||
import envoy.client.ui.renderer.MessageListRenderer;
|
|
||||||
import envoy.client.ui.renderer.UserListRenderer;
|
import envoy.client.ui.renderer.UserListRenderer;
|
||||||
import envoy.client.ui.settings.SettingsScreen;
|
import envoy.client.ui.settings.SettingsScreen;
|
||||||
import envoy.data.Message;
|
import envoy.data.Message;
|
||||||
@ -54,8 +51,7 @@ import envoy.util.EnvoyLog;
|
|||||||
public class ChatWindow extends JFrame {
|
public class ChatWindow extends JFrame {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This int defines the maximum amount of chars allowed per message. Currently
|
* This integer defines the maximum amount of chars allowed per message.
|
||||||
* set at 200.
|
|
||||||
*
|
*
|
||||||
* @since Envoy 0.1-beta
|
* @since Envoy 0.1-beta
|
||||||
*/
|
*/
|
||||||
@ -77,7 +73,6 @@ public class ChatWindow extends JFrame {
|
|||||||
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");
|
||||||
@SuppressWarnings("unused")
|
|
||||||
private JPopupMenu contextMenu;
|
private JPopupMenu contextMenu;
|
||||||
|
|
||||||
// Contacts Header
|
// Contacts Header
|
||||||
@ -90,9 +85,8 @@ public class ChatWindow extends JFrame {
|
|||||||
private final PrimaryButton cancelButton = new PrimaryButton("x");
|
private final PrimaryButton cancelButton = new PrimaryButton("x");
|
||||||
private final PrimaryTextArea searchField = new PrimaryTextArea(space);
|
private final PrimaryTextArea searchField = new PrimaryTextArea(space);
|
||||||
private final PrimaryScrollPane scrollForPossibleContacts = new PrimaryScrollPane();
|
private final PrimaryScrollPane scrollForPossibleContacts = new PrimaryScrollPane();
|
||||||
private final ContactsSearchRenderer contactRenderer = new ContactsSearchRenderer();
|
private final Model<User> contactsModel = new Model<>();
|
||||||
private final ComponentListModel<User> contactsModel = new ComponentListModel<>();
|
private final ComponentList<User> contactList = new ComponentList<User>().setRenderer(ContactSearchComponent::new);
|
||||||
private final ComponentList<User> contactList = new ComponentList<>(contactRenderer);
|
|
||||||
|
|
||||||
private static final Logger logger = EnvoyLog.getLogger(ChatWindow.class);
|
private static final Logger logger = EnvoyLog.getLogger(ChatWindow.class);
|
||||||
|
|
||||||
@ -125,16 +119,14 @@ public class ChatWindow extends JFrame {
|
|||||||
gbl_contentPane.rowWeights = new double[] { 0.03, 0.001, 1.0, 0.005 };
|
gbl_contentPane.rowWeights = new double[] { 0.03, 0.001, 1.0, 0.005 };
|
||||||
contentPane.setLayout(gbl_contentPane);
|
contentPane.setLayout(gbl_contentPane);
|
||||||
|
|
||||||
messageList.setBorder(new EmptyBorder(space, space, space, space));
|
// ContextMenu
|
||||||
messageList.setSelectionMode(SelectionMode.SINGLE);
|
|
||||||
Map<String, ActionListener> commands = new HashMap<>() {
|
Map<String, ActionListener> commands = new HashMap<>() {
|
||||||
|
|
||||||
private static final long serialVersionUID = -2755235774946990126L;
|
private static final long serialVersionUID = -2755235774946990126L;
|
||||||
|
|
||||||
{
|
{
|
||||||
put("forward selected message",
|
put("forward selected message",
|
||||||
evt -> forwardMessageToMultipleUsers(messageList
|
evt -> forwardMessageToMultipleUsers(messageList.getSingleSelectedElement(),
|
||||||
.getSingleSelectedElement(),
|
|
||||||
ContactsChooserDialog
|
ContactsChooserDialog
|
||||||
.showForwardingDialog("Forward selected message to", messageList.getSingleSelectedElement(), client)));
|
.showForwardingDialog("Forward selected message to", messageList.getSingleSelectedElement(), client)));
|
||||||
put("copy", evt -> {
|
put("copy", evt -> {
|
||||||
@ -151,6 +143,14 @@ public class ChatWindow extends JFrame {
|
|||||||
};
|
};
|
||||||
contextMenu = new ContextMenu(null, messageList, commands, null, null).build();
|
contextMenu = new ContextMenu(null, messageList, commands, null, null).build();
|
||||||
|
|
||||||
|
messageList.setBorder(new EmptyBorder(space, space, space, space));
|
||||||
|
messageList.setSelectionMode(SelectionMode.SINGLE);
|
||||||
|
messageList.setSelectionHandler((message, comp, isSelected) -> {
|
||||||
|
final var theme = Settings.getInstance().getCurrentTheme();
|
||||||
|
comp.setBackground(isSelected ? theme.getSelectionColor() : theme.getCellColor());
|
||||||
|
contextMenu.show(comp, 0, 0);
|
||||||
|
});
|
||||||
|
|
||||||
scrollPane.setViewportView(messageList);
|
scrollPane.setViewportView(messageList);
|
||||||
scrollPane.addComponentListener(new ComponentAdapter() {
|
scrollPane.addComponentListener(new ComponentAdapter() {
|
||||||
|
|
||||||
@ -396,11 +396,11 @@ public class ChatWindow extends JFrame {
|
|||||||
gbc_addContact.gridy = 0;
|
gbc_addContact.gridy = 0;
|
||||||
gbc_addContact.insets = insets;
|
gbc_addContact.insets = insets;
|
||||||
|
|
||||||
addContact.addActionListener((evt) -> { drawContactSearch(gbc_searchPane); });
|
addContact.addActionListener(evt -> drawContactSearch(gbc_searchPane));
|
||||||
|
|
||||||
contactsHeader.add(addContact, gbc_addContact);
|
contactsHeader.add(addContact, gbc_addContact);
|
||||||
|
|
||||||
applyTheme(Settings.getInstance().getThemes().get(Settings.getInstance().getCurrentTheme()));
|
applyTheme(Settings.getInstance().getCurrentTheme());
|
||||||
|
|
||||||
contentPane.add(contactsHeader, gbc_contactsHeader);
|
contentPane.add(contactsHeader, gbc_contactsHeader);
|
||||||
contentPane.revalidate();
|
contentPane.revalidate();
|
||||||
@ -645,7 +645,7 @@ public class ChatWindow extends JFrame {
|
|||||||
this.localDb = localDb;
|
this.localDb = localDb;
|
||||||
this.writeProxy = writeProxy;
|
this.writeProxy = writeProxy;
|
||||||
|
|
||||||
messageList.setRenderer(new MessageListRenderer(client.getSender().getId()));
|
messageList.setRenderer((list, message) -> new MessageComponent(list, message, client.getSender().getId()));
|
||||||
|
|
||||||
// Load users and chats
|
// Load users and chats
|
||||||
new Thread(() -> {
|
new Thread(() -> {
|
||||||
|
@ -14,11 +14,10 @@ import javax.swing.border.EmptyBorder;
|
|||||||
import envoy.client.data.Settings;
|
import envoy.client.data.Settings;
|
||||||
import envoy.client.net.Client;
|
import envoy.client.net.Client;
|
||||||
import envoy.client.ui.Theme;
|
import envoy.client.ui.Theme;
|
||||||
|
import envoy.client.ui.UserComponent;
|
||||||
import envoy.client.ui.list.ComponentList;
|
import envoy.client.ui.list.ComponentList;
|
||||||
import envoy.client.ui.list.ComponentList.SelectionMode;
|
import envoy.client.ui.list.ComponentList.SelectionMode;
|
||||||
import envoy.client.ui.list.ComponentListModel;
|
import envoy.client.ui.list.Model;
|
||||||
import envoy.client.ui.renderer.MessageListRenderer;
|
|
||||||
import envoy.client.ui.renderer.UserComponentListRenderer;
|
|
||||||
import envoy.data.Message;
|
import envoy.data.Message;
|
||||||
import envoy.data.User;
|
import envoy.data.User;
|
||||||
|
|
||||||
@ -36,11 +35,11 @@ public class ContactsChooserDialog extends JDialog {
|
|||||||
|
|
||||||
private static final long serialVersionUID = -5774558118579032256L;
|
private static final long serialVersionUID = -5774558118579032256L;
|
||||||
|
|
||||||
private ComponentList<User> contactList = new ComponentList<>(new UserComponentListRenderer());
|
private ComponentList<User> contactList = new ComponentList<User>().setRenderer(UserComponent::new);
|
||||||
private JButton okButton = new JButton("Ok");
|
private JButton okButton = new JButton("Ok");
|
||||||
private JButton cancelButton = new JButton("Cancel");
|
private JButton cancelButton = new JButton("Cancel");
|
||||||
|
|
||||||
private final Theme theme = Settings.getInstance().getTheme(Settings.getInstance().getCurrentTheme());
|
private final Theme theme = Settings.getInstance().getCurrentTheme();
|
||||||
|
|
||||||
private final JPanel contentPanel = new JPanel();
|
private final JPanel contentPanel = new JPanel();
|
||||||
|
|
||||||
@ -67,16 +66,18 @@ public class ContactsChooserDialog extends JDialog {
|
|||||||
dialog.setTitle(title);
|
dialog.setTitle(title);
|
||||||
dialog.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
|
dialog.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
|
||||||
dialog.addCancelButtonActionListener(e -> dialog.dispose());
|
dialog.addCancelButtonActionListener(e -> dialog.dispose());
|
||||||
dialog.getContentPanel()
|
// dialog.getContentPanel()
|
||||||
.add(new MessageListRenderer(client.getSender().getId()).getListCellComponent(null, message, false), BorderLayout.NORTH);
|
// .add(new
|
||||||
|
// MessageListRenderer(client.getSender().getId()).getListCellComponent(null,
|
||||||
|
// message, false), BorderLayout.NORTH);
|
||||||
List<User> results = new ArrayList<>();
|
List<User> results = new ArrayList<>();
|
||||||
dialog.addOkButtonActionListener(e -> { results.addAll(dialog.getContactList().getSelectedElements()); dialog.dispose(); });
|
dialog.addOkButtonActionListener(e -> { results.addAll(dialog.getContactList().getSelectedElements()); dialog.dispose(); });
|
||||||
ComponentListModel<User> contactListModel = dialog.getContactList().getModel();
|
Model<User> contactListModel = dialog.getContactList().getModel();
|
||||||
client.getContacts().getContacts().forEach(user -> contactListModel.add(user));
|
client.getContacts().getContacts().forEach(user -> contactListModel.add(user));
|
||||||
dialog.setVisible(true);
|
dialog.setVisible(true);
|
||||||
dialog.repaint();
|
dialog.repaint();
|
||||||
dialog.revalidate();
|
dialog.revalidate();
|
||||||
return results.size() > 0 ? results : null;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -84,7 +85,8 @@ public class ContactsChooserDialog extends JDialog {
|
|||||||
*/
|
*/
|
||||||
private ContactsChooserDialog() {
|
private ContactsChooserDialog() {
|
||||||
contactList.setSelectionMode(SelectionMode.MULTIPLE);
|
contactList.setSelectionMode(SelectionMode.MULTIPLE);
|
||||||
// setBounds(100, 100, 450, 300);
|
contactList
|
||||||
|
.setSelectionHandler((user, comp, isSelected) -> comp.setBackground(isSelected ? theme.getSelectionColor() : theme.getCellColor()));
|
||||||
setModal(true);
|
setModal(true);
|
||||||
getContentPane().setLayout(new BorderLayout());
|
getContentPane().setLayout(new BorderLayout());
|
||||||
setBackground(theme.getBackgroundColor());
|
setBackground(theme.getBackgroundColor());
|
||||||
@ -121,6 +123,4 @@ public class ContactsChooserDialog extends JDialog {
|
|||||||
private void addOkButtonActionListener(ActionListener l) { okButton.addActionListener(l); }
|
private void addOkButtonActionListener(ActionListener l) { okButton.addActionListener(l); }
|
||||||
|
|
||||||
private void addCancelButtonActionListener(ActionListener l) { cancelButton.addActionListener(l); }
|
private void addCancelButtonActionListener(ActionListener l) { cancelButton.addActionListener(l); }
|
||||||
|
|
||||||
private JPanel getContentPanel() { return contentPanel; }
|
|
||||||
}
|
}
|
||||||
|
@ -291,7 +291,7 @@ public class LoginDialog extends JDialog {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void setTheme() {
|
private void setTheme() {
|
||||||
Theme theme = Settings.getInstance().getThemes().get(Settings.getInstance().getCurrentTheme());
|
Theme theme = Settings.getInstance().getCurrentTheme();
|
||||||
|
|
||||||
// Panels
|
// Panels
|
||||||
contentPanel.setBackground(theme.getBackgroundColor());
|
contentPanel.setBackground(theme.getBackgroundColor());
|
||||||
|
@ -10,7 +10,7 @@ import javax.swing.*;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides a vertical list layout of components provided in a
|
* Provides a vertical list layout of components provided in a
|
||||||
* {@link ComponentListModel}. Similar to {@link javax.swing.JList} but capable
|
* {@link Model}. Similar to {@link javax.swing.JList} but capable
|
||||||
* of rendering {@link JPanel}s.<br>
|
* of rendering {@link JPanel}s.<br>
|
||||||
* <br>
|
* <br>
|
||||||
* Project: <strong>envoy-client</strong><br>
|
* Project: <strong>envoy-client</strong><br>
|
||||||
@ -23,8 +23,9 @@ import javax.swing.*;
|
|||||||
*/
|
*/
|
||||||
public class ComponentList<E> extends JPanel {
|
public class ComponentList<E> extends JPanel {
|
||||||
|
|
||||||
private ComponentListModel<E> model;
|
private Model<E> model;
|
||||||
private ComponentListCellRenderer<E> renderer;
|
private Renderer<E> renderer;
|
||||||
|
private SelectionHandler<E> selectionHandler;
|
||||||
private SelectionMode selectionMode = SelectionMode.NONE;
|
private SelectionMode selectionMode = SelectionMode.NONE;
|
||||||
private Set<Integer> selection = new HashSet<>();
|
private Set<Integer> selection = new HashSet<>();
|
||||||
|
|
||||||
@ -53,64 +54,20 @@ public class ComponentList<E> extends JPanel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes a default {@link ComponentList} without a model or a renderer.
|
* Creates an instance of {@link ComponentList}.
|
||||||
*
|
*
|
||||||
* @since Envoy v0.1-beta
|
* @since Envoy v0.3-alpha
|
||||||
*/
|
*/
|
||||||
public ComponentList() { setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); }
|
public ComponentList() { setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); }
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates an instance of {@link ComponentList}.
|
|
||||||
*
|
|
||||||
* @param renderer the list cell renderer used to display elements provided by
|
|
||||||
* the {@link ComponentListModel}
|
|
||||||
* @since Envoy v0.3-alpha
|
|
||||||
*/
|
|
||||||
public ComponentList(ComponentListCellRenderer<E> renderer) {
|
|
||||||
this();
|
|
||||||
setRenderer(renderer);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates an instance of {@link ComponentList}.
|
|
||||||
*
|
|
||||||
* @param model the list model providing the list elements to render
|
|
||||||
* @param renderer the list cell renderer used to display elements provided by
|
|
||||||
* the {@link ComponentListModel}
|
|
||||||
* @since Envoy v0.3-alpha
|
|
||||||
*/
|
|
||||||
public ComponentList(ComponentListModel<E> model, ComponentListCellRenderer<E> renderer) {
|
|
||||||
this(renderer);
|
|
||||||
setModel(model);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the list model providing the list elements to render. The rendered
|
|
||||||
* components will be synchronized with the contents of the new model or removed
|
|
||||||
* if the new model is {@code null}.
|
|
||||||
*
|
|
||||||
* @param model the list model to set
|
|
||||||
* @since Envoy v0.3-alpha
|
|
||||||
*/
|
|
||||||
public void setModel(ComponentListModel<E> model) {
|
|
||||||
|
|
||||||
// Remove old model
|
|
||||||
if (this.model != null) this.model.setComponentList(null);
|
|
||||||
|
|
||||||
// Synchronize with new model
|
|
||||||
this.model = model;
|
|
||||||
if (model != null) model.setComponentList(this);
|
|
||||||
synchronizeModel();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes all child components and then adds all components representing the
|
* Removes all child components and then adds all components representing the
|
||||||
* elements of the {@link ComponentListModel}.
|
* elements of the {@link Model}.
|
||||||
*
|
*
|
||||||
* @since Envoy v0.3-alpha
|
* @since Envoy v0.3-alpha
|
||||||
*/
|
*/
|
||||||
public void synchronizeModel() {
|
public void synchronizeModel() {
|
||||||
if (model != null && renderer != null) {
|
if (model != null) {
|
||||||
removeAll();
|
removeAll();
|
||||||
model.forEach(this::addElement);
|
model.forEach(this::addElement);
|
||||||
revalidate();
|
revalidate();
|
||||||
@ -125,10 +82,12 @@ public class ComponentList<E> extends JPanel {
|
|||||||
* @since Envoy v0.1-beta
|
* @since Envoy v0.1-beta
|
||||||
*/
|
*/
|
||||||
public void selectElement(int index) {
|
public void selectElement(int index) {
|
||||||
|
final JComponent element = getComponent(index);
|
||||||
|
|
||||||
if (selection.contains(index)) {
|
if (selection.contains(index)) {
|
||||||
|
|
||||||
// Remove selection of element at index
|
// Remove selection of element at index
|
||||||
updateElement(index, false);
|
if (selectionHandler != null) selectionHandler.selectionChanged(model.get(index), element, true);
|
||||||
selection.remove(index);
|
selection.remove(index);
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
@ -141,7 +100,7 @@ public class ComponentList<E> extends JPanel {
|
|||||||
selection.add(index);
|
selection.add(index);
|
||||||
|
|
||||||
// Update element
|
// Update element
|
||||||
updateElement(index, true);
|
if (selectionHandler != null) selectionHandler.selectionChanged(model.get(index), element, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -155,49 +114,25 @@ public class ComponentList<E> extends JPanel {
|
|||||||
* @since Envoy v0.1-alpha
|
* @since Envoy v0.1-alpha
|
||||||
*/
|
*/
|
||||||
public void clearSelection() {
|
public void clearSelection() {
|
||||||
selection.forEach(i -> updateElement(i, false));
|
if (selectionHandler != null) selection.forEach(i -> selectionHandler.selectionChanged(model.get(i), getComponent(i), false));
|
||||||
selection.clear();
|
selection.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds an object to the list by rendering it with the current
|
* Adds an object to the list by rendering it with the current
|
||||||
* {@link ComponentListCellRenderer}.
|
* {@link Renderer}.
|
||||||
*
|
*
|
||||||
* @param elem the element to add
|
* @param elem the element to add
|
||||||
* @since Envoy v0.3-alpha
|
* @since Envoy v0.3-alpha
|
||||||
*/
|
*/
|
||||||
void addElement(E elem) { addElement(elem, getComponentCount(), false); }
|
void addElement(E elem) {
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds an object to the list by rendering it with the current
|
|
||||||
* {@link ComponentListRenderer}. If the renderer is {@code null}, no action is
|
|
||||||
* performed.
|
|
||||||
*
|
|
||||||
* @param elem the element to add
|
|
||||||
* @param index the index at which to add the element
|
|
||||||
* @param isSelected the selection state of the element
|
|
||||||
* @since Envoy v0.1-beta
|
|
||||||
*/
|
|
||||||
private void addElement(E elem, int index, boolean isSelected) {
|
|
||||||
if (renderer != null) {
|
if (renderer != null) {
|
||||||
final JComponent component = renderer.getListCellComponent(this, elem, isSelected);
|
final JComponent component = renderer.getListCellComponent(this, elem);
|
||||||
component.addMouseListener(getSelectionListener(index));
|
component.addMouseListener(getSelectionListener(getComponentCount()));
|
||||||
add(component, index);
|
add(component, getComponentCount());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Replaces a list element with a newly rendered instance of its contents.
|
|
||||||
*
|
|
||||||
* @param index the index of the element to update
|
|
||||||
* @param isSelected the selection state passed to the {@link ListCellRenderer}
|
|
||||||
* @since Envoy v0.1-beta
|
|
||||||
*/
|
|
||||||
private void updateElement(int index, boolean isSelected) {
|
|
||||||
remove(index);
|
|
||||||
addElement(model.get(index), index, isSelected);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param componentIndex the index of the list component to which the mouse
|
* @param componentIndex the index of the list component to which the mouse
|
||||||
* listener will be added
|
* listener will be added
|
||||||
@ -214,6 +149,9 @@ public class ComponentList<E> extends JPanel {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JComponent getComponent(int n) { return (JComponent) super.getComponent(n); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return a set of all selected indices
|
* @return a set of all selected indices
|
||||||
* @since Envoy v0.1-beta
|
* @since Envoy v0.1-beta
|
||||||
@ -248,19 +186,45 @@ public class ComponentList<E> extends JPanel {
|
|||||||
* @return the model
|
* @return the model
|
||||||
* @since Envoy v0.1-beta
|
* @since Envoy v0.1-beta
|
||||||
*/
|
*/
|
||||||
public ComponentListModel<E> getModel() { return model; }
|
public Model<E> getModel() { return model; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the list model providing the list elements to render. The rendered
|
||||||
|
* components will be synchronized with the contents of the new model or removed
|
||||||
|
* if the new model is {@code null}.
|
||||||
|
*
|
||||||
|
* @param model the list model to set
|
||||||
|
* @return this component list
|
||||||
|
* @since Envoy v0.3-alpha
|
||||||
|
*/
|
||||||
|
public ComponentList<E> setModel(Model<E> model) {
|
||||||
|
|
||||||
|
// Remove old model
|
||||||
|
if (this.model != null) this.model.setComponentList(null);
|
||||||
|
|
||||||
|
// Synchronize with new model
|
||||||
|
this.model = model;
|
||||||
|
if (model != null) model.setComponentList(this);
|
||||||
|
synchronizeModel();
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the renderer
|
* @return the renderer
|
||||||
* @since Envoy v0.1-beta
|
* @since Envoy v0.1-beta
|
||||||
*/
|
*/
|
||||||
public ComponentListCellRenderer<E> getRenderer() { return renderer; }
|
public Renderer<E> getRenderer() { return renderer; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param renderer the renderer to set
|
* @param renderer the renderer to set
|
||||||
|
* @return this component list
|
||||||
* @since Envoy v0.1-beta
|
* @since Envoy v0.1-beta
|
||||||
*/
|
*/
|
||||||
public void setRenderer(ComponentListCellRenderer<E> renderer) { this.renderer = renderer; }
|
public ComponentList<E> setRenderer(Renderer<E> renderer) {
|
||||||
|
this.renderer = renderer;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the selection mode
|
* @return the selection mode
|
||||||
@ -269,8 +233,28 @@ public class ComponentList<E> extends JPanel {
|
|||||||
public SelectionMode getSelectionMode() { return selectionMode; }
|
public SelectionMode getSelectionMode() { return selectionMode; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Sets a new selection mode. The current selection will be cleared during this
|
||||||
|
* action.
|
||||||
|
*
|
||||||
* @param selectionMode the selection mode to set
|
* @param selectionMode the selection mode to set
|
||||||
|
* @return this component list
|
||||||
* @since Envoy v0.1-beta
|
* @since Envoy v0.1-beta
|
||||||
*/
|
*/
|
||||||
public void setSelectionMode(SelectionMode selectionMode) { this.selectionMode = selectionMode; }
|
public ComponentList<E> setSelectionMode(SelectionMode selectionMode) {
|
||||||
|
this.selectionMode = selectionMode;
|
||||||
|
clearSelection();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the selection handler
|
||||||
|
* @since Envoy v0.1-beta
|
||||||
|
*/
|
||||||
|
public SelectionHandler<E> getSelectionHandler() { return selectionHandler; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param selectionHandler the selection handler to set
|
||||||
|
* @since Envoy v0.1-beta
|
||||||
|
*/
|
||||||
|
public void setSelectionHandler(SelectionHandler<E> selectionHandler) { this.selectionHandler = selectionHandler; }
|
||||||
}
|
}
|
||||||
|
@ -9,19 +9,19 @@ import java.util.List;
|
|||||||
* Stores objects that will be displayed in a {@link ComponentList}.<br>
|
* Stores objects that will be displayed in a {@link ComponentList}.<br>
|
||||||
* <br>
|
* <br>
|
||||||
* Project: <strong>envoy-client</strong><br>
|
* Project: <strong>envoy-client</strong><br>
|
||||||
* File: <strong>ComponentListModel.java</strong><br>
|
* File: <strong>Model.java</strong><br>
|
||||||
* Created: <strong>25.01.2020</strong><br>
|
* Created: <strong>25.01.2020</strong><br>
|
||||||
*
|
*
|
||||||
* @param <E> the type of object displayed in this list
|
* @param <E> the type of object displayed in this list
|
||||||
* @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>, Serializable {
|
public final class Model<E> implements Iterable<E>, Serializable {
|
||||||
|
|
||||||
private List<E> elements = new ArrayList<>();
|
private List<E> elements = new ArrayList<>();
|
||||||
transient private ComponentList<E> componentList;
|
transient private ComponentList<E> componentList;
|
||||||
|
|
||||||
private static final long serialVersionUID = 4815005915255497331L;
|
private static final long serialVersionUID = 0L;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds an element to this model and notifies the associated
|
* Adds an element to this model and notifies the associated
|
@ -7,14 +7,15 @@ import javax.swing.JComponent;
|
|||||||
* that can be rendered.<br>
|
* that can be rendered.<br>
|
||||||
* <br>
|
* <br>
|
||||||
* Project: <strong>envoy-client</strong><br>
|
* Project: <strong>envoy-client</strong><br>
|
||||||
* File: <strong>ComponentListCellRenderer.java</strong><br>
|
* File: <strong>Renderer.java</strong><br>
|
||||||
* Created: <strong>25.01.2020</strong><br>
|
* Created: <strong>25.01.2020</strong><br>
|
||||||
*
|
*
|
||||||
* @param <E> the type of object displayed in this list
|
* @param <E> the type of object displayed in this list
|
||||||
* @author Kai S. K. Engelbart
|
* @author Kai S. K. Engelbart
|
||||||
* @since Envoy v0.3-alpha
|
* @since Envoy v0.3-alpha
|
||||||
*/
|
*/
|
||||||
public interface ComponentListCellRenderer<E> {
|
@FunctionalInterface
|
||||||
|
public interface Renderer<E> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides a Swing component representing a list element.
|
* Provides a Swing component representing a list element.
|
||||||
@ -26,5 +27,5 @@ public interface ComponentListCellRenderer<E> {
|
|||||||
* @return the component representing the list element
|
* @return the component representing the list element
|
||||||
* @since Envoy v0.3-alpha
|
* @since Envoy v0.3-alpha
|
||||||
*/
|
*/
|
||||||
JComponent getListCellComponent(ComponentList<? extends E> list, E value, boolean isSelected);
|
JComponent getListCellComponent(ComponentList<? extends E> list, E value);
|
||||||
}
|
}
|
27
src/main/java/envoy/client/ui/list/SelectionHandler.java
Normal file
27
src/main/java/envoy/client/ui/list/SelectionHandler.java
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
package envoy.client.ui.list;
|
||||||
|
|
||||||
|
import javax.swing.JComponent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles the selection of elements in a {@link ComponentList}.<br>
|
||||||
|
* <br>
|
||||||
|
* Project: <strong>envoy-client</strong>
|
||||||
|
* File: <strong>SelectionHandler.java</strong>
|
||||||
|
* Created: <strong>21.03.2020</strong>
|
||||||
|
*
|
||||||
|
* @author Kai S. K. Engelbart
|
||||||
|
* @since Envoy v0.1-beta
|
||||||
|
*/
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface SelectionHandler<E> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notifies the handler about a selection.
|
||||||
|
*
|
||||||
|
* @param element the selected element
|
||||||
|
* @param component the selected component
|
||||||
|
* @param isSelected contains the selection state
|
||||||
|
* @since Envoy v0.1-beta
|
||||||
|
*/
|
||||||
|
void selectionChanged(E element, JComponent component, boolean isSelected);
|
||||||
|
}
|
@ -1,11 +1,6 @@
|
|||||||
package envoy.client.ui.primary;
|
package envoy.client.ui.primary;
|
||||||
|
|
||||||
import java.awt.Color;
|
import java.awt.*;
|
||||||
import java.awt.Dimension;
|
|
||||||
import java.awt.Graphics;
|
|
||||||
import java.awt.Graphics2D;
|
|
||||||
import java.awt.Rectangle;
|
|
||||||
import java.awt.RenderingHints;
|
|
||||||
|
|
||||||
import javax.swing.JButton;
|
import javax.swing.JButton;
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
@ -98,11 +93,11 @@ public class PrimaryScrollBar extends BasicScrollBarUI {
|
|||||||
g2.setPaint(color);
|
g2.setPaint(color);
|
||||||
if (isVertical) {
|
if (isVertical) {
|
||||||
g2.fillRoundRect(r.x - 9, r.y, r.width, r.height, arcSize, arcSize);
|
g2.fillRoundRect(r.x - 9, r.y, r.width, r.height, arcSize, arcSize);
|
||||||
g2.setPaint(Settings.getInstance().getThemes().get(Settings.getInstance().getCurrentTheme()).getCellColor());
|
g2.setPaint(Settings.getInstance().getCurrentTheme().getCellColor());
|
||||||
g2.drawRoundRect(r.x - 9, r.y, r.width, r.height, arcSize, arcSize);
|
g2.drawRoundRect(r.x - 9, r.y, r.width, r.height, arcSize, arcSize);
|
||||||
} else {
|
} else {
|
||||||
g2.fillRoundRect(r.x, r.y + 9, r.width, r.height - 10, arcSize, arcSize);
|
g2.fillRoundRect(r.x, r.y + 9, r.width, r.height - 10, arcSize, arcSize);
|
||||||
g2.setPaint(Settings.getInstance().getThemes().get(Settings.getInstance().getCurrentTheme()).getCellColor());
|
g2.setPaint(Settings.getInstance().getCurrentTheme().getCellColor());
|
||||||
g2.drawRoundRect(r.x, r.y + 9, r.width, r.height - 10, arcSize, arcSize);
|
g2.drawRoundRect(r.x, r.y + 9, r.width, r.height - 10, arcSize, arcSize);
|
||||||
}
|
}
|
||||||
g2.dispose();
|
g2.dispose();
|
||||||
|
@ -52,7 +52,7 @@ public class PrimaryToggleSwitch extends JButton {
|
|||||||
g.setColor(state ? Color.GREEN : Color.LIGHT_GRAY);
|
g.setColor(state ? Color.GREEN : Color.LIGHT_GRAY);
|
||||||
g.fillRoundRect(0, 0, getWidth(), getHeight(), 25, 25);
|
g.fillRoundRect(0, 0, getWidth(), getHeight(), 25, 25);
|
||||||
|
|
||||||
g.setColor(Settings.getInstance().getThemes().get(Settings.getInstance().getCurrentTheme()).getInteractableBackgroundColor());
|
g.setColor(Settings.getInstance().getCurrentTheme().getInteractableBackgroundColor());
|
||||||
g.fillRoundRect(state ? 25 : 0, 0, 25, 25, 25, 25);
|
g.fillRoundRect(state ? 25 : 0, 0, 25, 25, 25, 25);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,70 +0,0 @@
|
|||||||
package envoy.client.ui.renderer;
|
|
||||||
|
|
||||||
import java.awt.BorderLayout;
|
|
||||||
import java.awt.Dimension;
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
import javax.swing.JComponent;
|
|
||||||
import javax.swing.JLabel;
|
|
||||||
import javax.swing.JPanel;
|
|
||||||
|
|
||||||
import envoy.client.data.Settings;
|
|
||||||
import envoy.client.ui.Color;
|
|
||||||
import envoy.client.ui.Theme;
|
|
||||||
import envoy.client.ui.list.ComponentList;
|
|
||||||
import envoy.client.ui.list.ComponentListCellRenderer;
|
|
||||||
import envoy.data.User;
|
|
||||||
import envoy.data.User.UserStatus;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Project: <strong>envoy-client</strong><br>
|
|
||||||
* File: <strong>UserComponentListRenderer.java</strong><br>
|
|
||||||
* Created: <strong>15 Mar 2020</strong><br>
|
|
||||||
*
|
|
||||||
* @author Leon Hofmeister
|
|
||||||
* @since Envoy v0.1-beta
|
|
||||||
*/
|
|
||||||
public class UserComponentListRenderer implements ComponentListCellRenderer<User>, Serializable {
|
|
||||||
|
|
||||||
private static final long serialVersionUID = -2379244319112111284L;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JComponent getListCellComponent(ComponentList<? extends User> list, User user, boolean isSelected) {
|
|
||||||
final Theme theme = Settings.getInstance().getThemes().get(Settings.getInstance().getCurrentTheme());
|
|
||||||
|
|
||||||
final JPanel panel = new JPanel();
|
|
||||||
panel.setLayout(new BorderLayout());
|
|
||||||
|
|
||||||
// Panel background
|
|
||||||
panel.setBackground(isSelected ? theme.getSelectionColor() : theme.getCellColor());
|
|
||||||
panel.setOpaque(true);
|
|
||||||
panel.setPreferredSize(new Dimension(100, 35));
|
|
||||||
|
|
||||||
// TODO add profile picture support in BorderLayout.West
|
|
||||||
|
|
||||||
JLabel username = new JLabel(user.getName());
|
|
||||||
username.setForeground(theme.getUserNameColor());
|
|
||||||
panel.add(username, BorderLayout.CENTER);
|
|
||||||
|
|
||||||
final UserStatus status = user.getStatus();
|
|
||||||
JLabel statusLabel = new JLabel(status.toString());
|
|
||||||
Color foreground;
|
|
||||||
switch (status) {
|
|
||||||
case AWAY:
|
|
||||||
foreground = Color.yellow;
|
|
||||||
break;
|
|
||||||
case BUSY:
|
|
||||||
foreground = Color.blue;
|
|
||||||
break;
|
|
||||||
case ONLINE:
|
|
||||||
foreground = Color.green;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
foreground = Color.lightGray;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
statusLabel.setForeground(foreground);
|
|
||||||
panel.add(statusLabel, BorderLayout.NORTH);
|
|
||||||
return panel;
|
|
||||||
}
|
|
||||||
}
|
|
@ -46,7 +46,7 @@ public class UserListRenderer extends JLabel implements ListCellRenderer<User> {
|
|||||||
|
|
||||||
// Getting the UserNameColor of the current theme
|
// Getting the UserNameColor of the current theme
|
||||||
String textColor = null;
|
String textColor = null;
|
||||||
textColor = Settings.getInstance().getThemes().get(Settings.getInstance().getCurrentTheme()).getUserNameColor().toHex();
|
textColor = Settings.getInstance().getCurrentTheme().getUserNameColor().toHex();
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case ONLINE:
|
case ONLINE:
|
||||||
setText(String
|
setText(String
|
||||||
|
@ -43,7 +43,7 @@ public class GeneralSettingsPanel extends SettingsPanel {
|
|||||||
*/
|
*/
|
||||||
public GeneralSettingsPanel(SettingsScreen parent) {
|
public GeneralSettingsPanel(SettingsScreen parent) {
|
||||||
super(parent);
|
super(parent);
|
||||||
theme = Settings.getInstance().getThemes().get(Settings.getInstance().getCurrentTheme());
|
theme = Settings.getInstance().getCurrentTheme();
|
||||||
|
|
||||||
setBackground(theme.getCellColor());
|
setBackground(theme.getCellColor());
|
||||||
|
|
||||||
|
@ -61,7 +61,7 @@ public class NewThemeScreen extends JDialog {
|
|||||||
setDimensions(true);
|
setDimensions(true);
|
||||||
setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
|
setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
|
||||||
|
|
||||||
Theme theme = Settings.getInstance().getThemes().get(Settings.getInstance().getCurrentTheme());
|
Theme theme = Settings.getInstance().getCurrentTheme();
|
||||||
|
|
||||||
getContentPane().setLayout(new BorderLayout());
|
getContentPane().setLayout(new BorderLayout());
|
||||||
standardPanel.setBackground(theme.getBackgroundColor());
|
standardPanel.setBackground(theme.getBackgroundColor());
|
||||||
|
@ -156,7 +156,7 @@ public class SettingsScreen extends JDialog {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Apply current theme
|
// Apply current theme
|
||||||
applyTheme(Settings.getInstance().getThemes().get(Settings.getInstance().getCurrentTheme()));
|
applyTheme(Settings.getInstance().getCurrentTheme());
|
||||||
|
|
||||||
// Respond to theme changes
|
// Respond to theme changes
|
||||||
EventBus.getInstance().register(ThemeChangeEvent.class, evt -> applyTheme(evt.get()));
|
EventBus.getInstance().register(ThemeChangeEvent.class, evt -> applyTheme(evt.get()));
|
||||||
|
@ -38,6 +38,7 @@ public class ThemeCustomizationPanel extends SettingsPanel {
|
|||||||
|
|
||||||
private final Insets insets = new Insets(5, 5, 5, 5);
|
private final Insets insets = new Insets(5, 5, 5, 5);
|
||||||
|
|
||||||
|
private static final Settings settings = Settings.getInstance();
|
||||||
private static final Logger logger = EnvoyLog.getLogger(ThemeCustomizationPanel.class);
|
private static final Logger logger = EnvoyLog.getLogger(ThemeCustomizationPanel.class);
|
||||||
private static final long serialVersionUID = -8697897390666456624L;
|
private static final long serialVersionUID = -8697897390666456624L;
|
||||||
|
|
||||||
@ -52,7 +53,7 @@ public class ThemeCustomizationPanel extends SettingsPanel {
|
|||||||
*/
|
*/
|
||||||
public ThemeCustomizationPanel(SettingsScreen parent) {
|
public ThemeCustomizationPanel(SettingsScreen parent) {
|
||||||
super(parent);
|
super(parent);
|
||||||
temporaryTheme = new Theme("temporaryTheme", Settings.getInstance().getThemes().get(Settings.getInstance().getCurrentTheme()));
|
temporaryTheme = new Theme("temporaryTheme", settings.getCurrentTheme());
|
||||||
|
|
||||||
GridBagLayout gbl_themeLayout = new GridBagLayout();
|
GridBagLayout gbl_themeLayout = new GridBagLayout();
|
||||||
|
|
||||||
@ -63,7 +64,7 @@ public class ThemeCustomizationPanel extends SettingsPanel {
|
|||||||
|
|
||||||
setLayout(gbl_themeLayout);
|
setLayout(gbl_themeLayout);
|
||||||
|
|
||||||
themes.setSelectedItem(Settings.getInstance().getCurrentTheme());
|
themes.setSelectedItem(settings.getCurrentTheme());
|
||||||
|
|
||||||
GridBagConstraints gbc_themes = new GridBagConstraints();
|
GridBagConstraints gbc_themes = new GridBagConstraints();
|
||||||
gbc_themes.fill = GridBagConstraints.HORIZONTAL;
|
gbc_themes.fill = GridBagConstraints.HORIZONTAL;
|
||||||
@ -83,7 +84,7 @@ public class ThemeCustomizationPanel extends SettingsPanel {
|
|||||||
|
|
||||||
colorsPanel.setLayout(gbl_colorCustomizations);
|
colorsPanel.setLayout(gbl_colorCustomizations);
|
||||||
|
|
||||||
Theme theme = Settings.getInstance().getThemes().get(Settings.getInstance().getCurrentTheme());
|
Theme theme = settings.getCurrentTheme();
|
||||||
buildCustomizeElements(theme);
|
buildCustomizeElements(theme);
|
||||||
|
|
||||||
GridBagConstraints gbc_colorsPanel = new GridBagConstraints();
|
GridBagConstraints gbc_colorsPanel = new GridBagConstraints();
|
||||||
|
Reference in New Issue
Block a user