程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> [Eclipse]GEF入門系列(四、其他功能)

[Eclipse]GEF入門系列(四、其他功能)

編輯:關於JAVA

最近由於實驗室任務繁重,一直沒有繼續研究GEF,本來已經掌握的一些東西好象又丟掉 了不少,真是無奈啊,看來還是要經常碰碰。剛剛接觸GEF的朋友大都會有這樣的印象:GEF 裡概念太多,比較繞,一些能直接實現的功能非要拐幾個彎到另一個類裡做,而且很多類的 名字十分相似,加上不知道他們的作用,感覺就好象一團亂麻。我覺得這種情況是由圖形用 戶界面(GUI)的復雜性所決定的,GUI看似簡單,實際上包含了相當多的邏輯,特別是GEF處 理的這種圖形編輯方式,可以說是最復雜的一種。GEF裡每一個類,應該說都有它存在的理由 ,我們要盡可能了解作者的意圖,這就需要多看文檔和好的例子。

在Eclipse裡查看文檔和代碼相當便利,比如我們對某個類的用法不清楚,一般首先找它 的注釋(選中類或方法按F2),其次可以查看它在其他地方用法(選中類或方法按 Ctrl+Shift+G),還可以找它的源代碼(Ctrl+鼠標左鍵或F3)來看,另外Ctrl+Shift+T可以 按名稱查找一個類等等。學GEF是少不了看代碼的,當然還需要時間和耐心。

好,閒話少說,下面進入正題。這篇帖子將繼續上一篇內容,主要討論如何實現 DirectEdit、屬性頁和大綱視圖,這些都是一個完整GEF應用程序需要提供的基本功能。

實現DirectEdit

所謂DirectEdit(也稱In-Place-Edit),就是允許用戶在原本顯示內容的地方直接對內 容進行修改,例如在Windows資源管理器裡選中一個文件,然後按F2鍵就可以開始修改文件名 。實現DirectEdit的原理很直接:當用戶發出修改請求(REQ_DIRECT_EDIT)時,就在文字內 容所在位置覆蓋一個文本框(也可以是下拉框,這裡我們只討論文本的情況)作為編輯器, 編輯結束後,再將編輯器中的內容應用到模型裡即可。(作為類似的功能請參考:給表格的 單元格增加編輯功能)

圖1 Direct Edit

在GEF裡,這個彈出的編輯器由DirectEditManager類負責管理,在 我們的NodePart類裡,通過覆蓋performRequest()方法響應用戶的DirectEdit請求,在這個 方法裡一般要構造一個DirectEditManager類的實例(例子中的NodeDirectEditManager), 並傳入必要的參數,包括接受請求的EditPart(就是自己,this)、編輯器類型(使用 TextCellEditor)以及用來定位編輯器的CellEditorLocator(NodeCellEditorLocator), 然後用show()方法使編輯器顯示出來,而編輯器中顯示的內容已經在構造方法裡得到。簡單 看一下NodeCellEditorLocator類,它的關鍵方法在relocate()裡,當編輯器裡的內容改變時 ,這個方法被調用從而讓編輯器始終處於正確的坐標位置。DirectEditManager有一個重要的 initCellEditor()方法,它的主要作用是設置編輯器的初始值。在我們的例子裡,初始值設 置為被編輯NodePart對應模型 (Node)的name屬性值;這裡還另外完成了設置編輯器字體和 選中全部文字(selectAll)的功能,因為這樣更符合一般使用習慣。

在NodePart裡 還要增加一個角色為DIRECT_EDIT_ROLE的EditPolicy,它應該繼承自DirectEditPolicy,有 兩個方法需要實現:getDirectEditCommand()和showCurrentEditValue(),雖然還未遇到過 ,但前者的作用你不應該感到陌生--在編輯結束時生成一個Command對象將修改結果作用到模 型;後者的目的是更新Figure中的顯示,雖然我們的編輯器覆蓋了Figure中的文本,似乎並 不需要管Figure的顯示,但在編輯中時刻保持這兩個文本的一致才不會出現"蓋不住 "的情況,例如當編輯器裡的文本較短時。

實現屬性頁

在GEF裡實現屬性頁和普通應用程序基本一樣,例如我們希望可以通過屬性視圖 (PropertyView)顯示和編輯每個節點的屬性,則可以讓Node類實現IPropertySource接口, 並通過一個IPropertyDescriptor[]類型的成員變量描述要在屬性視圖裡顯示的那些屬性。有 朋友問,要在屬性頁裡增加一個屬性都該改哪些地方,主要是三個地方:首先要在你的 IPropertyDescriptor[]變量裡增加對應的描述,包括屬性名和屬性編輯方式(比如文本或是 下拉框,如果是後者還要指定選項列表),其次是getPropertyValue()和setPropertyValue ()裡增加讀取屬性值和將結果寫入的代碼,這兩個方法裡一般都是像下面的結構(以前者為 例):

public Object getPropertyValue(Object id) {
   if (PROP_NAME.equals(id))
     return getName();
   if (PROP_VISIBLE.equals(id))
     return isVisible() ? new Integer(0) : new Integer(1);
   return null;
}

也就是根據要處理的屬性名做不同操作。要注意的是,下拉框類型的編輯器是以Integer 類型數據代表選中項序號的,而不是int或String,例如上面的代碼根據visible屬性返回第 零項或第一項,否則會出現ClassCastException。

圖2 屬性頁

實現大綱視圖

在Eclipse裡,當編輯器(Editor)被激活時,大綱視圖自動通過這個編輯器的 getAdapter()方法尋找它提供的大綱(大綱實現IcontentOutlinePage接口)。GEF提供了 ContentOutlinePage類用來實現大綱視圖,我們要做的就是實現一個它的子類,並重點實現 createControl()方法。ContentOutlinePage是org.eclipse.ui.part.Page的一個子類,大綱 視圖則是PageBookView的子類,在大綱視圖中有一個PageBook,包含了很多Page並可以在它 們之間切換,切換的依據就是當前活動的Editor。因此,我們在createControl()方法裡要做 的就是構造這個Page,簡化後的代碼如下所示:

private Control outline;
public OutlinePage() {
   super(new TreeViewer());
}
public void createControl(Composite parent) {
   outline = getViewer().createControl(parent);
   getSelectionSynchronizer().addViewer(getViewer());
   getViewer().setEditDomain(getEditDomain());
   getViewer().setEditPartFactory(new TreePartFactory());
   getViewer().setContents(getDiagram());
}

由於我們在構造方法裡指定了使用樹結構顯示大綱,所以createControl()裡的第一句就 會使outline變量得到一個Tree(見org.eclipse.gef.ui.parts.TreeViewer的代碼),第二 句把TreeViewer加到選擇同步器中,從而讓用戶不論在大綱或編輯區域裡選擇EditPart時, 另一方都能自動做出同樣的選擇;最後三行的作用在以前的帖子裡都有介紹,總體目的是把 大綱視圖的模型與編輯區域的模型聯系在一起,這樣,對於同一個模型我們就有了兩個視圖 ,體會到MVC的好處了吧。

實現大綱視圖最重要的工作基本就是這些,但還沒有完,我們要在init()方法裡綁定 UNDO/REDO/DELETE等命令到Eclipse主窗口,否則當大綱視圖處於活動狀態時,主工具條上的 這些命令就會變為不可用狀態;在 getControl()方法裡要返回我們的outline成員變量,也 就是指定讓這個控件出現在大綱視圖中;在dispose()方法裡應該把這個TreeViewer從選擇同 步器中移除;最後,必須在PracticeEditor裡覆蓋getAdapter()方法,前面說過,這個方法 是在Editor激活時被大綱視圖調用的,所以在這裡必須把我們實現好的OutlinePage返回給大 綱視圖使用,代碼如下:

public Object getAdapter(Class type) {
   if (type == IContentOutlinePage.class)
     return new OutlinePage();
   return super.getAdapter(type);
}

這樣,樹型大綱視圖就完成了,見下圖。很多GEF應用程序同時具有樹型和縮略圖兩種大 綱,實現的基本思路是一樣的,但代碼會稍微復雜一些,因為這兩種大綱一般要通過一個 PageBook進行切換,縮略圖一般由org.eclipse.draw2d.parts.ScrollableThumbnail負責實 現,這裡暫時不講了(也許以後會詳細說),你也可以通過看logic例子的LogicEditor這個 類的代碼來了解。

圖3 大綱視圖

P.S.寫這篇帖子的時候,我對例子又做了一些修改,都是和這篇帖子所說的內容相關的, 所以如果你以前下載過,會發現那時的代碼與現在稍有不同(功能還是完全一樣的,下載) 。另外要說一下,這個例子並不完善,比如刪除一個節點的時候,它的連接就沒同時刪除, 一些鍵盤快捷鍵不起作用,還存在很多被注釋掉的代碼等等。如果有興趣你可以來修改它們 ,也是不錯的學習途徑。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved