首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

GEF 入門系列(一):Draw2D 圖形框架基礎

     編輯:Java 相關知識

關於 Java2D 大家不陌生,它是基於 AWT/Swing 的二維圖形處理包,JDK 附帶示例展示了 Java2D 強大能力。Draw2D 出現前,SWT 應用在這方面一直處於下風,而 Draw2D 這個 SWT 世界裡的 Java2D 改變了這形勢。

可能很多人不十分了解 GEF 和 Draw2D 關係:一些應用只使用 Draw2D,看起來卻和 GEF 應用有相似外觀。原因簡單解釋:

GEF 是具有標準 MVC 結構的圖形編輯框架,Model 由我們根據業務設計,需提供模型改變通知機制,把 Model 變化告訴 Control 層;Control 層由 EditPart 實現,EditPart 是 GEF 核心部件,機制和功能後續介紹;View 層(大多數情況)就是 Draw2D,作用是把 Model 以圖形化方式表現給使用者。雖然 GEF 可使用任何圖形包作為 View 層,但實際上 GEF 對 Draw2D 依賴很強。例如:EditPart 介面不要求引入 Draw2D 類,但最常用的 AbstractGraphicalEditPart 的 createFigure() 需返回 IFigure 類型。因此 GEF SDK 包含 Draw2D 包不奇怪,同樣道理,只有先了解 Draw2D 才可能掌握 GEF。

總結:Draw2D 是基於 SWT 的圖形處理包,適合作 GEF View 層。若應用僅需顯示圖形,只用 Draw2D 夠了;若模型要求以圖形化方式被編輯,最好用 GEF 框架。

Draw2D 結構

圖1 Draw2D 結構

Draw2D 通過 LightweightSystem(以下簡稱 LWS)與 SWT 中某個 Canvas 實例相連,此 Canvas 在 Draw2D 應用中一般是應用的 Shell,在 GEF 應用中多為某個 Editor 的 Control(createPartControl() 方法參數)。界面上雖看不到 LWS 存在,但其他所有可見圖形都放在它裡面,這些圖形按父子包含關係形成樹狀層次結構。

LWS 是 Draw2D 核心部件,包含三主要組成部分:RootFigure 是 LWS 中所有圖形根,其他圖形直接或間接放在其中;EventDispatcher 把 Canvas 上各種事件分派給 RootFigure,最終分派給適當圖形;注意此 RootFigure 和應用中最頂層 IFigure 不是同一對象,前者是看不見被 LWS 內部使用,後者通常是可見畫布,直接放在前者中;UpdateManager 用來重繪圖形,Canvas 被要求重繪時,LWS 調用其 performUpdate() 方法。

LWS 是連接 SWT 和 Draw2D 的橋梁,利用它不僅可輕鬆創建任意形狀圖形(不僅限於矩形),同時能節省系統資源(因是輕量級組件)。典型純 Draw2D 應用代碼結構類似:

// 創建 SWT Canvas(Shell 是 Canvas 子類)
Shell shell = new Shell();
shell.open();
shell.setText("A Draw2d application");
// 創建 LightweightSystem,放在 shell 上
LightweightSystem lws = new LightweightSystem(shell);
// 創建應用中最頂層圖形
IFigure panel = new Figure();
panel.setLayoutManager(new FlowLayout());
// 把圖形放置於 LightweightSystem 的 RootFigure 裡
lws.setContents(panel);
// 創建其他圖形,放置於應用頂層圖形中
panel.add();
while (!shell.isDisposed()) {
    if (!display.readAndDispatch())
        display.sleep();
}

圖形系統

Draw2D 圖形皆實現 IFigure(org.eclipse.draw2d.IFigure)介面,不僅是屏幕上形狀,除控制尺寸位置外,還可監聽圖形事件(滑鼠事件、圖形結構改變等,來自 LWS EventDispatcher)、設置滑鼠指針形狀、讓圖形變透明、聚焦等,每個圖形甚至擁有自己的 Tooltip,十分靈活。

Draw2D 提供許多預設圖形,常見三類:1、形狀(Shape),如矩形、三角形、橢圓等;2、控件(Widget),如標籤、按鈕、滾動條等;3、層(Layer),為其中圖形提供縮放、滾動等功能。GEF 3.0 新增 GridLayer 和 GuideLayer 實現「吸附到網格」功能。以 IFigure 為根節點類樹下有相當多類,組織感覺有些混亂,幸好大部分情況只用常用那部分。

圖2 一個 Draw2D 應用程序

每個圖形可擁有邊框(Border),Draw2D 提供邊框類型:GroupBoxBorder、TitleBarBorder、ImageBorder、ButtonBorder、可組合兩種邊框的 CompoundBorder 等。Draw2D 專門有 Insets 類表示邊框在圖形中佔位置,含上下左右四整型數值。

圖形可包含很多子圖形,顯示時必須以某種方式排列,負責此任務是父圖形的 LayoutManager。Draw2D 提供一系列可直接使用的 LayoutManager,如 FlowLayout 適合表格式排列,XYLayout 適合讓用戶隨意改變圖形位置等。若無適合應用的 LayoutManager,可自定義。每個 LayoutManager 包含某種算法,考慮與每個子圖形關聯的 Constraint 對象,計算得出子圖形最終位置和大小。

連接線實現

圖形化應用常見任務是在兩個圖形間做連接,如 UML 類圖連接線、程序流程圖數據流線條,它們外觀不同,有些連接線還顯示名稱,最好不交叉。利用 Draw2D Router、Anchor 和 Locator 可實現多種連接樣式:Router 負責連接線外觀和操作方式,最簡單設為 null(無 Router),使用直線連接;其他方式包括折線、具有控制點的折線等(見圖3),若想控制連接線不交叉也需在 Router 作文章。Anchor 控制連接線端點在圖形上位置(錨點),最易用是 ChopBoxAnchor,假設圖形中心為連接點,計算假想連線與圖形邊緣交匯點作為實際錨點;其他 Anchor 有 EllipseAnchor、LabelAnchor、XYAnchor 等;Locator 作用是定位圖形,如希望在連接線中點以標籤顯示名稱/作用,可用 MidpointLocator 定位標籤;其他有 ArrowLocator(定位可旋轉修飾如 PolygonDecoration)、BendpointerLocator(定位連接控制點)、ConnectionEndpointLocator(定位連接端點,通過指定 uDistance 和 vDistance 設置以端點為原點座標)。

圖3 三種 Router 外觀

此外,Draw2D 在 org.eclipse.draw2d.geometry 包提供幾個方便類型:Dimension、Rectangle、Insets、Point、PointList 等,廣泛用於 Draw2D 內部,也可供開發人員簡化計算。如 Rectangle 表示矩形區域,提供 getIntersection() 計算與另一矩形重疊區域、getTransposed() 得到長寬交換後矩形、scale() 進行矩形拉伸等。自行實現 LayoutManager 時涉及複雜幾何計算,更推薦使用這些類。

以上介紹 Draw2D 大部分功能,利用這些已能畫出漂亮圖形。但對大多數實際應用還遠不夠,還要能編輯並把修改反映到模型。為漂亮完成此艱巨任務,GEF 絕對不二之選。下次正式進入 GEF 世界。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved