Eclipse Plug-in - How to monitor Preference page if not saved

之前曾經寫過關於Preferences的文章,主要是針對IPreferenceChangeListener事件監聽

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

但這個部分是在被監聽者有變動值並且做過儲存的情況之下才會觸發!

而在這邊將會探討的是,如何針對Preference Page在切換頁面的當下就可以觸發事件,也就是

當我們click左邊的TreeViewer,如從CA Preference切換到CTest Preference時,就會觸發CA

Preference內預先設置好的event,而這個event會取得CTest Preference object,因此可以呼叫

其內部的method,在沒有save的情況下!

因為一般的例子是,CTest Preference若要監聽CA Preference有做變更的話,需要在CTest頁面

內建置IPreferenceChangeListener,還必須是CA Preference有變更值且儲存的情況下才會觸發!

而今天提的例子無需做儲存也可以觸發事件!

PS. 上面提到的CTest、CA Preference出自於下面的文章

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

由於若從CA切換至CTest要觸發事件,因此需在CA內增加相關的code,如下:
try{
    Field field = PreferencePage.class.getDeclaredField("container");
    field.setAccessible(true);
    final PreferenceDialog dialog = (PreferenceDialog) field.get(this);
    final TreeViewer tviewer = dialog.getTreeViewer();
    tviewer.addPostSelectionChangedListener(new ISelectionChangedListener() {
       @Override
       public void selectionChanged(SelectionChangedEvent event) {
          // TODO Auto-generated method stub
          final IStructuredSelection selection = (IStructuredSelection) event.getSelection();
          final Object obj = selection.getFirstElement();
          if (obj instanceof IPreferenceNode) {
          BusyIndicator.showWhile(getShell().getDisplay(), new Runnable(){
             @Override
             public void run() {
                if(syncTPreferencePage){
                   IPreferenceNode node = (IPreferenceNode) obj;
                   IPreferencePage page = node.getPage();
                   if(page instanceof TPreferencePage){
                      TPreferencePage cpage = (TPreferencePage) page;
                      System.out.println(cpage.getTitle());
                      syncTPreferencePage = false;
                   }
                }
             }
         });
      } 
     }
    });
}catch(Exception e){
   e.printStackTrace();
}

這邊開始將說明如何取得Preference Dialog左邊TreeView object,這個部分需要去瀏覽Eclipse

底層的source code!

一般來說像CA Preference class會繼承FieldEditorPreferencePage,而此page又會繼承

PreferencePage,PreferencePage class下的成員變數container所代表的就是Preference

Dialog object,但這個變數的型態是IPreferencePageContainer!

但因為PreferenceDialog實作IPreferencePageContainer,所以container可轉型至PreferenceDialog!

因此透過PreferenceDialog object可以取得TreeViewer。此時針對TreeViewer object add event

,這一段可以參考PreferenceDialog內的addListeners method,本身PreferenceDialog就有實作

如果Preference page內的項目有不合法的值,此時將無法切換page,在這邊就會先被擋掉了!

因此本身Eclipse就有切換page event的設計! (在此也是參考這一段code得到靈感)

當我們click CTest時,此時selectionChanged's被選擇的項目將會是CTest本身! 在此之前,CTest

會先初始化,若尚未拜訪CTest的情況之下! 而syncTPreferencePage變數乃是針對CA的頁面若

有做相關項目的變更的話,自行記錄的flag! 如,針對CA內點選create button,則

syncTPreferencePage將設為true,此時切換至CTest就會印出它的title出來!(如上面sample code)

最後,DEMO如下:


由於本篇的重點在上面相關的code,因此也不列出CA Preference建置基本code,您可以自行

發揮囉!

留言