Added selection capability to ComponentList (#112)
* Fixed Javadoc error in EnvoyLog * Added selection support to ComponentList using MouseListener injection * Added selection support to MessageListRenderer * Clearing selection when reselecting an already selected element
This commit is contained in:
		@@ -3,7 +3,9 @@ package envoy.client.ui;
 | 
			
		||||
import java.awt.Dimension;
 | 
			
		||||
import java.text.SimpleDateFormat;
 | 
			
		||||
 | 
			
		||||
import javax.swing.*;
 | 
			
		||||
import javax.swing.BorderFactory;
 | 
			
		||||
import javax.swing.JLabel;
 | 
			
		||||
import javax.swing.JPanel;
 | 
			
		||||
 | 
			
		||||
import envoy.client.data.Settings;
 | 
			
		||||
import envoy.client.ui.list.ComponentList;
 | 
			
		||||
@@ -24,18 +26,12 @@ import envoy.data.Message;
 | 
			
		||||
public class MessageListRenderer implements ComponentListCellRenderer<Message> {
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public JComponent getListCellComponent(ComponentList<? extends Message> list, Message value, boolean isSelected) {
 | 
			
		||||
		final JPanel panel = new JPanel();
 | 
			
		||||
		if (isSelected) {
 | 
			
		||||
			panel.setBackground(Color.DARK_GRAY);
 | 
			
		||||
			panel.setForeground(Color.RED);
 | 
			
		||||
			// TODO: Selection
 | 
			
		||||
			// setBackground(list.getSelectionBackground());
 | 
			
		||||
			// setForeground(list.getSelectionForeground());
 | 
			
		||||
		} else {
 | 
			
		||||
			panel.setBackground(list.getBackground());
 | 
			
		||||
			panel.setForeground(list.getForeground());
 | 
			
		||||
		}
 | 
			
		||||
	public JPanel getListCellComponent(ComponentList<? extends Message> list, Message value, boolean isSelected) {
 | 
			
		||||
		final JPanel	panel	= new JPanel();
 | 
			
		||||
		final Theme		theme	= Settings.getInstance().getThemes().get(Settings.getInstance().getCurrentTheme());
 | 
			
		||||
 | 
			
		||||
		// Panel background
 | 
			
		||||
		panel.setBackground(isSelected ? theme.getSelectionColor() : theme.getCellColor());
 | 
			
		||||
 | 
			
		||||
		// TODO: Handle message attachments
 | 
			
		||||
 | 
			
		||||
@@ -43,11 +39,11 @@ public class MessageListRenderer implements ComponentListCellRenderer<Message> {
 | 
			
		||||
		final String	state	= value.getStatus().toString();
 | 
			
		||||
		final String	date	= new SimpleDateFormat("dd.MM.yyyy HH.mm").format(value.getCreationDate());
 | 
			
		||||
 | 
			
		||||
		// Getting the MessageColor in the Chat of the current theme
 | 
			
		||||
		String textColor = Settings.getInstance().getThemes().get(Settings.getInstance().getCurrentTheme()).getMessageColorChat().toHex();
 | 
			
		||||
		// Message text color
 | 
			
		||||
		String textColor = theme.getMessageColorChat().toHex();
 | 
			
		||||
 | 
			
		||||
		// Getting the DateColor in the Chat of the current theme
 | 
			
		||||
		String dateColor = Settings.getInstance().getThemes().get(Settings.getInstance().getCurrentTheme()).getDateColorChat().toHex();
 | 
			
		||||
		// Message date color
 | 
			
		||||
		String dateColor = theme.getDateColorChat().toHex();
 | 
			
		||||
 | 
			
		||||
		panel.add(new JLabel(String.format("<html><p style=\"color:%s\"><b><small>%s</b></small><br><p style=\"color:%s\">%s :%s</html>",
 | 
			
		||||
				dateColor,
 | 
			
		||||
@@ -57,10 +53,10 @@ public class MessageListRenderer implements ComponentListCellRenderer<Message> {
 | 
			
		||||
				state)));
 | 
			
		||||
 | 
			
		||||
		// Define some space to the messages below
 | 
			
		||||
		panel.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(0, 0, 15, 0), BorderFactory.createEtchedBorder()));
 | 
			
		||||
		panel.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(), BorderFactory.createEtchedBorder()));
 | 
			
		||||
 | 
			
		||||
		// Define a maximum height of 50px
 | 
			
		||||
		Dimension size = new Dimension(list.getWidth() - 25, 50);
 | 
			
		||||
		// Set the width to the list width
 | 
			
		||||
		Dimension size = new Dimension(list.getWidth() - 25, panel.getPreferredSize().height);
 | 
			
		||||
		panel.setMaximumSize(size);
 | 
			
		||||
		panel.setMinimumSize(size);
 | 
			
		||||
		panel.setPreferredSize(size);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,10 @@
 | 
			
		||||
package envoy.client.ui.list;
 | 
			
		||||
 | 
			
		||||
import javax.swing.BoxLayout;
 | 
			
		||||
import javax.swing.JPanel;
 | 
			
		||||
import java.awt.event.MouseAdapter;
 | 
			
		||||
import java.awt.event.MouseEvent;
 | 
			
		||||
import java.awt.event.MouseListener;
 | 
			
		||||
 | 
			
		||||
import javax.swing.*;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Provides a vertical list layout of components provided in a
 | 
			
		||||
@@ -21,6 +24,8 @@ public class ComponentList<E> extends JPanel {
 | 
			
		||||
	private ComponentListModel<E>			model;
 | 
			
		||||
	private ComponentListCellRenderer<E>	renderer;
 | 
			
		||||
 | 
			
		||||
	private int currentSelection = -1;
 | 
			
		||||
 | 
			
		||||
	private static final long serialVersionUID = 1759644503942876737L;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
@@ -50,22 +55,22 @@ public class ComponentList<E> extends JPanel {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Sets the list model providing the list elements to render
 | 
			
		||||
	 * 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);
 | 
			
		||||
		if (this.model != null) this.model.setComponentList(null);
 | 
			
		||||
 | 
			
		||||
		// Synchronize with new model
 | 
			
		||||
		this.model = model;
 | 
			
		||||
		if (model != null) {
 | 
			
		||||
			this.model.setComponentList(this);
 | 
			
		||||
			synchronizeModel();
 | 
			
		||||
		} else removeAll();
 | 
			
		||||
		if (model != null) this.model.setComponentList(this);
 | 
			
		||||
		synchronizeModel();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
@@ -76,8 +81,7 @@ public class ComponentList<E> extends JPanel {
 | 
			
		||||
	 */
 | 
			
		||||
	public void synchronizeModel() {
 | 
			
		||||
		removeAll();
 | 
			
		||||
		if (model != null) for (E elem : model)
 | 
			
		||||
			add(elem);
 | 
			
		||||
		if (model != null) model.forEach(this::add);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
@@ -87,7 +91,83 @@ public class ComponentList<E> extends JPanel {
 | 
			
		||||
	 * @param elem the element to add
 | 
			
		||||
	 * @since Envoy v0.3-alpha
 | 
			
		||||
	 */
 | 
			
		||||
	void add(E elem) {
 | 
			
		||||
		add(renderer.getListCellComponent(this, elem, false));
 | 
			
		||||
	void add(E elem) { add(elem, getComponentCount(), false); }
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Adds an object to the list by rendering it with the current
 | 
			
		||||
	 * {@link ComponentListRenderer}.
 | 
			
		||||
	 *
 | 
			
		||||
	 * @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 add(E elem, int index, boolean isSelected) {
 | 
			
		||||
		final JComponent component = renderer.getListCellComponent(this, elem, isSelected);
 | 
			
		||||
		component.addMouseListener(getSelectionListener(index));
 | 
			
		||||
		add(component, index);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * @param componentIndex the index of the list component to which the mouse
 | 
			
		||||
	 *                       listener will be added
 | 
			
		||||
	 * @return a mouse listener calling the
 | 
			
		||||
	 *         {@link ComponentList#componentSelected(int)} method with the
 | 
			
		||||
	 *         component's index when a left click is performed by the user
 | 
			
		||||
	 * @since Envoy v0.1-beta
 | 
			
		||||
	 */
 | 
			
		||||
	private MouseListener getSelectionListener(int componentIndex) {
 | 
			
		||||
		return new MouseAdapter() {
 | 
			
		||||
 | 
			
		||||
			@Override
 | 
			
		||||
			public void mouseClicked(MouseEvent e) { if (SwingUtilities.isLeftMouseButton(e)) { componentSelected(componentIndex); } }
 | 
			
		||||
		};
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Gets called when a list component has been clicked on by the user. Any
 | 
			
		||||
	 * previous selections are then removed and the selected component gets
 | 
			
		||||
	 * redrawn.<br>
 | 
			
		||||
	 * <br>
 | 
			
		||||
	 * If the currently selected component gets selected again, the selection is
 | 
			
		||||
	 * removed.
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param index the index of the selected component
 | 
			
		||||
	 * @since Envoy v0.1-beta
 | 
			
		||||
	 */
 | 
			
		||||
	private void componentSelected(int index) {
 | 
			
		||||
		if (index == currentSelection) {
 | 
			
		||||
 | 
			
		||||
			// Clear selection
 | 
			
		||||
			update(currentSelection, false);
 | 
			
		||||
			currentSelection = -1;
 | 
			
		||||
			
 | 
			
		||||
		} else {
 | 
			
		||||
 | 
			
		||||
			// Remove old selection
 | 
			
		||||
			if (currentSelection >= 0) update(currentSelection, false);
 | 
			
		||||
 | 
			
		||||
			// Assign new selection
 | 
			
		||||
			currentSelection = index;
 | 
			
		||||
 | 
			
		||||
			// Update current selection
 | 
			
		||||
			update(currentSelection, true);
 | 
			
		||||
			
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		revalidate();
 | 
			
		||||
		repaint();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * 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 update(int index, boolean isSelected) {
 | 
			
		||||
		remove(index);
 | 
			
		||||
		add(model.get(index), index, isSelected);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -61,7 +61,7 @@ public class EnvoyLog {
 | 
			
		||||
	 * path to use the console and file handlers.
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param path the path to the loggers to configure
 | 
			
		||||
	 * @since Envoy Client v0.4-alpha
 | 
			
		||||
	 * @since Envoy Client v0.1-beta
 | 
			
		||||
	 */
 | 
			
		||||
	public static void attach(String path) {
 | 
			
		||||
		// Get root logger
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user