The Eclipse platform supports preferences for persisting data between application restarts.
Preferences are stored as key / value pairs.
The key is an arbitrary String.
The value can be a boolean, String, int or another primitive type.
For example, the user key may point to the value vogella.

The preference support in Eclipse is based on the Preferences class from the org.osgi.service.prefs package.
Eclipse preferences are very similar to the standard Java preferences API.
As additional functionality they use the Eclipse framework to save and retrieve the configuration and support scopes.

The scope defines how the preference data is stored and how it is changeable.
The Eclipse runtime defines three scopes as explained in the following table.

Table 1. Eclipse Preference scope

Scope

Description

Instance scope

Preferences in this scope are specific to a single Eclipse workspace.
If the user runs start same Eclipse
application
for different workspaces, the
settings
between the
applications
can be different.

Configuration scope

Settings for identical for the same installation.
Preferences stored in this scope are shared across all
workspaces.

Default scope

Default values can not be changed.
This scope is not stored on disk at all but can be used to store
default
values for all your keys.
These preferences
are supplied via
configuration files in plug-ins and product
definitions.

BundleDefaultsScope

Similar to the default scope, these values are not written to disk.
They are read from a
file, typically named
preferences.ini.

Eclipse stores the preferences in the workspace of your
application in
the
.metadata/.plugins/org.eclipse.core.runtime/.settings/
directory in the
<nodePath>.prefs file.

The <nodePath>
is by default the Bundle-SymbolicName of the plug-in but can be
specified via the preference API.
The workspace is by
default the
directory
in which the
application starts.

You can configure the storage location of the preferences via the -data path
launch parameter in Eclipse. To place the preferences in the user
home directory use the
-data @user.home
parameter setting.

You can create and manipulate preferences directly via Singletons provided by the Eclipse runtime.
You have the InstanceScope, ConfigurationScope and DefaultScope classes which give access to the corresponding instance via the INSTANCE field.

Preference values are read and saved by get() and put() methods.
In the get() method you specify a default value in case the key can not be found.
The clear() method removes all preferences and the remove() method allows you
to delete a selected preference value. Via the
flush()
method you persist the preferences to the file system.

// We access the instanceScopePreferencespreferences=InstanceScope.INSTANCE.getNode("com.vogella.eclipse.preferences.test");Preferencessub1=preferences.node("node1");Preferencessub2=preferences.node("node2");sub1.put("h1","Hello");sub1.put("h2","Hello again");sub2.put("h1","Moin");try{// forces the application to save the preferencespreferences.flush();}catch(BackingStoreExceptione){e.printStackTrace();}}

When starting the Eclipse IDE first of all a workspace location has to be specified.
There are several ways to specify a workspace location in an RCP application as well, which might be more suitable for an end user than having a dialog, which asks for a workspace location.

The default workspace location is the install location of the Eclipse RCP application.

The osgi.instance.area.default property can be used to declaratively define an alternative workspace location.

The property can be specified in the config.ini file of the RCP application.

Usually properties of the config.ini file are specified in a product configuration:

It is also possible to use variables like @user.home as value.
This is especially useful when an enviroment like Citrix is used, where several users might use the same application, but should have a different workspace.

Many RCP applications have a login screen at startup and the actual workspace location should be set according to the user being logged in.

In E4 applications a login screen is usually created in a lifecycle class in the method annotated with @PostContextCreate.

importjava.io.IOException;importjava.net.MalformedURLException;importjava.net.URL;importorg.eclipse.core.runtime.Platform;importorg.eclipse.e4.ui.workbench.lifecycle.PostContextCreate;publicclassLifeCycleManager{@PostContextCreatepublicvoidpostContextCreate()throwsIllegalStateException,IOException{// Show login dialog to the userStringuserName=// get username from login dialog;// check if the instance location is already set,// otherwise setting another one will throw an IllegalStateExceptionif(!Platform.getInstanceLocation().isSet()){StringdefaultPath=System.getProperty("user.home");// build the desired path for the workspaceStringpath=defaultPath+"/"+userName+"/workspace/";URLinstanceLocationUrl=newURL("file",null,path);Platform.getInstanceLocation().set(instanceLocationUrl,false);}}}

The instance location can only be set once! Therefore the if statement with if(Platform.getInstanceLocation().isSet()) is used.

When running the RCP application during development from the Eclipse IDE there usually already is a workspace in the run configuration.
To be able to set the location during development the Location field must be empty.

The Eclipse platform allows you to use dependency injection for preferences handling.
To access preference you use the @Preference annotation as qualifier for the dependency injection annotation.
This means that @Preference must be used together with @Inject or one of the other annotations which implies dependency injection, e.g., the @Execute annotation.

The @Preference annotation allows you to specify the nodePath and the value as optional parameters.

The nodePath is the file name used to save the
preference values to disk.
By default, this is the Bundle-SymbolicName of the plug-in.
The value parameter specifies the preference key for the value which should be injected.

Eclipse can also inject the
IEclipsePreference
object. You can use this object for storing values. If you use the
value
parameter, Eclipse injects the value directly. Use the
value
parameter for read access, while for storing or changing values, use
the
IEclipsePreference
object.

The following code snippet demonstrates how to put values into the preferences store.
Please note that @Preference is used in combination with @Execute.

// get IEclipsePreferences injected to change a value@Executepublicvoidexecute(@Preference(nodePath="com.example.e4.rcp.todo")IEclipsePreferencesprefs){// more stuff...prefs.put("user","TestUser");prefs.put("password","Password");// Persiststry{prefs.flush();}catch(BackingStoreExceptione){e.printStackTrace();}}

The next snippet demonstrates the read access of preference values.
This time the preference annotation is used a qualifier for @Inject.

The Eclipse platform automatically tracks the values and re-injects them into fields and methods if they change.
Eclipse tracks changes of preferences in the InstanceScope scope.
Preference values in the ConfigurationScope and DefaultScope are not tracked.

If you use the injected IEclipsePreference to store new preference values, these values are stored in the instance scope.

Eclipse provides the @PersistState annotation for parts.
This annotation can be applied to a method in a class referred to a part.

Such an annotated method can be used to store the instance state of the part.
The Eclipse framework calls such a method whenever the part or the application closes.
The stored information can be used in the method annotated with the @PostConstruct annotation.
A typical use case for such a method would be to store the state of a checkbox.

The usage of this annotation is demonstrated in the following example code.

Eclipse 3.x provides a standard dialog to display and change preference values via a preference dialog.
To open the Preference dialog, you can use the org.eclipse.ui.window.preferences command.

This functionality is specific to the Eclipse IDE and will not work for Eclipse 4 RCP applications.
See e4 preferences for a pure e4 implementation.

To add a new preference page a plug-in must provide an contribution to the org.eclipse.ui.preferencePages extension point.

This extension point defines a class which is responsible for creating a user interface and storing the preference values.
This class must implement IWorkbenchPreferencePage and must have a non-parameter constructor.
The keywordReference id attribute in this extension point can be used to define search terms for the preference page.

The PreferencePage class or one of its subclasses can get extended; a good template is usually FieldEditorPreferencePage.

You can register IPropertyChangeListener instances to changes in the preference values.
These listener are called by the Eclipse framework if the reference value changes.

Activator.getDefault().getPreferenceStore().addPropertyChangeListener(newIPropertyChangeListener(){@OverridepublicvoidpropertyChange(PropertyChangeEventevent){if(event.getProperty()=="MySTRING1"){Stringvalue=event.getNewValue().toString()// do something with the new value}}});

The key / value pairs will be stored in the secure.storage file in the .eclipse/org.eclipse.equinox.security folder of the users home directory.
Eclipse uses a class of type PasswordProvider for encrypting the preferences and has a default class registered.

Via the org.eclipse.equinox.security.secureStorage extension point you can register your own PasswordProvider.

Enter the following code for your VogellaPrefPage class.
Method init() sets the preferences store and the method createFieldEditors() registers editors for the values.
checkState() allows to perform a validations.
To get notified about value changes you need to override the propertyChange method.

Finally create a new view to show one of the preference values.
Also register a PropertyChangeListener to the preferences store to get informed in case the preference
settings change.

packagecom.vogella.preferences.page;importorg.eclipse.core.runtime.preferences.InstanceScope;importorg.eclipse.jface.preference.IPreferenceStore;importorg.eclipse.jface.util.IPropertyChangeListener;importorg.eclipse.jface.util.PropertyChangeEvent;importorg.eclipse.swt.SWT;importorg.eclipse.swt.layout.GridData;importorg.eclipse.swt.widgets.Composite;importorg.eclipse.swt.widgets.Label;importorg.eclipse.ui.part.ViewPart;importorg.eclipse.ui.preferences.ScopedPreferenceStore;/*
* Using Eclipse 3.x API view as example, do not forget to register it
* as an org.eclipse.ui.views extension.
*/publicclassViewextendsViewPart{privateLabellabel;@OverridepublicvoidcreatePartControl(Compositeparent){IPreferenceStorepreferenceStore=newScopedPreferenceStore(InstanceScope.INSTANCE,"com.vogella.preferences.page");Stringstring=preferenceStore.getString("MySTRING1");label=newLabel(parent,SWT.NONE);label.setLayoutData(newGridData(SWT.BEGINNING,SWT.CENTER,false,false));label.setText(string);// add change listener to the preferences store so that we are notified// in case of changespreferenceStore.addPropertyChangeListener(newIPropertyChangeListener(){@OverridepublicvoidpropertyChange(PropertyChangeEventevent){if(event.getProperty()=="MySTRING1"){label.setText(event.getNewValue().toString());}}});}@OverridepublicvoidsetFocus(){label.setFocus();}}

The following code demonstrates the view registration in the plugin.xml file.

Similar to the above you could also access the values in a handler.
The following code demonstrates that.

publicclassShowPreferenceValues{@ExecutepublicObjectexecute(Shellshell){IPreferenceStorestore=newScopedPreferenceStore(InstanceScope.INSTANCE,"com.vogella.ide.preferencepage");MessageDialog.openInformation(shell,"Info",myPrefString);BooleanmyPrefBoolean=store.getBoolean("BOOLEAN_VALUE");// RadioGroupFieldEditor can get accessStringchoice=store.getString("CHOICE");System.out.println(choice);MessageDialog.openInformation(shell,"Info",myPrefBoolean.toString());// I assume you get the rest by yourself}}