2016-06-13 2 views
0

Я хотел бы добавить слушателя, который будет срабатывать, когда любой Eclipse предпочтение изменено.Как добавить функцию IPreferenceChangeListener, которая отвечает на любое изменение предпочтений?

Я знаю, как это сделать для конкретной страницы предпочтений, используя активатор плагина пользовательского интерфейса, который объявляет страницу. Вы можете использовать следующий API вызывается из метода Activator.start():

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() не выполняется, когда я вношу изменения в настройки (например: Окно> Настройки> Общие> Всегда запускать в фоновом режиме).

ответ

1

Там нет никакого способа, чтобы иметь один слушатель, который уведомляется для всех узлов, вы должны добавить слушатель к каждому узлу вас интересуют.

Вы можете найти все существующие узлы, используя IPreferenceNodeVisitor

IPreferencesService prefsService = Platform.getPreferencesService(); 

IEclipsePreferences root = prefsService.getRootNode(); 

root.accept(visitor); 

Вы также должны использовать IEclipsePreferences.addNodeChangeListener, чтобы рассказать о новых узлов.

Также обратите внимание, что метод вашего активатора start не запускается до тех пор, пока не будет использован другой код в вашем плагине - он обычно не запускается во время запуска Eclipse.

+0

Привет Greg-449, отлично спасибо за это. Я могу получить первый бит для работы - посетитель, но я не уверен, как заполнить addNodeChangeListener. В удаленном (событие NodeChangeEvent) или добавленном (NodeChangeEvent event) методе я могу сделать event.getChild(), но он дает мне org.osgi.service.prefs.Preferences. Что я могу сделать с этим? Я ожидал узел IEclipsePreferences, поэтому я могу выполнить другой accept (guest) и добавить моего слушателя к новому узлу. – betamax

+0

IEclipsePreferences extends Preferences, я думаю, что вы должны просто использовать значение. –

+0

Да, вы правы.Внутри добавленного (событие NodeChangeEvent) я был в состоянии сделать это: \t \t \t \t \t \t \t IEclipsePreferences узла = (IEclipsePreferences) event.getChild(); \t \t \t \t \t \t \t node.addPreferenceChangeListener (fPreferenceChangeListener); Однако я не смог удалить слушателя в remove(), потому что исключение выбрано потому, что узел удален. Я видел, что другой код упоминает об этом. – betamax

1

Благодаря greg-449 для его ответа. Вот мой последний код для справки. Отклоненные слушатели добавляются из метода запуска активатора. Обратите внимание, что этот плагин запускается при запуске с использованием 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; 
    } 
} 
Смежные вопросы