Extracted MessageComponent from MessageListRenderer
This commit is contained in:
		@@ -50,7 +50,6 @@ public class ContextMenu extends JPopupMenu {
 | 
			
		||||
 | 
			
		||||
	private ButtonGroup	radioButtonGroup	= new ButtonGroup();
 | 
			
		||||
	private boolean		built				= false;
 | 
			
		||||
	private boolean		visible				= false;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * @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));
 | 
			
		||||
			add(item);
 | 
			
		||||
		});
 | 
			
		||||
		getInvoker().addMouseListener(getShowingListener());
 | 
			
		||||
		built = true;
 | 
			
		||||
		if (getInvoker() != null) {
 | 
			
		||||
			getInvoker().addMouseListener(getShowingListener());
 | 
			
		||||
			built = true;
 | 
			
		||||
		}
 | 
			
		||||
		return this;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -138,10 +139,8 @@ public class ContextMenu extends JPopupMenu {
 | 
			
		||||
				if (!built) build();
 | 
			
		||||
				if (e.isPopupTrigger()) {
 | 
			
		||||
					// hides the menu if already visible
 | 
			
		||||
					visible = !visible;
 | 
			
		||||
					if (visible) show(e.getComponent(), e.getX(), e.getY());
 | 
			
		||||
					if (!isVisible()) show(e.getComponent(), e.getX(), e.getY());
 | 
			
		||||
					else setVisible(false);
 | 
			
		||||
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		};
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										120
									
								
								src/main/java/envoy/client/ui/MessageComponent.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										120
									
								
								src/main/java/envoy/client/ui/MessageComponent.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,120 @@
 | 
			
		||||
package envoy.client.ui;
 | 
			
		||||
 | 
			
		||||
import java.awt.*;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.text.SimpleDateFormat;
 | 
			
		||||
import java.util.EnumMap;
 | 
			
		||||
 | 
			
		||||
import javax.swing.*;
 | 
			
		||||
 | 
			
		||||
import envoy.client.data.Settings;
 | 
			
		||||
import envoy.client.ui.list.ComponentList;
 | 
			
		||||
import envoy.data.Message;
 | 
			
		||||
import envoy.data.Message.MessageStatus;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Project: <strong>envoy-client</strong>
 | 
			
		||||
 * File: <strong>MessageComponent.java</strong>
 | 
			
		||||
 * Created: <strong>21.03.2020</strong>
 | 
			
		||||
 *
 | 
			
		||||
 * @author Kai S. K. Engelbart
 | 
			
		||||
 * @since Envoy v0.1-beta
 | 
			
		||||
 */
 | 
			
		||||
public class MessageComponent extends JPanel {
 | 
			
		||||
 | 
			
		||||
	private static final long serialVersionUID = 103920706139926996L;
 | 
			
		||||
 | 
			
		||||
	private static EnumMap<MessageStatus, ImageIcon>	statusIcons;
 | 
			
		||||
	private static ImageIcon							forwardIcon;
 | 
			
		||||
 | 
			
		||||
	static {
 | 
			
		||||
		try {
 | 
			
		||||
			statusIcons	= IconUtil.loadByEnum(MessageStatus.class, 16);
 | 
			
		||||
			forwardIcon	= IconUtil.load("/icons/forward.png", 16);
 | 
			
		||||
		} catch (IOException e) {
 | 
			
		||||
			e.printStackTrace();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public MessageComponent(ComponentList<? extends Message> list, Message message, boolean isSelected, long senderId) {
 | 
			
		||||
		this(list.getMaximumSize().width, message, isSelected, senderId);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public MessageComponent(int width, Message message, boolean isSelected, long senderId) {
 | 
			
		||||
		final var	theme	= Settings.getInstance().getThemes().get(Settings.getInstance().getCurrentTheme());
 | 
			
		||||
		final int	padding	= (int) (width * 0.35);
 | 
			
		||||
 | 
			
		||||
		GridBagLayout gbl_panel = new GridBagLayout();
 | 
			
		||||
		gbl_panel.columnWidths	= new int[] { 1, 1 };
 | 
			
		||||
		gbl_panel.rowHeights	= new int[] { 1, 1 };
 | 
			
		||||
		gbl_panel.columnWeights	= new double[] { 1, 1 };
 | 
			
		||||
		gbl_panel.rowWeights	= new double[] { 1, 1 };
 | 
			
		||||
 | 
			
		||||
		setLayout(gbl_panel);
 | 
			
		||||
		setBackground(isSelected ? theme.getSelectionColor() : theme.getCellColor());
 | 
			
		||||
 | 
			
		||||
		// 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()));
 | 
			
		||||
		dateLabel.setForeground(theme.getDateColor());
 | 
			
		||||
		dateLabel.setAlignmentX(1f);
 | 
			
		||||
		dateLabel.setFont(new Font("Arial", Font.PLAIN, 12));
 | 
			
		||||
		dateLabel.setPreferredSize(dateLabel.getPreferredSize());
 | 
			
		||||
 | 
			
		||||
		var gbc_dateLabel = new GridBagConstraints();
 | 
			
		||||
		gbc_dateLabel.fill	= GridBagConstraints.BOTH;
 | 
			
		||||
		gbc_dateLabel.gridx	= 0;
 | 
			
		||||
		gbc_dateLabel.gridy	= 0;
 | 
			
		||||
		add(dateLabel, gbc_dateLabel);
 | 
			
		||||
 | 
			
		||||
		// Message area - The JTextArea that displays the text content of a message.
 | 
			
		||||
		var messageTextArea = new JTextArea(message.getText());
 | 
			
		||||
		messageTextArea.setLineWrap(true);
 | 
			
		||||
		messageTextArea.setWrapStyleWord(true);
 | 
			
		||||
		messageTextArea.setForeground(theme.getMessageTextColor());
 | 
			
		||||
		messageTextArea.setAlignmentX(0.5f);
 | 
			
		||||
		messageTextArea.setBackground(theme.getCellColor());
 | 
			
		||||
		messageTextArea.setEditable(false);
 | 
			
		||||
		var font = new Font("Arial", Font.PLAIN, 14);
 | 
			
		||||
		messageTextArea.setFont(font);
 | 
			
		||||
		messageTextArea.setSize(width - padding - 16, 10);
 | 
			
		||||
 | 
			
		||||
		var gbc_messageTextArea = new GridBagConstraints();
 | 
			
		||||
		gbc_messageTextArea.fill	= GridBagConstraints.HORIZONTAL;
 | 
			
		||||
		gbc_messageTextArea.gridx	= 0;
 | 
			
		||||
		gbc_messageTextArea.gridy	= 1;
 | 
			
		||||
		add(messageTextArea, gbc_messageTextArea);
 | 
			
		||||
 | 
			
		||||
		// Status Label - displays the status of the message
 | 
			
		||||
		var statusLabel = new JLabel(statusIcons.get(message.getStatus()));
 | 
			
		||||
 | 
			
		||||
		var gbc_statusLabel = new GridBagConstraints();
 | 
			
		||||
		gbc_statusLabel.gridx	= 1;
 | 
			
		||||
		gbc_statusLabel.gridy	= 1;
 | 
			
		||||
		add(statusLabel, gbc_statusLabel);
 | 
			
		||||
 | 
			
		||||
		// Forwarding
 | 
			
		||||
		if (message.isForwarded()) {
 | 
			
		||||
			var forwardLabel = new JLabel("Forwarded", forwardIcon, SwingConstants.CENTER);
 | 
			
		||||
			forwardLabel.setBackground(getBackground());
 | 
			
		||||
			forwardLabel.setForeground(Color.lightGray);
 | 
			
		||||
 | 
			
		||||
			var gbc_forwardLabel = new GridBagConstraints();
 | 
			
		||||
			gbc_forwardLabel.fill	= GridBagConstraints.BOTH;
 | 
			
		||||
			gbc_forwardLabel.gridx	= 1;
 | 
			
		||||
			gbc_forwardLabel.gridy	= 0;
 | 
			
		||||
			add(forwardLabel, gbc_forwardLabel);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Define an etched border and some space to the messages below
 | 
			
		||||
		var ours = senderId == message.getSenderId();
 | 
			
		||||
		setBorder(BorderFactory.createCompoundBorder(
 | 
			
		||||
				BorderFactory.createEmptyBorder(0, ours ? padding : 10, 10, ours ? 0 : padding),
 | 
			
		||||
				BorderFactory.createEtchedBorder()));
 | 
			
		||||
 | 
			
		||||
		var size = new Dimension(width - 50, getPreferredSize().height);
 | 
			
		||||
 | 
			
		||||
		setPreferredSize(size);
 | 
			
		||||
		setMinimumSize(size);
 | 
			
		||||
		setMaximumSize(size);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -125,16 +125,14 @@ public class ChatWindow extends JFrame {
 | 
			
		||||
		gbl_contentPane.rowWeights		= new double[] { 0.03, 0.001, 1.0, 0.005 };
 | 
			
		||||
		contentPane.setLayout(gbl_contentPane);
 | 
			
		||||
 | 
			
		||||
		messageList.setBorder(new EmptyBorder(space, space, space, space));
 | 
			
		||||
		messageList.setSelectionMode(SelectionMode.SINGLE);
 | 
			
		||||
		// ContextMenu
 | 
			
		||||
		Map<String, ActionListener> commands = new HashMap<>() {
 | 
			
		||||
 | 
			
		||||
			private static final long serialVersionUID = -2755235774946990126L;
 | 
			
		||||
 | 
			
		||||
			{
 | 
			
		||||
				put("forward selected message",
 | 
			
		||||
						evt -> forwardMessageToMultipleUsers(messageList
 | 
			
		||||
							.getSingleSelectedElement(),
 | 
			
		||||
						evt -> forwardMessageToMultipleUsers(messageList.getSingleSelectedElement(),
 | 
			
		||||
								ContactsChooserDialog
 | 
			
		||||
									.showForwardingDialog("Forward selected message to", messageList.getSingleSelectedElement(), client)));
 | 
			
		||||
				put("copy", evt -> {
 | 
			
		||||
@@ -151,6 +149,11 @@ public class ChatWindow extends JFrame {
 | 
			
		||||
		};
 | 
			
		||||
		contextMenu = new ContextMenu(null, messageList, commands, null, null).build();
 | 
			
		||||
 | 
			
		||||
		messageList.setBorder(new EmptyBorder(space, space, space, space));
 | 
			
		||||
		messageList.setSelectionMode(SelectionMode.SINGLE);
 | 
			
		||||
		messageList.setSelectionListener((list, comp) -> 
 | 
			
		||||
		contextMenu.show(comp, 0, 0));
 | 
			
		||||
 | 
			
		||||
		scrollPane.setViewportView(messageList);
 | 
			
		||||
		scrollPane.addComponentListener(new ComponentAdapter() {
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -76,7 +76,7 @@ public class ContactsChooserDialog extends JDialog {
 | 
			
		||||
		dialog.setVisible(true);
 | 
			
		||||
		dialog.repaint();
 | 
			
		||||
		dialog.revalidate();
 | 
			
		||||
		return results.size() > 0 ? results : null;
 | 
			
		||||
		return results;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,7 @@ import java.awt.event.MouseEvent;
 | 
			
		||||
import java.awt.event.MouseListener;
 | 
			
		||||
import java.util.HashSet;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
import java.util.function.BiConsumer;
 | 
			
		||||
 | 
			
		||||
import javax.swing.*;
 | 
			
		||||
 | 
			
		||||
@@ -23,10 +24,11 @@ import javax.swing.*;
 | 
			
		||||
 */
 | 
			
		||||
public class ComponentList<E> extends JPanel {
 | 
			
		||||
 | 
			
		||||
	private ComponentListModel<E>			model;
 | 
			
		||||
	private ComponentListCellRenderer<E>	renderer;
 | 
			
		||||
	private SelectionMode					selectionMode	= SelectionMode.NONE;
 | 
			
		||||
	private Set<Integer>					selection		= new HashSet<>();
 | 
			
		||||
	private ComponentListModel<E>						model;
 | 
			
		||||
	private ComponentListCellRenderer<E>				renderer;
 | 
			
		||||
	private SelectionMode								selectionMode	= SelectionMode.NONE;
 | 
			
		||||
	private Set<Integer>								selection		= new HashSet<>();
 | 
			
		||||
	private BiConsumer<ComponentList<E>, JComponent>	selectionListener;
 | 
			
		||||
 | 
			
		||||
	private static final long serialVersionUID = 1759644503942876737L;
 | 
			
		||||
 | 
			
		||||
@@ -142,6 +144,9 @@ public class ComponentList<E> extends JPanel {
 | 
			
		||||
 | 
			
		||||
				// Update element
 | 
			
		||||
				updateElement(index, true);
 | 
			
		||||
 | 
			
		||||
				// Trigger selection listener
 | 
			
		||||
				if (selectionListener != null) selectionListener.accept(this, (JComponent) getComponents()[index]);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
@@ -273,4 +278,14 @@ public class ComponentList<E> extends JPanel {
 | 
			
		||||
	 * @since Envoy v0.1-beta
 | 
			
		||||
	 */
 | 
			
		||||
	public void setSelectionMode(SelectionMode selectionMode) { this.selectionMode = selectionMode; }
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * @return the selectionListener
 | 
			
		||||
	 */
 | 
			
		||||
	public BiConsumer<ComponentList<E>, JComponent> getSelectionListener() { return selectionListener; }
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * @param selectionListener the selectionListener to set
 | 
			
		||||
	 */
 | 
			
		||||
	public void setSelectionListener(BiConsumer<ComponentList<E>, JComponent> selectionListener) { this.selectionListener = selectionListener; }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,19 +1,11 @@
 | 
			
		||||
package envoy.client.ui.renderer;
 | 
			
		||||
 | 
			
		||||
import java.awt.*;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.text.SimpleDateFormat;
 | 
			
		||||
import java.util.EnumMap;
 | 
			
		||||
import javax.swing.JPanel;
 | 
			
		||||
 | 
			
		||||
import javax.swing.*;
 | 
			
		||||
 | 
			
		||||
import envoy.client.data.Settings;
 | 
			
		||||
import envoy.client.ui.Color;
 | 
			
		||||
import envoy.client.ui.IconUtil;
 | 
			
		||||
import envoy.client.ui.MessageComponent;
 | 
			
		||||
import envoy.client.ui.list.ComponentList;
 | 
			
		||||
import envoy.client.ui.list.ComponentListCellRenderer;
 | 
			
		||||
import envoy.data.Message;
 | 
			
		||||
import envoy.data.Message.MessageStatus;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Defines how a message is displayed.<br>
 | 
			
		||||
@@ -29,18 +21,6 @@ import envoy.data.Message.MessageStatus;
 | 
			
		||||
 */
 | 
			
		||||
public class MessageListRenderer implements ComponentListCellRenderer<Message> {
 | 
			
		||||
 | 
			
		||||
	private static EnumMap<MessageStatus, ImageIcon>	statusIcons;
 | 
			
		||||
	private static ImageIcon							forwardIcon;
 | 
			
		||||
 | 
			
		||||
	static {
 | 
			
		||||
		try {
 | 
			
		||||
			statusIcons = IconUtil.loadByEnum(MessageStatus.class, 16);
 | 
			
		||||
			forwardIcon	= IconUtil.load("/icons/forward.png", 16);
 | 
			
		||||
		} catch (IOException e) {
 | 
			
		||||
			e.printStackTrace();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private final long senderId;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
@@ -57,84 +37,6 @@ public class MessageListRenderer implements ComponentListCellRenderer<Message> {
 | 
			
		||||
 | 
			
		||||
	@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();
 | 
			
		||||
		gbl_panel.columnWidths	= new int[] { 1, 1 };
 | 
			
		||||
		gbl_panel.rowHeights	= new int[] { 1, 1 };
 | 
			
		||||
		gbl_panel.columnWeights	= new double[] { 1, 1 };
 | 
			
		||||
		gbl_panel.rowWeights	= new double[] { 1, 1 };
 | 
			
		||||
 | 
			
		||||
		panel.setLayout(gbl_panel);
 | 
			
		||||
		panel.setBackground(isSelected ? theme.getSelectionColor() : theme.getCellColor());
 | 
			
		||||
 | 
			
		||||
		// 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()));
 | 
			
		||||
		dateLabel.setForeground(theme.getDateColor());
 | 
			
		||||
		dateLabel.setAlignmentX(1f);
 | 
			
		||||
		dateLabel.setFont(new Font("Arial", Font.PLAIN, 12));
 | 
			
		||||
		dateLabel.setPreferredSize(dateLabel.getPreferredSize());
 | 
			
		||||
 | 
			
		||||
		var gbc_dateLabel = new GridBagConstraints();
 | 
			
		||||
		gbc_dateLabel.fill	= GridBagConstraints.BOTH;
 | 
			
		||||
		gbc_dateLabel.gridx	= 0;
 | 
			
		||||
		gbc_dateLabel.gridy	= 0;
 | 
			
		||||
		panel.add(dateLabel, gbc_dateLabel);
 | 
			
		||||
 | 
			
		||||
		// Message area - The JTextArea that displays the text content of a message.
 | 
			
		||||
		var messageTextArea = new JTextArea(message.getText());
 | 
			
		||||
		messageTextArea.setLineWrap(true);
 | 
			
		||||
		messageTextArea.setWrapStyleWord(true);
 | 
			
		||||
		messageTextArea.setForeground(theme.getMessageTextColor());
 | 
			
		||||
		messageTextArea.setAlignmentX(0.5f);
 | 
			
		||||
		messageTextArea.setBackground(theme.getCellColor());
 | 
			
		||||
		messageTextArea.setEditable(false);
 | 
			
		||||
		var font = new Font("Arial", Font.PLAIN, 14);
 | 
			
		||||
		messageTextArea.setFont(font);
 | 
			
		||||
		messageTextArea.setSize(list.getMaximumSize().width - padding - 16, 10);
 | 
			
		||||
 | 
			
		||||
		var gbc_messageTextArea = new GridBagConstraints();
 | 
			
		||||
		gbc_messageTextArea.fill	= GridBagConstraints.HORIZONTAL;
 | 
			
		||||
		gbc_messageTextArea.gridx	= 0;
 | 
			
		||||
		gbc_messageTextArea.gridy	= 1;
 | 
			
		||||
		panel.add(messageTextArea, gbc_messageTextArea);
 | 
			
		||||
 | 
			
		||||
		// Status Label - displays the status of the message
 | 
			
		||||
		var statusLabel = new JLabel(statusIcons.get(message.getStatus()));
 | 
			
		||||
 | 
			
		||||
		var gbc_statusLabel = new GridBagConstraints();
 | 
			
		||||
		gbc_statusLabel.gridx	= 1;
 | 
			
		||||
		gbc_statusLabel.gridy	= 1;
 | 
			
		||||
		panel.add(statusLabel, gbc_statusLabel);
 | 
			
		||||
 | 
			
		||||
		// Forwarding
 | 
			
		||||
		if (message.isForwarded()) {
 | 
			
		||||
			var forwardLabel = new JLabel("Forwarded", forwardIcon, SwingConstants.CENTER);
 | 
			
		||||
			forwardLabel.setBackground(panel.getBackground());
 | 
			
		||||
			forwardLabel.setForeground(Color.lightGray);
 | 
			
		||||
 | 
			
		||||
			var gbc_forwardLabel = new GridBagConstraints();
 | 
			
		||||
			gbc_forwardLabel.fill	= GridBagConstraints.BOTH;
 | 
			
		||||
			gbc_forwardLabel.gridx	= 1;
 | 
			
		||||
			gbc_forwardLabel.gridy	= 0;
 | 
			
		||||
			panel.add(forwardLabel, gbc_forwardLabel);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Define an etched border and some space to the messages below
 | 
			
		||||
		var ours = senderId == message.getSenderId();
 | 
			
		||||
		panel.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(0, ours ? padding : 0, 10, ours ? 0 : padding),
 | 
			
		||||
				BorderFactory.createEtchedBorder()));
 | 
			
		||||
 | 
			
		||||
		var size = new Dimension(list.getMaximumSize().width - 50, panel.getPreferredSize().height);
 | 
			
		||||
 | 
			
		||||
		panel.setPreferredSize(size);
 | 
			
		||||
		panel.setMinimumSize(size);
 | 
			
		||||
		panel.setMaximumSize(size);
 | 
			
		||||
 | 
			
		||||
		return panel;
 | 
			
		||||
		return new MessageComponent(list, message, isSelected, senderId);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user