GEF property view的使用

GEF作爲一個圖形框架,對於其中圖形元素的屬性的設定是非常重要的,這是因爲每一個圖形元素的背後都是一個模型,而這些模型可以包含很多業務數據,如果我們最終選定GEF作爲我們應用的解決方案的話,我們可以利用property view來實現對這些業務數據屬性的設定; 這就是我們這裏即將討論的問題。
Eclipse中property view一共有兩種,普通的property view,也就是key/value類型的property view和tabbed property view,後者將viewer分成了若干個tab page;利用tab page將不同的屬性分組;從我使用的經驗來看,我比較傾向於前者,因爲前者可以解決絕大部分的問題,即便是我們希望編輯一個非常複雜的屬性,也可以自定義屬性編輯器來完成。比如我們常用的SWT Designer就是使用了第一種方式,當然我們不能否認後一種方式由於可以在property viewer中自定義佈局及控件,界面比較炫,但是由於需要三個擴展點的配合,操作起來還是比較麻煩的;不過這裏我不是要討論兩者的優劣,而是要討論如何使用這兩個東西,因此還是書歸正傳吧。
org.eclipse.ui.views.properties.tabbed,這是絕不能少的。只有這樣,屬性頁面才能顯示出來;
首先要想使用eclipse的property view,必須在相應的RCP程序或者Plugin程序中配置Dependencies,如果是第一種,需要增加org.eclipse.ui.views,如果是後一種,需要增加

其次,如果應用爲RCP,那麼可以在視圖文件中以“org.eclipse.ui.views.PropertySheet”爲id值,增加一個view,這個id就是Eclipse默認的屬性頁id;如果你記不住,那麼用IPageLayout.ID_PROP_SHEET好了;當然這一步並不是必須的,你可以在自己的WorkbenchWindowAdvisor中配置setShowFastViewBars(true);這樣程序運行時就可以通過fast view bar來動態打開這個view了,怎麼做隨你;我的建議是兩者都要,以防用戶將屬性頁關閉了,無法打開;(題外話是可以建一個Command/Action來打開屬性頁,但是我覺得沒有必要);

經過以上兩步,我們的準備工作就完成了,下面就是如何在我們的Editor點選了某一個圖形元素時,屬性頁能夠被通知。事實上這裏說的圖形元素是不確切的,而應該是這個圖形元素對應的模型元素;讓我們把眼光放得更寬廣一點,事實上並不僅僅侷限於GEF,任何實現了IPropertySource接口的模型元素都可以被屬性頁顯示出來;
模型元素實現IPropertySource後需要實現以下方法,具體含義就不說了:
·public Object getEditableValue();
·public IPropertyDescriptor[] getPropertyDescriptors();
·public Object getPropertyValue(Object id);
·public boolean isPropertySet(Object id);
·public void resetPropertyValue(Object id);
·public void setPropertyValue(Object id, Object value);
其中最最重要的是第1、2和6個方法;尤其是第二個方法尤爲重要。在定義PropertyDescriptor時,Eclipse已經提供了兩個主要的屬性描述類TextPropertyDescriptor和ComboBoxPropertyDescriptor,分別對應文本框和組合下拉框,但是如果是比較複雜的屬性,例如像字體、顏色這樣的屬性,相應的屬性描述類就要自己定義了,這時需要繼承PropertyDescriptor類定義自己的屬性描述類,而在定義這個類的過程中,必須指定相應的CellEditor,也就是屬性編輯器類,我的建議是對於非常複雜的屬性,比如屬性中包含了很多不同類型的子屬性,這些子屬性的個數會發生變化等等,那麼可以定義一個DialogCellEditor的子類,以對話框的形式顯示所有的子屬性,並在對話框中對有子屬性進行顯示、操作。也就是說:
MyPropertyDescriptor(繼承PropertyDescriptor)--->MyCellEditor(繼承CellEditor)--->MyDialog(繼承Dialog)--->子屬性顯示、操作;

經過這些操作對於第一種property view已經足夠了,在GEF應用中當你選擇了某一個圖形時,其屬性就能顯示出來了。但是對於後者來說,這還遠遠不夠,因爲它比較吊!

對於tabbed property view來說,以上的步驟是不能缺的,除此而外還需要配置org.eclipse.ui.views.properties.tabbed.propertyContributor、org.eclipse.ui.views.properties.tabbed.propertyTabs和org.eclipse.ui.views.properties.tabbed.propertySections三個擴展點;第一個擴展點的最主要作用是通知屬性頁究竟是workbench part爲屬性頁提供屬性,說白了(我的理解,就是所有我們想最終選擇的那些元素放在了哪個workbench part上),因此相應的contributorId往往是editor的id;這裏需要超級注意的是對於GEF應用來說,必須要配置typeMapper,也就是定義實現ITypeMapper的類,如下:
public Class mapType(Object object) {
  Class type = object.getClass();
  if(object instanceof EditPart) {
   type = ((EditPart)object).getModel().getClass();
  }
  return type;
 }
沒有這一步,毛也顯示不出來;其實我們可以通過以上代碼看出,這個轉換就是將控制器轉換爲模型;此外相應的editor必須繼承ITabbedPropertySheetPageContributor接口,提供getContributorId()方法,也就是返回editor的ID;而且還要重載getAdapter方法提供如下實現:
public Object getAdapter(Class adapter) {
  if(adapter == IPropertySheetPage.class) {
    return new TabbedPropertySheetPage(this);
  }
        return super.getAdapter(adapter);
}

當完成了以上所有步驟之後,分頁的屬性頁就顯示出來了。具體的Section的定義就不說了,其實不過是定義public void createControls(Composite parent, TabbedPropertySheetPage aTabbedPropertySheetPage)這個函數罷了;它和其他的createControl沒什麼區別,只是我們可以利用getWidgetFactory()來構造界面元素,其他的沒有什麼新鮮的;

以上就是屬性頁在GEF中的應用。

發佈了40 篇原創文章 · 獲贊 59 · 訪問量 25萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章