使用圖形編輯框架創(chuàng)建基于 Eclipse 的應(yīng)用程序
本文為您從頭到尾地介紹了使用 GEF 的步驟。我們不是完整地完成每個(gè)步驟,而是將使用您的應(yīng)用程序模型的子集,并先使該子集工作。例如,開始我們可能會(huì)忽略連接,或者只注重于您應(yīng)用程序中圖形元素類型的子集。
GEF 假定您擁有一個(gè)希望以圖形方式顯示和編輯的模型。為了做到這一點(diǎn),GEF 提供了可在 Eclipse 工作臺(tái)中任何地方使用的查看器(類型為 EditPartViewer
)。象 JFace 查看器一樣,GEF 查看器是 SWT 控件上的適配器。但是它們的類似之處僅此而已。GEF 查看器基于模型-視圖-控制器(model-view-controller,MVC)體系結(jié)構(gòu)。
控制器作為視圖和模型之間的橋梁(請(qǐng)參閱圖 1)。每個(gè)控制器(即本文所謂的 EditPart)負(fù)責(zé)將模型映射到它的視圖,也負(fù)責(zé)對(duì)模型進(jìn)行更改。EditPart 還觀察模型并更新視圖,以反映模型狀態(tài)中的變化。EditPart 是一種對(duì)象,用戶將與這種對(duì)象進(jìn)行交互。稍后將更詳細(xì)地介紹 EditPart。
GEF 提供了兩種查看器類型:圖形的和基于樹的。每種查看器都主管一種不同類型的 視圖。圖形查看器使用了在 SWT 畫布(Canvas)上繪制的 圖形(figure)。圖形是在 Draw2D 插件中定義的,該插件是 GEF 的一部分。TreeViewer 將 SWT 樹和 TreeItem 用于其視圖。
![]() ![]() |
![]()
|
GEF 對(duì)于模型一無(wú)所知。任何模型類型都可工作,只要它符合下面描述的特性。
所有東西都在模型中。模型是唯一會(huì)被持久存儲(chǔ)和恢復(fù)的東西。您的應(yīng)用程序應(yīng)當(dāng)將所有重要數(shù)據(jù)都存儲(chǔ)在模型中。在編輯、撤銷和重做的過程中,模型是唯一保持不變的。隨著時(shí)間推移,將對(duì)圖形和 EditPart 進(jìn)行垃圾收集處理并重新創(chuàng)建。
當(dāng)用戶與 EditPart 交互時(shí),EditPart 并不直接操作模型。而是創(chuàng)建一個(gè)封裝了更改的 命令(Command)。命令可用來(lái)驗(yàn)證用戶的交互,并且提供撤銷和重做支持。
嚴(yán)格地說(shuō),命令概念上也是模型一部分。它們 本身并不是模型,而是一些方法,模型是由這些方法編輯的。命令用于執(zhí)行用戶的所有可撤銷的更改。理論上,命令應(yīng)當(dāng)只了解模型。它們應(yīng)當(dāng)避免引用 EditPart 或圖形。類似地,如果可能,命令應(yīng)當(dāng)避免調(diào)用用戶界面(例如彈出式對(duì)話框)。
一個(gè)簡(jiǎn)單的 GEF 應(yīng)用程序就是用于繪制圖的編輯器。(這里 圖只意味著圖片,而不是類圖等)圖可以被建模成某些形狀。一個(gè)形狀可能具有位置、顏色等特性,并且可能是多個(gè)形狀構(gòu)成的一組結(jié)構(gòu)。這里沒有什么可驚訝的,并且前述需求也易于維護(hù)(請(qǐng)參閱圖 2)。
另一種常見的 GEF 應(yīng)用程序是 UML 編輯器,例如類圖編輯器。圖中的一段重要信息就是 (x, y) 位置,類就出現(xiàn)在該位置上。根據(jù)前一節(jié)的介紹,您可能會(huì)以為模型必須將一個(gè) 類描述成具有 x和 y特性。大多數(shù)開發(fā)人員都不希望由于無(wú)意義的屬性而“污染”其模型。在這類應(yīng)用程序中,術(shù)語(yǔ)“業(yè)務(wù)”模型可用于指代基本模型,重要語(yǔ)義的詳細(xì)信息存儲(chǔ)在基本模型中。而特定于圖的信息存儲(chǔ)在“視圖”模型(它指的是業(yè)務(wù)模型中某樣?xùn)|西的“視圖”;在一個(gè)圖中可多次查看某個(gè)對(duì)象)中。有時(shí)候這種劃分甚至?xí)从吃诠ぷ骺臻g中,其中不同的資源可能被分別用來(lái)持久存儲(chǔ)圖和業(yè)務(wù)模型。甚至可能有多個(gè)圖對(duì)應(yīng)于同一個(gè)業(yè)務(wù)模型(請(qǐng)參閱圖 3)。
不管您的模型劃分成了兩個(gè)部分,還是劃分成了多個(gè)資源,對(duì)于 GEF 而言這都是無(wú)關(guān)緊要的。術(shù)語(yǔ)模型用于指代整個(gè)應(yīng)用程序模型。屏幕上的一個(gè)對(duì)象可能對(duì)應(yīng)于模型中的多個(gè)對(duì)象。GEF 旨在允許開發(fā)人員方便地處理這類映射。
對(duì)視圖進(jìn)行更新幾乎總是由來(lái)自模型的通知而導(dǎo)致的。您的模型必須提供某種通知機(jī)制,該機(jī)制必須映射到您應(yīng)用程序中相應(yīng)的更新。而只讀模型或不能進(jìn)行通知的模型(例如文件系統(tǒng)或遠(yuǎn)程連接)可能是例外。
通知策略通常是分布式的(每對(duì)象)或集中式的(每域)。域通知器了解到對(duì)模型中任何對(duì)象的每次更改,然后將這些更改向域偵聽器廣播。如果您的應(yīng)用程序使用了這種通知模型,您可能要為每個(gè)查看器添加一個(gè)域偵聽器。當(dāng)該偵聽器接收到更改時(shí),它將查找受影響的 EditPart,然后適當(dāng)?shù)刂匦路峙稍摳摹H绻膽?yīng)用程序使用了分布式通知,那么每個(gè) EditPart 通常都將把自己的偵聽器添加到任何一個(gè)影響它的模型對(duì)象。
![]() ![]() |
![]()
|
下一步是決定將如何使用來(lái)自 Draw2D 插件的圖形顯示您的模型。某些圖形可直接用來(lái)顯示模型的某個(gè)對(duì)象。例如,Label 圖形可用來(lái)顯示 Image 和 String。有時(shí)候,通過組合多個(gè)圖形、布局管理器和/或邊框可以獲得期望的結(jié)果。最后,您可能要編寫自己的圖形實(shí)現(xiàn),該實(shí)現(xiàn)以特定于您應(yīng)用程序的方式繪圖。
有關(guān)組合或?qū)崿F(xiàn)圖形和布局的更多信息可在 Draw2D 開發(fā)人員指南中找到,該指南包含在 GEF SDK 中。
在和 GEF 一起使用 Draw2D 時(shí),通過遵循下列方針,可以使您的項(xiàng)目更便于管理,并且可以更靈活地更改需求:
-
不要從頭做起。您可以組合所提供的布局管理器以呈現(xiàn)大多數(shù)東西。請(qǐng)考慮使用工具欄布局(在垂直或水平方向上)和邊框布局的組合來(lái)組合多個(gè)圖形。只有在萬(wàn)不得已時(shí)才編寫自己的布局管理器。作為參考,請(qǐng)查看 GEF 中提供的調(diào)色板。該調(diào)色板是使用 Draw2D 中的許多標(biāo)準(zhǔn)圖形和布局呈現(xiàn)的。
-
保持 EditPart 和圖形之間“徹底”的分離。如果您的 EditPart 使用了幾個(gè)圖形、布局和/或邊框的復(fù)合結(jié)構(gòu),那么請(qǐng)盡量對(duì) EditPart 隱藏詳細(xì)信息。讓 EditPart 自己構(gòu)建所有東西是可能的(但不是個(gè)好主意)。不過這樣做并不會(huì)導(dǎo)致控制器和視圖之間“徹底”分離。EditPart 非常熟悉圖形結(jié)構(gòu),因此以類似的 EditPart 重用該結(jié)構(gòu)是不可能的。此外,更改外觀或結(jié)構(gòu)可能會(huì)導(dǎo)致意想不到的錯(cuò)誤。
替代方法是,您應(yīng)當(dāng)編寫自己的 Figure 子類,該子類掩藏了圖形結(jié)構(gòu)的詳細(xì)信息。然后定義這個(gè)子類最少數(shù)量的 API,EditPart(控制器)用這些 API 來(lái)更新視圖。這種實(shí)踐(稱為 關(guān)注分離(separation of concerns))可提高重用機(jī)會(huì)并使錯(cuò)誤更少。 -
不要從圖形引用模型或 EditPart。圖形不應(yīng)該具有對(duì) EditPart 或模型的訪問權(quán)。在某些情形中,EditPart 可能會(huì)將自己作為偵聽器添加到圖形,但是只會(huì)認(rèn)為它是偵聽器,而不是 EditPart。這種去耦合(de-coupling)實(shí)踐也可以產(chǎn)生更多的重用機(jī)會(huì)。
- 使用內(nèi)容窗格。有時(shí)候您擁有一個(gè)容器,該容器將包含其它圖形元素,但是您需要在容器四周進(jìn)行一些裝飾。例如,一個(gè) UML 類通常顯示為框,其頂部標(biāo)有類名,可能還有一些原型,而底部是為屬性和方法保留的。通過組合多個(gè)圖形可以做到這一點(diǎn)。第一個(gè)圖形是類的標(biāo)題框,而另一個(gè)圖形被指派為 內(nèi)容窗格。該圖形將最終包含表示屬性和方法的圖形。稍后在編寫 EditPart 實(shí)現(xiàn)時(shí),并不一定要表明應(yīng)該將內(nèi)容窗格用作所有子元素的父元素。
![]() ![]() |
![]()
|
接下來(lái)我們將利用控制器(即 EditPart)將模型和視圖聯(lián)接起來(lái)。該步驟在 GEF 中放置“框架”。所提供的類是抽象的,因此客戶實(shí)際上必須編寫代碼。結(jié)果證明,生成子類不僅是人們熟悉的方法,而且可能也是將模型映射到視圖最靈活和簡(jiǎn)單的方法。
所提供的用于生成子類的基本實(shí)現(xiàn)有三種。對(duì)于出現(xiàn)在樹查看器中的 EditPart 使用 AbstractTreeEditPart
。圖形查看器中的繼承 AbstractGraphicalEditPart
和 AbstractConnectionEditPart
。本文將著重討論圖形 EditPart。相同的原理同樣適用于樹查看器。
在編寫您的 EditPart 之前,了解它們來(lái)自哪里,以及當(dāng)不再需要它們時(shí)怎樣處理它們,這是有幫助的。每個(gè)查看器都配置有一個(gè)用于創(chuàng)建 EditPart 的工廠(factory)。當(dāng)您設(shè)置查看器的內(nèi)容時(shí),通過提供表示該查看器輸入的模型對(duì)象,可以做到這一點(diǎn)。輸入通常是最頂部的模型對(duì)象,通過該對(duì)象可遍歷其它所有對(duì)象。然后查看器可以使用自己的工廠來(lái)構(gòu)造用于該輸入對(duì)象的 內(nèi)容 EditPart。之后,查看器中的每個(gè) EditPart 將填充和管理其自己的子 EditPart(和連接 EditPart),當(dāng)需要新的 EditPart 時(shí),將委派給 EditPart 工廠,直到填充該查看器。當(dāng)用戶添加新的模型對(duì)象時(shí),包含這些對(duì)象的 EditPart 將通過構(gòu)造相應(yīng)的 EditPart 做出響應(yīng)。請(qǐng)注意,視圖的構(gòu)造與 EditPart 的構(gòu)造是同時(shí)進(jìn)行的。因此,構(gòu)造每個(gè) EditPart 并將它添加到它的父 EditPart 之后,視圖(不管是圖形還是樹項(xiàng))也會(huì)發(fā)生同樣的過程。
一旦用戶除去與某些 EditPart 對(duì)應(yīng)的模型對(duì)象,就丟棄這些 EditPart。如果用戶撤銷了一個(gè)刪除操作,那么用于表示被恢復(fù)對(duì)象而重新創(chuàng)建的 EditPart 與原先的 EditPart 是不同的。這就是為什么 EditPart 不能包含長(zhǎng)期信息,以及為什么不應(yīng)由命令引用的原因。
您的第一個(gè) EditPart:內(nèi)容 EditPart
您編寫的第一個(gè) EditPart 是對(duì)應(yīng)于圖本身的 EditPart。這個(gè) EditPart 稱為查看器的 內(nèi)容。它對(duì)應(yīng)于模型中最頂部的元素,并且其父元素為查看器的 根EditPart(請(qǐng)參閱圖 4)。根通過提供各種圖形層(例如連接層和句柄層等)以及可能會(huì)在查看器級(jí)別提供的視圖縮放或其它功能,為內(nèi)容打下基礎(chǔ)。請(qǐng)注意,根的功能不依賴于任何模型對(duì)象,GEF 為根提供了幾個(gè)現(xiàn)成的實(shí)現(xiàn)。
內(nèi)容的圖形不是很有趣,并且它通常只是一個(gè)空面板,該面板將包含圖的子圖。它的圖形應(yīng)該為不透明類型(opaque),并且應(yīng)當(dāng)利用布局管理器進(jìn)行初始化,該布局管理器將對(duì)圖的子圖進(jìn)行布局。但是,它將擁有結(jié)構(gòu)。圖的直系子圖是由返回的子模型對(duì)象列表確定的。清單 1 顯示了一個(gè)樣本內(nèi)容 EditPart,它創(chuàng)建了一個(gè)不透明類型的圖形,后者將使用 XYLayout 定位其子圖。
清單 1. 內(nèi)容 EditPart 的初始實(shí)現(xiàn)
|
要確定圖上的項(xiàng),需要實(shí)現(xiàn)方法 getModelChildren()
。該方法返回子模型對(duì)象的列表(例如圖中的節(jié)點(diǎn))。超類將使用這個(gè)模型對(duì)象列表來(lái)創(chuàng)建對(duì)應(yīng)的 EditPart。新創(chuàng)建的 EditPart 被添加到部件的子 EditPart 列表。這樣又會(huì)將每個(gè)子 EditPart 的圖形添加到示例圖。缺省情況下,將返回一個(gè)空的列表,這表明沒有子對(duì)象。
其余的 EditPart(表示圖中的項(xiàng))可能擁有要以圖形方式顯示的數(shù)據(jù)。它們可能還擁有自己的結(jié)構(gòu),例如連接或自己的子 EditPart。許多 GEF 應(yīng)用程序利用由標(biāo)簽注明的圖標(biāo)之間的連接來(lái)描述這些圖標(biāo)。讓我們假定您的 EditPart 將使用 Label 作為它的圖形,并且您的模型提供了名稱、圖標(biāo)以及與標(biāo)簽之間的連接。清單 2 顯示了實(shí)現(xiàn)這種類型 EditPart 的第一次嘗試。
清單 2. “節(jié)點(diǎn)”EditPart 的初始實(shí)現(xiàn)
|
這里覆蓋了一個(gè)新方法 refreshVisuals()
。當(dāng)需要利用來(lái)自模型的數(shù)據(jù)更新圖形時(shí),就調(diào)用該方法。在本案例中,模型的名稱和圖標(biāo)被反映在標(biāo)簽中。但更為重要的是,該標(biāo)簽是通過將其布局約束傳遞給父元素來(lái)定位的。在內(nèi)容 EditPart 中,我們使用了 XY 布局管理器。該布局使用 Rectangle 約束來(lái)確定在何處放置子圖形。寬和高的值為“-1”,表明應(yīng)當(dāng)為該圖提供理想的大小。
![]() |
|
方法 refreshVisuals()
僅在 EditPart 初始化的過程中調(diào)用一次,并且決不會(huì)被再次調(diào)用。在響應(yīng)模型通知時(shí),應(yīng)用程序負(fù)責(zé)根據(jù)需要再次調(diào)用 refreshVisuals()
以更新圖形。要改進(jìn)性能,您可能希望將每個(gè)模型屬性的代碼分解成其自己的方法(或者是一個(gè)帶有“開關(guān)(switch)”的方法)。這樣,當(dāng)模型發(fā)出通知時(shí),可以運(yùn)行最少的代碼以便只刷新那些發(fā)生更改的內(nèi)容。
另一個(gè)有趣的區(qū)別是連接支持的代碼。與 getModelChildren()
類似, getModelSourceConnections()
和 getModelTargetConnections()
應(yīng)當(dāng)返回表示節(jié)點(diǎn)之間連接的模型對(duì)象。超類在必要時(shí)創(chuàng)建對(duì)應(yīng)的 EditPart,并將它們添加到源和目標(biāo)連接 EditPart 列表。請(qǐng)注意,連接是由每端的節(jié)點(diǎn)引用的,而其 EditPart 只需創(chuàng)建一次。GEF 確保只創(chuàng)建一次連接,該工作是通過首先檢查查看器中是否已經(jīng)存在連接來(lái)完成的。
![]() ![]() |
![]()
|
編寫連接 EditPart 實(shí)現(xiàn)沒有太大的區(qū)別。首先生成 AbstractConnectionEditPart
的子類。跟前面一樣,可以實(shí)現(xiàn) refreshVisuals()
,以將屬性從模型映射到圖形。連接可能還擁有約束,盡管這些約束與前面的約束略有不同。這里,連接路由器使用約束來(lái)使連接轉(zhuǎn)向(bend)。此外,連接 EditPart 的圖形必須是 Draw2D Connection
,它引入了另一個(gè)需求:連接錨(connection anchor)。
連接必須由 ConnectionAnchor
“錨定”在兩端。因此,必須在連接 EditPart 中或在節(jié)點(diǎn)實(shí)現(xiàn)中表明使用哪些錨。缺省情況下,GEF 假定節(jié)點(diǎn) EditPart 將通過實(shí)現(xiàn) NodeEditPart
接口而提供錨。這樣假定的一個(gè)原因是,錨的選擇取決于各端上的節(jié)點(diǎn)正在使用的圖形。連接 EditPart 不應(yīng)了解節(jié)點(diǎn)正在使用的圖形的任何內(nèi)容。另一個(gè)原因是,當(dāng)用戶創(chuàng)建連接時(shí),連接 EditPart 是不存在的,因此節(jié)點(diǎn)必須能夠自己顯示反饋。作為清單 2 的延續(xù),我們?cè)谇鍐?3 中添加了必要的錨支持。
清單 3. 將錨支持添加到“節(jié)點(diǎn)”EditPart
|
![]() |
|
以連接(connection)為參數(shù)的方法是對(duì)現(xiàn)有連接 EditPart 設(shè)置錨時(shí)使用的方法。其它兩個(gè)方法以請(qǐng)求(request)作為參數(shù)。這些方法是用戶創(chuàng)建新連接時(shí)的編輯過程中使用的。對(duì)于本示例,所有情形都將返回 chopbox 錨。chopbox 錨只查找線與節(jié)點(diǎn)圖形的邊框相交的點(diǎn)。
實(shí)現(xiàn)連接 EditPart 是比較簡(jiǎn)單的。請(qǐng)注意,甚至無(wú)需創(chuàng)建圖形,因?yàn)槿笔〉?PolylineConnection
創(chuàng)建適合于大多數(shù)場(chǎng)合(請(qǐng)參閱清單 4)。
清單 4. 初始的連接 EditPart 實(shí)現(xiàn)
|
![]() |
|
創(chuàng)建 EditPart 之后,它應(yīng)該開始偵聽來(lái)自模型的更改通知。由于 GEF 是與模型無(wú)關(guān)的,因此所有應(yīng)用程序都必須添加自己的偵聽器,并處理產(chǎn)生的通知。接收到通知時(shí),處理程序可以調(diào)用某個(gè)提供的方法來(lái)強(qiáng)制進(jìn)行一次刷新。例如,如果刪除了一個(gè)子模型對(duì)象,那么調(diào)用 refreshChildren()
將導(dǎo)致對(duì)應(yīng)的 EditPart 及其圖形被除去。對(duì)于簡(jiǎn)單的屬性更改,可以使用 refreshVisuals()
。正如我們前面提及的,可將該方法分解成幾個(gè)部分,從而避免沒有必要地更新每個(gè)顯示的屬性。
添加偵聽器但卻忘記除去它們是導(dǎo)致內(nèi)存泄漏的常見原因。出于這個(gè)原因,添加和除去偵聽器的地方應(yīng)該在 API 中清晰地注明。您的 EditPart 必須繼承 activate()
,以便添加稍后必須除去的任何偵聽器。通過繼承 deactivate()
可除去那些相同的偵聽器。清單 5 顯示了向節(jié)點(diǎn) EditPart 實(shí)現(xiàn)添加的模型通知內(nèi)容。
清單 5. 偵聽“節(jié)點(diǎn)”EditPart 中的模型更改
|
到目前為止,我們已經(jīng)講解了如何創(chuàng)建 EditPart,它們?nèi)绾蝿?chuàng)建自己的可視圖(visual)以及當(dāng)模型發(fā)生變化時(shí)它們?nèi)绾巫晕腋隆3酥猓珽ditPart 也是對(duì)模型進(jìn)行更改的主要參與者。當(dāng)命令的請(qǐng)求被發(fā)送給 EditPart 時(shí)就會(huì)發(fā)生這種情況。請(qǐng)求還用來(lái)要求 EditPart 顯示諸如在鼠標(biāo)拖動(dòng)期間發(fā)生的反饋。EditPart 支持、阻止或忽略給定的請(qǐng)求。所支持或阻止的請(qǐng)求類型決定了 EditPart 的行為。
到目前為止,側(cè)重點(diǎn)都是將模型的結(jié)構(gòu)和特性映射到視圖。結(jié)果表明,這基本上是您在 EditPart 類自身中所做的所有工作。其行為是由一組名為 EditPolicies 的可插入的助手類決定的。在所提供的示例中,我們忽略了方法 createEditPolicies()
。一旦您實(shí)現(xiàn)該方法,您就幾乎已經(jīng)完成了您的 EditPart。當(dāng)然,您仍需要提供編輯策略,該策略知道如何修改您應(yīng)用程序的模型。
因?yàn)榫庉嬓袨槭强刹迦氲模栽陂_發(fā)各種 EditPart 實(shí)現(xiàn)時(shí),可以根據(jù)將模型映射到視圖和處理模型更新這種任務(wù),來(lái)創(chuàng)建類層次結(jié)構(gòu)。
![]() ![]() |
![]()
|
現(xiàn)在,您已經(jīng)完成了以圖形方式顯示您的模型所需的所有部分。對(duì)于最后的組裝,我們將使用 IEditorPart
。但是,也可以在視圖、對(duì)話框或者可以放置控件的幾乎任何地方使用 GEF 的查看器。對(duì)于本步驟,您必須擁有自己的 UI 插件,它將為正在打開的資源定義編輯器和文件擴(kuò)展名。可在同一個(gè)插件或一個(gè)不同的插件中定義您的模型。您還需要一個(gè)預(yù)填充的模型,因?yàn)槟壳斑€沒有編輯功能。
提供樣本模型數(shù)據(jù)的方法有幾種。對(duì)于本示例而言,當(dāng)編輯器打開時(shí),我們將在代碼中創(chuàng)建模型,從而忽略了文件的實(shí)際內(nèi)容。要做到這一點(diǎn),我們假定已經(jīng)存在一個(gè)測(cè)試工廠。或者,您可以創(chuàng)建一個(gè)示例向?qū)В撓驅(qū)в脭?shù)據(jù)對(duì)資源進(jìn)行預(yù)填充(普通向?qū)е粍?chuàng)建空?qǐng)D)。最后,您可以利用文本編輯器以手工方式編寫文檔的內(nèi)容。
既然您有了樣本模型,那么讓我們創(chuàng)建將顯示模型的編輯器部件。有一種快速的方法,就是生成子類或復(fù)制 GEF 的 GraphicalEditor
。該類創(chuàng)建 ScrollingGraphicalViewer
的一個(gè)實(shí)例,并且構(gòu)造一個(gè)畫布來(lái)充當(dāng)編輯器的控件。它是一個(gè)很方便的類,用來(lái)幫助您開始使用 GEF;一個(gè)可以正確工作的 Eclipse 編輯器需要考慮很多其它事情,例如不利的團(tuán)隊(duì)環(huán)境(pessimistic team environment)和要?jiǎng)h除或移動(dòng)資源等。
清單 6 顯示了一個(gè)樣本編輯器實(shí)現(xiàn)。有幾個(gè)必須實(shí)現(xiàn)的抽象方法。出于本文所討論范圍的限制,我們將忽略模型持久性和標(biāo)記。要讓您的圖出現(xiàn)在圖形查看器中,您必須做兩件事情。首先,利用自己的 EditPart 工廠配置查看器,以從第 3 步構(gòu)造 EditPart。然后,將圖模型對(duì)象傳遞給查看器。
清單 6. 實(shí)現(xiàn)您的編輯器部件(Editor Part)
|
![]() ![]() |
![]()
|
我們已經(jīng)經(jīng)歷了從僅擁有一個(gè)模型到在圖形編輯器中顯示該模型的全過程。但是我們只打下了基礎(chǔ)。我們簡(jiǎn)要提及了編輯策略。通過閱讀與 GEF SDK 一起提供的開發(fā)人員文檔,可以獲得有關(guān)編輯策略的更多信息。還可從 GEF 的主頁(yè)(請(qǐng)參閱文章結(jié)尾的 參考資料)獲得一個(gè)示例,該示例演示了如何使用各種編輯策略類型。
GEF 還提供了一個(gè)調(diào)色板。該調(diào)色板顯示了一組工具,用于在圖中創(chuàng)建對(duì)象。用戶可以激活這些工具,或者使用本機(jī)拖放直接從該調(diào)色板拖動(dòng)項(xiàng)。它還支持讓用戶定制內(nèi)容。
在 GEF 中還可以使用幾個(gè) JFace 操作。應(yīng)用程序可以在菜單、工具欄或上下文菜單中使用諸如撤銷、對(duì)齊和刪除之類的操作。
最后,您的應(yīng)用程序應(yīng)當(dāng)支持大綱(outline)視圖和特性(properties)視圖。大綱視圖用于導(dǎo)航和有限的編輯用途。GEF 的 TreeViewer 和/或概述(overview)窗口可以在這里使用。特性表(property sheet)允許用戶查看和編輯任何當(dāng)前選定項(xiàng)的詳細(xì)特性。
為了顯示所選擇的項(xiàng)并允許用戶進(jìn)行更改,您必須將編輯策略添加到 EditPart。請(qǐng)參閱 GEF 主頁(yè)上的示例,并參閱與 GEF SDK 一起提供的開發(fā)人員文檔。
有關(guān) GEF 和 Eclipse 工作臺(tái)提供的其它功能的詳細(xì)信息不在本文的討論范疇之內(nèi),但是您可能有興趣對(duì)它們稍做了解:
- 調(diào)色板。該工具的調(diào)色板是用于在圖中創(chuàng)建新對(duì)象的 實(shí)際方法。GEF 包含了一個(gè)功能豐富的調(diào)色板,它支持拖放、多繪圖程序和布局設(shè)置,如果應(yīng)用程序希望,它甚至可支持讓用戶定制內(nèi)容。
- 操作欄。編輯器(Editor)和視圖(View)可以為工具欄、菜單和上下文菜單提供操作(Action)。GEF 提供了幾個(gè)可重用的操作實(shí)現(xiàn),但是將它們顯示在什么地方取決于應(yīng)用程序。
- 特性表。特性表可用于顯示所選項(xiàng)特性的詳細(xì)信息。GEF 允許您在 EditPart 上或在模型中添加特性表支持。
- 大綱。大綱視圖通常用于顯示圖的結(jié)構(gòu)化表示,但是一般來(lái)說(shuō),它可用于任何工作。GEF 的 TreeViewer 通常在大綱視圖中使用。
![]() ![]() |
![]()
|
- 您可以參閱本文在 developerWorks 全球站點(diǎn)上的 英文原文.
- 請(qǐng)?jiān)?GEF 主頁(yè)上下載插件并查找有關(guān) GEF 的其它信息。
-
GEF 新聞組
是查找答案和進(jìn)行提問的極佳場(chǎng)所。
-
Eclipse 項(xiàng)目
主管著 Eclipse 工作臺(tái)、GEF 和其它開放源碼技術(shù)。
- 請(qǐng)?jiān)?developerWorks上瀏覽 針對(duì)開發(fā)人員的其它 Eclipse 文章。
![]() ![]() |
![]()
|
![]() |
||
|
![]() |
Randy Hudson 是北卡羅來(lái)納州 Research Triangle Park 的 IBM 軟件工程師。作為圖形編輯框架(Graphical Editing Framework,GEF)的技術(shù)領(lǐng)導(dǎo),他幫助將這個(gè)曾經(jīng)是內(nèi)部的項(xiàng)目轉(zhuǎn)變成了開放源碼技術(shù)。他目前的工作側(cè)重于可用性、圖形編輯、圖形布局和邊緣路由(edge routing)。可以通過 buchu at nc.rr.com與 Randy 聯(lián)系。 |
from: http://www-128.ibm.com/developerworks/cn/linux/opensource/os-gef/index.html
posted on 2006-09-04 10:57 weidagang2046 閱讀(318) 評(píng)論(0) 編輯 收藏 所屬分類: Java