首先我们来创建一个基于GEF的浏览器(而不是编辑器),也就是说,它只能浏览一个模型,而不能够进行编辑。先关注于浏览而不是编辑,有助于理解GEF的一些核心的概念。
GraphicalViewer和createControl()方法
在开始之前,最先要弄明白的是,一个GEF的图如何能够显示在由ViewPart在createPartControl(Component parent)中提供的这个parent控件上。这是通过GEF的GraphicalViewer(准确的说应该是EditPartViewer,GraphicalViewer是EditPartViewer的子接口,EditPartViewer的名字可能更容易理解一些:是为EditPart创建一个Viewer进行显示)来进行的。GraphicalViewer可以将其自身适配到任何一个SWT Control上。它的createControl()方法接受一个SWT Control来作为适配的对象,将GEF所生成的Figure显示在这个SWT Control之上。(在内部实现上,GraphicalViewer使用Draw2D的LightweightSystem来做这个事情,将Draw2d的Figure对象绘制在SWT的Control上)
在弄明白了这一点之后,我们就会知道,实际上是将GEF放在ViewPart中还是放在EditorPart对于GEF而言是没有本质的区别的,甚至将GEF放在任何的SWT Composite上都是可以的。不过GEF框架中提供了对创建EditorPart的缺省实现。而如果要在Editor之外使用GEF的话,需要额外的对GraphicalViewer做一些设置。
下面的这个图,给出了GEF中的几个主要关系,下面会有对这个图的解释。
setContent()
GraphicalViewer的思想,类似于JFace中所实现的Viewer思想:要显示一个控件,需要输入的是一个模型对象,要显示的内容根据输入的模型对象来进行的。因此,GraphicalViewer同所有JFace Viewer一样有一个方法,叫做setContent(Object o)来接受一个模型对象,而对这个模型对象如何进行处理并显示,就是GEF的工作了。
在创建一个GraphicalViewer之后,要使GEF能够运转起来,还需要做如下几件事情:
1. 设置一个RootEditPart:RootEditPart的是使整个GEF框架运行起来的关键之一。RootEditPart并不对应于任何的模型对象,它将从setContents()方法中接收到的模型对象进行转换,并添加到整个的EditPart体系中去,具体的添加过程后面会有详细讨论。
2. 设置其EditPartFactory:负责从模型到EditPart的转换。一般来说一个模型对象对应于一个EditPart。这个类的
3. 设置EditDomain:用来接收事件并选择恰当的事件处理函数进行处理,因为我们尚不需要进行编辑,因此这一个可以暂时略过。
4. 调用setContents()方法:为其设置要显示的内容。
由GraphicalViewer所显示的内容,肯定是一个Draw2d中的IFigure对象。而如何从一个模型对象到一个Figure对象呢?这中间的联系就是通过EditPart来完成的。GEF使用的是MVC模式,Model部分可以使任意的模型对象;View部分就是Draw2d的IFigure对象,联系Model和View的Controller,在GEF中称为EditPart。简单的说,GEF中的EditPart,负责将模型转换为IFigure的显示,它从模型中读取信息,生成Figure;另一方面,EditPart负责从View接收事件,并将这些事件转化为对模型的修改。在这一部分中,我们暂时只关注于第一个方面:EditPart是如何将一个模型转换为Figure以进行显示的。