Eclipse Graphical Modeling Framework (GMF)能够帮助我们快速构造基于EMF和GEF的图形化编辑器,实际上对于不是很复杂的应用来说,开发人员并不需要了解EMF和GEF就可以使用GMF。这篇帖子通过从零开始生成一个数据库设计器的全过程,演示了在使用GMF创建应用
Eclipse Graphical Modeling Framework (GMF)能够帮助我们快速构造基于EMF和GEF的图形化编辑器,实际上对于不是很复杂的应用来说,开发人员并不需要了解EMF和GEF就可以使用GMF。这篇帖子通过从零开始生成一个数据库设计器的全过程,演示了在使用GMF创建应用程序时,构造ecore模型、构造.gmfgraph文件、构造.gmftool 文件、构造.gmfmap文件和生成编辑器的这几个步骤。
一、开发环境
由于目前gmf还没有发布正式版,所以这篇帖子使用的是相对稳定的GMF 1.0M4版本,1.0正式版将在2006年7月初发布。gmf对eclipse平台和一些插件的要求比较高,所以你可能要对你的开发环境进行一些升级更新才能感受gmf带来的方便,具体要求是这样的:Eclipse 3.2M4、EMF 2.2.0M4、GEF 3.2M4和UML2 2.0M2;此外还要下载一个名为ANTLR的包,解压后要把antlr.jar文件放在gmf插件目录的antlr/lib下,这个依赖只是暂时的,gmf正式版发布之前会去掉它。
二、构造ecore模型
因为只是为了演示gmf,这里构造的是一个非常简化的数据库设计器。用户通过设计器可以创建表格,为每个表格增加一些列,定义这些列的属性,以及在表格之间建立外键关系。所以在ecore模型里应该有Database、Table和Column这几个类,此外还有一个FKRelation类代表表格之间的连接,在Database类下有一个名为fkrelations的引用用来记录一个数据库设计中所有的这些连接。
创建名为com.my.dbdesigner的Empty EMF Project项目,有多种方式可以创建ecore文件,在gmf的example里有一个例子是ecore文件的图形编辑器,如果你安装了这个例子,可以在项目的根目录下New->Other->Examples->Ecore Diagram创建名为dbdesigner的文件,这将生成dbdesigner.ecore和dbdesigner.ecore_diagram文件。我在使用它编辑ecore文件时遇到了一些同步的问题,所以后来还是用eclipseUML来编辑的,不过这只是一个方法问题了。总之,我们这个数据库设计器的ecore模型如图1所示(如果嫌麻烦,可以点这里下载现成的ecore文件)。
图1 数据库设计器的简化ecore模型图
三、构造.gmfgraph文件
主菜单New->Other->Example EMF Model Creation Wizards->GMFGraph Model创建名为dbdesigner.gmfgraph的文件,向导最后一步中Model Object选择为Canvas,然后按Finish按钮。在编辑器里,把Canvas命名为DBDesignerDiagram,这将成为数据库设计器的画布。在Canvas下New Child创建一个名为Default的Figure Gallery,Figure Gallery的作用是容纳一些可供重用的Figure。在Figure Galley下创建一个名为BasicRectangle的Rectangle节点,在这个例子里大多数图形只用矩形就够了(除了连接线)。现在,在 Canvas下创建一个名为TableNode的Node节点,它代表数据库设计器里的表格,这个节点的Figure属性选择为刚才定义的 BasicRectangle,见图2,也就是指定在将来生成的数据库设计器里,表格显示为矩形。
图2 TableNode节点
可以想象,现在生成的数据库设计器里已经可以在画布上创建矩形的表格了,那么怎样实现在表格里创建列呢?这稍微麻烦一些,因为表格图形并不是全部面积都用来放置列,而要留出顶部的一行用来显示表格名称,而且这些列也不是像表格在画布上那样随意放置,而是按由上到下的顺序排放的,这就需要在表格图形里加一个隔间(Compartment),隔间的概念可以在图3中看到,它的作用就是放置子元素,但隔间本身一般不代表模型中的某个元素。
图3 红色虚线部分所示为表格图形里的隔间
创建一个与TableNode同级的名为ColumnCompartment的Compartment,意即用来放置列的隔间,在属性视图里把它的 Figure属性设置为BasicRectangle。再创建一个名为ColumnChild的同级Child节点,它的Figure属性同样为 BasicRectangle,这个ColumnChild就是作为子元素的列,如图4所示。
图4 ColumnChild节点
图5 FKConnection节点
四、构造.gmftool文件
主菜单New->Other->Example EMF Model Creation Wizards->GMFTool Model创建名为dbdesigner.gmftool的文件,向导最后一步中Model Object选择为Tool Registry,然后按Finish按钮。在Tool Registry下创建Palette,在Palette下创建标题为DBDesigner的Tool Group,在这个Tool Group下为Table和Column分别创建一个Creation Tool,它们将成为数据库设计器中用来创建表格和列的那的两个按钮。同样在这个Tool Group下,为连线也创建一个Creation Tool,如图6所示。
图6 ForeignKey节点
五、构造.gmfmap文件
主菜单New->Other->Example EMF Model Creation Wizards->GMFMap Model创建名为dbdesigner.gmfmap的文件,向导最后一步中Model Object选择为Mapping,然后按Finish按钮。从主菜单GMF Editor里选择“Load Resource...”命令,在对话框里按Browse Workspace按钮,选中我们的dbdesigner.ecore、dbdesigner.gmfgraph和dbdesigner.gmftool 这三个文件,见图7,再按OK关闭对话框。
图7 为定义映射载入需要的资源
在编辑器的Mapping节点下创建一个Canvas Mapping,可以看到在属性视图里它的属性被分为三类,分别对应ecore模型、工具和图形这三个方面,对于Canvas Mapping,必须设置Domain Model、Element和Diagram Canvas这三个属性,值分别为EPackage dbdesigner、EClass Database和Canvas DBDesignerDiagram,它们都是下拉选项,所以很容易确定。
刚才的设置相当于告诉了GMF我们要把Database类映射为画布,现在要告诉GMF我们还要把Table类映射为画布上的矩形,所以要创建另一个Mapping的子节点Node Mapping,它的属性见图8,注意可能要先选择了Element属性值后Edit Feature属性才可选。
图8 为数据库表格定义Node Mapping
还要告诉GMF表格里要能创建列,因此在Node Mapping下创建Compartment Mapping和Child Node Mapping各一个,前者只要将Compartment属性选择为在.gmfgraph里定义的ColumnCompartment即可;后者的属性如图9所示,注意Compartment Mapping的Child Nodes属性与Child Node Mapping的Compartment属性是双向的,我们只用定义其中一个方向即可,另一个方向会自动填充。
图9 为列定义Child Node Mapping
最后要处理一下连接线,方法是在Mapping下创建一个Link Mapping,它的属性比较多,见图10。
图10 为外键关系定义Link Mapping
六、生成编辑器
该做的准备工作都已就绪,现在到了激动人心的最后一个步骤了。首先是要生成基本的EMF代码,包括核心模型代码和.Edit代码,因为gmf的图形化编辑器依赖这两个部分,而EMF传统的Editor部分则并不需要。这个步骤在EMF的帖子里已经介绍过了,这里不再重复。接下来打开 dbdesigner.gmfmap文件,在编辑器里点右键,选择“Create generator model...”命令,在对话框里接受缺省的dbdesigner.gmfgen文件名,按OK确定后就会生成一个.gmfgen文件。打开这个文件,还是在编辑器里点右键,选择“Create diagram code”命令,这样就会生成图形化编辑器的代码,这些代码放在名为com.my.dbdesigner.gmf.editor的项目中。
如果在执行上面步骤中出现了错误,就要检查那些模型文件是否正确,特别是.ecore文件的package中Ns Prefix和Ns URI这两个属性不应为空,如果错误信息为“java.lang.IllegalStateException: Can't find genFeature for feature 'XXX' in class XXX”则很可能是由于更改了.ecore文件后没有更新.genmodel文件。
运行这个生成的插件后,你就可以通过主菜单File->New->Example->DBDesigner Diagram创建数据库设计了,图11是它的工作界面。功能不错,但在我的机器上响应不是很快。点此下载生成后的项目打包
图11 数据库设计器的运行画面