Eclipse Plug-in - How to use IPreferenceChangeListener and propertyChange on Preferences

這邊主要說明的是IPreferenceChangeListener(類別)與propertyChange(方法)的使用,它們皆

與Preferences相關,假設您建置一個Preferences page,若只是內部的元件值有變動時,要監

聽此元件可透過propertyChange來達到!  若您內部的元件值有變動並儲存時,要觸發其他頁

面定義的IPreferenceChangeListener來達到對這個page監聽的話,就可以定義此Listener!

關於Preferences相關的詳細介紹可以參考

http://www.vogella.com/tutorials/EclipsePreferences/article.html

通常我們使用它的目的可作為一個設定頁面並且儲存相關設定值,它的範圍為一workspace,

因此當您切換成不同workspace時就會重新再開始新的設定!

範例說明如下:

這邊會建立兩個Preferences pages,當page 1勾選選項後並做了Apply,Eclipse console會印出

相關訊息,但前提是page2已經初始化了!

這兩個Preferences page分別為不同的plugin,如下

1. PLUGIN_ID => com.bin.practice.prefs
2. PLUGIN_ID => com.bin.practice.ui

以com.bin.practice.prefs來說明plugin.xml如何設定建置Preferences

定義頁面

定義初始頁面

1. InitializePreference.java

用在第一次進入Preferences page帶入相關元件的預設值
  1. public class InitializePreference extends AbstractPreferenceInitializer{
  2. @Override
  3. public void initializeDefaultPreferences() {
  4. IPreferenceStore store = Activator.getDefault().getPreferenceStore();
  5. System.out.println("initialize...CTest Preference");
  6. store.setDefault("testcheckbox", true);
  7. }
  8. }

首先,先Demo這個page執行的過程,來了解一下儲存過程

checkbox default值為true (配合InitializePreference),因此會自動勾選起來


此時,當您去追蹤儲存的檔案時,路徑如下

C:\runtime-EclipseApplication\.metadata\.plugins\org.eclipse.core.runtime\.settings\
com.bin.practice.prefs.prefs

會發現該檔案並不存在,但是當您取消勾選後進行存檔,這個檔案就會生成,且內容如下
eclipse.preferences.version=1
testcheckbox=false

如此看來,假設您是使用Preferences packages下定義FieldEditor,除了可設定預設值外,當與

預設值吻合的情況下.pref檔案不會產生! 算是一個考慮周到的機制!

2. TPreferencePage.java
  1. public class TPreferencePage extends FieldEditorPreferencePage implements IWorkbenchPreferencePage{
  2. Button btn;
  3. @Override
  4. public void init(IWorkbench workbench) {
  5. // TODO Auto-generated method stub
  6. }
  7. @Override
  8. protected void createFieldEditors() {
  9. // TODO Auto-generated method stub
  10. Composite parent = getFieldEditorParent();
  11. BooleanFieldEditor testCheckBox =
  12. new BooleanFieldEditor("testcheckbox", "Test CheckBox", parent);
  13. addField(testCheckBox);
  14. btn = new Button(parent, SWT.NONE);
  15. btn.setText("Test Button");
  16. IEclipsePreferences otherPreferences = InstanceScope.INSTANCE.getNode("com.bin.practice.ui");
  17. IPreferenceChangeListener otherPreferencesListener = new IPreferenceChangeListener() {
  18. @Override
  19. public void preferenceChange(PreferenceChangeEvent event) {
  20. String k = event.getKey();
  21. System.out.println(k+" changed..."+event.getNewValue()+"...."+event.getOldValue());
  22. }
  23. };
  24. otherPreferences.addPreferenceChangeListener(otherPreferencesListener);
  25. parent.pack();
  26. }
  27. @Override
  28. public void propertyChange(PropertyChangeEvent event) {
  29. if ((event.getSource() instanceof BooleanFieldEditor) && event.getNewValue() != event.getOldValue()) {
  30. btn.setEnabled((Boolean) event.getNewValue());
  31. }
  32. super.propertyChange(event);
  33. }
  34. }

首先必須override這兩個method,createFieldEditors內可以建置page要使用的項目

在這邊使用的是preferences相關的BooleanFieldEditor => checkbox + label

使用preferences的元件好處是我們繼承的父類別會自動幫你在按下OK or Apply的按鈕時幫

你儲存資料(InstanceScope),而您不必再去處理這一塊! 前提是要做addField動作!

PS. 儲存檔為一.prefs,裡面的格式為key = value關係

先說明propertyChange,在這邊應用在當checkbox做勾選時來改變button狀態!



而IPreferenceChangeListener的定義就比較複雜,在此將會監聽com.bin.practice.ui plugin的

Preferences page(CA Preference)若有值的變動且存檔的話就會觸發! 前提是CTest Preference

要初始化過才行!

下圖是CA Preference內的元件做變動並且Apply之後,CTest Preference內的preferenceChange

就會帶出該元件的name與相關value!

雖然CTest Preference若沒有初始化的話就無法監聽CA Preference的變化,但是當它第一次切

換到CTest時,CTest可以去讀取CA's .pref檔案,一樣可以得到CA最新的變化,前提是CA已

經做過儲存的動作!


PS. 在此CA Preference的相關code在此就不列出了,跟CTest Preference類似!

補充

關於runtime-EclipseApplication就是你執行plugin後會產生另一Eclipse,這個資料夾就是模擬

你新Open的Eclipse的workspace,當你在run configuration時就可以定義! 而InstanceScope綁定

的是workspace的範圍! 也就是你換了另一個workspace後,原本的設定就會讀不到(當然,不

同目錄壓)! 因此你可以設定儲存的該筆資料範圍是ConfigurationScope,因此就不會因為換了

workspace而讀不到該設定資料,因為它跨越了不同workspace的限制!


若你是存ConfigurationScope則須至org.eclipse.pde.core內而不是org.eclipse.core.runtime

留言