Options installed into the system are automatically saved to disk when changed.
Note that all property values must be serializable!
Conventionally, option class names are based on the module
providing them, and ought to end in Settings
: e.g.,
MyModuleSettings
. This does not affect display, however;
every option must implement
{@link org.openide.options.SystemOption#displayName() SystemOption.displayName() }
to provide a reasonable name to present to users in the Control Panel.
If it makes other code in the module more convenient, you may want to have a static "get the default" method in the option which returns the singleton of the option - but this is in no way required. Keeping the singleton as a static variable in any class is discouraged as it forces the system to load the stored option's settings as soon as that class is resolved, when otherwise loading the settings might never have been required.
/** Property name for foreground color of my module, of type {@link java.awt.Color}. */ public static final String PROPERTY_FOREGROUND = "foreground";Doing so makes it possible for other components to listen to changes in the option object.
Then, a nonstatic getter/setter pair should be provided for each property, which should update the static class-wide state. For this purpose, it is possible to manually keep static variables with the current state, and manually fire property change events; but it is more convenient to use the automatically-managed state provided by {@link org.openide.util.SharedClassObject SharedClassObject }:
public Color getForeground () { // Retrieves from class-wide state: return (Color) {@link org.openide.util.SharedClassObject#getProperty(java.lang.Object) getProperty} (PROPERTY_FOREGROUND); } public void setForeground (Color fg) { // make sure it is sane... if (fg == null) throw new NullPointerException (); // Stores in class-wide state and fires property changes if needed: {@link org.openide.util.SharedClassObject#putProperty(java.lang.String,java.lang.Object,boolean) putProperty } (PROPERTY_FOREGROUND, fg, true); }Note that
getProperty
and putProperty
automatically
provide sufficient synchronization for the option as well.
Note: when using these methods, your getters and setters will not
be called during project save and restore; instead, the actual property value you
stored will be serialized and deserialized. This is convenient for some purposes, e.g.
you may make a property of declared type
{@link org.openide.ServiceType ServiceType }
(and have a pleasant default property editor) while actually storing the correct
{@link org.openide.ServiceType.Handle ServiceType.Handle }
in the project. However, it can be dangerous in some cases, e.g.
if you are associating some sort of runtime service configuration with the property
which you need the setter to immediately modify: your setter will not be used at project
restore time. To make sure the setter is used, just manually store the property without
using putProperty
.
By default,
{@link java.beans.Introspector JavaBeans introspection }
is used to find the properties associated with a system option, and to
read and write them. You may want to have more control over this
process. If so, you should create a valid
{@link java.beans.BeanInfo BeanInfo }
class for the option. The easiest way to do this is of course to
create a class named e.g. MyModuleSettingsBeanInfo
.
You might want to do this because:
If any property may take one of a set of possible values, then you of course should make public constants representing these values, and provide e.g. a tagged {@link java.beans.PropertyEditorSupport property edito}.
Such a cluster should be used for any system options for which one property list would be unwieldy; or if it makes sense to have multiple and separate customizer components.
When such a property is set, it should fire its change using {@link org.openide.options.VetoSystemOption#fireVetoableChange(java.lang.String,java.lang.Object,java.lang.Object) VetoSystemOption.fireVetoableChange(...) } and be prepared to revoke the change if a veto occurs.
Options can be installed via module manifest, but are better installed as settings using the Services API.
If it necessary to access some other option, you may use:
OtherOption oo = (OtherOption) {@link org.openide.util.SharedClassObject#findObject(java.lang.Class,boolean) SystemOption.findObject }(OtherOption.class, true);You may also use this method to obtain the default instance for local use.