From 935ee58c4bdf0c57c930578372f6525373e45e8c Mon Sep 17 00:00:00 2001 From: kske Date: Fri, 10 Apr 2020 21:52:19 +0200 Subject: [PATCH 1/8] Added a rudimentary settings scene with an empty controller --- .../client/ui/SettingsSceneController.java | 13 +++++++++ src/main/resources/fxml/SettingsScene.fxml | 29 +++++++++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 src/main/java/envoy/client/ui/SettingsSceneController.java create mode 100644 src/main/resources/fxml/SettingsScene.fxml diff --git a/src/main/java/envoy/client/ui/SettingsSceneController.java b/src/main/java/envoy/client/ui/SettingsSceneController.java new file mode 100644 index 0000000..1fa8be6 --- /dev/null +++ b/src/main/java/envoy/client/ui/SettingsSceneController.java @@ -0,0 +1,13 @@ +package envoy.client.ui; + +/** + * Project: envoy-client
+ * File: SettingsSceneController.java
+ * Created: 10.04.2020
+ * + * @author Kai S. K. Engelbart + * @since Envoy Client v0.1-beta + */ +public class SettingsSceneController { + +} diff --git a/src/main/resources/fxml/SettingsScene.fxml b/src/main/resources/fxml/SettingsScene.fxml new file mode 100644 index 0000000..12edf7c --- /dev/null +++ b/src/main/resources/fxml/SettingsScene.fxml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + From 2cba9352df91cc3a6923411c7b651a89da4d6b49 Mon Sep 17 00:00:00 2001 From: kske Date: Sat, 18 Apr 2020 12:03:32 +0200 Subject: [PATCH 3/8] Added GeneralSettingsPane, added JavaFX support in SettingsItem Also removed the old settings ui components. --- src/main/java/envoy/client/data/Settings.java | 2 +- .../java/envoy/client/data/SettingsItem.java | 63 ++--- .../envoy/client/ui/GeneralSettingsPane.java | 21 ++ .../java/envoy/client/ui/SettingsPane.java | 13 +- .../client/ui/SettingsSceneController.java | 6 +- .../ui/settings/GeneralSettingsPanel.java | 89 ------- .../client/ui/settings/NewThemeScreen.java | 228 ---------------- .../client/ui/settings/SettingsPanel.java | 30 --- .../client/ui/settings/SettingsScreen.java | 172 ------------ .../ui/settings/ThemeCustomizationPanel.java | 246 ------------------ .../client/ui/settings/package-info.java | 9 - 11 files changed, 47 insertions(+), 832 deletions(-) create mode 100644 src/main/java/envoy/client/ui/GeneralSettingsPane.java delete mode 100644 src/main/java/envoy/client/ui/settings/GeneralSettingsPanel.java delete mode 100644 src/main/java/envoy/client/ui/settings/NewThemeScreen.java delete mode 100644 src/main/java/envoy/client/ui/settings/SettingsPanel.java delete mode 100644 src/main/java/envoy/client/ui/settings/SettingsScreen.java delete mode 100755 src/main/java/envoy/client/ui/settings/ThemeCustomizationPanel.java delete mode 100644 src/main/java/envoy/client/ui/settings/package-info.java diff --git a/src/main/java/envoy/client/data/Settings.java b/src/main/java/envoy/client/data/Settings.java index 5bff58c..fcde72a 100644 --- a/src/main/java/envoy/client/data/Settings.java +++ b/src/main/java/envoy/client/data/Settings.java @@ -103,7 +103,7 @@ public class Settings { private void supplementDefaults() { items.putIfAbsent("enterToSend", new SettingsItem<>(true, "Enter to send", "Sends a message by pressing the enter key.")); items.putIfAbsent("onCloseMode", new SettingsItem<>(true, "Hide on close", "Hides the chat window when it is closed.")); - items.putIfAbsent("currentTheme", new SettingsItem<>("dark", null)); + items.putIfAbsent("currentTheme", new SettingsItem<>("dark", "Current Theme Name", "The name of the currently selected theme.")); } /** diff --git a/src/main/java/envoy/client/data/SettingsItem.java b/src/main/java/envoy/client/data/SettingsItem.java index 2c9ac39..e9c498c 100644 --- a/src/main/java/envoy/client/data/SettingsItem.java +++ b/src/main/java/envoy/client/data/SettingsItem.java @@ -4,10 +4,11 @@ import java.io.Serializable; import java.util.HashMap; import java.util.Map; import java.util.function.Consumer; +import java.util.function.Function; import javax.swing.JComponent; -import envoy.client.ui.primary.PrimaryToggleSwitch; +import javafx.scene.Node; /** * Encapsulates a persistent value that is directly or indirectly mutable by the @@ -23,18 +24,18 @@ import envoy.client.ui.primary.PrimaryToggleSwitch; */ public class SettingsItem implements Serializable { - private T value; - private Class componentClass; - private String userFriendlyName, description; + private T value; + private String userFriendlyName, description; - transient private Consumer changeHandler; + private transient Consumer changeHandler; + private transient Function, Node> nodeCreator; - private static final Map, Class> componentClasses = new HashMap<>(); + private static final Map, Function, Node>> nodeCreators = new HashMap<>(); - private static final long serialVersionUID = 0L; + private static final long serialVersionUID = 1L; static { - componentClasses.put(Boolean.class, PrimaryToggleSwitch.class); + } /** @@ -48,37 +49,11 @@ public class SettingsItem implements Serializable { * @since Envoy Client v0.3-alpha */ public SettingsItem(T value, String userFriendlyName, String description) { - this(value, componentClasses.get(value.getClass())); + this.value = value; this.userFriendlyName = userFriendlyName; this.description = description; - } - /** - * Initializes a {@link SettingsItem}. The default value's class will be mapped - * to a specific {@link JComponent}. The mapping can also be disables if this - * parameter is {@code null}. In that case a {@link NullPointerException} will - * be thrown if the method {@link SettingsItem#getComponent()} is called. - * - * @param value the default value - * @param componentClass the class of the {@link JComponent} to represent this - * {@link SettingsItem} with - * @since Envoy Client v0.3-alpha - */ - public SettingsItem(T value, Class componentClass) { - this.value = value; - this.componentClass = componentClass; - } - - /** - * @return an instance of the {@link JComponent} that represents this - * {@link SettingsItem} - * @throws ReflectiveOperationException if the component initialization failed - * @throws SecurityException if the component initialization failed - * @since Envoy Client v0.3-alpha - */ - public JComponent getComponent() throws ReflectiveOperationException, SecurityException { - if (componentClass == null) throw new NullPointerException("Component class is null"); - return componentClass.getConstructor(SettingsItem.class).newInstance(this); + if (nodeCreators.containsKey(value.getClass())) nodeCreator = nodeCreators.get(value.getClass()); } /** @@ -99,18 +74,6 @@ public class SettingsItem implements Serializable { this.value = value; } - /** - * @return the componentClass - * @since Envoy Client v0.3-alpha - */ - public Class getComponentClass() { return componentClass; } - - /** - * @param componentClass the componentClass to set - * @since Envoy Client v0.3-alpha - */ - public void setComponentClass(Class componentClass) { this.componentClass = componentClass; } - /** * @return the userFriendlyName * @since Envoy Client v0.3-alpha @@ -147,4 +110,8 @@ public class SettingsItem implements Serializable { this.changeHandler = changeHandler; changeHandler.accept(value); } + + public boolean hasNodeCreator() { return nodeCreator != null; } + + public Node getNode() { return nodeCreator.apply(this); } } diff --git a/src/main/java/envoy/client/ui/GeneralSettingsPane.java b/src/main/java/envoy/client/ui/GeneralSettingsPane.java new file mode 100644 index 0000000..20f74f0 --- /dev/null +++ b/src/main/java/envoy/client/ui/GeneralSettingsPane.java @@ -0,0 +1,21 @@ +package envoy.client.ui; + +import envoy.client.data.Settings; + +/** + * Project: envoy-client
+ * File: GeneralSettingsPane.java
+ * Created: 18.04.2020
+ * + * @author Kai S. K. Engelbart + * @since Envoy Client v0.1-beta + */ +public class GeneralSettingsPane extends SettingsPane { + + private static final Settings settings = Settings.getInstance(); + + /** + * @since Envoy Client v0.1-beta + */ + public GeneralSettingsPane() { super("General"); } +} diff --git a/src/main/java/envoy/client/ui/SettingsPane.java b/src/main/java/envoy/client/ui/SettingsPane.java index 85d2d35..79bec4b 100644 --- a/src/main/java/envoy/client/ui/SettingsPane.java +++ b/src/main/java/envoy/client/ui/SettingsPane.java @@ -1,7 +1,6 @@ package envoy.client.ui; -import javafx.scene.Node; - +import javafx.scene.layout.Pane; /** * Project: envoy-client
@@ -11,9 +10,15 @@ import javafx.scene.Node; * @author Kai S. K. Engelbart * @since Envoy Client v0.1-beta */ -public abstract class SettingsPane extends Node { +public abstract class SettingsPane extends Pane { protected String title; - public abstract String getTitle(); + protected SettingsPane(String title) { this.title = title; } + + /** + * @return the title of this settings pane + * @since Envoy Client v0.1-beta + */ + public String getTitle() { return title; } } diff --git a/src/main/java/envoy/client/ui/SettingsSceneController.java b/src/main/java/envoy/client/ui/SettingsSceneController.java index 761d8cb..2d6eccd 100644 --- a/src/main/java/envoy/client/ui/SettingsSceneController.java +++ b/src/main/java/envoy/client/ui/SettingsSceneController.java @@ -3,8 +3,6 @@ package envoy.client.ui; import javafx.fxml.FXML; import javafx.scene.control.*; -import envoy.client.data.Settings; - /** * Project: envoy-client
* File: SettingsSceneController.java
@@ -13,7 +11,7 @@ import envoy.client.data.Settings; * @author Kai S. K. Engelbart * @since Envoy Client v0.1-beta */ -public class SettingsSceneController { +public final class SettingsSceneController { @FXML private ListView settingsList; @@ -21,8 +19,6 @@ public class SettingsSceneController { @FXML private TitledPane titledPane; - private static final Settings settings = Settings.getInstance(); - @FXML private void initialize() { settingsList.setCellFactory(listView -> new ListCell<>() { diff --git a/src/main/java/envoy/client/ui/settings/GeneralSettingsPanel.java b/src/main/java/envoy/client/ui/settings/GeneralSettingsPanel.java deleted file mode 100644 index 372478b..0000000 --- a/src/main/java/envoy/client/ui/settings/GeneralSettingsPanel.java +++ /dev/null @@ -1,89 +0,0 @@ -package envoy.client.ui.settings; - -import java.awt.GridBagConstraints; -import java.awt.GridBagLayout; -import java.awt.Insets; -import java.util.logging.Level; -import java.util.logging.Logger; - -import javax.swing.JComponent; -import javax.swing.JTextPane; - -import envoy.client.data.Settings; -import envoy.client.data.SettingsItem; -import envoy.client.ui.Theme; -import envoy.util.EnvoyLog; - -/** - * Displays GUI components that allow general settings regarding the client.
- *
- * Project: envoy-client
- * File: GeneralSettingsPanel.java
- * Created: 21 Dec 2019
- * - * @author Maximilian Käfer - * @since Envoy Client v0.3-alpha - */ -public class GeneralSettingsPanel extends SettingsPanel { - - private Theme theme; - - private static final String[] items = { "onCloseMode", "enterToSend" }; - private static final Logger logger = EnvoyLog.getLogger(GeneralSettingsPanel.class); - private static final long serialVersionUID = 0L; - - /** - * 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 Client v0.3-alpha - */ - public GeneralSettingsPanel(SettingsScreen parent) { - super(parent); - theme = Settings.getInstance().getCurrentTheme(); - - setBackground(theme.getCellColor()); - - GridBagLayout gbl_general = new GridBagLayout(); - gbl_general.columnWidths = new int[] { 1, 1 }; - gbl_general.rowHeights = new int[] { 1, 1, 1 }; - gbl_general.columnWeights = new double[] { 1.0, 0.1 }; - gbl_general.rowWeights = new double[] { 0.02, 0.02, 1.0 }; - - setLayout(gbl_general); - - for (int i = 0; i < items.length; i++) - try { - createSettingElement(i, Settings.getInstance().getItems().get(items[i])); - } catch (SecurityException | ReflectiveOperationException e) { - logger.log(Level.WARNING, "Could not create settings item", e); - } - } - - private void createSettingElement(int gridy, SettingsItem settingsItem) throws SecurityException, ReflectiveOperationException { - JTextPane descriptionText = new JTextPane(); - - JComponent settingComponent = settingsItem.getComponent(); - - GridBagConstraints gbc_toggleSwitch = new GridBagConstraints(); - gbc_toggleSwitch.gridx = 1; - gbc_toggleSwitch.gridy = gridy; - - add(settingComponent, gbc_toggleSwitch); - - descriptionText.setText(settingsItem.getDescription()); - descriptionText.setBackground(theme.getBackgroundColor()); - descriptionText.setForeground(theme.getBackgroundColor().invert()); - descriptionText.setEditable(false); - - GridBagConstraints gbc_descriptionText = new GridBagConstraints(); - gbc_descriptionText.fill = GridBagConstraints.BOTH; - gbc_descriptionText.gridx = 0; - gbc_descriptionText.gridy = gridy; - gbc_descriptionText.insets = new Insets(5, 5, 5, 5); - - add(descriptionText, gbc_descriptionText); - } -} diff --git a/src/main/java/envoy/client/ui/settings/NewThemeScreen.java b/src/main/java/envoy/client/ui/settings/NewThemeScreen.java deleted file mode 100644 index a486e85..0000000 --- a/src/main/java/envoy/client/ui/settings/NewThemeScreen.java +++ /dev/null @@ -1,228 +0,0 @@ -package envoy.client.ui.settings; - -import java.awt.*; -import java.util.function.Consumer; - -import javax.swing.JDialog; -import javax.swing.JPanel; -import javax.swing.JTextPane; - -import envoy.client.data.Settings; -import envoy.client.ui.Theme; -import envoy.client.ui.primary.PrimaryButton; -import envoy.client.ui.primary.PrimaryTextArea; - -/** - * Displays window where you can choose a name for the new {@link Theme}. - *
- * Project: envoy-client
- * File: NewThemeScreen.java
- * Created: 26 Dec 2019
- * - * @author Maximilian Käfer - * @since Envoy Client v0.3-alpha - */ -public class NewThemeScreen extends JDialog { - - private final JPanel standardPanel = new JPanel(); - private final JPanel secondaryPanel = new JPanel(); - private JTextPane text = new JTextPane(); - private PrimaryTextArea nameEnterTextArea = new PrimaryTextArea(4); - private PrimaryButton confirmButton = new PrimaryButton("Confirm"); - - private JTextPane errorText = new JTextPane(); - private PrimaryButton otherName = new PrimaryButton("Other Name"); - private PrimaryButton overwrite = new PrimaryButton("Overwrite"); - - private final Consumer newThemeAction, modifyThemeAction; - - private static final long serialVersionUID = 0L; - - /** - * Creates a window, where you can choose a name for a new {@link Theme}.
- * There are two versions of this Window. The first one is responsible for - * choosing the name, the second one appears, if the name already exists. - * - * @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 Client v0.3-alpha - */ - public NewThemeScreen(SettingsScreen parent, Consumer newThemeAction, Consumer modifyThemeAction) { - this.newThemeAction = newThemeAction; - this.modifyThemeAction = modifyThemeAction; - - setLocationRelativeTo(parent); - setTitle("New Theme"); - setModal(true); - - setDimensions(true); - setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); - - Theme theme = Settings.getInstance().getCurrentTheme(); - - getContentPane().setLayout(new BorderLayout()); - standardPanel.setBackground(theme.getBackgroundColor()); - secondaryPanel.setBackground(theme.getBackgroundColor()); - loadStandardContent(theme); - } - - 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) { - getContentPane().removeAll(); - - // ContentPane - GridBagLayout gbl_contentPanel = new GridBagLayout(); - - gbl_contentPanel.columnWidths = new int[] { 1, 1 }; - gbl_contentPanel.rowHeights = new int[] { 1, 1, 1 }; - gbl_contentPanel.columnWeights = new double[] { 1, 1 }; - gbl_contentPanel.rowWeights = new double[] { 1, 1, 1 }; - - getContentPane().add(standardPanel, BorderLayout.CENTER); - standardPanel.setLayout(gbl_contentPanel); - - // text.setFont(new Font()); - text.setText("Please enter a name for the new Theme"); - text.setAlignmentX(CENTER_ALIGNMENT); - text.setBackground(theme.getCellColor()); - text.setForeground(theme.getUserNameColor()); - text.setEditable(false); - - GridBagConstraints gbc_text = new GridBagConstraints(); - gbc_text.fill = GridBagConstraints.HORIZONTAL; - gbc_text.gridx = 0; - gbc_text.gridy = 0; - gbc_text.gridwidth = 2; - gbc_text.insets = new Insets(5, 5, 5, 5); - - standardPanel.add(text, gbc_text); - - nameEnterTextArea.setBackground(theme.getCellColor()); - nameEnterTextArea.setForeground(theme.getTypingMessageColor()); - nameEnterTextArea.setText(""); - nameEnterTextArea.setEditable(true); - - GridBagConstraints gbc_input = new GridBagConstraints(); - gbc_input.fill = GridBagConstraints.HORIZONTAL; - gbc_input.gridx = 0; - gbc_input.gridy = 1; - gbc_input.gridwidth = 2; - gbc_input.insets = new Insets(5, 5, 5, 5); - - standardPanel.add(nameEnterTextArea, gbc_input); - - confirmButton.setBackground(theme.getInteractableBackgroundColor()); - confirmButton.setForeground(theme.getInteractableForegroundColor()); - - GridBagConstraints gbc_confirmButton = new GridBagConstraints(); - gbc_confirmButton.gridx = 0; - gbc_confirmButton.gridy = 2; - gbc_confirmButton.gridwidth = 2; - gbc_confirmButton.insets = new Insets(5, 5, 5, 5); - - standardPanel.add(confirmButton, gbc_confirmButton); - - confirmButton.addActionListener((evt) -> { - if (!nameEnterTextArea.getText().isEmpty()) if (Settings.getInstance().getThemes().containsKey(nameEnterTextArea.getText())) { - // load other panel - setDimensions(false); - loadSecondaryPage(theme); - } else { - newThemeAction.accept(nameEnterTextArea.getText()); - dispose(); - } - }); - } - - private void loadSecondaryPage(Theme theme) { - // ContentPane - getContentPane().removeAll(); - - GridBagLayout gbl_secondaryPanel = new GridBagLayout(); - - gbl_secondaryPanel.columnWidths = new int[] { 1, 1 }; - gbl_secondaryPanel.rowHeights = new int[] { 1, 1, 1, 1 }; - gbl_secondaryPanel.columnWeights = new double[] { 1, 1 }; - gbl_secondaryPanel.rowWeights = new double[] { 1, 1, 1, 1 }; - - getContentPane().add(secondaryPanel, BorderLayout.CENTER); - secondaryPanel.setLayout(gbl_secondaryPanel); - - // text.setFont(new Font()); - text.setText("Please enter a name for the new Theme"); - text.setAlignmentX(CENTER_ALIGNMENT); - text.setBackground(theme.getCellColor()); - text.setForeground(theme.getUserNameColor()); - text.setEditable(false); - - GridBagConstraints gbc_text = new GridBagConstraints(); - gbc_text.fill = GridBagConstraints.HORIZONTAL; - gbc_text.gridx = 0; - gbc_text.gridy = 0; - gbc_text.gridwidth = 2; - gbc_text.insets = new Insets(5, 5, 5, 5); - - secondaryPanel.add(text, gbc_text); - - nameEnterTextArea.setBackground(theme.getCellColor()); - nameEnterTextArea.setForeground(theme.getTypingMessageColor()); - nameEnterTextArea.setEditable(false); - - GridBagConstraints gbc_input = new GridBagConstraints(); - gbc_input.fill = GridBagConstraints.HORIZONTAL; - gbc_input.gridx = 0; - gbc_input.gridy = 1; - gbc_input.gridwidth = 2; - gbc_input.insets = new Insets(5, 5, 5, 5); - - secondaryPanel.add(nameEnterTextArea, gbc_input); - - errorText.setText("The name does already exist. Choose another one or overwrite the old theme."); - errorText.setAlignmentX(CENTER_ALIGNMENT); - errorText.setBackground(theme.getCellColor()); - errorText.setForeground(theme.getUserNameColor()); - errorText.setEditable(false); - - GridBagConstraints gbc_errorText = new GridBagConstraints(); - gbc_errorText.fill = GridBagConstraints.HORIZONTAL; - gbc_errorText.gridx = 0; - gbc_errorText.gridy = 2; - gbc_errorText.gridwidth = 2; - gbc_errorText.insets = new Insets(5, 5, 5, 5); - - secondaryPanel.add(errorText, gbc_errorText); - - otherName.setBackground(theme.getInteractableBackgroundColor()); - otherName.setForeground(theme.getInteractableForegroundColor()); - - GridBagConstraints gbc_otherName = new GridBagConstraints(); - gbc_otherName.gridx = 0; - gbc_otherName.gridy = 3; - gbc_otherName.insets = new Insets(5, 5, 5, 5); - - secondaryPanel.add(otherName, gbc_otherName); - - overwrite.setBackground(theme.getInteractableBackgroundColor()); - overwrite.setForeground(theme.getInteractableForegroundColor()); - - GridBagConstraints gbc_overwrite = new GridBagConstraints(); - gbc_overwrite.gridx = 1; - gbc_overwrite.gridy = 3; - gbc_overwrite.insets = new Insets(5, 5, 5, 5); - - secondaryPanel.add(overwrite, gbc_overwrite); - - otherName.addActionListener((evt) -> { setDimensions(true); loadStandardContent(theme); }); - - overwrite.addActionListener((evt) -> { modifyThemeAction.accept(nameEnterTextArea.getText()); dispose(); }); - } -} diff --git a/src/main/java/envoy/client/ui/settings/SettingsPanel.java b/src/main/java/envoy/client/ui/settings/SettingsPanel.java deleted file mode 100644 index b72eb66..0000000 --- a/src/main/java/envoy/client/ui/settings/SettingsPanel.java +++ /dev/null @@ -1,30 +0,0 @@ -package envoy.client.ui.settings; - -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 Client v0.2-alpha - */ -public abstract class SettingsPanel extends JPanel { - - protected final SettingsScreen parent; - - private static final long serialVersionUID = 0L; - - /** - * 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; } -} diff --git a/src/main/java/envoy/client/ui/settings/SettingsScreen.java b/src/main/java/envoy/client/ui/settings/SettingsScreen.java deleted file mode 100644 index 87482d2..0000000 --- a/src/main/java/envoy/client/ui/settings/SettingsScreen.java +++ /dev/null @@ -1,172 +0,0 @@ -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.data.Settings; -import envoy.client.event.ThemeChangeEvent; -import envoy.client.ui.Theme; -import envoy.client.ui.primary.PrimaryButton; -import envoy.event.EventBus; -import envoy.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 Client v0.2-alpha - */ -public class SettingsScreen extends JDialog { - - private static final long serialVersionUID = 0L; - - 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 PrimaryButton cancelButton = new PrimaryButton("Cancel"); - - private final Insets insets = new Insets(5, 5, 5, 5); - - private SettingsPanel settingsPanel; - - private static final Logger logger = EnvoyLog.getLogger(SettingsScreen.class); - - /** - * Initializes the settings screen. - * - * @since Envoy Client v0.1-alpha - */ - public SettingsScreen() { - // Initialize settings pages - Map> panels = new HashMap<>(); - panels.put("General", GeneralSettingsPanel.class); - 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(getClass()).newInstance(this); - - // 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[] { 1, 1 }; - gbl_buttonPane.rowHeights = new int[] { 25 }; - gbl_buttonPane.columnWeights = new double[] { 1.0, 1.0 }; - gbl_buttonPane.rowWeights = new double[] { 0.0 }; - - 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(); }); - } - } - - // Apply current theme - applyTheme(Settings.getInstance().getCurrentTheme()); - - // Respond to theme changes - EventBus.getInstance().register(ThemeChangeEvent.class, evt -> applyTheme(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()); - - // 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 deleted file mode 100755 index b6eb832..0000000 --- a/src/main/java/envoy/client/ui/settings/ThemeCustomizationPanel.java +++ /dev/null @@ -1,246 +0,0 @@ -package envoy.client.ui.settings; - -import java.awt.*; -import java.util.logging.Level; -import java.util.logging.Logger; - -import javax.swing.*; - -import envoy.client.data.Settings; -import envoy.client.event.ThemeChangeEvent; -import envoy.client.ui.Color; -import envoy.client.ui.Theme; -import envoy.client.ui.primary.PrimaryButton; -import envoy.event.EventBus; -import envoy.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 - * @author Maximilian Käfer - * @since Envoy Client v0.2-alpha - */ -public class ThemeCustomizationPanel extends SettingsPanel { - - private JPanel colorsPanel = new JPanel(); - - private DefaultComboBoxModel themesModel; - private JComboBox themes; - private Theme temporaryTheme; - private PrimaryButton createThemeButton = new PrimaryButton("Create Theme"); - - private boolean themeChanged; - private final Insets insets = new Insets(5, 5, 5, 5); - - private static final Logger logger = EnvoyLog.getLogger(ThemeCustomizationPanel.class); - private static final long serialVersionUID = 0L; - - /** - * Initializes a {@link ThemeCustomizationPanel} that enables the user to change - * 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 Client v0.2-alpha - */ - public ThemeCustomizationPanel(SettingsScreen parent) { - super(parent); - temporaryTheme = new Theme("temporaryTheme", Settings.getInstance().getCurrentTheme()); - - var themeNames = Settings.getInstance().getThemes().keySet().toArray(new String[0]); - String currentThemeName = Settings.getInstance().getCurrentThemeName(); - for (int i = 0; i < themeNames.length; i++) - if (currentThemeName.equals(themeNames[i])) { - themeNames[i] = themeNames[0]; - themeNames[0] = currentThemeName; - break; - } - themesModel = new DefaultComboBoxModel<>(themeNames); - themes = new JComboBox<>(themesModel); - GridBagLayout gbl_themeLayout = new GridBagLayout(); - - gbl_themeLayout.columnWidths = new int[] { 1, 1 }; - gbl_themeLayout.rowHeights = new int[] { 1, 1, 1 }; - gbl_themeLayout.columnWeights = new double[] { 1.0, 1.0 }; - gbl_themeLayout.rowWeights = new double[] { 0.01, 1.0, 0.01 }; - - setLayout(gbl_themeLayout); - - themes.setSelectedItem(Settings.getInstance().getCurrentTheme()); - - GridBagConstraints gbc_themes = new GridBagConstraints(); - gbc_themes.fill = GridBagConstraints.HORIZONTAL; - gbc_themes.gridwidth = 2; - gbc_themes.gridx = 0; - gbc_themes.gridy = 0; - gbc_themes.anchor = GridBagConstraints.NORTHWEST; - gbc_themes.insets = new Insets(10, 10, 20, 10); - - add(themes, gbc_themes); - GridBagLayout gbl_colorCustomizations = new GridBagLayout(); - - gbl_colorCustomizations.columnWidths = new int[] { 1, 1 }; - gbl_colorCustomizations.rowHeights = new int[] { 1, 1, 1, 1, 1, 1, 1, 1, 1 }; - gbl_colorCustomizations.columnWeights = new double[] { 1, 1 }; - gbl_colorCustomizations.rowWeights = new double[] { 1, 1, 1, 1, 1, 1, 1, 1 }; - - colorsPanel.setLayout(gbl_colorCustomizations); - - Theme theme = 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); - - createThemeButton.addActionListener((evt) -> { - if (themeChanged) { - 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)); - if (themes.getSelectedItem().equals(name)) - EventBus.getInstance().dispatch(new ThemeChangeEvent(Settings.getInstance().getTheme(name))); - else themes.setSelectedItem(name); - }).setVisible(true); - themeChanged = false; - } - }); - GridBagConstraints gbc_createThemeButton = new GridBagConstraints(); - gbc_createThemeButton.fill = GridBagConstraints.HORIZONTAL; - gbc_createThemeButton.gridx = 0; - gbc_createThemeButton.gridy = 2; - gbc_createThemeButton.anchor = GridBagConstraints.CENTER; - gbc_createThemeButton.insets = insets; - add(createThemeButton, gbc_createThemeButton); - - colorsPanel.setBackground(theme.getCellColor()); - - // Apply theme upon selection - themes.addItemListener(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 -> { - final Theme currentTheme = evt.get(); - temporaryTheme = new Theme("temporaryTheme", currentTheme); - applyTheme(currentTheme); - }); - } - - private void applyTheme(Theme theme) { - // themeContent - setForeground(theme.getUserNameColor()); - setBackground(theme.getCellColor()); - - // createThemeButton - createThemeButton.setForeground(theme.getInteractableForegroundColor()); - createThemeButton.setBackground(theme.getInteractableBackgroundColor()); - - // themes - themes.setBackground(theme.getInteractableBackgroundColor()); - themes.setForeground(theme.getInteractableForegroundColor()); - colorsPanel.setBackground(theme.getCellColor()); - - // Color panel - updateColorVariables(theme); - - revalidate(); - repaint(); - } - - private void updateColorVariables(Theme theme) { - colorsPanel.removeAll(); - buildCustomizeElements(theme); - } - - private void buildCustomizeElements(Theme theme) { - buildCustomizeElement(theme, theme.getBackgroundColor(), "Background", "backgroundColor", 1); - buildCustomizeElement(theme, theme.getCellColor(), "Cells", "cellColor", 2); - buildCustomizeElement(theme, theme.getInteractableForegroundColor(), "Interactable Foreground", "interactableForegroundColor", 3); - buildCustomizeElement(theme, theme.getInteractableBackgroundColor(), "Interactable Background", "interactableBackgroundColor", 4); - buildCustomizeElement(theme, theme.getTextColor(), "Text Color", "textColor", 5); - buildCustomizeElement(theme, theme.getDateColor(), "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); - } - - private void buildCustomizeElement(Theme theme, Color color, String name, String colorName, int gridy) { - JButton button = new JButton(); - JTextPane textPane = new JTextPane(); - - textPane.setFont(new Font("Arial", Font.PLAIN, 14)); - textPane.setBackground(theme.getBackgroundColor()); - textPane.setForeground(theme.getBackgroundColor().invert()); - textPane.setText(name); - textPane.setEditable(false); - - button.setBackground(color); - button.setPreferredSize(new Dimension(25, 25)); - - button.addActionListener((evt) -> { - java.awt.Color c = JColorChooser.showDialog(null, "Choose a color", color); - 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); - } - }); - - GridBagConstraints gbc_textPane = new GridBagConstraints(); - gbc_textPane.fill = GridBagConstraints.BOTH; - gbc_textPane.gridx = 0; - gbc_textPane.gridy = gridy; - gbc_textPane.anchor = GridBagConstraints.CENTER; - gbc_textPane.insets = insets; - - colorsPanel.add(textPane, gbc_textPane); - - GridBagConstraints gbc_button = new GridBagConstraints(); - gbc_button.fill = GridBagConstraints.BOTH; - gbc_button.gridx = 1; - gbc_button.gridy = gridy; - gbc_button.anchor = GridBagConstraints.CENTER; - gbc_button.insets = insets; - - colorsPanel.add(button, gbc_button); - } -} diff --git a/src/main/java/envoy/client/ui/settings/package-info.java b/src/main/java/envoy/client/ui/settings/package-info.java deleted file mode 100644 index 5325a73..0000000 --- a/src/main/java/envoy/client/ui/settings/package-info.java +++ /dev/null @@ -1,9 +0,0 @@ -/** - * This package contains user interface classes related to the settings screen. - * - * @author Kai S. K. Engelbart - * @author Leon Hofmeister - * @author Maximilian Käfer - * @since Envoy Client v0.2-alpha - */ -package envoy.client.ui.settings; From e4e903b8bf530df1de4f22756e7907f84b33c20d Mon Sep 17 00:00:00 2001 From: kske Date: Sat, 18 Apr 2020 16:04:47 +0200 Subject: [PATCH 4/8] Added SettingsToggleButton --- .../java/envoy/client/data/SettingsItem.java | 18 +++++---------- .../envoy/client/ui/GeneralSettingsPane.java | 10 +++++++- .../envoy/client/ui/SettingsToggleButton.java | 23 +++++++++++++++++++ src/main/java/module-info.java | 1 + 4 files changed, 39 insertions(+), 13 deletions(-) create mode 100644 src/main/java/envoy/client/ui/SettingsToggleButton.java diff --git a/src/main/java/envoy/client/data/SettingsItem.java b/src/main/java/envoy/client/data/SettingsItem.java index e9c498c..fc8552c 100644 --- a/src/main/java/envoy/client/data/SettingsItem.java +++ b/src/main/java/envoy/client/data/SettingsItem.java @@ -1,8 +1,6 @@ package envoy.client.data; import java.io.Serializable; -import java.util.HashMap; -import java.util.Map; import java.util.function.Consumer; import java.util.function.Function; @@ -10,11 +8,13 @@ import javax.swing.JComponent; import javafx.scene.Node; +import envoy.client.ui.SettingsToggleButton; + /** * Encapsulates a persistent value that is directly or indirectly mutable by the * user.
*
- * Project: envoy-clientChess
+ * Project: envoy-client
* File: SettingsItem.java
* Created: 23.12.2019
* @@ -27,17 +27,11 @@ public class SettingsItem implements Serializable { private T value; private String userFriendlyName, description; - private transient Consumer changeHandler; - private transient Function, Node> nodeCreator; - - private static final Map, Function, Node>> nodeCreators = new HashMap<>(); + private transient Consumer changeHandler; + private transient Function, ? extends Node> nodeCreator; private static final long serialVersionUID = 1L; - static { - - } - /** * Initializes a {@link SettingsItem}. The default value's class will be mapped * to a {@link JComponent} that can be used to display this {@link SettingsItem} @@ -53,7 +47,7 @@ public class SettingsItem implements Serializable { this.userFriendlyName = userFriendlyName; this.description = description; - if (nodeCreators.containsKey(value.getClass())) nodeCreator = nodeCreators.get(value.getClass()); + if (value.getClass() == Boolean.class) nodeCreator = s -> new SettingsToggleButton((SettingsItem) s); } /** diff --git a/src/main/java/envoy/client/ui/GeneralSettingsPane.java b/src/main/java/envoy/client/ui/GeneralSettingsPane.java index 20f74f0..29c65d2 100644 --- a/src/main/java/envoy/client/ui/GeneralSettingsPane.java +++ b/src/main/java/envoy/client/ui/GeneralSettingsPane.java @@ -1,5 +1,7 @@ package envoy.client.ui; +import javafx.scene.layout.VBox; + import envoy.client.data.Settings; /** @@ -17,5 +19,11 @@ public class GeneralSettingsPane extends SettingsPane { /** * @since Envoy Client v0.1-beta */ - public GeneralSettingsPane() { super("General"); } + public GeneralSettingsPane() { + super("General"); + var vbox = new VBox(); + for (var name : new String[] { "onCloseMode", "enterToSend" }) + vbox.getChildren().add(settings.getItems().get(name).getNode()); + getChildren().add(vbox); + } } diff --git a/src/main/java/envoy/client/ui/SettingsToggleButton.java b/src/main/java/envoy/client/ui/SettingsToggleButton.java new file mode 100644 index 0000000..f91f7cb --- /dev/null +++ b/src/main/java/envoy/client/ui/SettingsToggleButton.java @@ -0,0 +1,23 @@ +package envoy.client.ui; + +import javafx.event.ActionEvent; +import javafx.scene.control.ToggleButton; + +import envoy.client.data.SettingsItem; + + +/** + * Project: envoy-client
+ * File: SettingsToggleButton.java
+ * Created: 18.04.2020
+ * + * @author Kai S. K. Engelbart + * @since Envoy Client v0.1-beta + */ +public final class SettingsToggleButton extends ToggleButton { + + public SettingsToggleButton(SettingsItem settingsItem) { + super(settingsItem.getUserFriendlyName()); + addEventHandler(ActionEvent.ACTION, e -> settingsItem.set(!settingsItem.get())); + } +} diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index 2de5fa8..9413967 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -17,6 +17,7 @@ module envoy { requires javafx.controls; requires javafx.fxml; requires javafx.base; + requires javafx.graphics; opens envoy.client.ui to javafx.graphics, javafx.fxml; } From 970f190389edfcc0762c2af5bb7ebf140b15fb0d Mon Sep 17 00:00:00 2001 From: delvh Date: Sat, 18 Apr 2020 19:46:04 +0200 Subject: [PATCH 5/8] added inelegant capability to switch scenes --- .../envoy/client/ui/ChatSceneController.java | 30 +++++--- .../client/ui/SettingsSceneController.java | 22 +++++- src/main/java/envoy/client/ui/Startup.java | 75 +++++++++++++++++-- 3 files changed, 107 insertions(+), 20 deletions(-) diff --git a/src/main/java/envoy/client/ui/ChatSceneController.java b/src/main/java/envoy/client/ui/ChatSceneController.java index b8927d4..e181121 100644 --- a/src/main/java/envoy/client/ui/ChatSceneController.java +++ b/src/main/java/envoy/client/ui/ChatSceneController.java @@ -5,6 +5,14 @@ import java.util.logging.Level; import java.util.logging.Logger; import java.util.stream.Collectors; +import javafx.application.Platform; +import javafx.collections.FXCollections; +import javafx.fxml.FXML; +import javafx.scene.control.*; +import javafx.scene.input.KeyCode; +import javafx.scene.input.KeyEvent; +import javafx.scene.layout.VBox; + import envoy.client.data.Chat; import envoy.client.data.LocalDB; import envoy.client.event.MessageCreationEvent; @@ -17,12 +25,6 @@ import envoy.event.EventBus; import envoy.event.MessageStatusChangeEvent; import envoy.event.UserStatusChangeEvent; import envoy.util.EnvoyLog; -import javafx.application.Platform; -import javafx.collections.FXCollections; -import javafx.fxml.FXML; -import javafx.scene.control.*; -import javafx.scene.input.KeyCode; -import javafx.scene.input.KeyEvent; /** * Project: envoy-client
@@ -58,6 +60,8 @@ public final class ChatSceneController { private Chat currentChat; + private Startup startup; + private static final EventBus eventBus = EventBus.getInstance(); private static final Logger logger = EnvoyLog.getLogger(ChatSceneController.class); @@ -91,10 +95,11 @@ public final class ChatSceneController { eventBus.register(UserStatusChangeEvent.class, e -> Platform.runLater(() -> userList.refresh())); } - void initializeData(LocalDB localDB, Client client, WriteProxy writeProxy) { - this.localDB = localDB; - this.client = client; - this.writeProxy = writeProxy; + void initializeData(Startup startup, LocalDB localDB, Client client, WriteProxy writeProxy) { + this.startup = startup; + this.localDB = localDB; + this.client = client; + this.writeProxy = writeProxy; // TODO: handle offline mode userList.setItems(FXCollections.observableList(localDB.getUser().getContacts().stream().collect(Collectors.toList()))); @@ -123,7 +128,10 @@ public final class ChatSceneController { private void postButtonClicked() { postMessage(); } @FXML - private void settingsButtonClicked() { logger.info("Settings Button clicked."); } + private void settingsButtonClicked() { + startup.changeScene("/fxml/SettingsScene.fxml", new VBox(), true); + Platform.runLater(() -> { ((SettingsSceneController) startup.getCurrentController()).initializeData(startup); }); + } @FXML private void messageTextUpdated(KeyEvent e) { diff --git a/src/main/java/envoy/client/ui/SettingsSceneController.java b/src/main/java/envoy/client/ui/SettingsSceneController.java index 2d6eccd..743a58c 100644 --- a/src/main/java/envoy/client/ui/SettingsSceneController.java +++ b/src/main/java/envoy/client/ui/SettingsSceneController.java @@ -7,25 +7,36 @@ import javafx.scene.control.*; * Project: envoy-client
* File: SettingsSceneController.java
* Created: 10.04.2020
- * + * * @author Kai S. K. Engelbart * @since Envoy Client v0.1-beta */ -public final class SettingsSceneController { +public class SettingsSceneController { + private Startup startup; @FXML - private ListView settingsList; + private ListView settingsList; @FXML private TitledPane titledPane; + /** + * initializes the object needed to reset the scene + * + * @param startup the instance of startup that stores the stage + * @since Envoy Client v0.1-beta + */ + public void initializeData(Startup startup) { this.startup = startup; } + @FXML private void initialize() { settingsList.setCellFactory(listView -> new ListCell<>() { @Override - protected void updateItem(SettingsPane item, boolean empty) { if (!empty && item != null) setGraphic(new Label(item.getTitle())); }; + protected void updateItem(SettingsPane item, boolean empty) { if (!empty && item != null) setGraphic(new Label(item.getTitle())); } }); + + // settingsList.getItems().add(new GeneralSettingsPane()); } @FXML @@ -34,4 +45,7 @@ public final class SettingsSceneController { titledPane.setText(pane.getTitle()); titledPane.setContent(pane); } + + @FXML + private void backButtonClicked() { startup.restoreScene(false); } } diff --git a/src/main/java/envoy/client/ui/Startup.java b/src/main/java/envoy/client/ui/Startup.java index becc467..9b5405a 100644 --- a/src/main/java/envoy/client/ui/Startup.java +++ b/src/main/java/envoy/client/ui/Startup.java @@ -8,12 +8,14 @@ import java.util.logging.Level; import java.util.logging.Logger; import javafx.application.Application; +import javafx.application.Platform; import javafx.fxml.FXMLLoader; import javafx.scene.Scene; import javafx.scene.control.Alert; import javafx.scene.control.Alert.AlertType; import javafx.scene.image.Image; import javafx.scene.layout.GridPane; +import javafx.scene.layout.Pane; import javafx.stage.Stage; import envoy.client.data.*; @@ -40,6 +42,11 @@ public final class Startup extends Application { private WriteProxy writeProxy; private Cache cache; + private FXMLLoader loader = new FXMLLoader(); + private Stage stage; + + private Scene previousScene; + private static final ClientConfig config = ClientConfig.getInstance(); private static final Logger logger = EnvoyLog.getLogger(Startup.class); @@ -48,6 +55,7 @@ public final class Startup extends Application { */ @Override public void start(Stage stage) throws Exception { + this.stage = stage; try { // Load the configuration from client.properties first Properties properties = new Properties(); @@ -124,20 +132,67 @@ public final class Startup extends Application { .forEach(u -> u.setStatus(UserStatus.OFFLINE)); // Prepare stage and load ChatScene - var loader = new FXMLLoader(getClass().getResource("/fxml/ChatScene.fxml")); - var anchorPane = loader.load(); - var chatScene = new Scene(anchorPane); + changeScene("/fxml/ChatScene.fxml", new GridPane(), false); + Platform.runLater(() -> { ((ChatSceneController) loader.getController()).initializeData(this, localDB, client, writeProxy); }); stage.setTitle("Envoy"); stage.getIcons().add(new Image(getClass().getResourceAsStream("/icons/envoy_logo.png"))); - stage.setScene(chatScene); - loader.getController().initializeData(localDB, client, writeProxy); stage.show(); // Relay unread messages from cache if (cache != null && client.isOnline()) cache.relay(); } + /** + * Changes the scene of the stage. + * + * @param the type of the layout to use + * @param fxmlLocation the location of the fxml file + * @param layout the layout to use + * @param savePrevious if true, the previous stage will be stored in this + * instance of Startup, else the variable storing it will be + * set to null + * @since Envoy Client v0.1-beta + */ + public void changeScene(String fxmlLocation, T layout, boolean savePrevious) { + Platform.runLater(() -> { + try { + // Clearing the loader so that a new Scene can be initialised + loader = new FXMLLoader(); + var rootNode = loader.load(getClass().getResourceAsStream(fxmlLocation)); + var chatScene = new Scene(rootNode); + previousScene = (savePrevious) ? stage.getScene() : null; + stage.setScene(chatScene); + stage.show(); + // return loader.getController(); + } catch (IOException e) { + new Alert(AlertType.ERROR, "The screen could not be updated due to reasons. (...bad programming...)"); + e.printStackTrace(); + logger.severe("Something happened (while loading the new scene from " + fxmlLocation + ")"); + } + }); + } + + /** + * Changes the visual scene back to the saved value. The currently active scene + * can be saved. + * + * @param storeCurrent the old scene to store, if wanted. Can be null + * @since Envoy Client v0.1-beta + */ + public void restoreScene(boolean storeCurrent) { + Platform.runLater(() -> { + if (previousScene == null) throw new IllegalStateException("Someone tried restoring a null scene. (Something happened)"); + else { + // switching previous and current + var temp = (storeCurrent) ? stage.getScene() : null; + stage.setScene(previousScene); + previousScene = temp; + stage.show(); + } + }); + } + /** * {@inheritDoc} */ @@ -159,4 +214,14 @@ public final class Startup extends Application { @SuppressWarnings("javadoc") public static void main(String[] args) { launch(args); } + + /** + * @return the controller of the current scene or a {@link NullPointerException} + * if there is none + * @since Envoy Client v0.1-beta + */ + public Object getCurrentController() { + if (loader.getController() == null) throw new NullPointerException("Cannot deliver current controller as its undefined (duh!)"); + else return loader.getController(); + } } From 55bea0d8462705115f5d55a5223a18f54fa6f3ca Mon Sep 17 00:00:00 2001 From: kske Date: Sat, 18 Apr 2020 21:37:44 +0200 Subject: [PATCH 6/8] Fixed settings pane selection --- src/main/java/envoy/client/data/Settings.java | 4 ++-- src/main/java/envoy/client/data/SettingsItem.java | 12 ------------ .../java/envoy/client/ui/GeneralSettingsPane.java | 12 ++++++++++-- .../envoy/client/ui/SettingsSceneController.java | 13 +++++++++---- 4 files changed, 21 insertions(+), 20 deletions(-) diff --git a/src/main/java/envoy/client/data/Settings.java b/src/main/java/envoy/client/data/Settings.java index fcde72a..419d22a 100644 --- a/src/main/java/envoy/client/data/Settings.java +++ b/src/main/java/envoy/client/data/Settings.java @@ -88,11 +88,11 @@ public class Settings { /** * Updates the preferences when the save button is clicked. * - * @throws IOException if an error occurs while saving the themes to the theme - * file + * @throws IOException if an error occurs while saving the themes * @since Envoy Client v0.2-alpha */ public void save() throws IOException { + // Save settings to settings file SerializationUtils.write(settingsFile, items); diff --git a/src/main/java/envoy/client/data/SettingsItem.java b/src/main/java/envoy/client/data/SettingsItem.java index fc8552c..98a562d 100644 --- a/src/main/java/envoy/client/data/SettingsItem.java +++ b/src/main/java/envoy/client/data/SettingsItem.java @@ -2,14 +2,9 @@ package envoy.client.data; import java.io.Serializable; import java.util.function.Consumer; -import java.util.function.Function; import javax.swing.JComponent; -import javafx.scene.Node; - -import envoy.client.ui.SettingsToggleButton; - /** * Encapsulates a persistent value that is directly or indirectly mutable by the * user.
@@ -28,7 +23,6 @@ public class SettingsItem implements Serializable { private String userFriendlyName, description; private transient Consumer changeHandler; - private transient Function, ? extends Node> nodeCreator; private static final long serialVersionUID = 1L; @@ -46,8 +40,6 @@ public class SettingsItem implements Serializable { this.value = value; this.userFriendlyName = userFriendlyName; this.description = description; - - if (value.getClass() == Boolean.class) nodeCreator = s -> new SettingsToggleButton((SettingsItem) s); } /** @@ -104,8 +96,4 @@ public class SettingsItem implements Serializable { this.changeHandler = changeHandler; changeHandler.accept(value); } - - public boolean hasNodeCreator() { return nodeCreator != null; } - - public Node getNode() { return nodeCreator.apply(this); } } diff --git a/src/main/java/envoy/client/ui/GeneralSettingsPane.java b/src/main/java/envoy/client/ui/GeneralSettingsPane.java index 29c65d2..b207867 100644 --- a/src/main/java/envoy/client/ui/GeneralSettingsPane.java +++ b/src/main/java/envoy/client/ui/GeneralSettingsPane.java @@ -1,8 +1,11 @@ package envoy.client.ui; +import java.util.List; + import javafx.scene.layout.VBox; import envoy.client.data.Settings; +import envoy.client.data.SettingsItem; /** * Project: envoy-client
@@ -22,8 +25,13 @@ public class GeneralSettingsPane extends SettingsPane { public GeneralSettingsPane() { super("General"); var vbox = new VBox(); - for (var name : new String[] { "onCloseMode", "enterToSend" }) - vbox.getChildren().add(settings.getItems().get(name).getNode()); + + // TODO: Support other value types + List.of("onCloseMode", "enterToSend") + .stream() + .map(settings.getItems()::get) + .map(i -> new SettingsToggleButton((SettingsItem) i)) + .forEach(vbox.getChildren()::add); getChildren().add(vbox); } } diff --git a/src/main/java/envoy/client/ui/SettingsSceneController.java b/src/main/java/envoy/client/ui/SettingsSceneController.java index 743a58c..33f45a6 100644 --- a/src/main/java/envoy/client/ui/SettingsSceneController.java +++ b/src/main/java/envoy/client/ui/SettingsSceneController.java @@ -33,17 +33,22 @@ public class SettingsSceneController { settingsList.setCellFactory(listView -> new ListCell<>() { @Override - protected void updateItem(SettingsPane item, boolean empty) { if (!empty && item != null) setGraphic(new Label(item.getTitle())); } + protected void updateItem(SettingsPane item, boolean empty) { + super.updateItem(item, empty); + if (!empty && item != null) setGraphic(new Label(item.getTitle())); + } }); - // settingsList.getItems().add(new GeneralSettingsPane()); + settingsList.getItems().add(new GeneralSettingsPane()); } @FXML private void settingsListClicked() { final var pane = settingsList.getSelectionModel().getSelectedItem(); - titledPane.setText(pane.getTitle()); - titledPane.setContent(pane); + if (pane != null) { + titledPane.setText(pane.getTitle()); + titledPane.setContent(pane); + } } @FXML From aba51abc10d35ba9a242642132498907aaf3b540 Mon Sep 17 00:00:00 2001 From: delvh Date: Sun, 19 Apr 2020 19:57:40 +0200 Subject: [PATCH 7/8] created ui.settings package --- .../java/envoy/client/ui/ChatSceneController.java | 1 + src/main/java/envoy/client/ui/package-info.java | 2 +- .../ui/{ => settings}/GeneralSettingsPane.java | 2 +- .../client/ui/{ => settings}/SettingsPane.java | 2 +- .../ui/{ => settings}/SettingsSceneController.java | 4 +++- .../ui/{ => settings}/SettingsToggleButton.java | 2 +- .../envoy/client/ui/settings/package-info.java | 14 ++++++++++++++ src/main/java/module-info.java | 1 + src/main/resources/fxml/SettingsScene.fxml | 2 +- 9 files changed, 24 insertions(+), 6 deletions(-) rename src/main/java/envoy/client/ui/{ => settings}/GeneralSettingsPane.java (96%) rename src/main/java/envoy/client/ui/{ => settings}/SettingsPane.java (93%) rename src/main/java/envoy/client/ui/{ => settings}/SettingsSceneController.java (95%) rename src/main/java/envoy/client/ui/{ => settings}/SettingsToggleButton.java (94%) create mode 100644 src/main/java/envoy/client/ui/settings/package-info.java diff --git a/src/main/java/envoy/client/ui/ChatSceneController.java b/src/main/java/envoy/client/ui/ChatSceneController.java index e181121..956a896 100644 --- a/src/main/java/envoy/client/ui/ChatSceneController.java +++ b/src/main/java/envoy/client/ui/ChatSceneController.java @@ -18,6 +18,7 @@ import envoy.client.data.LocalDB; import envoy.client.event.MessageCreationEvent; import envoy.client.net.Client; import envoy.client.net.WriteProxy; +import envoy.client.ui.settings.SettingsSceneController; import envoy.data.Contact; import envoy.data.Message; import envoy.data.MessageBuilder; diff --git a/src/main/java/envoy/client/ui/package-info.java b/src/main/java/envoy/client/ui/package-info.java index 10bf4ee..9f94ac2 100644 --- a/src/main/java/envoy/client/ui/package-info.java +++ b/src/main/java/envoy/client/ui/package-info.java @@ -1,8 +1,8 @@ /** * This package contains classes defining the user interface. * - * @author Kai S. K. Engelbart * @author Leon Hofmeister + * @author Kai S. K. Engelbart * @author Maximilian Käfer * @since Envoy Client v0.1-beta */ diff --git a/src/main/java/envoy/client/ui/GeneralSettingsPane.java b/src/main/java/envoy/client/ui/settings/GeneralSettingsPane.java similarity index 96% rename from src/main/java/envoy/client/ui/GeneralSettingsPane.java rename to src/main/java/envoy/client/ui/settings/GeneralSettingsPane.java index b207867..6c561f0 100644 --- a/src/main/java/envoy/client/ui/GeneralSettingsPane.java +++ b/src/main/java/envoy/client/ui/settings/GeneralSettingsPane.java @@ -1,4 +1,4 @@ -package envoy.client.ui; +package envoy.client.ui.settings; import java.util.List; diff --git a/src/main/java/envoy/client/ui/SettingsPane.java b/src/main/java/envoy/client/ui/settings/SettingsPane.java similarity index 93% rename from src/main/java/envoy/client/ui/SettingsPane.java rename to src/main/java/envoy/client/ui/settings/SettingsPane.java index 79bec4b..7c84221 100644 --- a/src/main/java/envoy/client/ui/SettingsPane.java +++ b/src/main/java/envoy/client/ui/settings/SettingsPane.java @@ -1,4 +1,4 @@ -package envoy.client.ui; +package envoy.client.ui.settings; import javafx.scene.layout.Pane; diff --git a/src/main/java/envoy/client/ui/SettingsSceneController.java b/src/main/java/envoy/client/ui/settings/SettingsSceneController.java similarity index 95% rename from src/main/java/envoy/client/ui/SettingsSceneController.java rename to src/main/java/envoy/client/ui/settings/SettingsSceneController.java index 33f45a6..e3cc4fb 100644 --- a/src/main/java/envoy/client/ui/SettingsSceneController.java +++ b/src/main/java/envoy/client/ui/settings/SettingsSceneController.java @@ -1,8 +1,10 @@ -package envoy.client.ui; +package envoy.client.ui.settings; import javafx.fxml.FXML; import javafx.scene.control.*; +import envoy.client.ui.Startup; + /** * Project: envoy-client
* File: SettingsSceneController.java
diff --git a/src/main/java/envoy/client/ui/SettingsToggleButton.java b/src/main/java/envoy/client/ui/settings/SettingsToggleButton.java similarity index 94% rename from src/main/java/envoy/client/ui/SettingsToggleButton.java rename to src/main/java/envoy/client/ui/settings/SettingsToggleButton.java index f91f7cb..adb7b92 100644 --- a/src/main/java/envoy/client/ui/SettingsToggleButton.java +++ b/src/main/java/envoy/client/ui/settings/SettingsToggleButton.java @@ -1,4 +1,4 @@ -package envoy.client.ui; +package envoy.client.ui.settings; import javafx.event.ActionEvent; import javafx.scene.control.ToggleButton; diff --git a/src/main/java/envoy/client/ui/settings/package-info.java b/src/main/java/envoy/client/ui/settings/package-info.java new file mode 100644 index 0000000..9774362 --- /dev/null +++ b/src/main/java/envoy/client/ui/settings/package-info.java @@ -0,0 +1,14 @@ +/** + * This package contains classes used for representing the settings + * visually.
+ *
+ * Project: envoy-client
+ * File: package-info.java
+ * Created: 19 Apr 2020
+ * + * @author Leon Hofmeister + * @author Kai S. K. Engelbart + * @author Maximilian Käfer + * @since Envoy Client v0.1-beta + */ +package envoy.client.ui.settings; \ No newline at end of file diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index 9413967..c34aeff 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -19,5 +19,6 @@ module envoy { requires javafx.base; requires javafx.graphics; + opens envoy.client.ui.settings to javafx.graphics, javafx.fxml; opens envoy.client.ui to javafx.graphics, javafx.fxml; } diff --git a/src/main/resources/fxml/SettingsScene.fxml b/src/main/resources/fxml/SettingsScene.fxml index 3aaee9a..d61fb53 100644 --- a/src/main/resources/fxml/SettingsScene.fxml +++ b/src/main/resources/fxml/SettingsScene.fxml @@ -7,7 +7,7 @@ - + From 5c4356f1e790d4bd12048e9f79734d06076d6a4f Mon Sep 17 00:00:00 2001 From: delvh Date: Sun, 19 Apr 2020 22:01:12 +0200 Subject: [PATCH 8/8] Readded enterToSend-Capability, ToggleButtons display current value additionally added developer comments (most important feature of v0.1-beta!). --- .settings/org.eclipse.jdt.ui.prefs | 2 +- .../java/envoy/client/DeveloperComments.java | 17 +++++++++++++++++ .../envoy/client/ui/ChatSceneController.java | 12 +++++++----- .../ui/settings/SettingsToggleButton.java | 13 +++++++++++-- .../envoy/client/ui/settings/package-info.java | 2 +- 5 files changed, 37 insertions(+), 9 deletions(-) create mode 100644 src/main/java/envoy/client/DeveloperComments.java diff --git a/.settings/org.eclipse.jdt.ui.prefs b/.settings/org.eclipse.jdt.ui.prefs index 8fecd4f..d1f3908 100644 --- a/.settings/org.eclipse.jdt.ui.prefs +++ b/.settings/org.eclipse.jdt.ui.prefs @@ -4,4 +4,4 @@ org.eclipse.jdt.ui.importorder=java;javax;javafx;org;com;envoy; org.eclipse.jdt.ui.javadoc=true org.eclipse.jdt.ui.ondemandthreshold=4 org.eclipse.jdt.ui.staticondemandthreshold=2 -org.eclipse.jdt.ui.text.custom_code_templates=