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