GMF实例解析.docx
- 文档编号:25528965
- 上传时间:2023-06-09
- 格式:DOCX
- 页数:28
- 大小:744.30KB
GMF实例解析.docx
《GMF实例解析.docx》由会员分享,可在线阅读,更多相关《GMF实例解析.docx(28页珍藏版)》请在冰豆网上搜索。
GMF实例解析
GMF实例解析
前言
作为MVC架构的完美实现品,GEF(GraphicalEditorFramework)被广泛用于构建可视化的图形编辑器。
然而在完美地隔离了编辑器与模型的同时,也引入了大量的冗余代码和陡峭的学习曲线。
在更多的时候,我们需要联合使用GEF与EMF(EclipseModelingFramework),以便使用后者来构建后台模型。
但是将EMF和GEF框架整合在一起不是一件容易的事,我们通常需要花费很长时间去了解EMF的模型设计方法和GEF的MVC框架,于是GMF便应运而生。
GMF对EMF和GEF做了进一步的封装,提供了一套图形化的开发环境和运行时框架,使我们可以轻松开发基于EMF和GEF的图形化编辑器。
此外如有需要,我们仍然可以跳过GMF直接取用GEF和EMF的功能来完成GMF无法完成或效率不彰的任务。
虽然GMF的出现已经大大简化了我们开发图形化应用程序的能力,但冷冰冰的API文档和诸多的功能介绍使我们无法窥探GMF的全貌。
我一直相信,动手实践才是学习的唯一捷径,而一个生动鲜活且功能全面的实例无疑是照亮捷径的明灯。
本文将通过深入GMF开发组给我们提供的Taipan实例,从安装过程到设计意图,再到实现方法,通过重构Taipan应用程序或插件,以期全面了解GMF的能力和运作方式。
1.
GMF2.0与Taipan的安装
作为Eclipse建模工程的一部分,GMF插件的安装需要大量其他组件(EMF,GEF,QVT,JET,(UML2,OCL,OMD,XSD,Query,Transaction等等)的支持,手动安装极为不便且容易出错,下面提供了两种安装方法可供选择,各位可根据实际情况选择最合适的安装方式。
1.1.升级法安装GMF
通过查看GMF官网的requirement信息,我的第一感觉就是如果我们想要一个一个从Eclipse官网把这些插件凑齐,再安装(无论是把插件的文件直接复制到plugin/feather文件夹下还是采用“link”方式)到Eclipse里都会相当繁琐且容易出错。
因为GMF的运行需要Eclipse3.3,GEF,EMF,OCL,Transaction,Validation…..而且这些插件之间还存在相互依赖的关系,所以对安装顺序也有一定的要求。
如果哪个插件安装错误或者漏掉,都会导致GMF无法正常使用。
所以比较聪明的做法利用Eclipse的更新管理器到Europa的更新站点进行自动升级,这样不但省力而且可以将GMF所需的组件一次性搞定。
惟一缺憾可能就是更新站点那超慢的更新速度了,但是如果网速快的话采用这种方法还是不错的。
具体方法是,点击“Help->Updates->FindandInstall….”,然后选“Serachfornewfeaturesforinstall->EuropaDiscoverySite”。
然后从“ModelsandModelDevelop”列表中选择GraphicalModelingFramework(EuropaEdition),然后点击“selectRequired”按钮来选择GMF所需要的相关组件。
图表1.11
1.2.下载GMFBasePlatform
除了上面的方法之外,我们还可以在GMF官网的下载页面下载GMF开发人员专门为GMF使用者准备的压缩包,该压缩包内含有GMF所需要的绝大部分基本组件。
图表1.21
虽然这个平台提供的GMF版本是2.0RC4(所用的Eclipse也同样是3.3RC4),但是应该对我们的使用不会造成任何影响。
而且还免除了升级时那漫长的等待,可谓是GMF安装的首选。
除此之外,下载GMFBasePlatform还有一个额外的好处。
那就是如果采用更新的方式下载GMF的话,更新后得到的都是最新版本的插件。
而我们知道无论是Eclipse还是GMF,其API都是会经常变动的,这导致我们在旧版本的平台上写的代码在新版本上可能无法通过编译。
所以大多数开发人员都选择坚持使用某一个自己认为Bug比较少且较为稳定的版本,而不为了“尝鲜”而轻易升级,起码不会在工程做到一半的时候更新版本,以避免由于Eclipse兼容性所导致的问题。
处在学习过程中的我们也同样面临兼容性的问题,我们也不希望由于API变动导致我们的学习过程被中断,转而去解决兼容性问题。
所以我推荐直接下载这个压缩包,并在整个学习过程中一直使用它。
无论是升级安装还是这种安装方式,对于运行Taipan都是不够的。
所以除了GMFBasePlatform所提供的组件之外,我们还应该下载并安装完整的GMFSDK2.0.0。
如果你对GMFTutorialpart1里面所提到的mindmap例子感兴趣的话,你还需要额外下载GMFExperimentalSDK1.1.0,因为其中的RCP应用程序lite需要用到相关的组件。
1.3.用CVS下载Taipan
似乎除了CVS之外,GMF开发人员没有给我们提供更直接的下载方式,但这样做并不是由于他们过于懒惰。
因为GMF的更新很快,可能每季度甚至每个月都会有新的功能发布,所以作为GMF的旗舰示例程序,Taipan也应该与时俱进,随时做出改动以提供最完善的功能演示。
有鉴于此,我们手头的Taipan的工程源码可能很快过时,如果提供直接的下载连接的话将费时费力,利用CVS我们就可以随时获取开发人员为我提供的最新Taipan源码了。
使用CVS下载资源之前,首先需要建立一个CVSRepositoryLocation,具体方法是点击new->other,在CVS目录窗格下选择“CVSRepositoryLocation”就会看到如下图的界面。
图表1.31
按照如上图所示的内容进行填写。
完成后再点击new->other,在CVS目录窗格下选择“ProjectsfromCVS”,这样,Eclipse就会把我们通过CVS下载的内容自动在工作空间中建立一个同名的插件工程。
然后我们访问/HEAD/org.eclipse.gmf/examples,并选择org.eclipse.gmf.examples.taipan.*模块(这里面好东西不少,希望多学一些的可以多下载些例子),右键点击并选择checkout就可以下载了。
我们总是可以通过检查与我们正在使用的版本相对应的日期来下载对应版本的Taipan示例工程。
很重要的一点是我们必须使GMFSDK的版本与Taipan示例工程的版本保持一致才行。
为了做到这一点,在校验完毕之后,可以右键单击该工程,并选择“Team|SwitchtoAnotherBranchorVersion...”,然后选择“Selectthetagfromthefollowinglist”并使用底部的“addDate…”按钮来输入GMF2.0M4release的日期(2007-09-15)。
最后点击Finish。
切换到插件开发透视图,并打开org.eclipse.gmf.examples.taipan工程下的model文件夹。
查看每一个可用模型,特别是taipan.gmfgraph和taipan.gmfmap模型以及他们的元素属性。
你会发现有很多RCP版本的Taipan例子可供学习。
需要注意的是,如果在下载过程中出现超时错误,说明工程并未下载完全,这时切换到Java视图我们会发现未下载完全的工程会出现编译错误。
这种情况下我们需要将未下载完全的工程重新checkout(注意不是checkout缺少的部分,这样做会导致建立一个新的工程)。
2.Taipan初探
2.1.运行设置
在正确下载GMF及Taipan之后,为了正确运行Taipan,我们需要进行一些必要的配置。
首先是建立一个新的运行时工作空间(runtimeworkspace)。
该运行时空间名字任君自便,我这里叫TaianAppSpace。
图表2.11
对于Taipan的启动方式,我们既可以采用以RCP应用程序的方式启动,也可以让它作为一个Eclipse平台的一个插件启动。
不过,由于后者需要更多的内存(因为运行需要启动一个新的Eclipse平台实例),所以我推荐使用第一种方式。
其次,在上图的WorkspaceData一栏,我们需要点选“Clear”以便在多个工程相互依赖的时候,启动的应用程序可以及时反映我们的修改情况。
如果我们以RCP方式启动Taipan的话,在Plug-ins页签中,先点击“DeselectAll”,然后选择Taipan插件的全部内容,最后点击“AddRequiredPlug-ins”,这样一来我们启动RCP应用程序时就只包含运行Taipan所需的插件,以期减少运行期所载入的插件数量,从而大大减少内存需求。
图表2.12
最后在“Configuration”页签中,请点选“cleartheconfigurationbeforelaunch”。
至此,所有配置大功告成,在“main”页签中点击“run”我们就可以看到Taipan的庐山真面目了。
2.2.功能及设计意图
无论是在官网还是借助Goolge、Yahoo、Baidu……的协助,我都没能够找到除源码之外的其他任何有关Taipan功能的说明,所以我只能通过其Model的设计以及图形编辑器的表现来对其功能进行推测(幸好不太复杂),而我们手头最重要的参考资料莫过于taipan.ecore了(对于*.ecore文件的功能,我会在后文中加以说明)。
在对照了Taipan图形编辑器的功能与ecore文件的内容之后,我将我所得到的结论记录如下:
图表2.21
从功能上看,Taipan应用程序应该是与船务或是水上货运有关,主要是以图表的形式描述水运物流的过程,其中主要的图形元素包括:
船只(ship/warship),港口(port)和航行路线(route)。
Ø船只:
其中船只又包括商船和战舰,普通的货船可以装载一些货物(LargeItem/SmalItems)或空箱子(EmptyBox),而军舰既可以护航(Escort)也可以对港口实施攻击(Besiege);
Ø港口:
船只运货需要遵循一定的航线(Route),航线又分可靠航线和不可靠航线,用可靠程度(reliablility)加以区分,该值满分是100%,如果航线上有礁石或经常刮台风,可靠度自然会变低。
Ø港口:
港口每艘船只最后都需要入港,而港口负责记录已经靠岸的船只的信息。
以上就是Taipan功能的简单描述,看似罗嗦而且和我们的主题没什么关系,实则不然。
上面所叙述的内容其实是描述“Taipan是用来做什么的”,是对程序功能的抽象,从MDA的角度讲叫“建模”。
这恰恰是最重要且是我们首先需要完成的。
对我们来说,这一过程的实现品将会是一个.ecore文件,其具体的生成方法我将在后文详细介绍,下图就是Taipan的ecore模型所包含的内容。
图中的有关元素的所代表的含义语UML中的概念十分相近,如空心三角代表“Generation”,实心箭头代表的“Aggregation”,普通箭头代表的“Association”以及“元素”、“属性”等概念,都可以在UML里找到对应的等价物,非常容易理解。
有关EMF的内容超出本文范围,更为详细的信息请参阅EMF的帮助文档或“八进制”的Blog。
图表2.22
注:
Taipan一词字典上的解释是:
1一种毒蛇,2旧中国洋行老板。
如果取前一种解释,那我们只能认为Taipan是一个开发代号。
而如果取后一种解释,则可以认为Taipan是用来为某老板提供水运物流参考示例的程序。
我趋向于取后者的解释。
2.3.关注重点
无论什么样的图形编辑器,总离不开画布、图形元素、连线等几种固定的可视化元素,只不过完成的功能越复杂,我们需要关注和实现的图形元素越多而已。
对照上图,我们可以先一步对Taipan的基本功能有一个初步的认识,下面所列出的则是作为一个GMF应用程序的开发者,我们所要关注的重点内容,我会在后面的章节中一一详细描述其实现过程。
工具选项板和总览视图[toolpaletteandoverview]
布局和选择工具[layoutandselectiontools]
图形图像的输出[diagramimageexport(svg,bmp,jpeg,gif)]
层叠的属性视图[tabbedpropertiesview]
选中元素的字体和颜色选项[fontandcoloroptionsforselectedelement]
连接路由和风格选项[linkroutingandstyleoptions]
弹出栏和连接柄[pop-upbarsandconnectionhandles]
注释和几何图形[notesandgeometricshapes]
即时缩放和布局[animatedzoomandlayout]
图表2.31
上图就是我构建的一个Taipan图表,对照本图和上面所列出的内容,我们可以先从直观上体会一下作为一个功能完备的GMF图形编辑器所能提供的功能。
上图所描述的内容(纯属虚构)是:
从大连港到广州港一共有两条航道,一条航道沿途风浪小安全系数高,而另一条则比较不安全。
大连港有一艘注册货船名为“货运2号”,装了50000吨大闸蟹和一些空箱子,与它一起航行的还有一艘护卫舰。
而广州港也有一艘注册的货船“货运3号”,没有装任何货物,正运行在较为安全的航道上,它的目的地是大连港。
在那条危险的航道上,有一艘图谋不轨的战舰,装载了15000吨火器弹药意图对广州港实施武装袭击。
在这个编辑器中,我们可以从工具选项板中选择要加入到图表中的组件,通过属性面板修改图形组件的属性信息,通过预览视图了解整个图表概貌。
通过右键菜单,我们还可以选择显示表格和标尺,设定元素的字体和颜色选项,控制图表的缩放以及添加注释一些几何图形。
在编辑结束之后我们还可以将划好的图形导出成多种格式的图片。
在了解了Taipan的功能和设计意图之后,现在我们可以开始动手实现它了。
3.重构Taipan
3.1.主要流程
在一般情况下,用GMF生成图形编辑器应用程序需要以下一些主要步骤:
创建一个领域模型(domainmodel),该模型定义了那些由编辑器管理的一些非图形化的信息。
在这一步我们会得到一个*.ecore文件,在Taipan例子中就是tanpan.ecore。
创建一个图形定义模型(diagramdefinitionmodel),该模型定义了编辑器中显示的各种图形元素。
这一步的产物是*.gmfgraph文件。
创建工具定义模型(toolingdefinitionmodel),该模型用于定义工具栏、菜单栏中要显示的各种图形元素。
将上面所说的图形定义模型和工具定义模型合并,创建一个图形影射模型(diagrammappingmodel),该模型定义了领域模型元素与图形元素之间的映射。
生成图形编辑器。
通过修改生成的代码来加强图形编辑器的功能。
在GMF的DashBoard中,我们可以看到这些步骤以及它们之间的关系。
图表3.11
下面我们就按照上面的步骤来重新构建一个Taipan图形编辑器。
3.2.创建领域模型
在“功能及设计意图”一节中,我们已经大致了解了Taipan的领域模型,我们只需要将其实现为ecore文件就行了。
具体方法是输入“Ctrl+N”,在“ExampleEMFModelCreationWizards”下选择“EcoreModel”,然后点“Next”,修改ecore文件名称(我将其命名为“rebuilt_taipan.ecore”)之后,然后点击“Finish”就可以了。
在成功生成ecore文件之后,我们就可以在ecore编辑器中以树形结构的方式对其进行编辑。
在这一步我们首先要在属性视图中将根节点的Name属性的名称改为“taipan”,然后我们就可以按照图表3.21所示的内容来构建领域模型。
如果你更喜欢可视化的编辑方式的话,可以在“PackageExplorer”中右键单击刚生成的rebuilt_taipan.ecore文件,在弹出菜单中选择“Initializeecore_diagramdiagramfile”,GMF就会为我们在于ecore相同目录下生成一个名为“rebuilt_taipan.ecore_diagram”文件,图表3.22展示了合理调整位置之后结果。
值得注意的是,ecore文件和ecore_diagram文件的内容是一一对应的,我们在其中一个文件中所作的修改在我们进行了“保存”动作之后就会立即反映到另一个文件当中。
3.3.创建图形定义模型
如前所述,图形定义模型被用来定义那些将会显示在我们所要构建的图形里的各个元素,如图形、节点、链接等等。
在“New”对话框中的GraphicalModelingFramework目录下,我们可以看到两种构建图形定义模型的方式,其中“GMFGraphModel”所生成的模型的内部是空的,画板中可以显示的元素以及各个元素之间的关系需要我们逐条手动添加;而用“SimpleGraphicalDefinitionModel”生成的模型内容就丰富得多,GMF可以根据ecore文件中所提供的元素之间的关联信息自动生成相应的元素、链接以及标签的全部内容。
图表3.31
3.3.1.SimpleGraphicalDefinitionModel方式构建图形定义模型
图表3.32
在图表3.31中选择“SimpleGraphicalDefinitionModel”,点击“Next”,在选择了相应的ecore文件之后,在下图所示的向导对话框中选择要定义的图形元素,在下一个向导页中我们就可以定制与所选图形元素相关的图形定义信息。
图表3.33
需要注意的是,在这一向导页的缺省情况下所选择的元素、链接以及标签是和上一个向导页所选择的Ecore元素存在“聚合”关系的那些元素。
例如,我们在上一页中选择的Ecore元素是Ship,而在Ship的Ecore文件定义中我们可以看到Ship有一个类型为Item的name属性。
所以在缺省情况下图表3.33所显示的要处理的领域模型元素中,Item的3个实现类:
LargeItem、SmallItems和EmptyBox是被缺省选取的。
图表3.34
同样地,如果我们在图表3.32所示的向导页中选择其他领域模型元素的话,则在图表3.33中默认选取的元素也将随之改变。
值得注意的是GMF在实现以上机制的时候采用的是第归的处理方式,例如如上图所示,Aquatory和Ship有聚合关系,且Ship和Item有聚合关系,则如果我们在图表3.32所示的向导页中选择了Aquatory的话,在图表3.33中默认选取的元素将会变成Ship+Item。
也就是说,GMF将所选元素的“关系网”都默认地替我们选择了。
假设我们在图表3.32所表示的向导页中选择了Ship,且在下一向导页中除了点选Ship及其属性name的选项之外其它均保留默认设置,在点击“Finish”之后,就获得了一个定义了Ship元素图形信息的gmfgraph文件,其结构如下所示:
图表3.35
下面我们来一一介绍图中所生成的元素及其用途(上图中SmallItemFigure和EmptyBoxFigure节点下面的内容与LargeItemFigure是类似的)。
ØCanvas:
首先看根节点,它是一个名为taipan的Canvas,它将称为taipan设计器的画布,用以放置其他图形组件。
ØFigureGallery:
根节点下的第一个子节点是一个名为Default的FigureGallery,它的用途是包含一些可以被其他节点重复使用的Figure元素。
在本例中,FigureGallery下面的4个FigureDescriptor就是可被重用的Figure—ShipFigure、LargeItemFigure、SmallItemFigure和EmptyBoxFigure,其中后3个分别对应Ship所能包含的3中Item。
而FigureDescriptor所包含的具体内容我会在下面详细说明。
ØNode:
上图中,与FigureGallery处于相同等级的元素是Node。
本例中的3种Node的属性分别对应上面FigureGallery里面的3种同名FigureDescriptor,又因为3个FigureDescriptor所包含的Figure元素都是矩形(Rectangle),所以在画布上这三种类型的节点都将是以矩形的状态存在。
ØDiagramLabel:
是附着在节点上用于显示信息的标签。
什么是FigureDescriptor?
图表3.36
FigureDescriptor用以描述一个figure的结构和内容,内含Figure和ChildAccess两种元素。
图表3.35中名位LargeItemFigure的Descriptor中含有一个类型为Rectangle的Figure和两个ChildAccess。
此外,它是在你的图形元素(DiagramElement)里唯一一个可以被引用的物件。
当然你也可以把它想象成一个图形元素的句柄,通过这个句柄我们才可以访问其内部的子内容。
3.3.2.手动构建图形定义模型
如果你对GMF自动生成的图形模型不满意,或者想要使用自定义的图形元素或形状,就要靠我们万能的双手来解决问题了。
首先要在图表3.31所示的向导框中选择“GMFGraphModel”,点击“Finish”之后将得到一个空的Canvas,我们首先在属性面板里将其Name属性改为taipan。
图表3.37
然后右键单击Canvas节点,为他添加子节点。
对照图表3.35的内容,我们就可以轻松地手动生成图形定义模型了。
图表3.38
构建图形定义模型的过程很像逛商场(我的噩梦,-_-!
),想象你在一个名字叫做Gallery大商场购物,你要做的就是进入装满Descriptor的楼层,浏览该层里面装满了各种形状的架子并从中选出一个你认为最合适的,然后把它放入你的购物筐。
通过上述的讲解,相信你可以比较轻松地用向导生成缺省的图形定义模型了。
但比较奇怪的是在Taipan的所有例子工程中都没有提供这个模型,所以一定有某种替代方法可以在不生成这个模型的情况下完成相同的功能,限于篇幅这里就不在深入这个议题了。
3.4.创建工具定义模型
使用过VE(VisualEditor)的朋友都知道,当我们以可视化的方式设计一个UI类的时候,VE就会在设计器的边缘提供一个装满控件的Palette供我们选择,工具定义模型的工作就是辅助我们生成Palette,构建各种工具及动作。
想象一下我们用GEF生成Palette的繁琐过程,再亲身体验一下GMF的便利,相信你再面对要求不是很高的应用得时候会毫不犹豫地选择GMF。
构建工具定义模型的过程与定义图形定义模型类似,正如图表3.31所示,也是有两种方式可供选择。
这里我们直接选择“SimpleToolingDefinitionModel”,修改了gmftool文件的名称之后,在选择领域模型的向导对话框里仍然选择Ship,这样一来在生成的Palette里面我们就只有下图中被钩选的元素可供使用了。
当然如果想要恢复Taipan的全貌,把该选的都选上就可以了。
图表3.41
我们可以看到在一个Palette中存在着
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- GMF 实例 解析
