如何添加响应任何首选项更改的IPreferenceChangeListener?

时间:2016-06-13 18:00:18

标签: eclipse preferences

我想添加一个侦听器,当 任何 Eclipse首选项发生更改时,该侦听器将会触发。

我知道如何使用声明页面的UI插件的Activator为特定的首选项页面执行此操作。您可以使用从Activator.start()方法调用的以下API:

getPreferenceStore().addPropertyChangeListener(IPropertyChangeListener listener)

但是我希望无论何时更改任何偏好都会通知听众。我尝试了以下方法,从我的Activator.start()方法调用:

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);
    }
}

我希望getNode的“/”可能表示首选项的根目录,但这似乎不起作用;当我更改首选项时,不会执行println()(例如:Window> Preferences> General> Always always in background)。

2 个答案:

答案 0 :(得分:1)

没有办法让一个侦听器通知所有节点,你必须为你感兴趣的每个节点添加一个监听器。

您可以使用www.ibm.com www.fr.ibm.com

找到所有现有节点
IPreferenceNodeVisitor

您还必须使用IPreferencesService prefsService = Platform.getPreferencesService(); IEclipsePreferences root = prefsService.getRootNode(); root.accept(visitor); 来了解新节点。

另请注意,在使用插件中的其他代码之前,激活器的IEclipsePreferences.addNodeChangeListener方法不会运行 - 它通常不会在Eclipse启动期间运行。

答案 1 :(得分:1)

感谢greg-449的回答。这是我的最终代码供参考。 偏好侦听器是从Activator start方法添加的。请注意,此插件使用extension point="org.eclipse.ui.startup"在启动时启动。 插件停止时会删除监听器。

对首选项的任何更改都会导致" PreferenceChangeEvent"打印。我抓住这一点来做我想要的实际工作;没有显示。 如果创建了新的首选项节点(例如创建一个新的环境变量(Window> Preferences> C / C ++> Build> Environment)并按Apply),那么" PreferenceChangeEvent"打印出来。每当随后在“首选项”中更改变量的值时也会打印。

import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.core.runtime.preferences.IPreferenceNodeVisitor;
import org.eclipse.core.runtime.preferences.IPreferencesService;
import org.eclipse.core.runtime.preferences.IEclipsePreferences.INodeChangeListener;
import org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener;
import org.eclipse.core.runtime.preferences.IEclipsePreferences.NodeChangeEvent;
import org.eclipse.core.runtime.preferences.IEclipsePreferences.PreferenceChangeEvent;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.osgi.framework.BundleContext;
import org.osgi.service.prefs.BackingStoreException;

public class Activator extends AbstractUIPlugin {

...

    public void start(BundleContext context) throws Exception {
        super.start(context);
        plugin = this;
        addPreferenceChangeListeners();
    }

    public void stop(BundleContext context) throws Exception {
        removePreferenceChangeListeners();
        plugin = null;
        super.stop(context);
    }

    private IPreferenceChangeListener fPreferenceChangeListener;
    private void addPreferenceChangeListeners() {
        /*
         * Create a single preference change listener; the same listener is
         * used for all the Preference Nodes.
         */
        fPreferenceChangeListener = new IPreferenceChangeListener() {
            @Override
            public void preferenceChange(PreferenceChangeEvent event) {
                System.err.println("PreferenceChangeEvent");
            }
        };

        IPreferencesService prefsService = Platform.getPreferencesService();
        IEclipsePreferences root = prefsService.getRootNode();
        /*
         * Create a visitor for adding the pref change listener to each node.
         */
        IPreferenceNodeVisitor addingVisitor = new IPreferenceNodeVisitor() {
            public boolean visit(IEclipsePreferences node) throws BackingStoreException {
                if(null!=fPreferenceChangeListener) {
                    System.out.println("Adding pref change listener");
                    node.addPreferenceChangeListener(fPreferenceChangeListener);
                    /*
                     * Add a addNodeChangeListener so that if any new preference nodes
                     * are added they will also have our listener added too. 
                     */
                    node.addNodeChangeListener(new INodeChangeListener() {
                        @Override
                        public void removed(NodeChangeEvent event) {
                            System.out.println("removed: event=" + event.toString());
                        }
                        @Override
                        public void added(NodeChangeEvent event) {
                            System.out.println("added: event=" + event.toString());
                            IEclipsePreferences node = (IEclipsePreferences) event.getChild();
                            node.addPreferenceChangeListener(fPreferenceChangeListener);
                        }
                    });
                }
                return true;
            }
        };

        /*
         * Add the listener to the root and all its children
         */
        try {
            root.accept(addingVisitor);
        } catch (BackingStoreException e) {
            e.printStackTrace();
        }
    }

    private class PreferenceChangeRemovingVisitor implements IPreferenceNodeVisitor {
        @Override
        public boolean visit(IEclipsePreferences node) {
            if(null!=fPreferenceChangeListener) {
                System.out.println("Removing pref change listener");
                node.removePreferenceChangeListener(fPreferenceChangeListener);
            }
            return true;
        }
    }

    private void removePreferenceChangeListeners() {
        IPreferencesService prefsService = Platform.getPreferencesService();
        IEclipsePreferences root = prefsService.getRootNode();
        IPreferenceNodeVisitor removingVisitor = new PreferenceChangeRemovingVisitor(); 
        try {
            root.accept(removingVisitor);
        } catch (BackingStoreException e) {
            e.printStackTrace();
        }
        fPreferenceChangeListener = null;
    }
}