很久很久以前

            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
            34 隨筆 :: 4 文章 :: 17 評論 :: 0 Trackbacks

          #

          上文已經說過了,GMF中,那些generator,definition,mapping model都是最后要合成為diagram runtime(or notation)model。
          以下是簡單的步驟:
          簡單的使用方法,首先應該定義ecore模型文件有很多種方法,比如用EclipseUML插件,或者使用gmf的example種的Ecore Diagram,這些圖形化的類圖編輯工具都可以方便的生成我們所需要的Ecore文件。這里我們使用的是EclipseUML的免費版本。是針對eclipse3.1的,不過好像3.2m1m2都可以用。
          生成ecore文件后 File/new/other/Eclipse Modeling Framwork/EMF Model 生成相應的genmodel文件,通過它來生成模型和.edit插件,這些都是GMF所需要的。然后再File/New/other/Example EMF Model Creation Wizards/GMFGraph Model 注意名字應該都是一樣的(擴展名不同)最后的Model Object選擇Canvas。在生成的gmfgraph文件中給canvas命名,canvas就相當于我們的畫布。在canvas下創建一個figure gallery(圖庫),在這里我們保存所需要的圖形。
          然后創建gmftool文件File/New/other/Example EMF Model Creation Wizards/GMFTool Model,可以使用File/New/other/GMF/GMFTool Simple Model來簡單的構造。
          再創建gmfmap文件,建立模型和圖形之間的映射關系。File/New/other/Example EMF Model Creation Wizards/GMFMap Model,名字應該和前面的一樣,最后的Model Object選擇Mapping。在生成的gmfmap文件中右鍵選擇Load Resource,選擇ecore,gmfgraph,gmftool文件。并且生成相應的映射信息,比如node mapping和canvas mapping。
          最后生成emf模型代碼和edit代碼,使用genmodel文件。
          使用gmfmap文件右鍵生成gmfgen文件,注意我們要有genmode文件才能生成gmfgen文件。
          最后用gmfgen生成editor插件。這時候共有三個插件 模型 edit和editor。
          使用時File/New/other/Example/中有個相應的diagram,一般再最上面,給一個名字,無擴展名,就打開相應的編輯器了。
          posted @ 2006-02-15 10:37 Long Long Ago 閱讀(979) | 評論 (1)編輯 收藏

          GMF有可能成為一個標準的Eclipse圖形模型編輯器,它分為兩個部分:運行時(the runtime)和工具(tooling),工具是由一些創建和編輯符號語義模型的編輯器組成的,工具還包含了圖形編輯器,并且有圖形編輯器的生成器。

          使用GMF開發一個類圖形模型編輯器的步驟如下:

          1。創建域模型,這個模型描述了通過編輯器編輯的非圖形信息。
          2。創建圖定義模型,這個模型描述了顯示在圖形編輯器中的圖形元素。
          3。創建圖映射模型,這個模型定義了域模型元素和圖形元素之間的對應關系。
          4。生成圖形編輯器。
          5。通過改進生成的代碼來提高圖形編輯器。
          介紹一點GMF的圖形編輯器的特性:
          1。折疊
          2。label的直接編輯
          3。提示
          4。彈出bar
          5。連接柄
          6。通用繪圖工具
          7。通用菜單命令
          8。通用工具條
          9。自動縮放和布局
          10。通用屬性編輯
          11。打印和打印預覽
          12。SVG和剪貼板支持

          http://www.eclipse.org/articles/Article-Introducing-GMF/article.html

          posted @ 2006-02-14 11:38 Long Long Ago 閱讀(1182) | 評論 (0)編輯 收藏

          uo       最近在學習GEF,本例子主要是修改了八進制的例子。在這里做一下總結。先來介紹一下gef,網上關于GEF的介紹越來越多,從另一方面也說明這個技術確實在熱起來,不過GEF為了實現可擴放性和可重用性,做的很是復雜(閑話一下,最近看了一本書《Better.Faster.Lighter.Java》,沒看多少,Justin Gehtland, Bruce A. Tate寫的,一開始就說了,為了滿足越來越多的需要,各種framework,library,language都是越來越復雜了,學習曲線也變得陡峭了,這個似乎是無法避免的,java語言也是,不信去看看jdk,1.1時才3.7MB,1.4時已經38MB了。我也一直堅信,Simply the best,呵呵)。
                 GEF的一些資源:
                    1。www.eclipse.org 這個是源頭啊,faq也可以看看 
                    2。ibm的dW 除了相關文章,這里還有本關于gef和emf的紅寶書,可以免費下載
                    3。eclipseworld.org 這個是一個關于eclipse中文社區
                    4。八進制的blog http://bjzhanghao.cnblogs.com/ 。
                    5。這里還有些中文教程 http://www.benisoft.com/cn/index.htm
                    6。還有一些blog http://www.aygfsteel.com/hopeshared/  http://www.aygfsteel.com/eclipshine/ http://www.aygfsteel.com/reloadcn/ http://www.aygfsteel.com/USTCEric
                好了,現在來介紹一下GEF的實現機制,主要是我的一些理解可能還有一不對的地方,歡迎大家幫我改正。
                GEF是具有標準MVC(Model-View-Control)結構的圖形編輯框架,其中Model由我們自己根據業務來設計,它要能夠提供某種模型改變通知的機制,用來把Model的變化告訴Control層;Control層由一些EditPart實現,EditPart是整個GEF的核心部件;而 View層,大多數情況下,使用Draw2D實現了,其作用是把Model以圖形化的方式表現給使用者,當然你也可以使用其他圖形包,不過gef與 Draw2D的結合還是非常緊密的,一般為了使用方便,View都是使用Draw2D實現的。
                  關于Draw2D,八進制有一篇相應的文章,還有eclipse上的一篇文章,可以參考,這里有幾點需要強調一下:
                   1。Draw2D提供了很多缺省圖形,最常見的有三類:1、形狀(Shape),如矩形、三角形、橢圓形等等;2、控件(Widget),如標簽、按鈕、滾動條等等;3、層(Layer),它們用來為放置于其中的圖形提供縮放、滾動等功能。
                  2。每個圖形都可以擁有一個邊框(Border),Draw2D所提供的邊框類型有GroupBoxBorder、TitleBarBorder、ImageBorder、 ButtonBorder,以及可以組合兩種邊框的CompoundBorder等等,在Draw2D里還專門有一個Insets類用來表示邊框在圖形中所占的位置,它包含上下左右四個整型數值。
                  3。一個圖形可以包含很多個子圖形,這些被包含的圖形在顯示的時候必須以某種方式被排列起來,負責這個任務的就是父圖形的LayoutManager,相應的約束(Constraint)對象就在這里,比如在子圖形刷新(refreshVisuals)時可以通過將其布局約束傳遞給其父元素來定位。
                  4。利用Draw2D中的Router、Anchor和Locator,可以實現多種連接樣式。Router負責連接線的外觀和操作方式;Anchor控制連接線端點在圖形上的位置,即"錨點"的位置;Locator的作用是定位圖形。
                  前面說過了GEF是通過MVC架構實現的,下面分別介紹這三個方面:
                  一、模型(Model):這個是相對比較容易理解,模型保存著業務邏輯,他是GEF這中唯一可以持久化的,并且需要提供相應的監聽機制,來通知 EditPart去更新View,監聽機制又可以分為分布式和集中式兩種,我們可以針對域監聽器進行轉有通知,也可以全局廣播;在這里我們認為 Command(EditPart用來更新模型的對象)也是模型的一個部分,因為它了解模型。此外,在有時候可能需要多種模型。我們對于業務模型,提供一個“視圖”模型,這樣便于實現和滿足相應的要求,不管內部模型是怎么樣的,都要實現通知機制。
                二、視圖。GEF提供了在EclipseWorkbench中使用Viewer,稱為EditPartViewer。它的作用和jface中的 Viewer很相,不過這時候它的ContentProvider和LabelProvider是EditPart,通過setContents設置(注意在八進制代碼中setContents參數為模型對象,通過分析發現,在AbstractEditPartViewer中此方法被重載,可以除了接受 org.eclipse.gef.editpart對象外可以接受Object對象,不過此時回調用EditPartFactory,通過給定的模型對象來創建相應的EditPart,個人認為這樣做并不與“View與Model無直接聯系”的要求相矛盾)。這個接口繼承了 org.eclipse.jface.viewers.ISelectionProvider接口(這個也和jface中的viewer一樣),因此使 viewer提供了監聽器,這樣可以將對view的操作傳遞到editpart。EditPartViewer會維護各個EditPart的選中狀態,如果沒有被選中的EditPart,則缺省選中的是作為contents的EditPart。
                   EditPartViewer可以適配到任何一個SWT控件,因為它要求有createControl方法,接受一個父SWT控件作為適配對象,從而將 GEF生成的Figure對象顯示在這個SWT控件上,因此GEF可以使用任何圖形包,不過GEF提供了對Draw2D的默認實現,比如 AbstractGraphicalEditPart類中的回調方法createFigure就要求返回一個IFigure對象。將一個GEF圖形顯示出來可以使用org.eclipse.ui.part.EditorPart也可以是org.eclipse.ui.part.ViewPart,如果使用 EditorPart,則需要實現繼承自WorkbenchPart的createPartControl,如果是ViewPart則需要自己實現與 GEF的交互,不過Eclipse Workbench對viewpart和editorpart的支持是一樣的,都是在plugin文件擴展相應的擴展點。一般來說,使用GEF對 Editorpart的模式實現是非常方便的。
                GEF目前提供兩種視圖分別是GraphicalViewer和TreeViewer,都間接繼承了EditPartViewer接口,前者利用 Draw2D圖形(IFigure)作為表現方式,多用于編輯區域,后者則多用于實現大綱展示,并且他們有兩個具體的實現,分別是 ScrollingGraphicalViewer和TreeViewer。其中ScrollingGraphicalViewer,通過分析GEF源代碼可知,是GraphicalEditor中Viewer的默認實現,我們可以通過GraphicalEditor類提供的 setGraphicalViewer(GraphicalViewer)方法重新設置其他viewer。我們在使用的時候通過 configureGraphicalViewer和initializeGraphicalViewer方法來配置GraphicalViewer。所不同的是,在configureGraphicalViewer之后initializeGraphicalViewer之前插入了一個 hookGraphicalViewer方法,其作用是同步選擇和把 EditPartViewer作為SelectionProvider注冊到所在的site,使其成為SelectionProvider。
                 此外,GEF中還提供一種成為調色板(PaletteViewer)的視圖,它也是間接實現了EditPartViewer接口。因此,我也像配置GraphicalViewer一樣來配置PaletteViewer,類似的使用 configurePaletteViewer和initializePaletteViewer方法,其間類似的插入了一個 hookPaletteViewer方法,用于設置相應EditDomain的PaletteViewer。
                 最后,總結一下如何配置GraphicalView,主要是四個方面:
                1。設置一個RootEditPart:RootEditPart的是使整個GEF框架運行起來的關鍵之一。RootEditPart并不對應于任何的模型對象,它將從setContents()方法中接收到的模型對象進行轉換,并添加到整個的EditPart體系中去。
                 2。設置其EditPartFactory:負責從模型到EditPart的轉換。一般來說一個模型對象對應于一個EditPart。
                 3。設置EditDomain:用來接收事件并選擇恰當的事件處理函數進行處理,這個主要是為了相應view所接收到的用戶的操作。
                 4。調用setContents()方法:為其設置要顯示的內容。
                 三、控制器(EditPart)。這是GEF最核心的地方了,它將model和view聯系起來。程序員可以繼承三種EditPart,分別是 org.eclipse.gef.editparts.AbstractGraphicalEditPart,org.eclipse.gef.editparts.AbstractConnectionEditPart(AbstractGraphicalEditPart的子類)和org.eclipse.gef.editparts.AbstractTreeEditPart。EditPart 的生命周期當setContents時,將模型對象輸入,此對象為頂層對象,通過它可以遍歷所有的模型對象。:EditPartViewer配備有 EditPartFactory,EditPartViewer通過EditPartFactory構造相應的Contents EditPart。然后EditPartViewer中的每個EditPart通過EditPartFactory構造相應的子EditPart。當用戶添加新的模型的時候,包含這些模型對象的所對應的EditPart將構造相應的EditPart作出相應。視圖的構造和EditPart的構造是同時進行的,每當EditPart構造并添加到它的父EditPart后相應的view也做同樣的事情,比如GraphicalEditor中就有 GraphicalViewer成員變量,在此edipart創建時回調用createPartControl,在這個方法中將會創建相應的view,并將其加入到父view中。
                 一旦用戶丟棄了某些模型對象,相應的EditPart就會被丟棄。比如用戶執行了刪除操作,則相應的模型對象和相應的EditPart都被刪除了,但用戶撤銷了刪除操作而重新創建的EditPart與原來的EditPart是不同的,所以EditPart是不能保存長期信息的,應該交給模型去保存,并且 EditPart也是不能被Command所引用。
              在具體使用時,應該先定一個Contents EditPart,它的父元素為EditPartViewer的RootEditPart。RootEditPart是EditPartView的 root,它將EditPartView和它的contents(一般認為是頂層模型對象所對應的EditPart)聯系起來,RootEditPart 為用戶的EditPart提供一致性的上下文(context)。并且,當沒有被選中的模型EditPart時,頂層對象的EditPart是默認被選中的,而RootEditPart是不能被選中的或者定位的,甚至不能與用戶相交互,他也就沒有對應的模型對象。GEF提供了幾個默認的 RootEditPart的實現:FreeformGraphicalRootEditPart,RootTreeEditPart, ScalableRootEditPart,ScalableFreeformRootEditPart(此類繼承于 FreeformGraphicalRootEditPart,增加了縮放Zoom支持,提供了ZoomManager;增加了一個LayerPane: ScalableFreeformLayeredPane。),(原來還有個GraphicalRootEditPart,已經deprecated,用 ScalableRootEditPart代替)。這里要注意的是:
              1)對于FreeformRootEditPart(以及它的子類 ScalableFreeformRootEditPart),它的Contents EditPart應該有一個org.eclipse.draw2d.FreeformFigure對象(比如FreeformLayer或FreeformLayeredPane)作為它的Figure。例如在我們的代碼里,對應的就是在 DiagramPart中的createFigure方法,它返回了一個FreeformLayer對象。
              2) FreeformGraphicalRootEditPart的Primery Layer沒有使用draw2d的LayoutManager,并且,除非contents的figure是個freeform figure,否則不能正確的調整大小。
              3)FreefromGraphicalRootEditPart使用FreeformViewport類作為它的primary figure,這個類必須和ScrollingGraphicalViewer使用。
              4)ScalableRootEditPart使用 Viewport作為primery figure,這個類必須和ScrollingGraphicalViewer使用。
              5)RootTreeEditPart是TreeViewer的RootEditPart。
              Contents EditPart的圖形一般是一個空面板,該面板將包含diagram的子圖。
              我們還要定義其他“視圖”模型的EditPart,比如節點(node),連接(connection)。對于節點,是Graphical,可以繼承 AbstractGraphicalEditPart。并且可以實現NodeEditPart接口,則可以支持源和目標的 ConnectionEditPart,使用Anchor,具體在下面有講述。在這里,我們的代碼的NodePart類中,重載了 refreshVisual方法,其中設置figure的布局約束是通過它的父元素來定位的,我不知道這是不是標準的方法,XYLayout使用的是 rectangle約束,如果長寬設為-1,表示為該圖形提供理想大小。不要使用setBounds,XYLayout布局管理器可以保證對滾動條進行更新,并能將相對約束轉化為絕對約束,如果長寬設置為-1,則能夠將圖形設置為理想的大小。此外,為了改進性能,我們可以將refreshVisual中有若干模型的分別刷新,或者設置是否需要刷新的開關。
              對于連接,可以繼承AbstractConnectionEditPart,這個抽象類已經實現了 ConnectionEditPart。和Node實現一樣,通過refreshVisual方法將屬性從模型映射到圖形。連接也可以有約束,不過與前面的約束不盡相同。在這里,連接路由器(connection router)使用約束來是連接轉向(bend)。需要注意的是,一個Connection EditPart的圖形必須是一個draw2d的Connection,這樣就引入了連接錨(Connection Anchor)。連接必須由連接錨(ConnectionAnchor)“錨定”在兩端。因此,需要在連接EditPart或者節點EditPart中實現使用什么樣的錨。缺省情況下,GEF使用節點EditPart通過實現NodeEditPart接口來提供錨。這是因為,錨的選擇取決與各個節點上正在使用的圖形,而連接EditPart不應了解節點上的圖形,并且,當用戶創建連接的時候,連接EditPart并沒有創建,這時候就由節點自己顯示反饋。這里需要注意的是:何時使用以及何時不使用ConnectionEditPart,當用戶可以選擇某些東西并可與之交互時,就需要 ConnectionEditPart。它可能與某行中的某個對象相對應,并且回自己刪除;如果這是需要一個繪制直線的節點或者容器,那么只需要用圖形的 paint方法繪制直線,或者組合一個圖形,這個圖形包含Polyline圖形。連接必須要擁有源和目標。如果要創建一個連接,并且在沒有源和目標存在的情況下,可以繼承AbstractGraphicalEditPart,并使用連接圖形,比如PolylineConnection。
              正如前面說的,模型需要實現某種通知機制,各個EditPart要將自己做為監聽者,注冊在模型上,以便在模型發生改變的時候收到相應的通知。   當EditPart收到相應的通知時,調用相應的處理方法,來進行一次強制的刷新,對于模型對象的增減可以調用refreshChildren方法,對于簡單屬性的更改可以調用refreshVisuals方法,這時,像前面提到的,可以只刷新改變的部分,以提高性能。一般,我們在Activate方法中注冊監聽器,在Deactivate方法中注銷監聽器。
              以上完成的是從模型到視圖的映射,你還需要實現的是編輯策略Edit Policies,因為EditPart并不直接對模型進行編輯,每一個EditPolicy都針對一個特定的編輯任務或者一組相關的工作。這樣的實現便于在不同的EditPart間重用(reuse)編輯行為,并且這樣的實現,可以動態的改變行為,比如改變layout或者routing時。在 createEditPolicies方法中,我們要insall我們的的Policies,這時候就需要roles,roles的作用就是作為關鍵字來標示不同的policies。policy中提供Command,每個應用程序都有個Command棧,Command的運行要通過Command棧,而不是直接調用execute方法。
              說到這里,要注意EditPartView是視圖的,一般放在一個UI插件上比如EditorPart,viewPart,甚至swt控件。EditPart是控制器,聯系視圖和模型。
              在本文的最后介紹一下GEF的運行機制:EditPartView接受用戶的操作,如節點的移動,增刪,每個節點對應一個EditPart對象,每個 EditPart都有一組由Role區分的EditPolicies,每個EditPolicy會對應一些Command對象,Command最終會對模型進行操作。用戶的操作會轉化為Request分配給特定的EditPolicy,由EditPolicy創建相應的Command對模型進行操作,這些 Command會保留在EditDomain的命令堆棧中,用于實現undo,redo功能,EditDomain是專門用于維護 EditPartView,Command信息的對象,一般每個EditPart有一個EditDomain。
              以上就是對所作的GEF部分的大概描述,可能有些地方寫的比較羅嗦,有的地方寫的也可能不對,希望大家指出,謝謝。下面還要對RCP部分進行一些描述。
          posted @ 2006-01-12 14:35 Long Long Ago 閱讀(3880) | 評論 (0)編輯 收藏

          考試結束后,打算將用rcp 實現的vivi寫一下,同時還有用rcp wrap 的gef
          posted @ 2006-01-03 21:03 Long Long Ago 閱讀(187) | 評論 (0)編輯 收藏

          僅列出標題
          共4頁: 上一頁 1 2 3 4 
          主站蜘蛛池模板: 综艺| 上虞市| 太谷县| 汪清县| 中江县| 广南县| 呼图壁县| 子洲县| 明星| 达日县| 石景山区| 包头市| 甘南县| 交口县| 松阳县| 长泰县| 南安市| 藁城市| 托里县| 福贡县| 宝兴县| 华容县| 通化县| 乡城县| 嘉荫县| 灵武市| 莲花县| 丹凤县| 增城市| 大厂| 定南县| 青川县| 松桃| 延寿县| 沅江市| 新丰县| 广宁县| 文山县| 弥勒县| 安西县| 彰化县|