前面的那篇文章:emf&gef之一example.my.gefpractice講述的是如何將emf與gef結合起來使用。
在實際的項目開發中模型的是根據需求來定的,可以說模型事實上是業務邏輯。聲明這一點是為了說明本文研究內容的必要性。
前面的文章中使用的模型定義,包含x,y,w,h(他們確定了編輯器的一個矩形區域,這個矩形區域用來顯示模型的圖像),除此之外還包含了一個connection對象,每個node有inputs和outputs。
簡單的說,前文中的模型是從編輯器的角度來定義模型的。
假如從業務的角度來看,模型之間的關系是什么樣的呢?
假如從業務上來看,node之間只有一個next關系,來表明先后順序。
一 定義模型
根據上面的分析,從新定義模型,如下圖所示:
第一篇文章中定義的模型,編輯器內容序列化為xml文件格式為:






那么本文中的格式為





二 創建工程
與前面的文章一樣,利用這個ecore文件創建EMF Project,并根據生成的genmodel文件生成模型代碼。
三 事件監聽
也與前面的文章一樣,對每個模型創建一個對應的PropertySource文件,在EditPart中將PropertySource安裝給模型,并在EditPart中監聽模型更改事件,做相應處理。
四 編輯器
對模型而言,Connection對象是可有可無的,但是對編輯器而言,沒有了Connection對象,如何創建連線對象呢?
所以我們需要寫Connection對象,這個對象只在GEF框架下使用,用來描述兩個節點間的next關系,不寫入xml文件。
Connection.java




































有了 Connection對象,并不代表就能正確使用它。
首先,在Node的EditPart中定義兩個變量以及相應的get方法
NodesEditPart.java




















接著在ConnectionCreateCommand中,在執行這個命令的時候,給node的next屬性賦值:













以上僅完成了創建一個Connection,完成了給Node的next賦值。保存編輯器內容,可以查看一下結果。
假如重新打開剛剛保存的文件,發現問題了嗎?連線對象消失了。
為什么呢?看看NodesEditPartFactory#createEditPart你會有收獲的。
EMF將xml文件反序列化為了一個數據結構,很明顯,這個數據結構中沒有Connection對象。GEF將按照這個數據結構提供的模型來初始化編輯器內容,那么當然會丟失連線。
解決方法:創建一個TargetAddConnectionTable,它用來保存未完成的連線。
NodesEditPartFactory.java



























































TargetAddConnectionTable.java
























































再試試打開xml文件,應該出現連線了。
這里需要說明的是,由于本例比較簡單,TargetAddConnectionTable沒有出現太大問題。在實際應用中發現TergetAddConnectionTable有不足,也做過了更正。筆者在此不再修改代碼。假如讀者有興趣,可以測測問題是什么,問題產生的原因以及如何解決。
五 其他
本例依然采用兩個action來打開編輯器。
本例的運行結果與前面的例子是一樣的,因為從編輯器的角度來看,沒有變化。
六 源碼
七 運行環境
JDK1.4
Eclipse 3.1
GEF
EMF