package nl.helixsoft.gui.preferences; import java.awt.Color; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.util.HashSet; import java.util.Properties; import java.util.Set; import nl.helixsoft.gui.ColorConverter; /** * Adapted from PathVisio. * <p> * Loads & saves application preferences * <p> * PreferenceManager is a wrapper of java.util.Properties. * It could be argued that java.util.Properties is implemented wrong - it should wrap a HashMap instead of extending it. * As it is, the Properties.get() method ignores defaults, whereas the Properties.getProperty() method does take them into account. * This class solves that issue. */ public class PreferenceManager { private final File propertiesFile; private final Properties defaults; /** * @param defaults default properties to be used in case a property is not defined in the defaults file. defaults specified in this way take priority over the value of Property.getDefault(). */ public PreferenceManager (File propertiesFile, Properties defaults) { this.propertiesFile = propertiesFile; this.defaults = defaults; } public PreferenceManager (File propertiesFile) { this (propertiesFile, null); } private Properties properties; private Set<PreferenceListener> listeners = new HashSet<PreferenceListener>(); private boolean dirty; public void addListener(PreferenceListener listener) { listeners.add(listener); } private void fireEvent(Preference modifiedPref) { PreferenceEvent event = new PreferenceEvent(modifiedPref); for (PreferenceListener l : listeners) { l.preferenceModified(event); } } /** * Stores preferences back to preference file, if necessary. * Only writes to disk if the properties have changed. */ public void store() { if (dirty) { System.out.println ("Preferences have changed. Writing preferences"); try { properties.store(new FileOutputStream(propertiesFile), ""); dirty = false; } catch (IOException e) { System.err.println ("Could not write properties"); } } } /** * Load preferences from file */ public void load() { properties = new Properties(defaults); try { if(propertiesFile.exists()) { properties.load(new FileInputStream(propertiesFile)); } else { System.out.println ("Preferences file " + propertiesFile + " doesn't exist, using defaults"); } } catch (IOException e) { System.err.println ("Could not read properties"); e.printStackTrace(); } dirty = false; } /** * Get a preference as String */ public String get (Preference p) { String key = p.name(); return properties.getProperty(key, p.getDefault()); } public void set (Preference p, String newVal) { String oldVal = get(p); if (oldVal == null ? newVal == null : oldVal.equals (newVal)) { // newVal is equal to oldVal, do nothing } else { if (newVal == null) properties.remove(p.name()); else properties.setProperty(p.name(), newVal); fireEvent(p); dirty = true; } } public PreferenceEntry getEntry (Preference p) { return new PreferenceEntryImpl(this, p); } public int getInt (Preference p) { return Integer.parseInt (get(p)); } public void setInt (Preference p, int val) { set (p, "" + val); } public File getFile (Preference p) { String result = get (p); return result == null ? null : new File (result); } public void setFile (Preference p, File val) { set (p, val == null ? null : val.toString()); } public Color getColor (Preference p) { return ColorConverter.parseColorString(get (p)); } public void setColor (Preference p, Color c) { set (p, ColorConverter.getRgbString(c)); } public void setBoolean (Preference p, Boolean val) { set (p, "" + val); } public boolean getBoolean (Preference p) { return (get(p).equals ("" + true)); } /** * Returns true if the current value of Preference p equals the default value. */ public boolean isDefault (Preference p) { return !properties.containsKey(p.name()); } }