Previous Page
Next Page

12.3. Preference APIs

The Preference API included in Eclipse provides simple string-based key/ value pair storage in a flat structure. The plug-in infrastructure provides every plug-in with its own preference storage file named pref_store.ini, located in the workspace metadata area. For example, if you use the Favorites preference page created in the previous sections to change column visibility, then examining the pref_store.ini file in <workspace>\.metadata\.plugins\com.qualityeclipse.favorites directory reveals:

#Mon Mar 20 12:00:00 EST 2006
favorites.view.name.column.visible=true
favorites.view.location.column.visible=true

Tip

If you have highly structured preference data that does not lend itself to simple, independent key/value pairs, then you might consider storing those preference elements in an XML-formatted preference file that is located in the plug-in's metadata area, similar to the way that the FavoritesManager stores its information (see Section 7.5.2, Saving global view information, on page 311).


12.3.1. Default preferences

Every preference has the following three values associated with it:

current valueEach preference has a current value, which is the same as the default value if the current value has not been specified.

default valueEach preference has a default value, which is the same as the default-default value if the default value has not been specified. The default value can be programmatically specified (see Section 12.3.3, Specifying default values programmatically, on page 471) or specified in a special file located in the plug-in's installation directory (see Section 12.3.4, Specifying default values in a file, on page 472).

default-default valueThe default-default value is hard-coded into the Eclipse preference system and is used if no current value and no default value is specified for the preference in question.

The default-default values hard-coded into the Eclipse system depend on the API being used to access the preference. In Table 12-2, the default-default value on the right is returned by a method with the return type shown on the left if no current value and no default value have been specified for a preference.

Table 12-2. Default Preference Values

Preference Method Return Type

Default-Default Value

Boolean

false

double

0.0

float

0.0f

int

0

long

0L

String

""


The contents of the preference file represent only those preferences whose values are different from the preference's default value. If the preference's current value is the same as the preference's default value, then that value is not written into the preference file.

12.3.2. Accessing preferences

There are two APIs for accessing preferences in Eclipse:

  • org.eclipse.core.runtime.Preferences

  • org.eclipse.jface.preference.IPreferenceStore

As covered in Section 3.4.6, Plugin and AbstractUIPlugin, on page 118 there is no advantage to using the older IPreferenceStore interface, so you need to concentrate on the newer Preferences interface and related API.

The preferences for a particular plug-in can be accessed using the getPluginPreferences() method in the plug-in class itself. The Preferences object returned by that method has many convenient methods for accessing the underlying string-based preference values in a variety of formats, including Boolean, int, long, and so on.

getBoolean(String) Returns the preference value as a Boolean. A value other than TRue is interpreted as false.

geTDefaultBoolean(String) Returns the default preference value as a Boolean. A value other than true is interpreted as false.

getdefaultDouble(String) Returns the default preference value as a double. A value that does not represent a double is interpreted as 0.0.

geTDefaultFloat(String) Returns the default preference value as a float. A value that does not represent a float is interpreted as 0.0f.

getdefaultInt(String) Returns the default preference value as an int. A value that does not represent an int is interpreted as 0.

getdefaultLong(String) Returns the default preference value as a long. A value that does not represent a long is interpreted as 0L.

getdefaultString(String) Returns the default preference value as a string.

getdouble(String) Returns the preference value as a double. A value that does not represent a double is interpreted as 0.0.

getFloat(String) Returns the preference value as a float. A value that does not represent a float is interpreted as 0.0f.

getInt(String) Returns the preference value as an int. A value that does not represent an int is interpreted as 0.

getLong(String) Returns the preference value as a long. A value that does not represent a long is interpreted as 0L.

getString(String) Returns the preference value as a string.

isDefault(String) Returns true if the current value of the specified preference is the same as its default value.

setDefault(String, boolean) Sets the default value of the specified preference to a Boolean.

setDefault(String, double) Sets the default value of the specified preference to a double.

setDefault(String, float) Sets the default value of the specified preference to a float.

setDefault(String, int) Sets the default value of the specified preference to an int.

setDefault(String, String) Sets the default value of the specified preference to a string.

setDefault(String, long) Sets the default value of the specified preference to a long.

setToDefault(String) Sets the current value of the specified preference to its default value.

setValue(String, boolean) Sets the value of the specified preference to a Boolean.

setValue(String, double) Sets the value of the specified preference to a double.

setValue(String, float) Sets the value of the specified preference to a float.

setValue(String, int) Sets the value of the specified preference to an int.

setValue(String, String) Sets the value of the specified preference to a string.

setValue(String, long) Sets the value of the specified preference to a long.

In addition, there are various methods for loading, saving, and checking the state of a preference object.

contains(String) Returns whether the given preference has a value that is not the default value or a default value that is not the default-default value.

defaultPropertyNames() Returns a list containing the names of all preferences that have default values other than their default-default value.

load(InputStream) Loads the non-default-valued preferences for the preference object from the specified InputStream using java.util. Properties.load(). Default preference values are not affected.

needsSaving() Returns whether at least one preference value has changed since the last time preferences were saved (see store()).

propertyNames() Returns a list containing the names of all preferences that have current values other than their default value.

store(OutputStream, String) Saves the non-default-valued preferences to the specified OutputStream using Properties.store(), and resets the dirty flag so that needsSaving() will return false until a preference value is modified.

Note

As covered in Section 3.4.6, Plugin and AbstractUIPlugin, on page 118, if your plug-in class is a subclass of org.eclipse.core.runtime.Plugin rather than org.eclipse.ui.plugin.AbstractUIPlugin, you must modify the stop() method to always call the savePluginPreferences() method so that preferences will persist across sessions.


12.3.3. Specifying default values programmatically

Default values can be specified programmatically using the Preferences API when a plug-in is first started. Extend the initializeDefaultPreferences() method of your plug-in's preference initializer class and call the various setDefault* methods. For the Favorites product, modify the PreferenceInitializer class created earlier in the chapter and implement the initializeDefaultPreferences() method to set the default value for the name column visibility preference. Now, when the Favorites preference page is displayed for the first time, the Show name column preference will already be checked.

public class PreferenceInitializer
   extends AbstractPreferenceInitializer {
   public void initializeDefaultPreferences() {
      IPreferenceStore store = FavoritesPlugin.getDefault()
        .getPreferenceStore();
      store.setDefault(
        PreferenceConstants.FAVORITES_VIEW_NAME_COLUMN_VISIBLE,true);
   }
}

The PreferenceInitializer class is referenced in the plugin.xml file by the org.eclipse.core.runtime.preferences extension point. This extension point was automatically extended by the Preference Page template used earlier.

<extension point="org.eclipse.core.runtime.preferences">
   <initializer class="com.qualityeclipse.favorites.>
                       preferences.PreferenceInitializer"/>
</extension>

Now that you have programmatically specified true as the default value for the name column visibility preference, the only time it will appear in the pref_store.ini file is when the preference is not true.

12.3.4. Specifying default values in a file

Default preferences can also be specified in a special preferences.ini file located in the plug-in's installation directory. This file has an identical format to the pref_store.ini file (see Section 12.3, Preference APIs, on page 467) and can be installed when the plug-in is installed. The advantage to placing default values in a file is that it extracts them from the code, making them more easily changeable without modifying code. The disadvantage is that default values specified in this way cannot be dynamically adjusted as they can if they are specified programmatically; however, typically, a default preference specification does not need that type of flexibility. For the Favorites product, you will add a new preferences.ini file in the project root containing a single line specifying a default value for the location column visibility:

favorites.view.location.column.visible=true

Tip

You can use the General > Editors > File Associations page in the workbench Preferences dialog (see Section 1.3.1, Workbench preferences, on page 15) to associate the internal text editor with any *.ini file so that double-clicking on the preferences.ini file will open a text editor on the file within Eclipse.


To complete the process, the build script must be modified to include this new preferences.ini file as part of the product (see Chapter 19, Building a Product, for more on building the product). Now that you have specified true as the default value for the location column visibility preference, the only time it will appear in the pref_store.ini file is when the preference is not true.

12.3.5. Hooking up the Favorites view

Now that the Favorites preference page is in place, you can hook up these preferences to the Favorites view. First, extract the initial column widths into constants using Extract Constant refactoring:

private static final int NAME_COLUMN_INITIAL_WIDTH = 200;

private static final int LOCATION_COLUMN_INITIAL_WIDTH = 450;

Next, you will create a new updateColumnWidths() method that is called from the createPartControl(Composite) method right after the table has been created.

private void updateColumnWidths() {
   Preferences prefs = FavoritesPlugin
      .getDefault().getPluginPreferences();

   boolean showNameColumn = prefs.getBoolean(
      PreferenceConstants.FAVORITES_VIEW_NAME_COLUMN_VISIBLE);
   nameColumn.setWidth(
      showNameColumn
         ? NAME_COLUMN_INITIAL_WIDTH
         : 0);

   boolean showLocationColumn = prefs.getBoolean(
      PreferenceConstants.FAVORITES_VIEW_LOCATION_COLUMN_VISIBLE);
   locationColumn.setWidth(
      showLocationColumn
         ? LOCATION_COLUMN_INITIAL_WIDTH
         : 0);
}

When these two changes are in place, the Favorites view will show the name and location columns as specified in the Favorites preference page.

12.3.6. Listening for preference changes

When the Favorites view is first opened, the columns conform to the settings specified on the Favorites preference page, but what if the preferences are changed while the Favorites view is already open? For the Favorites view to stay synchronized with the preferences specified on the Favorites preference page, you need to add listeners to the object containing the preferences. Back in the FavoritesView, you can add a new propertyChangeListener field that listens for property change events and calls updateColumnWidths() as appropriate.

private final IPropertyChangeListener propertyChangeListener
   = new IPropertyChangeListener() {
   public void propertyChange(PropertyChangeEvent event) {
      if (event.getProperty().equals(
            FAVORITES_VIEW_NAME_COLUMN_VISIBLE_PREF)
       || event.getProperty().equals(
            FAVORITES_VIEW_LOCATION_COLUMN_VISIBLE_PREF))
         updateColumnWidths();
   }
};

This new propertyChangeListener must be added as a listener when the view is created at the end of the createPartControl() method.

FavoritesPlugin
   .getDefault()
   .getPluginPreferences()
   .addPropertyChangeListener(propertyChangeListener);

The listener must be removed in the dispose() method when the view is closed.

FavoritesPlugin
   .getDefault()
   .getPluginPreferences()
   .removePropertyChangeListener(propertyChangeListener);


Previous Page
Next Page