diff --git a/.settings/org.eclipse.jdt.ui.prefs b/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 0000000..cdb456a
--- /dev/null
+++ b/.settings/org.eclipse.jdt.ui.prefs
@@ -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
diff --git a/src/main/java/envoy/client/Settings.java b/src/main/java/envoy/client/Settings.java
index 75a4355..d7e01de 100644
--- a/src/main/java/envoy/client/Settings.java
+++ b/src/main/java/envoy/client/Settings.java
@@ -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;
diff --git a/src/main/java/envoy/client/ui/ChatWindow.java b/src/main/java/envoy/client/ui/ChatWindow.java
index b21e2d9..eb8ae44 100644
--- a/src/main/java/envoy/client/ui/ChatWindow.java
+++ b/src/main/java/envoy/client/ui/ChatWindow.java
@@ -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();
diff --git a/src/main/java/envoy/client/ui/SettingsScreen.java b/src/main/java/envoy/client/ui/SettingsScreen.java
deleted file mode 100644
index 75ce884..0000000
--- a/src/main/java/envoy/client/ui/SettingsScreen.java
+++ /dev/null
@@ -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: envoy-client
- * File: SettingsScreen.java
- * Created: 31 Oct 2019
- *
- * @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 optionsListModel = new DefaultListModel<>();
- private final JList 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 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 selectedOption = (JList) 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()); }
-}
diff --git a/src/main/java/envoy/client/ui/Theme.java b/src/main/java/envoy/client/ui/Theme.java
index bd2ccb3..3e6c39e 100644
--- a/src/main/java/envoy/client/ui/Theme.java
+++ b/src/main/java/envoy/client/ui/Theme.java
@@ -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: envoy-client
@@ -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 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} of all colors defined for this theme
+ * with their names as keys
+ * @since Envoy v0.2-alpha
+ */
+ public Map 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
- * 0 = backgroundColor
- * 1 = cellColor
- * 2 = interactableForegroundColor
- * 3 = interactableBackgroundColor
- * 4 = messageColorChat
- * 5 = dateColorChat
- * 6 = selectionColor
- * 7 = typingMessageColor
- * 8 = userNameColor
- *
- *
- * @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); }
}
diff --git a/src/main/java/envoy/client/ui/settings/SettingsPanel.java b/src/main/java/envoy/client/ui/settings/SettingsPanel.java
new file mode 100644
index 0000000..9b8f239
--- /dev/null
+++ b/src/main/java/envoy/client/ui/settings/SettingsPanel.java
@@ -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.
+ *
+ * Project: envoy-client
+ * File: SettingsPanel.java
+ * Created: 20 Dec 2019
+ *
+ * @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();
+}
diff --git a/src/main/java/envoy/client/ui/settings/SettingsScreen.java b/src/main/java/envoy/client/ui/settings/SettingsScreen.java
new file mode 100644
index 0000000..d283d6b
--- /dev/null
+++ b/src/main/java/envoy/client/ui/settings/SettingsScreen.java
@@ -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.
+ *
+ * Project: envoy-client
+ * File: SettingsScreen.java
+ * Created: 31 Oct 2019
+ *
+ * @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 optionsListModel = new DefaultListModel<>();
+ private final JList 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> 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());
+ }
+}
diff --git a/src/main/java/envoy/client/ui/settings/ThemeCustomizationPanel.java b/src/main/java/envoy/client/ui/settings/ThemeCustomizationPanel.java
new file mode 100644
index 0000000..6a1aa66
--- /dev/null
+++ b/src/main/java/envoy/client/ui/settings/ThemeCustomizationPanel.java
@@ -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.
+ *
+ * Project: envoy-client
+ * File: ThemeCustomizationPanel.java
+ * Created: 20 Dec 2019
+ *
+ * @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 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()); }
+}
diff --git a/src/main/resources/envoy_logo_old.png b/src/main/resources/envoy_logo_old.png
deleted file mode 100644
index 35ef7d9..0000000
Binary files a/src/main/resources/envoy_logo_old.png and /dev/null differ