Revised the rendering and selection mechanism in ComponentList
This commit is contained in:
		| @@ -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; |  | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| @@ -36,12 +36,12 @@ public class MessageComponent extends JPanel { | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	public MessageComponent(ComponentList<? extends Message> list, Message message, boolean isSelected, long senderId) { | 	public MessageComponent(ComponentList<? extends Message> list, Message message, long senderId) { | ||||||
| 		this(list.getMaximumSize().width, message, isSelected, senderId); | 		this(list.getMaximumSize().width, message, senderId); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	public MessageComponent(int width, Message message, boolean isSelected, long senderId) { | 	public MessageComponent(int width, Message message, long senderId) { | ||||||
| 		final var	theme	= Settings.getInstance().getThemes().get(Settings.getInstance().getCurrentTheme()); | 		final var	theme	= Settings.getInstance().getCurrentTheme(); | ||||||
| 		final int	padding	= (int) (width * 0.35); | 		final int	padding	= (int) (width * 0.35); | ||||||
|  |  | ||||||
| 		GridBagLayout gbl_panel = new GridBagLayout(); | 		GridBagLayout gbl_panel = new GridBagLayout(); | ||||||
| @@ -51,7 +51,7 @@ public class MessageComponent extends JPanel { | |||||||
| 		gbl_panel.rowWeights	= new double[] { 1, 1 }; | 		gbl_panel.rowWeights	= new double[] { 1, 1 }; | ||||||
|  |  | ||||||
| 		setLayout(gbl_panel); | 		setLayout(gbl_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())); | ||||||
|   | |||||||
							
								
								
									
										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 | ||||||
| @@ -86,13 +81,12 @@ public class ChatWindow extends JFrame { | |||||||
| 	private PrimaryButton	addContact		= new PrimaryButton("+"); | 	private PrimaryButton	addContact		= new PrimaryButton("+"); | ||||||
|  |  | ||||||
| 	// Search Contacts | 	// Search Contacts | ||||||
| 	private final JPanel					searchPane					= new JPanel(); | 	private final JPanel				searchPane					= new JPanel(); | ||||||
| 	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); | ||||||
|  |  | ||||||
| @@ -151,8 +145,11 @@ public class ChatWindow extends JFrame { | |||||||
|  |  | ||||||
| 		messageList.setBorder(new EmptyBorder(space, space, space, space)); | 		messageList.setBorder(new EmptyBorder(space, space, space, space)); | ||||||
| 		messageList.setSelectionMode(SelectionMode.SINGLE); | 		messageList.setSelectionMode(SelectionMode.SINGLE); | ||||||
| 		messageList.setSelectionListener((list, comp) ->  | 		messageList.setSelectionHandler((message, comp, isSelected) -> { | ||||||
| 		contextMenu.show(comp, 0, 0)); | 			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() { | ||||||
| @@ -399,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(); | ||||||
| @@ -648,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,11 +66,13 @@ 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(); | ||||||
| @@ -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()); | ||||||
|   | |||||||
| @@ -5,13 +5,12 @@ import java.awt.event.MouseEvent; | |||||||
| import java.awt.event.MouseListener; | import java.awt.event.MouseListener; | ||||||
| import java.util.HashSet; | import java.util.HashSet; | ||||||
| import java.util.Set; | import java.util.Set; | ||||||
| import java.util.function.BiConsumer; |  | ||||||
|  |  | ||||||
| import javax.swing.*; | 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> | ||||||
| @@ -24,11 +23,11 @@ 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 SelectionMode								selectionMode	= SelectionMode.NONE; | 	private SelectionHandler<E>	selectionHandler; | ||||||
| 	private Set<Integer>								selection		= new HashSet<>(); | 	private SelectionMode		selectionMode	= SelectionMode.NONE; | ||||||
| 	private BiConsumer<ComponentList<E>, JComponent>	selectionListener; | 	private Set<Integer>		selection		= new HashSet<>(); | ||||||
|  |  | ||||||
| 	private static final long serialVersionUID = 1759644503942876737L; | 	private static final long serialVersionUID = 1759644503942876737L; | ||||||
|  |  | ||||||
| @@ -55,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(); | ||||||
| @@ -127,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 { | ||||||
|  |  | ||||||
| @@ -143,10 +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); | ||||||
|  |  | ||||||
| 				// Trigger selection listener |  | ||||||
| 				if (selectionListener != null) selectionListener.accept(this, (JComponent) getComponents()[index]); |  | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| @@ -160,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 | ||||||
| @@ -219,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 | ||||||
| @@ -253,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 | ||||||
| @@ -274,18 +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 selectionListener | 	 * @return the selection handler | ||||||
|  | 	 * @since Envoy v0.1-beta | ||||||
| 	 */ | 	 */ | ||||||
| 	public BiConsumer<ComponentList<E>, JComponent> getSelectionListener() { return selectionListener; } | 	public SelectionHandler<E> getSelectionHandler() { return selectionHandler; } | ||||||
|  |  | ||||||
| 	/** | 	/** | ||||||
| 	 * @param selectionListener the selectionListener to set | 	 * @param selectionHandler the selection handler to set | ||||||
|  | 	 * @since Envoy v0.1-beta | ||||||
| 	 */ | 	 */ | ||||||
| 	public void setSelectionListener(BiConsumer<ComponentList<E>, JComponent> selectionListener) { this.selectionListener = selectionListener; } | 	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,42 +0,0 @@ | |||||||
| package envoy.client.ui.renderer; |  | ||||||
|  |  | ||||||
| import javax.swing.JPanel; |  | ||||||
|  |  | ||||||
| import envoy.client.ui.MessageComponent; |  | ||||||
| import envoy.client.ui.list.ComponentList; |  | ||||||
| import envoy.client.ui.list.ComponentListCellRenderer; |  | ||||||
| import envoy.data.Message; |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * Defines how a message is displayed.<br> |  | ||||||
|  * <br> |  | ||||||
|  * Project: <strong>envoy-client</strong><br> |  | ||||||
|  * File: <strong>MessageListRenderer.java</strong><br> |  | ||||||
|  * Created: <strong>19 Oct 2019</strong><br> |  | ||||||
|  * |  | ||||||
|  * @author Kai S. K. Engelbart |  | ||||||
|  * @author Maximilian Käfer |  | ||||||
|  * @author Leon Hofmeister |  | ||||||
|  * @since Envoy v0.1-alpha |  | ||||||
|  */ |  | ||||||
| public class MessageListRenderer implements ComponentListCellRenderer<Message> { |  | ||||||
|  |  | ||||||
| 	private final long senderId; |  | ||||||
|  |  | ||||||
| 	/** |  | ||||||
| 	 * Initializes a message list renderer. Messages with the given sender ID will |  | ||||||
| 	 * be aligned on the right side, while all other messages will be aligned on |  | ||||||
| 	 * 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) { |  | ||||||
| 		return new MessageComponent(list, message, isSelected, senderId); |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| @@ -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,8 +38,9 @@ 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 Logger	logger				= EnvoyLog.getLogger(ThemeCustomizationPanel.class); | 	private static final Settings	settings			= Settings.getInstance(); | ||||||
| 	private static final long	serialVersionUID	= -8697897390666456624L; | 	private static final Logger		logger				= EnvoyLog.getLogger(ThemeCustomizationPanel.class); | ||||||
|  | 	private static final long		serialVersionUID	= -8697897390666456624L; | ||||||
|  |  | ||||||
| 	/** | 	/** | ||||||
| 	 * Initializes a {@link ThemeCustomizationPanel} that enables the user to change | 	 * Initializes a {@link ThemeCustomizationPanel} that enables the user to change | ||||||
| @@ -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