好好工作,好好生活
作GEF编辑器的人,不知道有没有发现这样一个问题:每当作一个新的编辑器的时候,有很多代码都和以前的类似。
我发现了这个问题,很多Command、Policy,包括EditPart都很类似,所以我经常采用Copy&Paste然后修改的方法来加快开发速度。
Eclipse采用的是插件扩展机制,做一次扩展就可以向Eclipse贡献一个新的功能。同理,GEF编辑器中,画板里的可编辑模型,是否也能这样添加呢?
让我们沿着这个思路走下去。
一 定义模型
初步的构想,仍然是继续前两篇文章的足迹,更改原来的例子。
模型的定义:
最开始做这个例子的时候,我将Node的Abstract设置为了true,因为我希望它就是一个抽象类,我将写RectangleNode和EllipseNode继承Node,他们才会出现在编辑器里。但是后来发现那样做的话,文件确实可以编辑,但是文件保存之后,再次用EMF序列化为对象的时候会出错。
什么?不信?那你自己试试。
这里,我给Node加了一个属性instance,它表示这个对象的实现类。它将给我们代来一些麻烦。
二 创建模型工程
与前面的文章一样,利用这个ecore文件创建一个EMF项目,并生成模型代码。Ok,就把代码放在这里,不再改动它了。这个工程的名称是nodenew。
三 创建编辑器工程
如果说前面的工程仅创建了“抽象模型”,那么本工程就仅创建了基于前面模型的一个编辑器框架。
创建一个名为nodenew.gef的插件项目,其他的全部按默认设置。首先,这个插件依赖于nodenew。将nodetest中的command、editpart、connectionhelp、properties、ui包copy过来,将Connection.java和ModelManager.java也copy过来,修改代码,尽可能的减少那些红叉。
创建一个扩展点,我们将利用它来初始化编辑器画板。
这个扩展点的用意很明确,就是贡献模型并设置模型与EditPart的对应关系。
创建一个接口类,所有使用这个扩展点的EditPart需要实现这个接口:
MyEditPart.java
创建一个类,从扩展点中找到模型与EditPart的对应关系:
ModelToEditPartMap.java
创建一个类,从扩展点中得到编辑器画板里的元素。
FactoryExtension.java
上面的类中使用的CreationFactory是自己重写的一个类,它的目的在于,当用户选中画板中的一个对象的时候,发出了一个create的request,我们创建一个对象,封装在这个request里,当编辑器截获这个request的时候,就直接得到了新创建的这个模型对象。
MyCreationFactory.java
在这里碰到了一个关于ClassLoader的问题。假如不使用WorkbenchPlugin.createExtension(element, MyConstants.ATTR_MODELCLASS);
从当前的插件项目中load这个class会出现ClassNotFound异常。目前的这个解决方法不是很好,正在寻找更好的解决方案。
接着,修改NodeEditorPaletteFactory,从扩展点中初始化编辑器画板:
最后,修改NodesEditPartFactory,有些对象需要从扩展点中得到EditPart对象: