Merge pull request #63 from informatik-ag-ngl/f/settings_panel
Added SettingsPanel architecture
This commit is contained in:
		@@ -1,12 +1,7 @@
 | 
			
		||||
package envoy.client;
 | 
			
		||||
 | 
			
		||||
import java.awt.Color;
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.io.FileInputStream;
 | 
			
		||||
import java.io.FileOutputStream;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.io.ObjectInputStream;
 | 
			
		||||
import java.io.ObjectOutputStream;
 | 
			
		||||
import java.io.*;
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.prefs.Preferences;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,34 +1,18 @@
 | 
			
		||||
package envoy.client.ui;
 | 
			
		||||
 | 
			
		||||
import java.awt.ComponentOrientation;
 | 
			
		||||
import java.awt.Font;
 | 
			
		||||
import java.awt.GridBagConstraints;
 | 
			
		||||
import java.awt.GridBagLayout;
 | 
			
		||||
import java.awt.Insets;
 | 
			
		||||
import java.awt.Toolkit;
 | 
			
		||||
import java.awt.*;
 | 
			
		||||
import java.awt.event.KeyAdapter;
 | 
			
		||||
import java.awt.event.KeyEvent;
 | 
			
		||||
import java.util.logging.Level;
 | 
			
		||||
import java.util.logging.Logger;
 | 
			
		||||
 | 
			
		||||
import javax.swing.DefaultListModel;
 | 
			
		||||
import javax.swing.JFrame;
 | 
			
		||||
import javax.swing.JList;
 | 
			
		||||
import javax.swing.JOptionPane;
 | 
			
		||||
import javax.swing.JPanel;
 | 
			
		||||
import javax.swing.JTextPane;
 | 
			
		||||
import javax.swing.ListSelectionModel;
 | 
			
		||||
import javax.swing.SwingUtilities;
 | 
			
		||||
import javax.swing.Timer;
 | 
			
		||||
import javax.swing.*;
 | 
			
		||||
import javax.swing.border.EmptyBorder;
 | 
			
		||||
 | 
			
		||||
import envoy.client.Chat;
 | 
			
		||||
import envoy.client.Client;
 | 
			
		||||
import envoy.client.Config;
 | 
			
		||||
import envoy.client.LocalDB;
 | 
			
		||||
import envoy.client.Settings;
 | 
			
		||||
import envoy.client.*;
 | 
			
		||||
import envoy.client.event.EventBus;
 | 
			
		||||
import envoy.client.event.ThemeChangeEvent;
 | 
			
		||||
import envoy.client.ui.settings.SettingsScreen;
 | 
			
		||||
import envoy.client.util.EnvoyLog;
 | 
			
		||||
import envoy.schema.Message;
 | 
			
		||||
import envoy.schema.User;
 | 
			
		||||
@@ -158,7 +142,6 @@ public class ChatWindow extends JFrame {
 | 
			
		||||
		settingsButton.addActionListener((evt) -> {
 | 
			
		||||
			try {
 | 
			
		||||
				new SettingsScreen().setVisible(true);
 | 
			
		||||
				changeChatWindowColors(Settings.getInstance().getThemes().get(Settings.getInstance().getCurrentTheme()));
 | 
			
		||||
			} catch (Exception e) {
 | 
			
		||||
				logger.log(Level.WARNING, "An error occured while opening the settings screen", e);
 | 
			
		||||
				e.printStackTrace();
 | 
			
		||||
 
 | 
			
		||||
@@ -1,458 +0,0 @@
 | 
			
		||||
package envoy.client.ui;
 | 
			
		||||
 | 
			
		||||
import java.awt.BorderLayout;
 | 
			
		||||
import java.awt.Color;
 | 
			
		||||
import java.awt.Component;
 | 
			
		||||
import java.awt.Dimension;
 | 
			
		||||
import java.awt.Font;
 | 
			
		||||
import java.awt.GridBagConstraints;
 | 
			
		||||
import java.awt.GridBagLayout;
 | 
			
		||||
import java.awt.Insets;
 | 
			
		||||
import java.awt.event.ItemEvent;
 | 
			
		||||
import java.awt.event.ItemListener;
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
import java.util.logging.Level;
 | 
			
		||||
import java.util.logging.Logger;
 | 
			
		||||
 | 
			
		||||
import javax.swing.BoxLayout;
 | 
			
		||||
import javax.swing.DefaultListModel;
 | 
			
		||||
import javax.swing.JButton;
 | 
			
		||||
import javax.swing.JColorChooser;
 | 
			
		||||
import javax.swing.JComboBox;
 | 
			
		||||
import javax.swing.JDialog;
 | 
			
		||||
import javax.swing.JList;
 | 
			
		||||
import javax.swing.JOptionPane;
 | 
			
		||||
import javax.swing.JPanel;
 | 
			
		||||
import javax.swing.JTextPane;
 | 
			
		||||
import javax.swing.ListSelectionModel;
 | 
			
		||||
 | 
			
		||||
import envoy.client.Settings;
 | 
			
		||||
import envoy.client.util.EnvoyLog;
 | 
			
		||||
import envoy.client.event.EventBus;
 | 
			
		||||
import envoy.client.event.ThemeChangeEvent;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * This class provides the GUI to change the user specific settings.
 | 
			
		||||
 *
 | 
			
		||||
 * Project: <strong>envoy-client</strong><br>
 | 
			
		||||
 * File: <strong>SettingsScreen.java</strong><br>
 | 
			
		||||
 * Created: <strong>31 Oct 2019</strong><br>
 | 
			
		||||
 *
 | 
			
		||||
 * @author Leon Hofmeister
 | 
			
		||||
 * @author Maximilian Käfer
 | 
			
		||||
 * @author Kai S. K. Engelbart
 | 
			
		||||
 */
 | 
			
		||||
public class SettingsScreen extends JDialog {
 | 
			
		||||
 | 
			
		||||
	private static final long	serialVersionUID	= -4476913491263077107L;
 | 
			
		||||
	private final JPanel		contentPanel		= new JPanel();
 | 
			
		||||
 | 
			
		||||
	private DefaultListModel<String>	optionsListModel	= new DefaultListModel<>();
 | 
			
		||||
	private final JList<String>			options				= new JList<>();
 | 
			
		||||
	private JPanel						buttonPane			= new JPanel();
 | 
			
		||||
 | 
			
		||||
	private JPanel				themeContent	= new JPanel();
 | 
			
		||||
	private String[]			themeArray		= Settings.getInstance().getThemes().keySet().toArray(new String[0]);
 | 
			
		||||
	private JComboBox<String>	themes			= new JComboBox<>(themeArray);
 | 
			
		||||
 | 
			
		||||
	private GridBagConstraints gbc_themeContent = new GridBagConstraints();
 | 
			
		||||
 | 
			
		||||
	private JButton	createNewThemeButton	= new JButton("Create New Theme");
 | 
			
		||||
	private JPanel	colorsPanel				= new JPanel();
 | 
			
		||||
	private JButton	okButton				= new JButton("Save");
 | 
			
		||||
	private JButton	cancelButton			= new JButton("Cancel");
 | 
			
		||||
 | 
			
		||||
	private static int	space			= 5;
 | 
			
		||||
 | 
			
		||||
	private Theme temporaryTheme, selectedTheme;
 | 
			
		||||
 | 
			
		||||
	private static final Logger logger = EnvoyLog.getLogger(SettingsScreen.class.getSimpleName());
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Builds the settings screen.
 | 
			
		||||
	 *
 | 
			
		||||
	 * @since Envoy v0.1-alpha
 | 
			
		||||
	 */
 | 
			
		||||
	public SettingsScreen() {
 | 
			
		||||
		logger.info(Settings.getInstance().getCurrentTheme());
 | 
			
		||||
 | 
			
		||||
		setBounds(10, 10, 450, 650);
 | 
			
		||||
		getContentPane().setLayout(new BorderLayout());
 | 
			
		||||
		{
 | 
			
		||||
 | 
			
		||||
			createNewThemeButton.setEnabled(false);
 | 
			
		||||
 | 
			
		||||
			temporaryTheme = new Theme("temporaryTheme", Settings.getInstance().getThemes().get(Settings.getInstance().getCurrentTheme()));
 | 
			
		||||
 | 
			
		||||
			// Content pane
 | 
			
		||||
			GridBagLayout gbl_contentPanel = new GridBagLayout();
 | 
			
		||||
 | 
			
		||||
			gbl_contentPanel.columnWidths	= new int[] { 1, 1 };
 | 
			
		||||
			gbl_contentPanel.rowHeights		= new int[] { 1 };
 | 
			
		||||
			gbl_contentPanel.columnWeights	= new double[] { 0.05, 1.0 };
 | 
			
		||||
			gbl_contentPanel.rowWeights		= new double[] { 1.0 };
 | 
			
		||||
 | 
			
		||||
			getContentPane().add(contentPanel, BorderLayout.CENTER);
 | 
			
		||||
			contentPanel.setLayout(gbl_contentPanel);
 | 
			
		||||
 | 
			
		||||
			options.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
 | 
			
		||||
 | 
			
		||||
			options.addListSelectionListener((listSelectionEvent) -> {
 | 
			
		||||
				if (!listSelectionEvent.getValueIsAdjusting()) {
 | 
			
		||||
					@SuppressWarnings("unchecked")
 | 
			
		||||
					final JList<String>	selectedOption	= (JList<String>) listSelectionEvent.getSource();
 | 
			
		||||
					final String		option			= selectedOption.getSelectedValue();
 | 
			
		||||
					logger.log(Level.FINEST, option);
 | 
			
		||||
 | 
			
		||||
					switch (option) {
 | 
			
		||||
						case "Color Themes":
 | 
			
		||||
							setContent(themeContent, gbc_themeContent);
 | 
			
		||||
							getContentPane().repaint();
 | 
			
		||||
							getContentPane().revalidate();
 | 
			
		||||
							break;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			});
 | 
			
		||||
 | 
			
		||||
			options.setFont(new Font("Arial", Font.PLAIN, 14));
 | 
			
		||||
 | 
			
		||||
			Theme theme = Settings.getInstance().getThemes().get(Settings.getInstance().getCurrentTheme());
 | 
			
		||||
 | 
			
		||||
			GridBagConstraints gbc_optionsList = new GridBagConstraints();
 | 
			
		||||
			gbc_optionsList.fill	= GridBagConstraints.BOTH;
 | 
			
		||||
			gbc_optionsList.gridx	= 0;
 | 
			
		||||
			gbc_optionsList.gridy	= 0;
 | 
			
		||||
			gbc_optionsList.anchor	= GridBagConstraints.PAGE_START;
 | 
			
		||||
			gbc_optionsList.insets	= new Insets(space, space, space, space);
 | 
			
		||||
 | 
			
		||||
			optionsListModel.addElement("Color Themes");
 | 
			
		||||
			options.setModel(optionsListModel);
 | 
			
		||||
			contentPanel.add(options, gbc_optionsList);
 | 
			
		||||
 | 
			
		||||
			// Theme content
 | 
			
		||||
			gbc_themeContent		= new GridBagConstraints();
 | 
			
		||||
			gbc_themeContent.fill	= GridBagConstraints.BOTH;
 | 
			
		||||
			gbc_themeContent.gridx	= 1;
 | 
			
		||||
			gbc_themeContent.gridy	= 0;
 | 
			
		||||
			gbc_themeContent.anchor	= GridBagConstraints.PAGE_START;
 | 
			
		||||
			gbc_themeContent.insets	= new Insets(space, space, space, space);
 | 
			
		||||
 | 
			
		||||
			GridBagLayout gbl_themeLayout = new GridBagLayout();
 | 
			
		||||
 | 
			
		||||
			gbl_themeLayout.columnWidths	= new int[] { 1, 1 };
 | 
			
		||||
			gbl_themeLayout.rowHeights		= new int[] { 1, 1 };
 | 
			
		||||
			gbl_themeLayout.columnWeights	= new double[] { 1.0, 1.0 };
 | 
			
		||||
			gbl_themeLayout.rowWeights		= new double[] { 0.01, 1.0 };
 | 
			
		||||
 | 
			
		||||
			themeContent.setLayout(gbl_themeLayout);
 | 
			
		||||
 | 
			
		||||
			themes.setSelectedItem(Settings.getInstance().getCurrentTheme());
 | 
			
		||||
 | 
			
		||||
			themes.addItemListener(new ItemListener() {
 | 
			
		||||
 | 
			
		||||
				@Override
 | 
			
		||||
				public void itemStateChanged(ItemEvent e) {
 | 
			
		||||
					String selectedValue = (String) themes.getSelectedItem();
 | 
			
		||||
					logger.log(Level.FINEST, selectedValue);
 | 
			
		||||
					selectedTheme = Settings.getInstance().getThemes().get(selectedValue);
 | 
			
		||||
				}
 | 
			
		||||
			});
 | 
			
		||||
 | 
			
		||||
			GridBagConstraints gbc_themes = new GridBagConstraints();
 | 
			
		||||
			gbc_themes.fill		= GridBagConstraints.HORIZONTAL;
 | 
			
		||||
			gbc_themes.gridx	= 0;
 | 
			
		||||
			gbc_themes.gridy	= 0;
 | 
			
		||||
			gbc_themes.anchor	= GridBagConstraints.NORTHWEST;
 | 
			
		||||
			gbc_themes.insets	= new Insets(space, space, space, space);
 | 
			
		||||
 | 
			
		||||
			themeContent.add(themes, gbc_themes);
 | 
			
		||||
 | 
			
		||||
			colorsPanel.setLayout(new BoxLayout(colorsPanel, BoxLayout.Y_AXIS));
 | 
			
		||||
			colorsPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
 | 
			
		||||
 | 
			
		||||
			buildCustomizeElement(new JPanel(), new JButton(), new JTextPane(), theme, theme.getBackgroundColor(), "Background", 0);
 | 
			
		||||
			buildCustomizeElement(new JPanel(), new JButton(), new JTextPane(), theme, theme.getCellColor(), "Cells", 1);
 | 
			
		||||
			buildCustomizeElement(new JPanel(),
 | 
			
		||||
					new JButton(),
 | 
			
		||||
					new JTextPane(),
 | 
			
		||||
					theme,
 | 
			
		||||
					theme.getInteractableForegroundColor(),
 | 
			
		||||
					"Interactable Foreground",
 | 
			
		||||
					2);
 | 
			
		||||
			buildCustomizeElement(new JPanel(),
 | 
			
		||||
					new JButton(),
 | 
			
		||||
					new JTextPane(),
 | 
			
		||||
					theme,
 | 
			
		||||
					theme.getInteractableBackgroundColor(),
 | 
			
		||||
					"Interactable Background",
 | 
			
		||||
					3);
 | 
			
		||||
			buildCustomizeElement(new JPanel(), new JButton(), new JTextPane(), theme, theme.getMessageColorChat(), "Messages Chat", 4);
 | 
			
		||||
			buildCustomizeElement(new JPanel(), new JButton(), new JTextPane(), theme, theme.getDateColorChat(), "Date Chat", 5);
 | 
			
		||||
			buildCustomizeElement(new JPanel(), new JButton(), new JTextPane(), theme, theme.getSelectionColor(), "Selection", 6);
 | 
			
		||||
			buildCustomizeElement(new JPanel(), new JButton(), new JTextPane(), theme, theme.getTypingMessageColor(), "Typing Message", 7);
 | 
			
		||||
			buildCustomizeElement(new JPanel(), new JButton(), new JTextPane(), theme, theme.getUserNameColor(), "User Names", 8);
 | 
			
		||||
 | 
			
		||||
			GridBagConstraints gbc_colorsPanel = new GridBagConstraints();
 | 
			
		||||
			gbc_colorsPanel.fill		= GridBagConstraints.HORIZONTAL;
 | 
			
		||||
			gbc_colorsPanel.gridx		= 0;
 | 
			
		||||
			gbc_colorsPanel.gridy		= 1;
 | 
			
		||||
			gbc_colorsPanel.gridwidth	= 2;
 | 
			
		||||
			gbc_colorsPanel.anchor		= GridBagConstraints.NORTHWEST;
 | 
			
		||||
			gbc_colorsPanel.insets		= new Insets(space, 0, 0, 0);
 | 
			
		||||
 | 
			
		||||
			themeContent.add(colorsPanel, gbc_colorsPanel);
 | 
			
		||||
 | 
			
		||||
			createNewThemeButton.setBackground(theme.getInteractableBackgroundColor());
 | 
			
		||||
			createNewThemeButton.setForeground(theme.getInteractableForegroundColor());
 | 
			
		||||
			colorsPanel.setBackground(theme.getCellColor());
 | 
			
		||||
 | 
			
		||||
			createNewThemeButton.addActionListener((evt) -> {
 | 
			
		||||
				try {
 | 
			
		||||
					String s = JOptionPane.showInputDialog("Enter a name for the new theme");
 | 
			
		||||
					logger.log(Level.FINEST, s);
 | 
			
		||||
					Settings.getInstance()
 | 
			
		||||
						.addNewThemeToMap(new Theme(s, temporaryTheme.getBackgroundColor(), temporaryTheme.getCellColor(),
 | 
			
		||||
								temporaryTheme.getInteractableForegroundColor(), temporaryTheme.getInteractableBackgroundColor(),
 | 
			
		||||
								temporaryTheme.getMessageColorChat(), temporaryTheme.getDateColorChat(), temporaryTheme.getSelectionColor(),
 | 
			
		||||
								temporaryTheme.getTypingMessageColor(), temporaryTheme.getUserNameColor()));
 | 
			
		||||
					themeArray							= Arrays.copyOf(themeArray, themeArray.length + 1);
 | 
			
		||||
					themeArray[themeArray.length - 1]	= Settings.getInstance().getThemes().get(s).getThemeName();
 | 
			
		||||
 | 
			
		||||
					temporaryTheme = new Theme("temporaryTheme", Settings.getInstance().getThemes().get(Settings.getInstance().getCurrentTheme()));
 | 
			
		||||
 | 
			
		||||
					createNewThemeButton.setEnabled(false);
 | 
			
		||||
					themes.addItem(themeArray[themeArray.length - 1]);
 | 
			
		||||
 | 
			
		||||
					contentPanel.revalidate();
 | 
			
		||||
					contentPanel.repaint();
 | 
			
		||||
 | 
			
		||||
				} catch (Exception e) {
 | 
			
		||||
					logger.info("New theme couldn't be created! " + e);
 | 
			
		||||
					e.printStackTrace();
 | 
			
		||||
				}
 | 
			
		||||
			});
 | 
			
		||||
 | 
			
		||||
			GridBagConstraints gbc_createNewTheme = new GridBagConstraints();
 | 
			
		||||
			gbc_createNewTheme.gridx	= 0;
 | 
			
		||||
			gbc_createNewTheme.gridy	= 10;
 | 
			
		||||
 | 
			
		||||
			colorsPanel.add(createNewThemeButton, gbc_createNewTheme);
 | 
			
		||||
 | 
			
		||||
			// ButtonPane-------------------------------------------------------
 | 
			
		||||
			GridBagLayout gbl_buttonPane = new GridBagLayout();
 | 
			
		||||
			gbl_buttonPane.columnWidths		= new int[] { 100, 250, 100, 0 };
 | 
			
		||||
			gbl_buttonPane.rowHeights		= new int[] { 25, 0 };
 | 
			
		||||
			gbl_buttonPane.columnWeights	= new double[] { 0.0, 0.0, 0.0, Double.MIN_VALUE };
 | 
			
		||||
			gbl_buttonPane.rowWeights		= new double[] { 0.0, Double.MIN_VALUE };
 | 
			
		||||
 | 
			
		||||
			getContentPane().add(buttonPane, BorderLayout.SOUTH);
 | 
			
		||||
			buttonPane.setLayout(gbl_buttonPane);
 | 
			
		||||
			{
 | 
			
		||||
				cancelButton.setActionCommand("Cancel");
 | 
			
		||||
				cancelButton.setBorderPainted(false);
 | 
			
		||||
				GridBagConstraints gbc_cancelButton = new GridBagConstraints();
 | 
			
		||||
				gbc_cancelButton.anchor	= GridBagConstraints.NORTHWEST;
 | 
			
		||||
				gbc_cancelButton.insets	= new Insets(space, space, space, space);
 | 
			
		||||
				gbc_cancelButton.gridx	= 0;
 | 
			
		||||
				gbc_cancelButton.gridy	= 0;
 | 
			
		||||
				buttonPane.add(cancelButton, gbc_cancelButton);
 | 
			
		||||
 | 
			
		||||
				cancelButton.addActionListener((evt) -> { dispose(); });
 | 
			
		||||
			}
 | 
			
		||||
			{
 | 
			
		||||
				okButton.setActionCommand("OK");
 | 
			
		||||
				okButton.setBorderPainted(false);
 | 
			
		||||
				GridBagConstraints gbc_okButton = new GridBagConstraints();
 | 
			
		||||
				gbc_okButton.anchor	= GridBagConstraints.NORTHEAST;
 | 
			
		||||
				gbc_okButton.fill	= GridBagConstraints.EAST;
 | 
			
		||||
				gbc_okButton.insets	= new Insets(space, space, space, space);
 | 
			
		||||
				gbc_okButton.gridx	= 2;
 | 
			
		||||
				gbc_okButton.gridy	= 0;
 | 
			
		||||
				buttonPane.add(okButton, gbc_okButton);
 | 
			
		||||
				getRootPane().setDefaultButton(okButton);
 | 
			
		||||
				okButton.addActionListener((evt) -> {
 | 
			
		||||
					try {
 | 
			
		||||
						Settings.getInstance().setEnterToSend(Settings.getInstance().isEnterToSend());// still temporary
 | 
			
		||||
 | 
			
		||||
						Settings.getInstance().setCurrentTheme(selectedTheme.getThemeName());
 | 
			
		||||
						logger.log(Level.FINER, selectedTheme.getThemeName());
 | 
			
		||||
 | 
			
		||||
						final Theme currentTheme = Settings.getInstance().getThemes().get(Settings.getInstance().getCurrentTheme());
 | 
			
		||||
						changeSettingsScreenColors(currentTheme);
 | 
			
		||||
						updateColorVariables(currentTheme);
 | 
			
		||||
						EventBus.getInstance().dispatch(new ThemeChangeEvent(currentTheme));
 | 
			
		||||
						Settings.getInstance().save();
 | 
			
		||||
 | 
			
		||||
						revalidate();
 | 
			
		||||
						repaint();
 | 
			
		||||
					} catch (Exception e) {
 | 
			
		||||
						logger.warning("Something went wrong when changing the setting");
 | 
			
		||||
						JOptionPane.showMessageDialog(this, "Something went wrong when changing the setting");
 | 
			
		||||
						dispose();
 | 
			
		||||
					}
 | 
			
		||||
				});
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		changeSettingsScreenColors(Settings.getInstance().getThemes().get(Settings.getInstance().getCurrentTheme()));
 | 
			
		||||
        
 | 
			
		||||
        setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
 | 
			
		||||
		setModal(true);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private void changeSettingsScreenColors(Theme theme) {
 | 
			
		||||
		// whole JDialog
 | 
			
		||||
		setBackground(theme.getBackgroundColor());
 | 
			
		||||
		// contentPanel
 | 
			
		||||
		contentPanel.setBackground(theme.getBackgroundColor());
 | 
			
		||||
		// buttonPane
 | 
			
		||||
		buttonPane.setBackground(theme.getCellColor());
 | 
			
		||||
		// cancelButton
 | 
			
		||||
		cancelButton.setBackground(theme.getInteractableBackgroundColor());
 | 
			
		||||
		cancelButton.setForeground(theme.getInteractableForegroundColor());
 | 
			
		||||
		// okButton
 | 
			
		||||
		okButton.setBackground(theme.getInteractableBackgroundColor());
 | 
			
		||||
		okButton.setForeground(theme.getInteractableForegroundColor());
 | 
			
		||||
		// options
 | 
			
		||||
		options.setSelectionForeground(theme.getUserNameColor());
 | 
			
		||||
		options.setSelectionBackground(theme.getSelectionColor());
 | 
			
		||||
		options.setForeground(theme.getUserNameColor());
 | 
			
		||||
		options.setBackground(theme.getCellColor());
 | 
			
		||||
		// themeContent
 | 
			
		||||
		themeContent.setForeground(theme.getUserNameColor());
 | 
			
		||||
		themeContent.setBackground(theme.getCellColor());
 | 
			
		||||
		// themes
 | 
			
		||||
		themes.setBackground(theme.getBackgroundColor());
 | 
			
		||||
		themes.setForeground(getInvertedColor(theme.getBackgroundColor()));
 | 
			
		||||
 | 
			
		||||
		createNewThemeButton.setBackground(theme.getInteractableBackgroundColor());
 | 
			
		||||
		createNewThemeButton.setForeground(theme.getInteractableForegroundColor());
 | 
			
		||||
		colorsPanel.setBackground(theme.getCellColor());
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private void updateColorVariables(Theme theme) {
 | 
			
		||||
		temporaryTheme = new Theme("temporaryTheme", theme);
 | 
			
		||||
 | 
			
		||||
		colorsPanel.removeAll();
 | 
			
		||||
 | 
			
		||||
		buildCustomizeElement(new JPanel(),
 | 
			
		||||
 | 
			
		||||
				new JButton(),
 | 
			
		||||
				new JTextPane(),
 | 
			
		||||
				theme,
 | 
			
		||||
				theme.getBackgroundColor(),
 | 
			
		||||
				"Background",
 | 
			
		||||
				0);
 | 
			
		||||
		buildCustomizeElement(new JPanel(),
 | 
			
		||||
 | 
			
		||||
				new JButton(),
 | 
			
		||||
				new JTextPane(),
 | 
			
		||||
				theme,
 | 
			
		||||
				theme.getCellColor(),
 | 
			
		||||
				"Cells",
 | 
			
		||||
				1);
 | 
			
		||||
		buildCustomizeElement(new JPanel(),
 | 
			
		||||
 | 
			
		||||
				new JButton(),
 | 
			
		||||
				new JTextPane(),
 | 
			
		||||
				theme,
 | 
			
		||||
				theme.getInteractableForegroundColor(),
 | 
			
		||||
				"Interactable Foreground",
 | 
			
		||||
				2);
 | 
			
		||||
		buildCustomizeElement(new JPanel(),
 | 
			
		||||
 | 
			
		||||
				new JButton(),
 | 
			
		||||
				new JTextPane(),
 | 
			
		||||
				theme,
 | 
			
		||||
				theme.getInteractableBackgroundColor(),
 | 
			
		||||
				"Interactable Background",
 | 
			
		||||
				3);
 | 
			
		||||
		buildCustomizeElement(new JPanel(),
 | 
			
		||||
 | 
			
		||||
				new JButton(),
 | 
			
		||||
				new JTextPane(),
 | 
			
		||||
				theme,
 | 
			
		||||
				theme.getMessageColorChat(),
 | 
			
		||||
				"Messages Chat",
 | 
			
		||||
				4);
 | 
			
		||||
		buildCustomizeElement(new JPanel(),
 | 
			
		||||
 | 
			
		||||
				new JButton(),
 | 
			
		||||
				new JTextPane(),
 | 
			
		||||
				theme,
 | 
			
		||||
				theme.getDateColorChat(),
 | 
			
		||||
				"Date Chat",
 | 
			
		||||
				5);
 | 
			
		||||
		buildCustomizeElement(new JPanel(),
 | 
			
		||||
 | 
			
		||||
				new JButton(),
 | 
			
		||||
				new JTextPane(),
 | 
			
		||||
				theme,
 | 
			
		||||
				theme.getSelectionColor(),
 | 
			
		||||
				"Selection",
 | 
			
		||||
				6);
 | 
			
		||||
		buildCustomizeElement(new JPanel(),
 | 
			
		||||
 | 
			
		||||
				new JButton(),
 | 
			
		||||
				new JTextPane(),
 | 
			
		||||
				theme,
 | 
			
		||||
				theme.getTypingMessageColor(),
 | 
			
		||||
				"Typing Message",
 | 
			
		||||
				7);
 | 
			
		||||
		buildCustomizeElement(new JPanel(),
 | 
			
		||||
 | 
			
		||||
				new JButton(),
 | 
			
		||||
				new JTextPane(),
 | 
			
		||||
				theme,
 | 
			
		||||
				theme.getUserNameColor(),
 | 
			
		||||
				"User Names",
 | 
			
		||||
				8);
 | 
			
		||||
 | 
			
		||||
		GridBagConstraints gbc_createNewTheme = new GridBagConstraints();
 | 
			
		||||
		gbc_createNewTheme.gridx	= 0;
 | 
			
		||||
		gbc_createNewTheme.gridy	= 10;
 | 
			
		||||
 | 
			
		||||
		colorsPanel.add(createNewThemeButton, gbc_createNewTheme);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private void setContent(JPanel content, GridBagConstraints layout) { contentPanel.add(content, layout); }
 | 
			
		||||
 | 
			
		||||
	private void buildCustomizeElement(JPanel panel, JButton button, JTextPane textPane, Theme theme, Color color, String name, int yIndex) {
 | 
			
		||||
		textPane.setFont(new Font("Arial", Font.PLAIN, 14));
 | 
			
		||||
		textPane.setBackground(theme.getBackgroundColor());
 | 
			
		||||
		textPane.setForeground(getInvertedColor(theme.getBackgroundColor()));
 | 
			
		||||
		textPane.setText(name);
 | 
			
		||||
		textPane.setEditable(false);
 | 
			
		||||
 | 
			
		||||
		button.setBackground(color);
 | 
			
		||||
		button.setPreferredSize(new Dimension(25, 25));
 | 
			
		||||
 | 
			
		||||
		button.addActionListener((evt) -> {
 | 
			
		||||
			try {
 | 
			
		||||
				Color newColor = JColorChooser.showDialog(null, "Choose a color", color);
 | 
			
		||||
				if (newColor.getRGB() != color.getRGB()) {
 | 
			
		||||
					logger.log(Level.FINEST, "New Color: " + String.valueOf(color.getRGB()));
 | 
			
		||||
					// TODO: When Theme changed in same settings screen, color variable doesnt
 | 
			
		||||
					// update.
 | 
			
		||||
					temporaryTheme.setColor(yIndex, newColor);
 | 
			
		||||
					createNewThemeButton.setEnabled(true);
 | 
			
		||||
				}
 | 
			
		||||
				button.setBackground(newColor);
 | 
			
		||||
 | 
			
		||||
			} catch (Exception e) {
 | 
			
		||||
				logger.info("An error occured while opening Color Chooser: " + e);
 | 
			
		||||
				e.printStackTrace();
 | 
			
		||||
			}
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		panel.add(textPane);
 | 
			
		||||
		panel.add(button);
 | 
			
		||||
		panel.setBackground(theme.getCellColor());
 | 
			
		||||
		panel.setAlignmentX(Component.LEFT_ALIGNMENT);
 | 
			
		||||
 | 
			
		||||
		colorsPanel.add(panel);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private Color getInvertedColor(Color color) { return new Color(255 - color.getRed(), 255 - color.getGreen(), 255 - color.getBlue()); }
 | 
			
		||||
}
 | 
			
		||||
@@ -2,6 +2,8 @@ package envoy.client.ui;
 | 
			
		||||
 | 
			
		||||
import java.awt.Color;
 | 
			
		||||
import java.io.Serializable;
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Project: <strong>envoy-client</strong><br>
 | 
			
		||||
@@ -15,16 +17,8 @@ public class Theme implements Serializable {
 | 
			
		||||
 | 
			
		||||
	private static final long serialVersionUID = 141727847527060352L;
 | 
			
		||||
 | 
			
		||||
	private String	themeName;
 | 
			
		||||
	private Color	backgroundColor;
 | 
			
		||||
	private Color	cellColor;
 | 
			
		||||
	private Color	interactableBackgroundColor;
 | 
			
		||||
	private Color	userNameColor;
 | 
			
		||||
	private Color	interactableForegroundColor;
 | 
			
		||||
	private Color	messageColorChat;
 | 
			
		||||
	private Color	dateColorChat;
 | 
			
		||||
	private Color	selectionColor;
 | 
			
		||||
	private Color	typingMessageColor;
 | 
			
		||||
	private String				themeName;
 | 
			
		||||
	private Map<String, Color>	colors	= new HashMap<>();
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Initializes a {@link Theme} with all colors relevant to the application GUI.
 | 
			
		||||
@@ -48,15 +42,15 @@ public class Theme implements Serializable {
 | 
			
		||||
 | 
			
		||||
		this.themeName = themeName;
 | 
			
		||||
 | 
			
		||||
		this.backgroundColor				= backgroundColor;
 | 
			
		||||
		this.cellColor						= cellColor;
 | 
			
		||||
		this.interactableForegroundColor	= interactableForegroundColor;
 | 
			
		||||
		this.interactableBackgroundColor	= interactableBackgroundColor;
 | 
			
		||||
		this.messageColorChat				= messageColorChat;
 | 
			
		||||
		this.dateColorChat					= dateColorChat;
 | 
			
		||||
		this.selectionColor					= selectionColor;
 | 
			
		||||
		this.typingMessageColor				= typingMessageColor;
 | 
			
		||||
		this.userNameColor					= userNameColor;
 | 
			
		||||
		colors.put("backgroundColor", backgroundColor);
 | 
			
		||||
		colors.put("cellColor", cellColor);
 | 
			
		||||
		colors.put("interactableForegroundColor", interactableForegroundColor);
 | 
			
		||||
		colors.put("interactableBackgroundColor", interactableBackgroundColor);
 | 
			
		||||
		colors.put("messageColorChat", messageColorChat);
 | 
			
		||||
		colors.put("dateColorChat", dateColorChat);
 | 
			
		||||
		colors.put("selectionColor", selectionColor);
 | 
			
		||||
		colors.put("typingMessageColor", typingMessageColor);
 | 
			
		||||
		colors.put("userNameColor", userNameColor);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
@@ -68,11 +62,17 @@ public class Theme implements Serializable {
 | 
			
		||||
	 * @since Envoy v0.2-alpha
 | 
			
		||||
	 */
 | 
			
		||||
	public Theme(String name, Theme other) {
 | 
			
		||||
		this(name, other.backgroundColor, other.cellColor, other.interactableForegroundColor,
 | 
			
		||||
				other.interactableBackgroundColor, other.messageColorChat, other.dateColorChat, other.selectionColor,
 | 
			
		||||
				other.typingMessageColor, other.userNameColor);
 | 
			
		||||
		themeName = name;
 | 
			
		||||
		colors.putAll(other.colors);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * @return a {@code Map<String, Color>} of all colors defined for this theme
 | 
			
		||||
	 *         with their names as keys
 | 
			
		||||
	 * @since Envoy v0.2-alpha
 | 
			
		||||
	 */
 | 
			
		||||
	public Map<String, Color> getColors() { return colors; }
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * @return name of the theme
 | 
			
		||||
	 * @since Envoy v0.2-alpha
 | 
			
		||||
@@ -83,104 +83,62 @@ public class Theme implements Serializable {
 | 
			
		||||
	 * @return interactableForegroundColor
 | 
			
		||||
	 * @since Envoy v0.2-alpha
 | 
			
		||||
	 */
 | 
			
		||||
	public Color getInteractableForegroundColor() { return interactableForegroundColor; }
 | 
			
		||||
	public Color getInteractableForegroundColor() { return colors.get("interactableForegroundColor"); }
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * @return messageColorChat
 | 
			
		||||
	 * @since Envoy v0.2-alpha
 | 
			
		||||
	 */
 | 
			
		||||
	public Color getMessageColorChat() { return messageColorChat; }
 | 
			
		||||
	public Color getMessageColorChat() { return colors.get("messageColorChat"); }
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * @return dateColorChat
 | 
			
		||||
	 * @since Envoy v0.2-alpha
 | 
			
		||||
	 */
 | 
			
		||||
	public Color getDateColorChat() { return dateColorChat; }
 | 
			
		||||
	public Color getDateColorChat() { return colors.get("dateColorChat"); }
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * @return selectionColor
 | 
			
		||||
	 * @since Envoy v0.2-alpha
 | 
			
		||||
	 */
 | 
			
		||||
	public Color getSelectionColor() { return selectionColor; }
 | 
			
		||||
	public Color getSelectionColor() { return colors.get("selectionColor"); }
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * @return typingMessageColor
 | 
			
		||||
	 * @since Envoy v0.2-alpha
 | 
			
		||||
	 */
 | 
			
		||||
	public Color getTypingMessageColor() { return typingMessageColor; }
 | 
			
		||||
	public Color getTypingMessageColor() { return colors.get("typingMessageColor"); }
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * @return backgroundColor
 | 
			
		||||
	 * @since Envoy v0.2-alpha
 | 
			
		||||
	 */
 | 
			
		||||
	public Color getBackgroundColor() { return backgroundColor; }
 | 
			
		||||
	public Color getBackgroundColor() { return colors.get("backgroundColor"); }
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * @return cellColor
 | 
			
		||||
	 * @since Envoy v0.2-alpha
 | 
			
		||||
	 */
 | 
			
		||||
	public Color getCellColor() { return cellColor; }
 | 
			
		||||
	public Color getCellColor() { return colors.get("cellColor"); }
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * @return interactableBackgroundColor
 | 
			
		||||
	 * @since Envoy v0.2-alpha
 | 
			
		||||
	 */
 | 
			
		||||
	public Color getInteractableBackgroundColor() { return interactableBackgroundColor; }
 | 
			
		||||
	public Color getInteractableBackgroundColor() { return colors.get("interactableBackgroundColor"); }
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * @return userNameColor
 | 
			
		||||
	 * @since Envoy v0.2-alpha
 | 
			
		||||
	 */
 | 
			
		||||
	public Color getUserNameColor() { return userNameColor; }
 | 
			
		||||
	public Color getUserNameColor() { return colors.get("userNameColor"); }
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Sets the a specific {@link Color} in this theme to a new {@link Color}
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param index    - index of the color </br>
 | 
			
		||||
	 *                 0 = backgroundColor </br>
 | 
			
		||||
	 *                 1 = cellColor </br>
 | 
			
		||||
	 *                 2 = interactableForegroundColor </br>
 | 
			
		||||
	 *                 3 = interactableBackgroundColor </br>
 | 
			
		||||
	 *                 4 = messageColorChat </br>
 | 
			
		||||
	 *                 5 = dateColorChat </br>
 | 
			
		||||
	 *                 6 = selectionColor </br>
 | 
			
		||||
	 *                 7 = typingMessageColor </br>
 | 
			
		||||
	 *                 8 = userNameColor </br>
 | 
			
		||||
	 *                 </br>
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param newColor - new {@link Color} to be set
 | 
			
		||||
	 * @param colorName the name of the {@link Color} to set
 | 
			
		||||
	 * @param newColor  the new {@link Color} to be set
 | 
			
		||||
	 * @since Envoy 0.2-alpha
 | 
			
		||||
	 */
 | 
			
		||||
	public void setColor(int index, Color newColor) {
 | 
			
		||||
		switch (index) {
 | 
			
		||||
			case 0:
 | 
			
		||||
				backgroundColor = newColor;
 | 
			
		||||
				break;
 | 
			
		||||
			case 1:
 | 
			
		||||
				cellColor = newColor;
 | 
			
		||||
				break;
 | 
			
		||||
			case 2:
 | 
			
		||||
				interactableForegroundColor = newColor;
 | 
			
		||||
				break;
 | 
			
		||||
			case 3:
 | 
			
		||||
				interactableBackgroundColor = newColor;
 | 
			
		||||
				break;
 | 
			
		||||
			case 4:
 | 
			
		||||
				messageColorChat = newColor;
 | 
			
		||||
				break;
 | 
			
		||||
			case 5:
 | 
			
		||||
				dateColorChat = newColor;
 | 
			
		||||
				break;
 | 
			
		||||
			case 6:
 | 
			
		||||
				selectionColor = newColor;
 | 
			
		||||
				break;
 | 
			
		||||
			case 7:
 | 
			
		||||
				typingMessageColor = newColor;
 | 
			
		||||
				break;
 | 
			
		||||
			case 8:
 | 
			
		||||
				userNameColor = newColor;
 | 
			
		||||
				break;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public void setColor(String colorName, Color newColor) { colors.put(colorName, newColor); }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										29
									
								
								src/main/java/envoy/client/ui/settings/SettingsPanel.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								src/main/java/envoy/client/ui/settings/SettingsPanel.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,29 @@
 | 
			
		||||
package envoy.client.ui.settings;
 | 
			
		||||
 | 
			
		||||
import java.awt.event.ActionListener;
 | 
			
		||||
 | 
			
		||||
import javax.swing.JPanel;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Serves as an interface between {@link SettingsScreen} and different
 | 
			
		||||
 * {@link JPanel}s with actual settings that are defined as sub classes of this
 | 
			
		||||
 * class.<br>
 | 
			
		||||
 * <br>
 | 
			
		||||
 * Project: <strong>envoy-client</strong><br>
 | 
			
		||||
 * File: <strong>SettingsPanel.java</strong><br>
 | 
			
		||||
 * Created: <strong>20 Dec 2019</strong><br>
 | 
			
		||||
 *
 | 
			
		||||
 * @author Kai S. K. Engelbart
 | 
			
		||||
 * @since Envoy v0.2-alpha
 | 
			
		||||
 */
 | 
			
		||||
public abstract class SettingsPanel extends JPanel {
 | 
			
		||||
 | 
			
		||||
	private static final long serialVersionUID = -3069212622468626050L;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * @return an {@link ActionListener} that should be invoked when the OK button
 | 
			
		||||
	 *         is pressed in the {@link SettingsScreen}
 | 
			
		||||
	 * @since Envoy v0.2-alpha
 | 
			
		||||
	 */
 | 
			
		||||
	public abstract ActionListener getOkButtonAction();
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										190
									
								
								src/main/java/envoy/client/ui/settings/SettingsScreen.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										190
									
								
								src/main/java/envoy/client/ui/settings/SettingsScreen.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,190 @@
 | 
			
		||||
package envoy.client.ui.settings;
 | 
			
		||||
 | 
			
		||||
import java.awt.*;
 | 
			
		||||
import java.lang.reflect.InvocationTargetException;
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.logging.Level;
 | 
			
		||||
import java.util.logging.Logger;
 | 
			
		||||
 | 
			
		||||
import javax.swing.*;
 | 
			
		||||
 | 
			
		||||
import envoy.client.Settings;
 | 
			
		||||
import envoy.client.event.EventBus;
 | 
			
		||||
import envoy.client.event.ThemeChangeEvent;
 | 
			
		||||
import envoy.client.ui.Theme;
 | 
			
		||||
import envoy.client.util.EnvoyLog;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * This class provides the GUI to change the user specific settings.<br>
 | 
			
		||||
 * <br>
 | 
			
		||||
 * Project: <strong>envoy-client</strong><br>
 | 
			
		||||
 * File: <strong>SettingsScreen.java</strong><br>
 | 
			
		||||
 * Created: <strong>31 Oct 2019</strong><br>
 | 
			
		||||
 *
 | 
			
		||||
 * @author Leon Hofmeister
 | 
			
		||||
 * @author Maximilian Käfer
 | 
			
		||||
 * @author Kai S. K. Engelbart
 | 
			
		||||
 * @since Envoy v0.2-alpha
 | 
			
		||||
 */
 | 
			
		||||
public class SettingsScreen extends JDialog {
 | 
			
		||||
 | 
			
		||||
	private static final long serialVersionUID = -4476913491263077107L;
 | 
			
		||||
 | 
			
		||||
	private final JPanel contentPanel = new JPanel();
 | 
			
		||||
 | 
			
		||||
	// Settings panel list
 | 
			
		||||
	private final DefaultListModel<String>	optionsListModel	= new DefaultListModel<>();
 | 
			
		||||
	private final JList<String>				options				= new JList<>(optionsListModel);
 | 
			
		||||
 | 
			
		||||
	// OK and cancel buttons
 | 
			
		||||
	private final JPanel	buttonPane		= new JPanel();
 | 
			
		||||
	private final JButton	okButton		= new JButton("Save");
 | 
			
		||||
	private final JButton	cancelButton	= new JButton("Cancel");
 | 
			
		||||
 | 
			
		||||
	private final Insets insets = new Insets(5, 5, 5, 5);
 | 
			
		||||
 | 
			
		||||
	private SettingsPanel settingsPanel;
 | 
			
		||||
 | 
			
		||||
	private static final Logger logger = EnvoyLog.getLogger(SettingsScreen.class.getSimpleName());
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Initializes the settings screen.
 | 
			
		||||
	 *
 | 
			
		||||
	 * @since Envoy v0.1-alpha
 | 
			
		||||
	 */
 | 
			
		||||
	public SettingsScreen() {
 | 
			
		||||
		// Initialize settings pages
 | 
			
		||||
		Map<String, Class<? extends SettingsPanel>> panels = new HashMap<>();
 | 
			
		||||
		panels.put("Color Themes", ThemeCustomizationPanel.class);
 | 
			
		||||
 | 
			
		||||
		setBounds(10, 10, 450, 650);
 | 
			
		||||
		getContentPane().setLayout(new BorderLayout());
 | 
			
		||||
		{
 | 
			
		||||
			// ContentPane
 | 
			
		||||
			GridBagLayout gbl_contentPanel = new GridBagLayout();
 | 
			
		||||
 | 
			
		||||
			gbl_contentPanel.columnWidths	= new int[] { 1, 1 };
 | 
			
		||||
			gbl_contentPanel.rowHeights		= new int[] { 1 };
 | 
			
		||||
			gbl_contentPanel.columnWeights	= new double[] { 0.05, 1.0 };
 | 
			
		||||
			gbl_contentPanel.rowWeights		= new double[] { 1.0 };
 | 
			
		||||
 | 
			
		||||
			getContentPane().add(contentPanel, BorderLayout.CENTER);
 | 
			
		||||
			contentPanel.setLayout(gbl_contentPanel);
 | 
			
		||||
 | 
			
		||||
			// Constraints for the settings panel
 | 
			
		||||
			GridBagConstraints gbc_panel = new GridBagConstraints();
 | 
			
		||||
			gbc_panel.fill		= GridBagConstraints.BOTH;
 | 
			
		||||
			gbc_panel.gridx		= 1;
 | 
			
		||||
			gbc_panel.gridy		= 0;
 | 
			
		||||
			gbc_panel.anchor	= GridBagConstraints.PAGE_START;
 | 
			
		||||
			gbc_panel.insets	= insets;
 | 
			
		||||
 | 
			
		||||
			options.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
 | 
			
		||||
			options.addListSelectionListener((listSelectionEvent) -> {
 | 
			
		||||
				if (!listSelectionEvent.getValueIsAdjusting()) {
 | 
			
		||||
					// Get selected settings panel
 | 
			
		||||
					final String option = options.getSelectedValue();
 | 
			
		||||
					logger.log(Level.FINEST, "Selected settings panel: " + option);
 | 
			
		||||
 | 
			
		||||
					// Remove previous settings panel
 | 
			
		||||
					if (settingsPanel != null) contentPanel.remove(settingsPanel);
 | 
			
		||||
 | 
			
		||||
					try {
 | 
			
		||||
						settingsPanel = panels.get(option).getDeclaredConstructor().newInstance();
 | 
			
		||||
 | 
			
		||||
						// Add selected settings panel
 | 
			
		||||
						contentPanel.add(settingsPanel, gbc_panel);
 | 
			
		||||
						revalidate();
 | 
			
		||||
						repaint();
 | 
			
		||||
					} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException
 | 
			
		||||
							| NoSuchMethodException | SecurityException e) {
 | 
			
		||||
						logger.log(Level.SEVERE, "Failed to invoke constructor of SettingsPanel " + option, e);
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			});
 | 
			
		||||
			options.setFont(new Font("Arial", Font.PLAIN, 14));
 | 
			
		||||
 | 
			
		||||
			GridBagConstraints gbc_optionsList = new GridBagConstraints();
 | 
			
		||||
			gbc_optionsList.fill	= GridBagConstraints.BOTH;
 | 
			
		||||
			gbc_optionsList.gridx	= 0;
 | 
			
		||||
			gbc_optionsList.gridy	= 0;
 | 
			
		||||
			gbc_optionsList.anchor	= GridBagConstraints.PAGE_START;
 | 
			
		||||
			gbc_optionsList.insets	= insets;
 | 
			
		||||
 | 
			
		||||
			panels.keySet().forEach(name -> optionsListModel.addElement(name));
 | 
			
		||||
			contentPanel.add(options, gbc_optionsList);
 | 
			
		||||
 | 
			
		||||
			// ButtonPane
 | 
			
		||||
			GridBagLayout gbl_buttonPane = new GridBagLayout();
 | 
			
		||||
			gbl_buttonPane.columnWidths		= new int[] { 100, 250, 100, 0 };
 | 
			
		||||
			gbl_buttonPane.rowHeights		= new int[] { 25, 0 };
 | 
			
		||||
			gbl_buttonPane.columnWeights	= new double[] { 0.0, 0.0, 0.0, Double.MIN_VALUE };
 | 
			
		||||
			gbl_buttonPane.rowWeights		= new double[] { 0.0, Double.MIN_VALUE };
 | 
			
		||||
 | 
			
		||||
			getContentPane().add(buttonPane, BorderLayout.SOUTH);
 | 
			
		||||
			buttonPane.setLayout(gbl_buttonPane);
 | 
			
		||||
			{
 | 
			
		||||
				cancelButton.setActionCommand("Cancel");
 | 
			
		||||
				cancelButton.setBorderPainted(false);
 | 
			
		||||
				GridBagConstraints gbc_cancelButton = new GridBagConstraints();
 | 
			
		||||
				gbc_cancelButton.anchor	= GridBagConstraints.NORTHWEST;
 | 
			
		||||
				gbc_cancelButton.insets	= insets;
 | 
			
		||||
				gbc_cancelButton.gridx	= 0;
 | 
			
		||||
				gbc_cancelButton.gridy	= 0;
 | 
			
		||||
				buttonPane.add(cancelButton, gbc_cancelButton);
 | 
			
		||||
 | 
			
		||||
				cancelButton.addActionListener((evt) -> { dispose(); });
 | 
			
		||||
			}
 | 
			
		||||
			{
 | 
			
		||||
				okButton.setActionCommand("OK");
 | 
			
		||||
				okButton.setBorderPainted(false);
 | 
			
		||||
				GridBagConstraints gbc_okButton = new GridBagConstraints();
 | 
			
		||||
				gbc_okButton.anchor	= GridBagConstraints.NORTHEAST;
 | 
			
		||||
				gbc_okButton.fill	= GridBagConstraints.EAST;
 | 
			
		||||
				gbc_okButton.insets	= insets;
 | 
			
		||||
				gbc_okButton.gridx	= 2;
 | 
			
		||||
				gbc_okButton.gridy	= 0;
 | 
			
		||||
				buttonPane.add(okButton, gbc_okButton);
 | 
			
		||||
				getRootPane().setDefaultButton(okButton);
 | 
			
		||||
 | 
			
		||||
				// Invoke settings panel action on button press
 | 
			
		||||
				okButton.addActionListener((evt) -> { if (settingsPanel != null) settingsPanel.getOkButtonAction().actionPerformed(evt); });
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Apply current theme
 | 
			
		||||
		applyTheme(Settings.getInstance().getThemes().get(Settings.getInstance().getCurrentTheme()));
 | 
			
		||||
 | 
			
		||||
		// Respond to theme changes
 | 
			
		||||
		EventBus.getInstance().register(ThemeChangeEvent.class, (evt) -> applyTheme(((ThemeChangeEvent) evt).get()));
 | 
			
		||||
 | 
			
		||||
		setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
 | 
			
		||||
		setModal(true);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private void applyTheme(Theme theme) {
 | 
			
		||||
		// JDialog
 | 
			
		||||
		setBackground(theme.getBackgroundColor());
 | 
			
		||||
 | 
			
		||||
		// contentPanel
 | 
			
		||||
		contentPanel.setBackground(theme.getBackgroundColor());
 | 
			
		||||
 | 
			
		||||
		// buttonPane
 | 
			
		||||
		buttonPane.setBackground(theme.getCellColor());
 | 
			
		||||
 | 
			
		||||
		// cancelButton
 | 
			
		||||
		cancelButton.setBackground(theme.getInteractableBackgroundColor());
 | 
			
		||||
		cancelButton.setForeground(theme.getInteractableForegroundColor());
 | 
			
		||||
 | 
			
		||||
		// okButton
 | 
			
		||||
		okButton.setBackground(theme.getInteractableBackgroundColor());
 | 
			
		||||
		okButton.setForeground(theme.getInteractableForegroundColor());
 | 
			
		||||
 | 
			
		||||
		// options
 | 
			
		||||
		options.setSelectionForeground(theme.getUserNameColor());
 | 
			
		||||
		options.setSelectionBackground(theme.getSelectionColor());
 | 
			
		||||
		options.setForeground(theme.getUserNameColor());
 | 
			
		||||
		options.setBackground(theme.getCellColor());
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,234 @@
 | 
			
		||||
package envoy.client.ui.settings;
 | 
			
		||||
 | 
			
		||||
import java.awt.*;
 | 
			
		||||
import java.awt.event.ActionListener;
 | 
			
		||||
import java.awt.event.ItemEvent;
 | 
			
		||||
import java.awt.event.ItemListener;
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
import java.util.logging.Level;
 | 
			
		||||
import java.util.logging.Logger;
 | 
			
		||||
 | 
			
		||||
import javax.swing.*;
 | 
			
		||||
 | 
			
		||||
import envoy.client.Settings;
 | 
			
		||||
import envoy.client.event.EventBus;
 | 
			
		||||
import envoy.client.event.ThemeChangeEvent;
 | 
			
		||||
import envoy.client.ui.Theme;
 | 
			
		||||
import envoy.client.util.EnvoyLog;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Displays GUI components that allow changing the current {@Theme} and creating
 | 
			
		||||
 * new ones.<br>
 | 
			
		||||
 * <br>
 | 
			
		||||
 * Project: <strong>envoy-client</strong><br>
 | 
			
		||||
 * File: <strong>ThemeCustomizationPanel.java</strong><br>
 | 
			
		||||
 * Created: <strong>20 Dec 2019</strong><br>
 | 
			
		||||
 *
 | 
			
		||||
 * @author Kai S. K. Engelbart
 | 
			
		||||
 * @since Envoy v0.2-alpha
 | 
			
		||||
 */
 | 
			
		||||
public class ThemeCustomizationPanel extends SettingsPanel {
 | 
			
		||||
 | 
			
		||||
	private static final long serialVersionUID = -8697897390666456624L;
 | 
			
		||||
 | 
			
		||||
	private JPanel	colorsPanel				= new JPanel();
 | 
			
		||||
	private JButton	createNewThemeButton	= new JButton("Create New Theme");
 | 
			
		||||
 | 
			
		||||
	private String[]			themeArray	= Settings.getInstance().getThemes().keySet().toArray(new String[0]);
 | 
			
		||||
	private JComboBox<String>	themes		= new JComboBox<>(themeArray);
 | 
			
		||||
	private Theme				temporaryTheme, selectedTheme;
 | 
			
		||||
 | 
			
		||||
	private final Insets insets = new Insets(5, 5, 5, 5);
 | 
			
		||||
 | 
			
		||||
	private static final Logger logger = EnvoyLog.getLogger(ThemeCustomizationPanel.class.getSimpleName());
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Initializes a {@link ThemeCustomizationPanel} that enables the user to change
 | 
			
		||||
	 * the current {@link Theme} and create new themes as part of the
 | 
			
		||||
	 * {@link SettingsScreen}.
 | 
			
		||||
	 * 
 | 
			
		||||
	 * @since Envoy v0.2-alpha
 | 
			
		||||
	 */
 | 
			
		||||
	public ThemeCustomizationPanel() {
 | 
			
		||||
		temporaryTheme = new Theme("temporaryTheme", Settings.getInstance().getThemes().get(Settings.getInstance().getCurrentTheme()));
 | 
			
		||||
 | 
			
		||||
		GridBagLayout gbl_themeLayout = new GridBagLayout();
 | 
			
		||||
 | 
			
		||||
		gbl_themeLayout.columnWidths	= new int[] { 1, 1 };
 | 
			
		||||
		gbl_themeLayout.rowHeights		= new int[] { 1, 1 };
 | 
			
		||||
		gbl_themeLayout.columnWeights	= new double[] { 1.0, 1.0 };
 | 
			
		||||
		gbl_themeLayout.rowWeights		= new double[] { 0.01, 1.0 };
 | 
			
		||||
 | 
			
		||||
		setLayout(gbl_themeLayout);
 | 
			
		||||
 | 
			
		||||
		themes.setSelectedItem(Settings.getInstance().getCurrentTheme());
 | 
			
		||||
 | 
			
		||||
		themes.addItemListener(new ItemListener() {
 | 
			
		||||
 | 
			
		||||
			@Override
 | 
			
		||||
			public void itemStateChanged(ItemEvent e) {
 | 
			
		||||
				String selectedValue = (String) themes.getSelectedItem();
 | 
			
		||||
				logger.log(Level.FINEST, selectedValue);
 | 
			
		||||
				selectedTheme = Settings.getInstance().getThemes().get(selectedValue);
 | 
			
		||||
			}
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		GridBagConstraints gbc_themes = new GridBagConstraints();
 | 
			
		||||
		gbc_themes.fill		= GridBagConstraints.HORIZONTAL;
 | 
			
		||||
		gbc_themes.gridx	= 0;
 | 
			
		||||
		gbc_themes.gridy	= 0;
 | 
			
		||||
		gbc_themes.anchor	= GridBagConstraints.NORTHWEST;
 | 
			
		||||
		gbc_themes.insets	= insets;
 | 
			
		||||
 | 
			
		||||
		add(themes, gbc_themes);
 | 
			
		||||
 | 
			
		||||
		colorsPanel.setLayout(new BoxLayout(colorsPanel, BoxLayout.Y_AXIS));
 | 
			
		||||
		colorsPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
 | 
			
		||||
 | 
			
		||||
		Theme theme = Settings.getInstance().getThemes().get(Settings.getInstance().getCurrentTheme());
 | 
			
		||||
		buildCustomizeElements(theme);
 | 
			
		||||
 | 
			
		||||
		GridBagConstraints gbc_colorsPanel = new GridBagConstraints();
 | 
			
		||||
		gbc_colorsPanel.fill		= GridBagConstraints.HORIZONTAL;
 | 
			
		||||
		gbc_colorsPanel.gridx		= 0;
 | 
			
		||||
		gbc_colorsPanel.gridy		= 1;
 | 
			
		||||
		gbc_colorsPanel.gridwidth	= 2;
 | 
			
		||||
		gbc_colorsPanel.anchor		= GridBagConstraints.NORTHWEST;
 | 
			
		||||
		gbc_colorsPanel.insets		= insets;
 | 
			
		||||
 | 
			
		||||
		add(colorsPanel, gbc_colorsPanel);
 | 
			
		||||
 | 
			
		||||
		createNewThemeButton.setEnabled(false);
 | 
			
		||||
		createNewThemeButton.setBackground(theme.getInteractableBackgroundColor());
 | 
			
		||||
		createNewThemeButton.setForeground(theme.getInteractableForegroundColor());
 | 
			
		||||
		colorsPanel.setBackground(theme.getCellColor());
 | 
			
		||||
 | 
			
		||||
		createNewThemeButton.addActionListener((evt) -> {
 | 
			
		||||
			try {
 | 
			
		||||
				String name = JOptionPane.showInputDialog("Enter a name for the new theme");
 | 
			
		||||
				logger.log(Level.FINEST, name);
 | 
			
		||||
				Settings.getInstance().addNewThemeToMap(new Theme(name, temporaryTheme));
 | 
			
		||||
				themeArray							= Arrays.copyOf(themeArray, themeArray.length + 1);
 | 
			
		||||
				themeArray[themeArray.length - 1]	= Settings.getInstance().getThemes().get(name).getThemeName();
 | 
			
		||||
 | 
			
		||||
				temporaryTheme = new Theme("temporaryTheme", Settings.getInstance().getThemes().get(Settings.getInstance().getCurrentTheme()));
 | 
			
		||||
 | 
			
		||||
				createNewThemeButton.setEnabled(false);
 | 
			
		||||
				themes.addItem(themeArray[themeArray.length - 1]);
 | 
			
		||||
 | 
			
		||||
			} catch (Exception e) {
 | 
			
		||||
				logger.info("New theme couldn't be created! " + e);
 | 
			
		||||
				e.printStackTrace();
 | 
			
		||||
			}
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		GridBagConstraints gbc_createNewTheme = new GridBagConstraints();
 | 
			
		||||
		gbc_createNewTheme.gridx	= 0;
 | 
			
		||||
		gbc_createNewTheme.gridy	= 10;
 | 
			
		||||
 | 
			
		||||
		colorsPanel.add(createNewThemeButton, gbc_createNewTheme);
 | 
			
		||||
 | 
			
		||||
		// Apply current theme
 | 
			
		||||
		applyTheme(theme);
 | 
			
		||||
 | 
			
		||||
		// Respond to theme changes
 | 
			
		||||
		EventBus.getInstance().register(ThemeChangeEvent.class, (evt) -> applyTheme(((ThemeChangeEvent) evt).get()));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public ActionListener getOkButtonAction() {
 | 
			
		||||
		return (evt) -> {
 | 
			
		||||
			Settings.getInstance().setCurrentTheme(selectedTheme.getThemeName());
 | 
			
		||||
			logger.log(Level.FINER, "Setting theme: " + selectedTheme.getThemeName());
 | 
			
		||||
 | 
			
		||||
			final Theme currentTheme = Settings.getInstance().getThemes().get(Settings.getInstance().getCurrentTheme());
 | 
			
		||||
			updateColorVariables(currentTheme);
 | 
			
		||||
			EventBus.getInstance().dispatch(new ThemeChangeEvent(currentTheme));
 | 
			
		||||
 | 
			
		||||
			revalidate();
 | 
			
		||||
			repaint();
 | 
			
		||||
		};
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private void applyTheme(Theme theme) {
 | 
			
		||||
		// themeContent
 | 
			
		||||
		setForeground(theme.getUserNameColor());
 | 
			
		||||
		setBackground(theme.getCellColor());
 | 
			
		||||
 | 
			
		||||
		// themes
 | 
			
		||||
		themes.setBackground(theme.getBackgroundColor());
 | 
			
		||||
		themes.setForeground(getInvertedColor(theme.getBackgroundColor()));
 | 
			
		||||
 | 
			
		||||
		createNewThemeButton.setBackground(theme.getInteractableBackgroundColor());
 | 
			
		||||
		createNewThemeButton.setForeground(theme.getInteractableForegroundColor());
 | 
			
		||||
		colorsPanel.setBackground(theme.getCellColor());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private void updateColorVariables(Theme theme) {
 | 
			
		||||
		temporaryTheme = new Theme("temporaryTheme", theme);
 | 
			
		||||
 | 
			
		||||
		colorsPanel.removeAll();
 | 
			
		||||
 | 
			
		||||
		buildCustomizeElements(theme);
 | 
			
		||||
 | 
			
		||||
		GridBagConstraints gbc_createNewTheme = new GridBagConstraints();
 | 
			
		||||
		gbc_createNewTheme.gridx	= 0;
 | 
			
		||||
		gbc_createNewTheme.gridy	= 10;
 | 
			
		||||
 | 
			
		||||
		colorsPanel.add(createNewThemeButton, gbc_createNewTheme);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private void buildCustomizeElements(Theme theme) {
 | 
			
		||||
		buildCustomizeElement(theme, theme.getBackgroundColor(), "Background", "backgroundColor");
 | 
			
		||||
		buildCustomizeElement(theme, theme.getCellColor(), "Cells", "cellColor");
 | 
			
		||||
		buildCustomizeElement(theme, theme.getInteractableForegroundColor(), "Interactable Foreground", "interactableForegroundColor");
 | 
			
		||||
		buildCustomizeElement(theme, theme.getInteractableBackgroundColor(), "Interactable Background", "interactableBackgroundColor");
 | 
			
		||||
		buildCustomizeElement(theme, theme.getMessageColorChat(), "Messages Chat", "messageColorChat");
 | 
			
		||||
		buildCustomizeElement(theme, theme.getDateColorChat(), "Date Chat", "dateColorCat");
 | 
			
		||||
		buildCustomizeElement(theme, theme.getSelectionColor(), "Selection", "selectionColor");
 | 
			
		||||
		buildCustomizeElement(theme, theme.getTypingMessageColor(), "Typing Message", "typingMessageColor");
 | 
			
		||||
		buildCustomizeElement(theme, theme.getUserNameColor(), "User Names", "userNameColor");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private void buildCustomizeElement(Theme theme, Color color, String name, String colorName) {
 | 
			
		||||
		JPanel		panel		= new JPanel();
 | 
			
		||||
		JButton		button		= new JButton();
 | 
			
		||||
		JTextPane	textPane	= new JTextPane();
 | 
			
		||||
 | 
			
		||||
		textPane.setFont(new Font("Arial", Font.PLAIN, 14));
 | 
			
		||||
		textPane.setBackground(theme.getBackgroundColor());
 | 
			
		||||
		textPane.setForeground(getInvertedColor(theme.getBackgroundColor()));
 | 
			
		||||
		textPane.setText(name);
 | 
			
		||||
		textPane.setEditable(false);
 | 
			
		||||
 | 
			
		||||
		button.setBackground(color);
 | 
			
		||||
		button.setPreferredSize(new Dimension(25, 25));
 | 
			
		||||
 | 
			
		||||
		button.addActionListener((evt) -> {
 | 
			
		||||
			try {
 | 
			
		||||
				Color newColor = JColorChooser.showDialog(null, "Choose a color", color);
 | 
			
		||||
				if (newColor.getRGB() != color.getRGB()) {
 | 
			
		||||
					logger.log(Level.FINEST, "New Color: " + String.valueOf(color.getRGB()));
 | 
			
		||||
					// TODO: When Theme changed in same settings screen, color variable doesn't
 | 
			
		||||
					// update
 | 
			
		||||
					temporaryTheme.setColor(colorName, newColor);
 | 
			
		||||
					createNewThemeButton.setEnabled(true);
 | 
			
		||||
				}
 | 
			
		||||
				button.setBackground(newColor);
 | 
			
		||||
 | 
			
		||||
			} catch (Exception e) {
 | 
			
		||||
				logger.info("An error occured while opening Color Chooser: " + e);
 | 
			
		||||
				e.printStackTrace();
 | 
			
		||||
			}
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		panel.add(textPane);
 | 
			
		||||
		panel.add(button);
 | 
			
		||||
		panel.setBackground(theme.getCellColor());
 | 
			
		||||
		panel.setAlignmentX(Component.LEFT_ALIGNMENT);
 | 
			
		||||
 | 
			
		||||
		colorsPanel.add(panel);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private Color getInvertedColor(Color color) { return new Color(255 - color.getRed(), 255 - color.getGreen(), 255 - color.getBlue()); }
 | 
			
		||||
}
 | 
			
		||||
										
											Binary file not shown.
										
									
								
							| 
		 Before Width: | Height: | Size: 8.0 KiB  | 
		Reference in New Issue
	
	Block a user