Added instantaneous theme change, fixed dialog modality
This commit is contained in:
		| @@ -186,4 +186,11 @@ public class Settings { | ||||
| 	 * @since Envoy v0.2-alpha | ||||
| 	 */ | ||||
| 	public void setThemes(Map<String, Theme> themes) { this.themes = themes; } | ||||
|  | ||||
| 	/** | ||||
| 	 * @param themeName the name of the {@link Theme} to get | ||||
| 	 * @return the {@link Theme} with the specified name | ||||
| 	 * @since Envoy v0.3-alpha | ||||
| 	 */ | ||||
| 	public Theme getTheme(String themeName) { return themes.get(themeName); } | ||||
| } | ||||
| @@ -79,6 +79,8 @@ public class Color extends java.awt.Color { | ||||
|  | ||||
| 	private static final long serialVersionUID = -9166233199998257344L; | ||||
|  | ||||
| 	public Color(java.awt.Color other) { this(other.getRGB()); } | ||||
|  | ||||
| 	public Color(int rgb) { super(rgb); } | ||||
|  | ||||
| 	public Color(int rgba, boolean hasalpha) { super(rgba, hasalpha); } | ||||
|   | ||||
| @@ -37,9 +37,12 @@ public class GeneralSettingsPanel extends SettingsPanel { | ||||
| 	 * This is the constructor for the General class. Here the user can set general | ||||
| 	 * settings for the client. | ||||
| 	 *  | ||||
| 	 * @param parent the {@link SettingsScreen} as a part of which this | ||||
| 	 *               {@link SettingsPanel} is displayed | ||||
| 	 * @since Envoy 0.3-alpha | ||||
| 	 */ | ||||
| 	public GeneralSettingsPanel() { | ||||
| 	public GeneralSettingsPanel(SettingsScreen parent) { | ||||
| 		super(parent); | ||||
| 		theme = Settings.getInstance().getThemes().get(Settings.getInstance().getCurrentTheme()); | ||||
|  | ||||
| 		setBackground(theme.getCellColor()); | ||||
|   | ||||
| @@ -1,15 +1,16 @@ | ||||
| package envoy.client.ui.settings; | ||||
|  | ||||
| import java.awt.*; | ||||
| import java.util.logging.Logger; | ||||
| import java.util.function.Consumer; | ||||
|  | ||||
| import javax.swing.*; | ||||
| import javax.swing.JDialog; | ||||
| import javax.swing.JPanel; | ||||
| import javax.swing.JTextPane; | ||||
|  | ||||
| import envoy.client.Settings; | ||||
| import envoy.client.ui.PrimaryButton; | ||||
| import envoy.client.ui.PrimaryTextArea; | ||||
| import envoy.client.ui.Theme; | ||||
| import envoy.client.util.EnvoyLog; | ||||
|  | ||||
| /** | ||||
|  * Displays window where you can choose a name for the new {@link Theme}. | ||||
| @@ -33,7 +34,8 @@ public class NewThemeScreen extends JDialog { | ||||
| 	private PrimaryButton	otherName	= new PrimaryButton("Other Name"); | ||||
| 	private PrimaryButton	overwrite	= new PrimaryButton("Overwrite"); | ||||
|  | ||||
| 	private static final Logger	logger				= EnvoyLog.getLogger(NewThemeScreen.class.getSimpleName()); | ||||
| 	private final Consumer<String> newThemeAction, modifyThemeAction; | ||||
|  | ||||
| 	private static final long serialVersionUID = 2369985550946300976L; | ||||
|  | ||||
| 	/** | ||||
| @@ -41,49 +43,38 @@ public class NewThemeScreen extends JDialog { | ||||
| 	 * There are two versions of this Window. The first one is responsible for | ||||
| 	 * choosing the name, the second one appears, the the name already exists. | ||||
| 	 *  | ||||
| 	 * @param parentClass The class, where this constructor is invoked. | ||||
| 	 * @param parent the dialog is launched with its location relative to this {@link SettingsScreen} | ||||
| 	 * @param newThemeAction is executed when a new theme name is entered | ||||
| 	 * @param modifyThemeAction is executed when an existing theme name is entered and confirmed | ||||
| 	 * @since Envoy v0.3-alpha | ||||
| 	 */ | ||||
| 	public NewThemeScreen(ThemeCustomizationPanel parentClass) { | ||||
| 	public NewThemeScreen(SettingsScreen parent, Consumer<String> newThemeAction, Consumer<String> modifyThemeAction) { | ||||
| 		this.newThemeAction		= newThemeAction; | ||||
| 		this.modifyThemeAction	= modifyThemeAction; | ||||
|  | ||||
| 		setLocationRelativeTo(parent); | ||||
| 		setTitle("New Theme"); | ||||
| 		setDimensions(true, parentClass); | ||||
| 		setVisible(true); | ||||
| 		setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); | ||||
| 		setModal(true); | ||||
| 		// TODO: check modalitly | ||||
| 		// setModalityType(DEFAULT_MODALITY_TYPE); | ||||
|  | ||||
| 		setDimensions(true); | ||||
| 		setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); | ||||
|  | ||||
| 		Theme theme = Settings.getInstance().getThemes().get(Settings.getInstance().getCurrentTheme()); | ||||
|  | ||||
| 		getContentPane().setLayout(new BorderLayout()); | ||||
| 		{ | ||||
| 		standardPanel.setBackground(theme.getBackgroundColor()); | ||||
| 		secondaryPanel.setBackground(theme.getBackgroundColor()); | ||||
| 			loadStandardContent(theme, parentClass); | ||||
| 		} | ||||
| 		loadStandardContent(theme); | ||||
| 	} | ||||
|  | ||||
| 	private void setDimensions(boolean isStandard, ThemeCustomizationPanel parentClass) { | ||||
| 		if (isStandard == true) { | ||||
| 			setPreferredSize(new Dimension(300, 170)); | ||||
| 			setMinimumSize(new Dimension(300, 170)); | ||||
| 			setMaximumSize(new Dimension(300, 170)); | ||||
| 			setBounds(parentClass.getLocation().x + (parentClass.getSize().width), | ||||
| 					parentClass.getLocation().y + (parentClass.getSize().height / 2), | ||||
| 					300, | ||||
| 					170); | ||||
| 		} else { | ||||
| 			setPreferredSize(new Dimension(300, 225)); | ||||
| 			setMinimumSize(new Dimension(300, 225)); | ||||
| 			setMaximumSize(new Dimension(300, 225)); | ||||
| 			setBounds(parentClass.getLocation().x + (parentClass.getSize().width), | ||||
| 					parentClass.getLocation().y + (parentClass.getSize().height / 2), | ||||
| 					300, | ||||
| 					225); | ||||
| 		} | ||||
| 	private void setDimensions(boolean isStandard) { | ||||
| 		Dimension size = isStandard ? new Dimension(300, 170) : new Dimension(300, 225); | ||||
| 		setPreferredSize(size); | ||||
| 		setMinimumSize(size); | ||||
| 		setMaximumSize(size); | ||||
| 	} | ||||
|  | ||||
| 	private void loadStandardContent(Theme theme, ThemeCustomizationPanel parentClass) { | ||||
| 	private void loadStandardContent(Theme theme) { | ||||
| 		getContentPane().removeAll(); | ||||
|  | ||||
| 		// ContentPane | ||||
| @@ -139,23 +130,18 @@ public class NewThemeScreen extends JDialog { | ||||
| 		standardPanel.add(confirmButton, gbc_confirmButton); | ||||
|  | ||||
| 		confirmButton.addActionListener((evt) -> { | ||||
| 			if (!nameEnterTextArea.getText().isEmpty()) try { | ||||
| 				if (Settings.getInstance().getThemes().containsKey(nameEnterTextArea.getText())) { | ||||
| 			if (!nameEnterTextArea.getText().isEmpty()) if (Settings.getInstance().getThemes().containsKey(nameEnterTextArea.getText())) { | ||||
| 				// load other panel | ||||
| 					setDimensions(false, parentClass); | ||||
| 					loadSecondaryPage(theme, parentClass); | ||||
| 				setDimensions(false); | ||||
| 				loadSecondaryPage(theme); | ||||
| 			} else { | ||||
| 					parentClass.newTheme(nameEnterTextArea.getText()); | ||||
| 				newThemeAction.accept(nameEnterTextArea.getText()); | ||||
| 				dispose(); | ||||
| 			} | ||||
| 			} catch (Exception e) { | ||||
| 				logger.info("" + "Name could not be set! " + e); | ||||
| 				e.printStackTrace(); | ||||
| 			} | ||||
| 		}); | ||||
| 	} | ||||
|  | ||||
| 	private void loadSecondaryPage(Theme theme, ThemeCustomizationPanel parentClass) { | ||||
| 	private void loadSecondaryPage(Theme theme) { | ||||
| 		// ContentPane | ||||
| 		getContentPane().removeAll(); | ||||
|  | ||||
| @@ -233,28 +219,8 @@ public class NewThemeScreen extends JDialog { | ||||
|  | ||||
| 		secondaryPanel.add(overwrite, gbc_overwrite); | ||||
|  | ||||
| 		otherName.addActionListener((evt) -> { | ||||
| 			try { | ||||
| 				setDimensions(true, parentClass); | ||||
| 				loadStandardContent(theme, parentClass); | ||||
| 		otherName.addActionListener((evt) -> { setDimensions(true); loadStandardContent(theme); }); | ||||
|  | ||||
| 			} catch (Exception e) { | ||||
| 				logger.info("Window could not be updated! " + e); | ||||
| 				e.printStackTrace(); | ||||
| 			} | ||||
|  | ||||
| 		}); | ||||
|  | ||||
| 		overwrite.addActionListener((evt) -> { | ||||
| 			try { | ||||
| 				dispose(); | ||||
| 				parentClass.overwriteTheme(nameEnterTextArea.getText()); | ||||
|  | ||||
| 			} catch (Exception e) { | ||||
| 				logger.info("Error while overwriting the theme! " + e); | ||||
| 				e.printStackTrace(); | ||||
| 			} | ||||
|  | ||||
| 		}); | ||||
| 		overwrite.addActionListener((evt) -> { modifyThemeAction.accept(nameEnterTextArea.getText()); dispose(); }); | ||||
| 	} | ||||
| } | ||||
| @@ -18,8 +18,18 @@ import javax.swing.JPanel; | ||||
|  */ | ||||
| public abstract class SettingsPanel extends JPanel { | ||||
|  | ||||
| 	protected final SettingsScreen parent; | ||||
|  | ||||
| 	private static final long serialVersionUID = -3069212622468626050L; | ||||
|  | ||||
| 	/** | ||||
| 	 * Initializes a {@link SettingsPanel}. | ||||
| 	 *  | ||||
| 	 * @param parent the {@link SettingsScreen} as a part of which this | ||||
| 	 *               {@link SettingsPanel} is displayed | ||||
| 	 */ | ||||
| 	public SettingsPanel(SettingsScreen parent) { this.parent = parent; } | ||||
|  | ||||
| 	/** | ||||
| 	 * @return an {@link ActionListener} that should be invoked when the OK button | ||||
| 	 *         is pressed in the {@link SettingsScreen} | ||||
|   | ||||
| @@ -93,7 +93,7 @@ public class SettingsScreen extends JDialog { | ||||
| 					if (settingsPanel != null) contentPanel.remove(settingsPanel); | ||||
|  | ||||
| 					try { | ||||
| 						settingsPanel = panels.get(option).getDeclaredConstructor().newInstance(); | ||||
| 						settingsPanel = panels.get(option).getDeclaredConstructor(getClass()).newInstance(this); | ||||
|  | ||||
| 						// Add selected settings panel | ||||
| 						contentPanel.add(settingsPanel, gbc_panel); | ||||
| @@ -162,8 +162,7 @@ public class SettingsScreen extends JDialog { | ||||
| 		EventBus.getInstance().register(ThemeChangeEvent.class, (evt) -> applyTheme(((ThemeChangeEvent) evt).get())); | ||||
|  | ||||
| 		setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); | ||||
| 		//setModal(true); | ||||
| 		//TODO: check modalitly | ||||
| 		setModal(true); | ||||
| 	} | ||||
|  | ||||
| 	private void applyTheme(Theme theme) { | ||||
|   | ||||
| @@ -4,7 +4,6 @@ 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; | ||||
|  | ||||
| @@ -33,10 +32,11 @@ public class ThemeCustomizationPanel extends SettingsPanel { | ||||
|  | ||||
| 	private JPanel colorsPanel = new JPanel(); | ||||
|  | ||||
| 	private String[]			themeArray		= Settings.getInstance().getThemes().keySet().toArray(new String[0]); | ||||
| 	private JComboBox<String>	themes			= new JComboBox<>(themeArray); | ||||
| 	private Theme				temporaryTheme, selectedTheme; | ||||
| 	private boolean				themeChanged	= false; | ||||
| 	private DefaultComboBoxModel<String>	themesModel	= new DefaultComboBoxModel<>( | ||||
| 			Settings.getInstance().getThemes().keySet().toArray(new String[0])); | ||||
| 	private JComboBox<String>				themes		= new JComboBox<>(themesModel); | ||||
| 	private Theme							temporaryTheme; | ||||
| 	private boolean							themeChanged; | ||||
|  | ||||
| 	private final Insets insets = new Insets(5, 5, 5, 5); | ||||
|  | ||||
| @@ -48,9 +48,12 @@ public class ThemeCustomizationPanel extends SettingsPanel { | ||||
| 	 * the current {@link Theme} and create new themes as part of the | ||||
| 	 * {@link SettingsScreen}. | ||||
| 	 *  | ||||
| 	 * @param parent the {@link SettingsScreen} as a part of which this | ||||
| 	 *               {@link SettingsPanel} is displayed | ||||
| 	 * @since Envoy v0.2-alpha | ||||
| 	 */ | ||||
| 	public ThemeCustomizationPanel() { | ||||
| 	public ThemeCustomizationPanel(SettingsScreen parent) { | ||||
| 		super(parent); | ||||
| 		temporaryTheme = new Theme("temporaryTheme", Settings.getInstance().getThemes().get(Settings.getInstance().getCurrentTheme())); | ||||
|  | ||||
| 		GridBagLayout gbl_themeLayout = new GridBagLayout(); | ||||
| @@ -64,16 +67,6 @@ public class ThemeCustomizationPanel extends SettingsPanel { | ||||
|  | ||||
| 		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.gridwidth	= 2; | ||||
| @@ -106,26 +99,53 @@ public class ThemeCustomizationPanel extends SettingsPanel { | ||||
| 		add(colorsPanel, gbc_colorsPanel); | ||||
| 		colorsPanel.setBackground(theme.getCellColor()); | ||||
|  | ||||
| 		// Apply theme upon selection | ||||
| 		themes.addItemListener(new ItemListener() { | ||||
|  | ||||
| 			@Override | ||||
| 			public void itemStateChanged(ItemEvent e) { | ||||
| 				String selectedValue = (String) themes.getSelectedItem(); | ||||
| 				logger.log(Level.FINEST, "Selected theme: " + selectedValue); | ||||
|  | ||||
| 				final Theme currentTheme = Settings.getInstance().getTheme(selectedValue); | ||||
| 				Settings.getInstance().setCurrentTheme(selectedValue); | ||||
| 				EventBus.getInstance().dispatch(new ThemeChangeEvent(currentTheme)); | ||||
| 			} | ||||
| 		}); | ||||
|  | ||||
| 		// Apply current theme | ||||
| 		applyTheme(theme); | ||||
|  | ||||
| 		// Respond to theme changes | ||||
| 		EventBus.getInstance().register(ThemeChangeEvent.class, (evt) -> applyTheme(((ThemeChangeEvent) evt).get())); | ||||
| 		EventBus.getInstance() | ||||
| 			.register(ThemeChangeEvent.class, | ||||
| 					(evt) -> { | ||||
| 						final Theme currentTheme = ((ThemeChangeEvent) evt).get(); | ||||
| 						temporaryTheme = new Theme("temporaryTheme", currentTheme); | ||||
| 						applyTheme(currentTheme); | ||||
| 					}); | ||||
| 	} | ||||
|  | ||||
| 	@Override | ||||
| 	public ActionListener getOkButtonAction() { | ||||
| 		return (evt) -> { | ||||
| 			if (themeChanged) { | ||||
| 				try { | ||||
| 					new NewThemeScreen(this).setVisible(true); | ||||
| 				} catch (Exception e) { | ||||
| 					logger.info("New theme couldn't be created! " + e); | ||||
| 					e.printStackTrace(); | ||||
| 				} | ||||
| 				new NewThemeScreen(parent, (name) -> { | ||||
| 					// Create new theme | ||||
| 					logger.log(Level.FINEST, name); | ||||
| 					Settings.getInstance().addNewThemeToMap(new Theme(name, temporaryTheme)); | ||||
|  | ||||
| 					// Add new theme name to combo box | ||||
| 					themesModel.addElement(name); | ||||
|  | ||||
| 					// Select new theme name | ||||
| 					themes.setSelectedIndex(themesModel.getSize() - 1); | ||||
| 				}, (name) -> { | ||||
| 					// Modify theme | ||||
| 					Settings.getInstance().getThemes().replace(name, new Theme(name, temporaryTheme)); | ||||
| 					themes.setSelectedItem(name); | ||||
| 				}).setVisible(true); | ||||
| 				themeChanged = false; | ||||
| 			} else { | ||||
| 				updateCurrentTheme(); | ||||
| 			} | ||||
| 		}; | ||||
| 	} | ||||
| @@ -139,13 +159,16 @@ public class ThemeCustomizationPanel extends SettingsPanel { | ||||
| 		themes.setBackground(theme.getInteractableBackgroundColor()); | ||||
| 		themes.setForeground(theme.getInteractableForegroundColor()); | ||||
| 		colorsPanel.setBackground(theme.getCellColor()); | ||||
|  | ||||
| 		// Color panel | ||||
| 		updateColorVariables(theme); | ||||
|  | ||||
| 		revalidate(); | ||||
| 		repaint(); | ||||
| 	} | ||||
|  | ||||
| 	private void updateColorVariables(Theme theme) { | ||||
| 		temporaryTheme = new Theme("temporaryTheme", theme); | ||||
|  | ||||
| 		colorsPanel.removeAll(); | ||||
|  | ||||
| 		buildCustomizeElements(theme); | ||||
| 	} | ||||
|  | ||||
| @@ -155,7 +178,7 @@ public class ThemeCustomizationPanel extends SettingsPanel { | ||||
| 		buildCustomizeElement(theme, theme.getInteractableForegroundColor(), "Interactable Foreground", "interactableForegroundColor", 3); | ||||
| 		buildCustomizeElement(theme, theme.getInteractableBackgroundColor(), "Interactable Background", "interactableBackgroundColor", 4); | ||||
| 		buildCustomizeElement(theme, theme.getMessageColorChat(), "Messages Chat", "messageColorChat", 5); | ||||
| 		buildCustomizeElement(theme, theme.getDateColorChat(), "Date Chat", "dateColorCat", 6); | ||||
| 		buildCustomizeElement(theme, theme.getDateColorChat(), "Date Chat", "dateColorChat", 6); | ||||
| 		buildCustomizeElement(theme, theme.getSelectionColor(), "Selection", "selectionColor", 7); | ||||
| 		buildCustomizeElement(theme, theme.getTypingMessageColor(), "Typing Message", "typingMessageColor", 8); | ||||
| 		buildCustomizeElement(theme, theme.getUserNameColor(), "User Names", "userNameColor", 9); | ||||
| @@ -175,21 +198,15 @@ public class ThemeCustomizationPanel extends SettingsPanel { | ||||
| 		button.setPreferredSize(new Dimension(25, 25)); | ||||
|  | ||||
| 		button.addActionListener((evt) -> { | ||||
| 			try { | ||||
| 			java.awt.Color c = JColorChooser.showDialog(null, "Choose a color", color); | ||||
| 				Color			newColor	= new Color(c.getRGB()); | ||||
| 				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 | ||||
| 			if (c != null) { | ||||
| 				Color newColor = new Color(c); | ||||
| 				if (!color.equals(newColor)) { | ||||
| 					logger.log(Level.FINEST, "New Color: " + newColor); | ||||
| 					temporaryTheme.setColor(colorName, newColor); | ||||
| 					themeChanged = true; | ||||
| 				} | ||||
| 				button.setBackground(newColor); | ||||
|  | ||||
| 			} catch (Exception e) { | ||||
| 				logger.info("An error occured while opening Color Chooser: " + e); | ||||
| 				e.printStackTrace(); | ||||
| 			} | ||||
| 		}); | ||||
|  | ||||
| @@ -211,48 +228,4 @@ public class ThemeCustomizationPanel extends SettingsPanel { | ||||
|  | ||||
| 		colorsPanel.add(button, gbc_button); | ||||
| 	} | ||||
|  | ||||
| 	private void updateCurrentTheme() { | ||||
| 		Settings.getInstance().setCurrentTheme(selectedTheme.getThemeName()); | ||||
| 		logger.log(Level.FINER, "Setting theme: " + selectedTheme.getThemeName()); | ||||
|  | ||||
| 		final Theme currentTheme = Settings.getInstance().getThemes().get(Settings.getInstance().getCurrentTheme()); | ||||
| 		applyTheme(currentTheme); | ||||
| 		updateColorVariables(currentTheme); | ||||
| 		EventBus.getInstance().dispatch(new ThemeChangeEvent(currentTheme)); | ||||
| 		temporaryTheme = new Theme("temporaryTheme", currentTheme); | ||||
|  | ||||
| 		revalidate(); | ||||
| 		repaint(); | ||||
| 	} | ||||
| 	 | ||||
| 	/** | ||||
| 	 * Adds a new {@link Theme} to the theme map. | ||||
| 	 *  | ||||
| 	 * @param name The name of the new {@link Theme}. | ||||
| 	 * @since Envoy v0.3-alpha | ||||
| 	 */ | ||||
| 	public void newTheme(String name) { | ||||
| 		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(); | ||||
|  | ||||
| 		themes.addItem(themeArray[themeArray.length - 1]); | ||||
| 		themes.setSelectedIndex(themeArray.length - 1); | ||||
|  | ||||
| 		updateCurrentTheme(); | ||||
| 	} | ||||
| 	 | ||||
| 	/** | ||||
| 	 * Overwrites a specific {@link Theme} located in the theme map and sets the selected {@link Theme} to this new {@link Theme}. | ||||
| 	 *  | ||||
| 	 * @param key The name of the {@link Theme} to be overwritten. | ||||
| 	 * @since Envoy v0.3-alpha | ||||
| 	 */ | ||||
| 	public void overwriteTheme(String key) { | ||||
| 		Settings.getInstance().getThemes().replace(key, new Theme(key, temporaryTheme)); | ||||
| 		selectedTheme = Settings.getInstance().getThemes().get(key); | ||||
| 		updateCurrentTheme(); | ||||
| 	} | ||||
| } | ||||
		Reference in New Issue
	
	Block a user