背景
坦白說:過去在 Eclipse 裡使用 Graphical Editor Framework(GEF)創建圖形化編輯器 既慢又痛苦。這個過程包括理解復雜的框架和大量的冗余代碼。但也說明 GEF 是創建圖形化編輯器的最佳框架,因為它與模型無關。另一方面,與模型無關本身也有一些問題。
GMF 雜談
GMF 的運行時組件是 IBM® 為使用 Eclipse Foundation 開發的,它以前還受 IBM Rational® 建模產品的支持。
GEF 是 Model-View-Controller(MVC)機制的精髓,它允許將您自己的模型引入表中。在使用 GEF 的早期,大多數人還使用自定義模型(考慮傳統 Java 對象 [Plain Old Java™ Object, POJO])。您會發現自定義模型帶來的問題是需要自己編寫通用代碼來支持模型,如序列化及偵聽模型更改的功能。
在 GEF 中使用模型的下一個邏輯步驟是要使用 Eclipse Modeling Framework(EMF),EMF 提供了以各種形式將模型序列化的工具和偵聽對模型默認值的更改的功能。
但是,將 EMF 模型與 GEF 框架整合在一起有一定的技術難度(如不同的命令堆棧),導致 EMF 模型並沒有很快被基於 GEF 的編輯器接受。最終,GMF 項目在這種逆境中應運而生,並希望能夠引入一種快速生成圖形化編輯器的方法。通過類似的方法,EMF 生成適用於 EMF 模型的基本編輯器。
創建 EMF 模型
創建模型的第一步就是定義 EMF 模型的協作對象。我寫這篇文章的目的只是說明定義模型的過程,而不是深入講解 EMF 提供的模型處理工具的用法。本例中將要使用的模型是一個簡單的圖形化模型。我將通過一張圖來幫助我說明模型的外觀。
圖 1. 可視的圖形化模型
如您所見,使用模型是幫助我們理解各部分之間關系的一種簡單方法。這個模型由圖形、連接和圖形化圖表組成。
EMF 支持通過多種方法定義模型。為簡單起見,我決定使用加注的 Java 技術。下面的代碼清單說明了如何使用 EMF 定義模型。第一個模型對象是一個有名稱屬性、源連接和目標連接(Connection 類型)的圖形。請注意,這是一個抽象的 EMF 類。
清單 1. Shape.java
/**
* @model abstract="true"
*/
public interface Shape {
/**
* @model
*/
String getName();
/**
* @model type="com.ibm.model.shapes.model.Connection" containment="true"
*/
List getSourceConnections();
/**
* @model type="com.ibm.model.shapes.model.Connection"
*/
List getTargetConnections();
}
接下來定義囊括所有圖形的列表的圖形化圖表。
清單 2. ShapesDiagram.java
/**
* @model
*/
public interface ShapesDiagram {
/**
* @model type="com.ibm.model.shapes.model.Shape" containment="true"
*/
List getShapes();
}
接下來定義一些特殊的圖形使模型更加生動。
清單 3. RectangularShape.java
/**
* @model
*/
public interface RectangularShape extends Shape {}
清單 4. EllipticalShape.java
/**
* @model
*/
public interface EllipticalShape extends Shape {}
最後,再添上連接就可以了,這樣就能將各種圖形真正連接在一起。
清單 5. Connection.java
/**
* @model
*/
public interface Connection {
/** @model */
Shape getSource();
/** @model */
Shape getTarget();
}
使用 Java 編程語言定義了模型後,請單擊 File > New > Eclipse Modeling Framework > EMF Model(參見圖 2)定義一個新的 EMF genmodel。注意:如果還沒有 EMF 項目,就先創建一個。
圖 2. EMF 加注的 Java importer
生成 EMF 模型
如果在生成 EMF 模型遇到問題,請參閱名為 "Generating an EMF Model" 的教程,它可以幫助您入門。
創建了 EMF genmodel 後,請在文件上單擊鼠標右鍵,並確保生成 Model 和 Edit 組件(您只需選擇 Generate All 就可以輕松地完成)。
創建 GMF 模型
GMF 需要您先創建一組模型,然後生成圖形化編輯器。圖 3 顯示了創建這些模型所涉及的過程。我們需要使用的第一個模型是圖形化定義,它定義了編輯器生成後的視覺效果。接下來是工具定義,它包括與編輯器面板、菜單等相關的事務。最後,還需要一個模型就是映射定義,相信您猜得到,它用於定義業務邏輯(EMF 圖形化模型)與可視化模型(圖形化和工具定義)之間的映射。
圖 3. GMF 概覽(來自 GMF 維基)
GMF 有個叫 GMF 指示板(Window > Show View > Other > GMF Dashboard)的實用程序非常好。它可以幫助您用一種簡單的方法完成圖形化編輯器生成過程。在這個階段,您必須選定域模型和域 genmodel。
圖 4. GMF 指示板
GMF 圖形化定義模型
GMF 備忘單
GMF 有一個優秀的備忘單,它可以幫助您完成用 GMF 生成編輯器的創建過程。建議將此備忘單與 GMF 指示板結合使用。請通過菜單項 Help > Cheat Sheets... 訪問備忘單。
需要創建的第一個模型是圖形化定義模型(在指示板的 Graphical Def Model 下單擊創建超級鏈接)。確保選擇 Canvas 為模型對象。這個模型很容易創建:
創建圖表中顯示的圖。方法是在編輯器中創建一個新的 Figure Gallery 條目,然後創建各種圖。
創建圖表中顯示的節點(矩形和橢圓形)。
在圖表中創建連接。
確保每個節點都與圖庫中創建的圖相匹配。
注意:如果您在執行此任務時遇到問題,您可以下載一個樣例插件,此插件為您准備好了所有模型。
圖 5. GMF 圖解模型
GMF 工具定義模型
這個步驟需要定義工具定義模型,使用此模型可以定義圖形化編輯器的信息類面板和菜單。要定義工具定義模型,請打開 GMF 指示板,然後單擊 Create。我們的簡單模型只需定義一個面板和一些創建工具來輔助創建模型(參見圖 6)。
圖 6. GMF 工具模型
GMF 映射定義模型
所有工作都從映射定義模型 開始。在此模型中,我們將可視化(圖形)模型映射到業務邏輯(域模型)中。GMF 有一組有序向導可以幫助您創建映射定義。請通過 File > New > Graphical Modeling Framework > Guide GMFMap Creation 調用這組向導。第一步要選擇所有 GMF 模型(參見圖 7)。
圖 7. GMFMap 向導 1
接下來,向導將智能地提示我們選擇要使用哪個模型元素作為圖表根元素。在我們舉的例子中,此模型元素為 ShapesDiagram。
圖 8. GMFMap 向導 2
最後,GMF 會像變魔術一樣算出哪些模型元素必須映射到哪些可視化元素上。
圖 9. GMFMap 向導 3
自定義 GMF 映射
可以使用基本編輯器編輯 GMF 映射定義文件來添加更多高級自定義功能。要勇敢地去嘗試!
必須注意的是:這些向導可能會隨著 GMF 的發展而改變。據說使用 GMF 自身提供的圖形化編輯器就可以幫助創建映射定義文件(和其他 GMF 模型)。
生成 GMF 編輯器
整個過程的最後一步也是最有趣的一步是生成圖形化編輯器。這需要您先通過映射定義模型創建一個 GMFGen 模型。然後,在映射定義文件上單擊鼠標右鍵並選擇 Create generator model...。這樣,一個包含使用圖形化編輯器所需的全部代碼的新項目就生成了。要使用圖形化編輯器,請啟動一個新的 Eclipse 運行時工作台,然後轉到 File > New > Examples > Model Diagram(參見圖 10)。
圖 10. 模型向導
模型文件創建後,您就應當能夠使用生成的編輯器了(參見圖 11)。很不錯,是吧?
圖 11. 圖形編輯器
自定義 GMFGen 模型
通過映射定義文件獲得的 GMFGen 模型是可以根據需要加以修改的。例如,GMFGen 模型的屬性就可以使用屬性視圖進行編輯。GMFGen 模型還有可以控制生成代碼的命名規則、生成的編輯器是否支持打印功能及很多其他自定義操作的屬性。試試這些選項,然後根據您的需求對其進行自定義。
GMF 特點
必須注意的是:我們構造並生成的編輯器僅用到了 GMF 功能的一小部分。您可以做很多改動來利用框架的高級功能。
例如,GMF 支持驗證。這句話的含義是:如果我們要限定圖形化模型,只許與每個模型元素有一個連接會怎樣?只允許相似的元素相互連接,還是對可用於圖形的名稱類型進行控制?GMF 完全能夠支持這些類型的驗證,甚至其他驗證。對於驗證,GMF 利用了 Eclipse Modeling Framework Technology(EMFT)來支持涉及使用 Java 代碼和對象約束語言(Object Constraint Language,OCL)來定義驗證器的情況。GMF 將給未通過驗證的文件安插錯誤標記,這類似於 Eclipse 對未編譯的 Java 文件的處理方法。
結束語
我的目的有兩個:一是展示支持模型驅動開發的 Eclipse Callisto 發行版中令人興奮的新的一面;二是讓您了解它有多棒,只需 15 分鐘就能在 Eclipse 中生成圖形化編輯器。
本文配套源碼