Search code examples
eclipsepreferences

How can I add an IPreferenceChangeListener that responds to any preference change?


I'd like to add a listener that will fire when any Eclipse preference is changed.

I know how to do this for a specific preference page using the Activator of the UI plugin that declares the page. You might use the following API called from the Activator.start() method:

getPreferenceStore().addPropertyChangeListener(IPropertyChangeListener listener)

But I'd like the listener to be notified whenever any preference is changed. I tried the following, called from my Activator.start() method:

import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.osgi.framework.BundleContext;

public class Activator extends AbstractUIPlugin {
...
    public void start(BundleContext context) throws Exception {
        super.start(context);
        plugin = this;
        addMyPreferenceChangeListener();
    }

    private IPreferenceChangeListener fPreferenceChangeListener;
    private void addMyPreferenceChangeListener() {
        fPreferenceChangeListener = new IPreferenceChangeListener() {
            public void preferenceChange(PreferenceChangeEvent event) {
                System.err.println("PreferenceChangeEvent");
            }
        };
        IEclipsePreferences prefs = InstanceScope.INSTANCE.getNode("/");
        prefs.addPreferenceChangeListener(fPreferenceChangeListener);
    }
}

I hoped the "/" of getNode might indicate the root of the preference, but this doesn't seem to work; the println() is not executed when I make a change to the preferences (eg: Window > Preferences > General > Always run in background).


Solution

  • There is no way to have a single listener that is notified for all nodes, you have to add a listener to each node you are interested in.

    You can find all the existing nodes using an IPreferenceNodeVisitor

    IPreferencesService prefsService = Platform.getPreferencesService();
    
    IEclipsePreferences root = prefsService.getRootNode();
    
    root.accept(visitor);
    

    You will also have to use IEclipsePreferences.addNodeChangeListener to be told about new nodes.

    Also note that the start method of your activator does not run until some other code in your plugin is used - it does not normally run during Eclipse startup.