创建了模型和显示模型图形之后,下一步就是把它们联系起来,也就是创建关联模型和图形的editpart。GEF提供的实现是抽象的,你必须进行扩展。但是,首先我们应该建立其基础。
GEF提供了ScrollingGraphicalViewer 类(一种对GraphicalViewer的实现),它使用Draw2d Figure Canvas ,大多数应用使用viewer,除非由于一些原因,不需要滚动条。下一步确定使用那一个root editpart,每一个editpart viewer需要一个叫做根的特殊editpart,这个editpart不对应任何模型,它的功能是建立显示组件(viewer),并为所有应用的“真正的”editpart提供一个统一的上下文(context),有两种可以使用的实现:
- ScalableRootEditPart - 提供一组标准的图层(layer)并支持缩放
- ScalableFreeformRootEditPart - 和上面的相似,但是所有的图层遵守自由形状(freeform)接口,这是一个灵活和常用的root editpart。
现在我们有了一个viewer和它的root editpart,所以下面我们为viewer设置一些内容(contents)。contents是指使viewer显示可视化图形的基础模型。viewer的EditPartFactory 负责维护contents和构造合适edipart,并设置为root editpart。它的图形加入在底层图层上,这时contents editpart将会重新使用EditPartFactory构造它的子editpart,然后子editpart继续创建它们自己的子editpart或连接connection,等等,直到所有的editpart和它们的视图都被创建
实现 Contents EditPart
所以首先要实现的是contents editpart,还需要实现一个工厂factory,识别主模型对象并建立控制器editpart,这个editpart的模型为其他的图形提供基础背景,通常它甚至不需要绘制图形,但是仍然需要选择布局管理器(layout manager)和root editpart上的图形类型。通过覆盖createFigure() 控制需要绘制的图形。如果使用一个freeform的root editpart,contents figure必须实现freeform API,可以使用FreeformLayer 。布局管理器通常为XYLayout 或者FreeformLayout ,这根据使用root editpart是否是freeform的。
在初始化期间,contents editpart 将会根据调用它的getModelChildren() 方法返回的列表值创建它的子editpart,editpart 应该覆盖这个方法返回一个模型对象列表,这些模型对象的editpart将会被创建。默认下,editpart会到EditpartFactory中创建每一个子editpart。
实现子EditParts
图表包含的子图形一般称为节点,通常显示对用户有用的数据,这些图形或者是一个默认的图形,或者是一个定做的图形,或者是一个复合图形。在重多的视图viewer中,每一个editpart都会调用自己的refreshVisuals() 方法,这个方法负责在视图中反映模型的属性。在复杂的情况下,这个方法可以被分解为几个更小的工具方法。最后,当我们监听模型的变化时,这个方法或它的工具方法可以再被调用。
如果图表中的一个子图形是一个拥有子图形的图形,需要象图表的根editpart(diagram editpart )一样覆盖getModelChildren() 这个方法。
加入Connection Editpart
Connection Editpart是一种在图表中连接两个editpart的特殊的editpart,如果一个editpart是一个连接的source或者target,则可以称为节点,source和target节点通过一种共享的方式创建和管理连接,每一个节点editpart必须重写 getModelSourceConnections() 和 getModelTargetConnections() 方法,返回模型对象关联的连接,然后GEF检查连接editpart是否被创建(被在另一端的其他节点),如果没有,则请求工厂factroy创建这个connection editpart。source节点负责创建连接图形并加入图标(diagram)。
connection editpart 的图形必须是一个Draw2d Connetion 。connection editpart通过把source和target节点转换成NodeEditpart 设置图形的锚点(anchor)。source和target必须返回合适的锚点或者具有伪固定位置的锚点。
有时,连接象其他图形一样,在模型中具有必须可视化的属性,甚至具有子连接,或者是连接到其他连接的节点。
总结
到这里,我们已经解释了可视化模型的过程,这需要继承AbstractGraphicalEditPart 类,覆盖基于模型的一些方法,下面列出了这些方法:
- createFigure() - 这个方法创建editpart的视图或图形,这个方法不需要在反映图形中反映模型的状态,这在refreshVisuals()方法中实现
- refreshVisuals() - 这个方法在视图中反映模型的属性,复杂的控制器可以把这个方法分解成结各小的helper方法。
- getModelChildren() - 调用这个方法,判断一个模型是否有子模型,并创建对应的子控制器editpart。
- getModelSource/TargetConnections() - 和子模型类似,不过这里返回的模型元素是连接,这些连接的editpart是source或者target。