### Implementing a preference page

#### Defining the page

The JFace plug-in provides a framework for implementing wizards, preference pages, and dialogs. The implementation for these dialogs follows a common pattern. The contents of a page or dialog is defined by implementing a createContents method that creates the SWT controls representing the page content. This method should also add listeners for any events of interest. The page is responsible for creating and returning the composite that will parent all of the controls in the page. The following snippet shows the highlights:

    protected Control createContents(Composite parent)
    {
    	...
    	//composite_textField << parent
    	Composite composite_textField = createComposite(parent, 2);
    	Label label_textField = createLabel(composite_textField, MessageUtil.getString("Text_Field"));
    	textField = createTextField(composite_textField);
    	pushButton_textField = createPushButton(composite_textField, MessageUtil.getString("Change"));

    	//composite_tab << parent
    	Composite composite_tab = createComposite(parent, 2);
    	Label label1 = createLabel(composite_tab, MessageUtil.getString("Radio_Button_Options"));

    	//
    	tabForward(composite_tab);
    	//radio button composite << tab composite
    	Composite composite_radioButton = createComposite(composite_tab, 1);
    	radioButton1 = createRadioButton(composite_radioButton, MessageUtil.getString("Radio_button_1"));
    	radioButton2 = createRadioButton(composite_radioButton, MessageUtil.getString("Radio_button_2"));
    	radioButton3 = createRadioButton(composite_radioButton, MessageUtil.getString("Radio_button_3"));

    	//composite_tab2 << parent
    	Composite composite_tab2 = createComposite(parent, 2);
    	Label label2 = createLabel(composite_tab2, MessageUtil.getString("Check_Box_Options")); //$NON-NLS-1$

    	//
    	tabForward(composite_tab2);
    	//composite_checkBox << composite_tab2
    	Composite composite_checkBox = createComposite(composite_tab2, 1);
    	checkBox1 = createCheckBox(composite_checkBox, MessageUtil.getString("Check_box_1"));
    	checkBox2 = createCheckBox(composite_checkBox, MessageUtil.getString("Check_box_2"));
    	checkBox3 = createCheckBox(composite_checkBox, MessageUtil.getString("Check_box_3"));

    	initializeValues();

    	return new Composite(parent, SWT.NULL);
    }

Most of the code in this method is concerned with creating and laying out the controls, so we won't dissect it here. Here is what the corresponding page looks like:

The other primary responsibility of a preference page is to react to the performOk message. Typically, this method updates and stores the user preferences and, if necessary, updates any other plug-in objects to reflect the change in preferences. The performDefaults method is used to restore preferences to their default state when the user presses the Restore Defaults button.

You may override performApply if you have additional processing when the user selects Apply. The default implementation is to call performOk.

Preference pages should override the doGetPreferenceStore() method to return a preference store for storing their values.

#### Plug-in preference store

Preference stores are a convenience mechanism for accessing and storing preference values in a plug-in class. They provide plug-in level access to preferences that are actually stored using the runtime preferences service. AbstractUIPlugin defines a plug-in wide preference store that is maintained during the lifetime of the plug-in. Your plug-in can add entries to this preference store and update the values as the user changes the settings in your preferences page. Since preference stores use the platform preferences service, they will take care of saving preference values at the appropriate scope and location, and initializing the preference store using the appropriate mechanisms.

The following code in the ReadmePreferencePage obtains the preference store for the ReadmePlugin.

       protected IPreferenceStore doGetPreferenceStore() {
          return ReadmePlugin.getDefault().getPreferenceStore();
       }

Because ReadmePlugin extends the AbstractUIPlugin class, it automatically inherits a preference store. This preference store is initialized using the platform preferences service. The only thing the ReadmePlugin has to do is implement a method that initializes the preference controls to their default values. These values are used the first time the preference page is shown or when the user presses the Defaults button in the preferences page.

    protected void initializeDefaultPreferences(IPreferenceStore store) {
    	// These settings will show up when Preference dialog
    	// opens up for the first time.
    	store.setDefault(IReadmeConstants.PRE_CHECK1, true);
    	store.setDefault(IReadmeConstants.PRE_CHECK2, true);
    	store.setDefault(IReadmeConstants.PRE_CHECK3, false);
    	store.setDefault(IReadmeConstants.PRE_RADIO_CHOICE, 2);
    	store.setDefault(IReadmeConstants.PRE_TEXT, MessageUtil.getString("Default_text")); //$NON-NLS-1$
    }

> Note: If there are no preferences saved anywhere for a plug-in, the plug-in will get an empty preference store.

#### Retrieving and saving preferences

Once you've associated your plug-in's preference store with your preference page, you can implement the logic for retrieving and saving the preferences.

Preference pages are responsible for initializing the values of their controls using the preferences settings from the preference store. This process is similar to initializing dialog control values from dialog settings. The ReadmePreferencePage initializes all of its controls in a single method, initializeValues, which is called from its createContents method.

    private void initializeValues() {
    	IPreferenceStore store = getPreferenceStore();
    	checkBox1.setSelection(store.getBoolean(IReadmeConstants.PRE_CHECK1));
    	checkBox2.setSelection(store.getBoolean(IReadmeConstants.PRE_CHECK2));
    	checkBox3.setSelection(store.getBoolean(IReadmeConstants.PRE_CHECK3));
    	...
    }

When the OK (or Apply) button is pressed, the current values of the controls on the preference page should be stored back into the preference store. The ReadmePreferencePage implements this logic in a separate method, storeValues.

    private void storeValues() {
    	IPreferenceStore store = getPreferenceStore();
    	store.setValue(IReadmeConstants.PRE_CHECK1, checkBox1.getSelection());
    	store.setValue(IReadmeConstants.PRE_CHECK2, checkBox2.getSelection());
    	store.setValue(IReadmeConstants.PRE_CHECK3, checkBox3.getSelection());
    	...
    }

When the user presses the Defaults button, the platform will restore all preference store values to the default values specified in the plug-in class. However, your preference page is responsible for reflecting these default values in the controls on the preference page. The ReadmePreferencePage implements this in initializeDefaults.

       private void initializeDefaults() {
          IPreferenceStore store = getPreferenceStore();
          checkBox1.setSelection(store.getDefaultBoolean(IReadmeConstants.PRE_CHECK1));
          checkBox2.setSelection(store.getDefaultBoolean(IReadmeConstants.PRE_CHECK2));
          checkBox3.setSelection(store.getDefaultBoolean(IReadmeConstants.PRE_CHECK3));
          ...
       }