Saving settings in a file, added SettingsItem class
This commit is contained in:
parent
7ec9e6b13a
commit
89e8fc62dc
@ -1,6 +1,7 @@
|
|||||||
package envoy.client;
|
package envoy.client;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
@ -11,6 +12,7 @@ import javax.xml.datatype.DatatypeFactory;
|
|||||||
import envoy.client.event.EventBus;
|
import envoy.client.event.EventBus;
|
||||||
import envoy.client.event.MessageCreationEvent;
|
import envoy.client.event.MessageCreationEvent;
|
||||||
import envoy.client.util.EnvoyLog;
|
import envoy.client.util.EnvoyLog;
|
||||||
|
import envoy.client.util.SerializationUtils;
|
||||||
import envoy.exception.EnvoyException;
|
import envoy.exception.EnvoyException;
|
||||||
import envoy.schema.*;
|
import envoy.schema.*;
|
||||||
import envoy.schema.Message.Metadata.MessageState;
|
import envoy.schema.Message.Metadata.MessageState;
|
||||||
@ -83,10 +85,10 @@ public class LocalDB {
|
|||||||
*/
|
*/
|
||||||
public void save() throws IOException {
|
public void save() throws IOException {
|
||||||
// Save users
|
// Save users
|
||||||
write(usersFile, users);
|
SerializationUtils.write(usersFile, users);
|
||||||
|
|
||||||
// Save chats
|
// Save chats
|
||||||
write(localDBFile, chats);
|
SerializationUtils.write(localDBFile, chats);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -95,8 +97,7 @@ public class LocalDB {
|
|||||||
* @throws EnvoyException if the loading process failed
|
* @throws EnvoyException if the loading process failed
|
||||||
* @since Envoy v0.2-alpha
|
* @since Envoy v0.2-alpha
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
public void loadUsers() throws EnvoyException { users = SerializationUtils.read(usersFile, HashMap.class); }
|
||||||
public void loadUsers() throws EnvoyException { users = read(usersFile, HashMap.class); }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads all chats saved by Envoy for the client user.
|
* Loads all chats saved by Envoy for the client user.
|
||||||
@ -104,31 +105,7 @@ public class LocalDB {
|
|||||||
* @throws EnvoyException if the loading process failed
|
* @throws EnvoyException if the loading process failed
|
||||||
* @since Envoy v0.1-alpha
|
* @since Envoy v0.1-alpha
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
public void loadChats() throws EnvoyException { chats = SerializationUtils.read(localDBFile, ArrayList.class); }
|
||||||
public void loadChats() throws EnvoyException { chats = read(localDBFile, ArrayList.class); }
|
|
||||||
|
|
||||||
private <T> T read(File file, Class<T> serializedClass) throws EnvoyException {
|
|
||||||
if (file == null) throw new NullPointerException("File is null");
|
|
||||||
try (ObjectInputStream in = new ObjectInputStream(new FileInputStream(file))) {
|
|
||||||
return serializedClass.cast(in.readObject());
|
|
||||||
} catch (ClassNotFoundException | IOException e) {
|
|
||||||
throw new EnvoyException("Could not load serialized object", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private <T> void write(File file, T obj) throws IOException {
|
|
||||||
if (file == null) throw new NullPointerException("File is null");
|
|
||||||
if (obj == null) throw new NullPointerException("Object to serialize is null");
|
|
||||||
if (!file.exists()) {
|
|
||||||
file.getParentFile().mkdirs();
|
|
||||||
file.createNewFile();
|
|
||||||
}
|
|
||||||
try (ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(file))) {
|
|
||||||
out.writeObject(obj);
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a {@link Message} object serializable to XML.
|
* Creates a {@link Message} object serializable to XML.
|
||||||
@ -238,8 +215,7 @@ public class LocalDB {
|
|||||||
// Updating UserStatus of all users in LocalDB
|
// Updating UserStatus of all users in LocalDB
|
||||||
for (User user : returnSync.getUsers())
|
for (User user : returnSync.getUsers())
|
||||||
for (Chat chat : getChats())
|
for (Chat chat : getChats())
|
||||||
if (user.getID() == chat.getRecipient().getID())
|
if (user.getID() == chat.getRecipient().getID()) chat.getRecipient().setStatus(user.getStatus());
|
||||||
chat.getRecipient().setStatus(user.getStatus());
|
|
||||||
|
|
||||||
sync.getMessages().clear();
|
sync.getMessages().clear();
|
||||||
sync.getUsers().clear();
|
sync.getUsers().clear();
|
||||||
@ -301,7 +277,8 @@ public class LocalDB {
|
|||||||
public void clearUnreadMessagesSync() { unreadMessagesSync.getMessages().clear(); }
|
public void clearUnreadMessagesSync() { unreadMessagesSync.getMessages().clear(); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return a {@code Map<String, User>} of all users stored locally with their user names as keys
|
* @return a {@code Map<String, User>} of all users stored locally with their
|
||||||
|
* user names as keys
|
||||||
* @since Envoy v0.2-alpha
|
* @since Envoy v0.2-alpha
|
||||||
*/
|
*/
|
||||||
public Map<String, User> getUsers() { return users; }
|
public Map<String, User> getUsers() { return users; }
|
||||||
|
@ -7,6 +7,8 @@ import java.util.prefs.Preferences;
|
|||||||
|
|
||||||
import envoy.client.ui.Color;
|
import envoy.client.ui.Color;
|
||||||
import envoy.client.ui.Theme;
|
import envoy.client.ui.Theme;
|
||||||
|
import envoy.client.util.SerializationUtils;
|
||||||
|
import envoy.exception.EnvoyException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manages all application settings, which are different objects that can be
|
* Manages all application settings, which are different objects that can be
|
||||||
@ -25,20 +27,18 @@ import envoy.client.ui.Theme;
|
|||||||
public class Settings {
|
public class Settings {
|
||||||
|
|
||||||
// Actual settings accessible by the rest of the application
|
// Actual settings accessible by the rest of the application
|
||||||
private boolean enterToSend = true;
|
private Map<String, SettingsItem<?>> items;
|
||||||
private Map<String, Theme> themes;
|
private Map<String, Theme> themes;
|
||||||
private String currentTheme;
|
|
||||||
private boolean currentOnCloseMode;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Required to save the settings.
|
* Settings are stored in this file.
|
||||||
*/
|
*/
|
||||||
private Preferences prefs = Preferences.userNodeForPackage(Settings.class);
|
private static final File settingsFile = new File(Config.getInstance().getHomeDirectory(), "settings.ser");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* User-defined themes are stored inside this file.
|
* User-defined themes are stored inside this file.
|
||||||
*/
|
*/
|
||||||
private File themeFile = new File(Config.getInstance().getHomeDirectory(), "themes.ser");
|
private static final File themeFile = new File(Config.getInstance().getHomeDirectory(), "themes.ser");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Singleton instance of this class.
|
* Singleton instance of this class.
|
||||||
@ -51,30 +51,21 @@ public class Settings {
|
|||||||
*
|
*
|
||||||
* @since Envoy v0.2-alpha
|
* @since Envoy v0.2-alpha
|
||||||
*/
|
*/
|
||||||
private Settings() { load(); }
|
private Settings() {
|
||||||
|
// Load settings from settings file
|
||||||
/**
|
try {
|
||||||
* This method is used to ensure that there is only one instance of Settings.
|
items = SerializationUtils.read(settingsFile, HashMap.class);
|
||||||
*
|
} catch (EnvoyException e) {
|
||||||
* @return the instance of Settings
|
items = new HashMap<>();
|
||||||
* @since Envoy v0.2-alpha
|
}
|
||||||
*/
|
supplementDefaults();
|
||||||
public static Settings getInstance() { return settings; }
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
private void load() {
|
|
||||||
setEnterToSend(prefs.getBoolean("enterToSend", true));
|
|
||||||
setCurrentTheme(prefs.get("theme", "dark"));
|
|
||||||
setCurrentOnCloseMode(prefs.getBoolean("onCloseMode", true));
|
|
||||||
|
|
||||||
// Load themes from theme file
|
// Load themes from theme file
|
||||||
try (ObjectInputStream in = new ObjectInputStream(new FileInputStream(themeFile))) {
|
try {
|
||||||
Object obj = in.readObject();
|
themes = SerializationUtils.read(themeFile, HashMap.class);
|
||||||
if (obj instanceof HashMap) themes = (Map<String, Theme>) obj;
|
} catch (EnvoyException e1) {
|
||||||
} catch (IOException | ClassNotFoundException e) {
|
|
||||||
themes = new HashMap<>();
|
themes = new HashMap<>();
|
||||||
currentTheme = "dark";
|
setCurrentTheme("dark");
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load standard themes not defined in the themes file
|
// Load standard themes not defined in the themes file
|
||||||
@ -86,6 +77,14 @@ public class Settings {
|
|||||||
Color.black, Color.black));
|
Color.black, Color.black));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is used to ensure that there is only one instance of Settings.
|
||||||
|
*
|
||||||
|
* @return the instance of Settings
|
||||||
|
* @since Envoy v0.2-alpha
|
||||||
|
*/
|
||||||
|
public static Settings getInstance() { return settings; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the preferences when the save button is clicked.
|
* Updates the preferences when the save button is clicked.
|
||||||
*
|
*
|
||||||
@ -94,15 +93,17 @@ public class Settings {
|
|||||||
* @since Envoy v0.2-alpha
|
* @since Envoy v0.2-alpha
|
||||||
*/
|
*/
|
||||||
public void save() throws IOException {
|
public void save() throws IOException {
|
||||||
prefs.put("theme", currentTheme);
|
// Save settings to settings file
|
||||||
prefs.putBoolean("enterToSend", isEnterToSend());
|
SerializationUtils.write(settingsFile, items);
|
||||||
prefs.putBoolean("onCloseMode", currentOnCloseMode);
|
|
||||||
|
|
||||||
// Save themes to theme file
|
// Save themes to theme file
|
||||||
themeFile.createNewFile();
|
SerializationUtils.write(themeFile, themes);
|
||||||
try (ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(themeFile))) {
|
|
||||||
out.writeObject(themes);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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<>(false, "Hide on close", "Hides the chat window when it is closed."));
|
||||||
|
items.putIfAbsent("currentTheme", new SettingsItem<>("dark", null));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -117,7 +118,7 @@ public class Settings {
|
|||||||
* @return the name of the currently active {@link Theme}
|
* @return the name of the currently active {@link Theme}
|
||||||
* @since Envoy v0.2-alpha
|
* @since Envoy v0.2-alpha
|
||||||
*/
|
*/
|
||||||
public String getCurrentTheme() { return currentTheme; }
|
public String getCurrentTheme() { return (String) items.get("currentTheme").get(); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the name of the current {@link Theme}.
|
* Sets the name of the current {@link Theme}.
|
||||||
@ -125,7 +126,8 @@ public class Settings {
|
|||||||
* @param themeName the name to set
|
* @param themeName the name to set
|
||||||
* @since Envoy v0.2-alpha
|
* @since Envoy v0.2-alpha
|
||||||
*/
|
*/
|
||||||
public void setCurrentTheme(String themeName) { currentTheme = themeName; }
|
@SuppressWarnings("unchecked")
|
||||||
|
public void setCurrentTheme(String themeName) { ((SettingsItem<String>) items.get("currentTheme")).set(themeName); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return {@code true}, if pressing the {@code Enter} key suffices to send a
|
* @return {@code true}, if pressing the {@code Enter} key suffices to send a
|
||||||
@ -133,7 +135,7 @@ public class Settings {
|
|||||||
* {@code Control} key.
|
* {@code Control} key.
|
||||||
* @since Envoy v0.2-alpha
|
* @since Envoy v0.2-alpha
|
||||||
*/
|
*/
|
||||||
public boolean isEnterToSend() { return enterToSend; }
|
public boolean isEnterToSend() { return (boolean) items.get("enterToSend").get(); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Changes the keystrokes performed by the user to send a message.
|
* Changes the keystrokes performed by the user to send a message.
|
||||||
@ -143,7 +145,23 @@ public class Settings {
|
|||||||
* conjunction with the {@code Control} key.
|
* conjunction with the {@code Control} key.
|
||||||
* @since Envoy v0.2-alpha
|
* @since Envoy v0.2-alpha
|
||||||
*/
|
*/
|
||||||
public void setEnterToSend(boolean enterToSend) { this.enterToSend = enterToSend; }
|
@SuppressWarnings("unchecked")
|
||||||
|
public void setEnterToSend(boolean enterToSend) { ((SettingsItem<Boolean>) items.get("enterToSend")).set(enterToSend); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the current on close mode.
|
||||||
|
* @since Envoy v0.3-alpha
|
||||||
|
*/
|
||||||
|
public boolean getCurrentOnCloseMode() { return (boolean) items.get("onCloseMode").get(); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the current on close mode.
|
||||||
|
*
|
||||||
|
* @param currentOnCloseMode the on close mode that should be set.
|
||||||
|
* @since Envoy v0.3-alpha
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public void setCurrentOnCloseMode(boolean currentOnCloseMode) { ((SettingsItem<Boolean>) items.get("onCloseMode")).set(currentOnCloseMode); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return a {@code Map<String, Theme>} of all themes with their names as keys
|
* @return a {@code Map<String, Theme>} of all themes with their names as keys
|
||||||
@ -158,18 +176,4 @@ public class Settings {
|
|||||||
* @since Envoy v0.2-alpha
|
* @since Envoy v0.2-alpha
|
||||||
*/
|
*/
|
||||||
public void setThemes(Map<String, Theme> themes) { this.themes = themes; }
|
public void setThemes(Map<String, Theme> themes) { this.themes = themes; }
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the current on close mode.
|
|
||||||
* @since Envoy v0.3-alpha
|
|
||||||
*/
|
|
||||||
public boolean getCurrentOnCloseMode() { return currentOnCloseMode; }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the current on close mode.
|
|
||||||
*
|
|
||||||
* @param currentOnCloseMode the on close mode that should be set.
|
|
||||||
* @since Envoy v0.3-alpha
|
|
||||||
*/
|
|
||||||
public void setCurrentOnCloseMode(boolean currentOnCloseMode) { this.currentOnCloseMode = currentOnCloseMode; }
|
|
||||||
}
|
}
|
87
src/main/java/envoy/client/SettingsItem.java
Normal file
87
src/main/java/envoy/client/SettingsItem.java
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
package envoy.client;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.swing.JComponent;
|
||||||
|
|
||||||
|
import envoy.client.ui.PrimaryToggleSwitch;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Project: <strong>envoy-clientChess</strong><br>
|
||||||
|
* File: <strong>SettingsItem.java</strong><br>
|
||||||
|
* Created: <strong>23.12.2019</strong><br>
|
||||||
|
*
|
||||||
|
* @author Kai S. K. Engelbart
|
||||||
|
*/
|
||||||
|
public class SettingsItem<T> implements Serializable {
|
||||||
|
|
||||||
|
private T value;
|
||||||
|
private Class<? extends JComponent> componentClass;
|
||||||
|
private String userFriendlyName, description;
|
||||||
|
|
||||||
|
private static final Map<Class<?>, Class<? extends JComponent>> componentClasses = new HashMap<>();
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 2146837835556852218L;
|
||||||
|
|
||||||
|
static {
|
||||||
|
componentClasses.put(boolean.class, PrimaryToggleSwitch.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SettingsItem(T value, String userFriendlyName, String description) {
|
||||||
|
this(value, componentClasses.get(value.getClass()));
|
||||||
|
this.userFriendlyName = userFriendlyName;
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SettingsItem(T value, Class<? extends JComponent> componentClass) {
|
||||||
|
this.value = value;
|
||||||
|
this.componentClass = componentClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JComponent getComponent() throws ReflectiveOperationException, SecurityException {
|
||||||
|
if (componentClass == null) throw new NullPointerException("Component class is null");
|
||||||
|
return componentClass.getConstructor(SettingsItem.class).newInstance(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the value
|
||||||
|
*/
|
||||||
|
public T get() { return value; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param value the value to set
|
||||||
|
*/
|
||||||
|
public void set(T value) { this.value = value; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the componentClass
|
||||||
|
*/
|
||||||
|
public Class<? extends JComponent> getComponentClass() { return componentClass; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param componentClass the componentClass to set
|
||||||
|
*/
|
||||||
|
public void setComponentClass(Class<? extends JComponent> componentClass) { this.componentClass = componentClass; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the userFriendlyName
|
||||||
|
*/
|
||||||
|
public String getUserFriendlyName() { return userFriendlyName; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param userFriendlyName the userFriendlyName to set
|
||||||
|
*/
|
||||||
|
public void setUserFriendlyName(String userFriendlyName) { this.userFriendlyName = userFriendlyName; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the description
|
||||||
|
*/
|
||||||
|
public String getDescription() { return description; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param description the description to set
|
||||||
|
*/
|
||||||
|
public void setDescription(String description) { this.description = description; }
|
||||||
|
}
|
@ -29,8 +29,8 @@ import envoy.client.util.EnvoyLog;
|
|||||||
public class General extends SettingsPanel {
|
public class General extends SettingsPanel {
|
||||||
|
|
||||||
private Theme theme;
|
private Theme theme;
|
||||||
private boolean onCloseState;
|
private boolean onCloseState = Settings.getInstance().getCurrentOnCloseMode();
|
||||||
private boolean enterToSend;
|
private boolean enterToSend = Settings.getInstance().isEnterToSend();
|
||||||
|
|
||||||
private PrimaryToggleSwitch toggleSwitch;
|
private PrimaryToggleSwitch toggleSwitch;
|
||||||
private JTextPane onCloseModeTextPane = new JTextPane();
|
private JTextPane onCloseModeTextPane = new JTextPane();
|
||||||
@ -134,8 +134,8 @@ public class General extends SettingsPanel {
|
|||||||
add(stateText, gbc_stateText);
|
add(stateText, gbc_stateText);
|
||||||
|
|
||||||
descriptionText.setText(text);
|
descriptionText.setText(text);
|
||||||
descriptionText.setBackground(theme.getBackgroundColor().invert());
|
descriptionText.setBackground(theme.getBackgroundColor());
|
||||||
descriptionText.setForeground(theme.getUserNameColor());
|
descriptionText.setForeground(theme.getBackgroundColor().invert());
|
||||||
descriptionText.setEditable(false);
|
descriptionText.setEditable(false);
|
||||||
|
|
||||||
GridBagConstraints gbc_descriptionText = new GridBagConstraints();
|
GridBagConstraints gbc_descriptionText = new GridBagConstraints();
|
||||||
|
38
src/main/java/envoy/client/util/SerializationUtils.java
Normal file
38
src/main/java/envoy/client/util/SerializationUtils.java
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
package envoy.client.util;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
|
||||||
|
import envoy.exception.EnvoyException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Project: <strong>envoy-clientChess</strong><br>
|
||||||
|
* File: <strong>SerializationUtils.javaEvent.java</strong><br>
|
||||||
|
* Created: <strong>23.12.2019</strong><br>
|
||||||
|
*
|
||||||
|
* @author Kai S. K. Engelbart
|
||||||
|
*/
|
||||||
|
public class SerializationUtils {
|
||||||
|
|
||||||
|
private SerializationUtils() {}
|
||||||
|
|
||||||
|
public static <T extends Serializable> T read(File file, Class<T> serializedClass) throws EnvoyException {
|
||||||
|
if (file == null) throw new NullPointerException("File is null");
|
||||||
|
try (ObjectInputStream in = new ObjectInputStream(new FileInputStream(file))) {
|
||||||
|
return serializedClass.cast(in.readObject());
|
||||||
|
} catch (ClassNotFoundException | IOException e) {
|
||||||
|
throw new EnvoyException("Could not load serialized object", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void write(File file, Object obj) throws IOException {
|
||||||
|
if (file == null) throw new NullPointerException("File is null");
|
||||||
|
if (obj == null) throw new NullPointerException("Object to serialize is null");
|
||||||
|
if (!file.exists()) {
|
||||||
|
file.getParentFile().mkdirs();
|
||||||
|
file.createNewFile();
|
||||||
|
}
|
||||||
|
try (ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(file))) {
|
||||||
|
out.writeObject(obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user