Merge pull request #63 from informatik-ag-ngl/f/settings_panel
Added SettingsPanel architecture
This commit is contained in:
		
							
								
								
									
										5
									
								
								.settings/org.eclipse.jdt.ui.prefs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								.settings/org.eclipse.jdt.ui.prefs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | ||||
| eclipse.preferences.version=1 | ||||
| org.eclipse.jdt.ui.ignorelowercasenames=true | ||||
| org.eclipse.jdt.ui.importorder=java;javax;org;com; | ||||
| org.eclipse.jdt.ui.ondemandthreshold=4 | ||||
| org.eclipse.jdt.ui.staticondemandthreshold=2 | ||||
| @@ -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> | ||||
| @@ -16,15 +18,7 @@ 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 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
	 GitHub
						GitHub