Saving settings in a file, added SettingsItem class
This commit is contained in:
parent
7ec9e6b13a
commit
89e8fc62dc
@ -1,6 +1,7 @@
|
||||
package envoy.client;
|
||||
|
||||
import java.io.*;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.time.Instant;
|
||||
import java.util.*;
|
||||
import java.util.logging.Logger;
|
||||
@ -11,6 +12,7 @@ import javax.xml.datatype.DatatypeFactory;
|
||||
import envoy.client.event.EventBus;
|
||||
import envoy.client.event.MessageCreationEvent;
|
||||
import envoy.client.util.EnvoyLog;
|
||||
import envoy.client.util.SerializationUtils;
|
||||
import envoy.exception.EnvoyException;
|
||||
import envoy.schema.*;
|
||||
import envoy.schema.Message.Metadata.MessageState;
|
||||
@ -83,10 +85,10 @@ public class LocalDB {
|
||||
*/
|
||||
public void save() throws IOException {
|
||||
// Save users
|
||||
write(usersFile, users);
|
||||
SerializationUtils.write(usersFile, users);
|
||||
|
||||
// Save chats
|
||||
write(localDBFile, chats);
|
||||
SerializationUtils.write(localDBFile, chats);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -95,8 +97,7 @@ public class LocalDB {
|
||||
* @throws EnvoyException if the loading process failed
|
||||
* @since Envoy v0.2-alpha
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void loadUsers() throws EnvoyException { users = read(usersFile, HashMap.class); }
|
||||
public void loadUsers() throws EnvoyException { users = SerializationUtils.read(usersFile, HashMap.class); }
|
||||
|
||||
/**
|
||||
* Loads all chats saved by Envoy for the client user.
|
||||
@ -104,31 +105,7 @@ public class LocalDB {
|
||||
* @throws EnvoyException if the loading process failed
|
||||
* @since Envoy v0.1-alpha
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
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;
|
||||
}
|
||||
}
|
||||
public void loadChats() throws EnvoyException { chats = SerializationUtils.read(localDBFile, ArrayList.class); }
|
||||
|
||||
/**
|
||||
* Creates a {@link Message} object serializable to XML.
|
||||
@ -238,8 +215,7 @@ public class LocalDB {
|
||||
// Updating UserStatus of all users in LocalDB
|
||||
for (User user : returnSync.getUsers())
|
||||
for (Chat chat : getChats())
|
||||
if (user.getID() == chat.getRecipient().getID())
|
||||
chat.getRecipient().setStatus(user.getStatus());
|
||||
if (user.getID() == chat.getRecipient().getID()) chat.getRecipient().setStatus(user.getStatus());
|
||||
|
||||
sync.getMessages().clear();
|
||||
sync.getUsers().clear();
|
||||
@ -301,7 +277,8 @@ public class LocalDB {
|
||||
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
|
||||
*/
|
||||
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.Theme;
|
||||
import envoy.client.util.SerializationUtils;
|
||||
import envoy.exception.EnvoyException;
|
||||
|
||||
/**
|
||||
* Manages all application settings, which are different objects that can be
|
||||
@ -25,20 +27,18 @@ import envoy.client.ui.Theme;
|
||||
public class Settings {
|
||||
|
||||
// Actual settings accessible by the rest of the application
|
||||
private boolean enterToSend = true;
|
||||
private Map<String, SettingsItem<?>> items;
|
||||
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.
|
||||
*/
|
||||
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.
|
||||
@ -51,30 +51,21 @@ public class Settings {
|
||||
*
|
||||
* @since Envoy v0.2-alpha
|
||||
*/
|
||||
private Settings() { load(); }
|
||||
|
||||
/**
|
||||
* 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; }
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void load() {
|
||||
setEnterToSend(prefs.getBoolean("enterToSend", true));
|
||||
setCurrentTheme(prefs.get("theme", "dark"));
|
||||
setCurrentOnCloseMode(prefs.getBoolean("onCloseMode", true));
|
||||
private Settings() {
|
||||
// Load settings from settings file
|
||||
try {
|
||||
items = SerializationUtils.read(settingsFile, HashMap.class);
|
||||
} catch (EnvoyException e) {
|
||||
items = new HashMap<>();
|
||||
}
|
||||
supplementDefaults();
|
||||
|
||||
// Load themes from theme file
|
||||
try (ObjectInputStream in = new ObjectInputStream(new FileInputStream(themeFile))) {
|
||||
Object obj = in.readObject();
|
||||
if (obj instanceof HashMap) themes = (Map<String, Theme>) obj;
|
||||
} catch (IOException | ClassNotFoundException e) {
|
||||
try {
|
||||
themes = SerializationUtils.read(themeFile, HashMap.class);
|
||||
} catch (EnvoyException e1) {
|
||||
themes = new HashMap<>();
|
||||
currentTheme = "dark";
|
||||
e.printStackTrace();
|
||||
setCurrentTheme("dark");
|
||||
}
|
||||
|
||||
// Load standard themes not defined in the themes file
|
||||
@ -86,6 +77,14 @@ public class Settings {
|
||||
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.
|
||||
*
|
||||
@ -94,15 +93,17 @@ public class Settings {
|
||||
* @since Envoy v0.2-alpha
|
||||
*/
|
||||
public void save() throws IOException {
|
||||
prefs.put("theme", currentTheme);
|
||||
prefs.putBoolean("enterToSend", isEnterToSend());
|
||||
prefs.putBoolean("onCloseMode", currentOnCloseMode);
|
||||
// Save settings to settings file
|
||||
SerializationUtils.write(settingsFile, items);
|
||||
|
||||
// Save themes to theme file
|
||||
themeFile.createNewFile();
|
||||
try (ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(themeFile))) {
|
||||
out.writeObject(themes);
|
||||
SerializationUtils.write(themeFile, 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}
|
||||
* @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}.
|
||||
@ -125,7 +126,8 @@ public class Settings {
|
||||
* @param themeName the name to set
|
||||
* @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
|
||||
@ -133,7 +135,7 @@ public class Settings {
|
||||
* {@code Control} key.
|
||||
* @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.
|
||||
@ -143,7 +145,23 @@ public class Settings {
|
||||
* conjunction with the {@code Control} key.
|
||||
* @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
|
||||
@ -158,18 +176,4 @@ public class Settings {
|
||||
* @since Envoy v0.2-alpha
|
||||
*/
|
||||
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 {
|
||||
|
||||
private Theme theme;
|
||||
private boolean onCloseState;
|
||||
private boolean enterToSend;
|
||||
private boolean onCloseState = Settings.getInstance().getCurrentOnCloseMode();
|
||||
private boolean enterToSend = Settings.getInstance().isEnterToSend();
|
||||
|
||||
private PrimaryToggleSwitch toggleSwitch;
|
||||
private JTextPane onCloseModeTextPane = new JTextPane();
|
||||
@ -134,8 +134,8 @@ public class General extends SettingsPanel {
|
||||
add(stateText, gbc_stateText);
|
||||
|
||||
descriptionText.setText(text);
|
||||
descriptionText.setBackground(theme.getBackgroundColor().invert());
|
||||
descriptionText.setForeground(theme.getUserNameColor());
|
||||
descriptionText.setBackground(theme.getBackgroundColor());
|
||||
descriptionText.setForeground(theme.getBackgroundColor().invert());
|
||||
descriptionText.setEditable(false);
|
||||
|
||||
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