GEF

更新时间:2024-06-07 03:14

GEF(Graphical Editing Framework)是一个图形化编辑框架,它允许开发人员以图形化的方式展示和编辑模型,从而提升用户体验。这样的应用程序有很多,例如:UML类图编辑器、图形化XML编辑器、界面设计工具以及图形化数据库结构设计工具等等。

GEF简介

归结一下,可以发现它们在图形化编辑方面具有以下共同之处:

提供一个编辑区域和一个工具条,用户在工具条里选择需要的工具,以拖动或单击的方式将节点或连接放置在编辑区域;

节点可以包含子节点;

用户能够查看和修改某个节点或连接的大部分属性;

连接端点锚定在节点上;

提供上下文菜单和键盘命令;

提供图形的缩放功能;

提供一个大纲视图,显示编辑区域的缩略图,或是树状模型结构;

支持撤消/重做功能;

等等。

工作界面

基于GEF的界面设计工具(Visual Editor,VE)的工作界面

GEF最早是Eclipse的一个内部项目,后来逐渐转变为Eclipse的一个开源工具项目,Eclipse的不少其他子项目都需要它的支持。Eclipse 3.0版本花了很大功夫在从Platform中剥离各种功能部件上,包括GEF和IDE在内的很多曾经只能在Eclipse内部使用的工具成为可以独立使用的软件/插件包了。理论上我们是可以脱离Eclipse用GEF包构造自己的应用程序的,但由于它们之间天然的联系,而且Eclipse确实是一个很值得支持的开发平台,所以我还是推荐你在Eclipse中使用它。

GEF的优势是提供了标准的MVC(Model-View-Control)结构,开发人员可以利用GEF来完成以上这些功能,而不需要自己重新设计。与其他一些MVC编辑框架相比,GEF的一个主要设计目标是尽量减少模型和视图之间的依赖,好处是可以根据需要选择任意模型和视图的组合,而不必受开发框架的局限(不过实际上还是很少有脱离Draw2D的实现)。

现在来看看GEF是如何实现MVC框架的吧,在这个帖子里我们先概括介绍一下它的各个组成部分,以后将结合例子进行更详细的说明。

GEF结构图

模型:GEF的模型只与控制器打交道,而不知道任何与视图有关的东西。为了能让控制器知道模型的变化,应该把控制器作为事件监听者注册在模型中,当模型发生变化时,就触发相应的事件给控制器,后者负责通知各个视图进行更新。

典型的模型对象会包含PropertyChangeSupport类型的成员变量,用来维护监听器成员即控制器;对于与其他对象具有连接关系的模型,要维护连入/连出的连接列表;如果模型对应的节点具有大小和位置信息,还要维护它们。这些变量并不是模型本身必须的信息,维护它们使模型变得不够清晰,但你可以通过构造一些抽象模型类(例如让所有具有连接的模型对象继承Node类)来维持它们的可读性。

相对来讲GEF中模型是MVC中最简单的一部分。

控制器:我们知道,在MVC结构里控制器是模型与视图之间的桥梁,也是整个GEF的核心。它不仅要监听模型的变化,当用户编辑视图时,还要把编辑结果反映到模型上。举个例子来说,用户在数据库结构图上删除一个表时,控制器应该从模型中删除这个表对象、表中的字段对象、以及与这些对象有关的所有连接。当然在GEF中这些操作不是由直接控制器完成的,这个稍后就会说到。

GEF中的控制器是所谓的EditPart对象,更确切的说应该是一组EditPart对象共同组成了GEF的控制器这部分,每一个模型对象都对应一个EditPart对象。你的应用程序中需要有一个EditPartFactory对象负责根据给定模型对象创建对应的EditPart对象,这个工厂类将被视图利用。

RootEditPart是一种特殊的EditPart,它和你的模型没有任何关系,它的作用是把EditPartViewer和contents(应用程序的最上层EditPart,一般代表一块画布)联系起来,可以把它想成是contents的容器。EditPartViewer有一个方法setRootEditPart()专门用来指定视图对应的RooEditPart。

EditPart对象

在GEF SDK提供的帮助文档(GEF开发指南)里有一份详细的EditPolicy、Role和Request类型列表,这里就不赘述了。

视图:前面说过,GEF的视图可以有很多种,GEF目前提供了图形(GraphicalViewer)和树状(TreeViewer)这两种,前者利用Draw2D图形(IFigure)作为表现方式,多用于编辑区域,后者则多用于实现大纲展示。视图的任务同样繁重,除了模型的显示功能以外,还要提供编辑功能、回显(Feedback)、工具提示(ToolTip)等等。

GEF使用EditPartViewer作为视图,它的作用和JFace中的Viewer十分类似,而EditPart就相当于是它的ContentProvider和LabelProvider,通过setContents()方法来指定。我们经常使用的Editor是一个GraphicalEditorWithPalette(GEF提供的Editor,是EditorPart的子类,具有图形化编辑区域和一个工具条),这个Editor使用GraphicalEditViewer和PaletteViewer这两个视图类,PaletteViewer也是GraphicalEditViewer的子类。开发人员要在configureGraphicalViewer()和initializeGraphicalViewer()这两个方法里对EditPartViewer进行定制,包括指定它的contents和EditPartFactory等等。

EditPartViewer同时也是ISelectionProvider,这样当用户在编辑区域做选择操作时,注册的SelectionChangeListener就可以收到选择事件。EditPartViewer会维护各个EditPart的选中状态,如果没有被选中的EditPart,则缺省选中的是作为contents的EditPart。

初步了解了GEF的MVC实现方式,让我们看看典型的GEF应用程序是什么样子的。大部分GEF应用程序都实现为Eclipse的Editor,也就是说整个编辑区域是放置在一个Editor里的。所以典型的GEF应用程序具有一个图形编辑区域包含在一个Editor(例如GraphicalEditorWithPalette)里,可能有一个大纲视图和一个属性页,一个用于创建EditPart实例的EditPartFactory,一些表示业务的模型对象,与模型对象对应的一些EditPart,每个EditPart对应一个IFigure的子类对象显示给用户,一些EditPolicy对象,以及一些Command对象

GEF应用程序的工作方式如下: EditPartViewer接受用户的操作,例如节点的选择、新增或删除等等,每个节点都对应一个EditPart对象,这个对象有一组按操作Role分开的EditPolicy,每个EditPolicy会对应一些Command对象,Command最终对模型进行直接修改。用户的操作转换为Request分配给适当的EditPolicy,由后者创建适当的Command来修改模型,这些Command会保留在EditDomain(专门用于维护EditPartViewer、Command等信息的对象,一般每个Editor对应一个该对象)的命令堆栈里,用于实现撤消/重做功能。

全球环境组织

GEF全球环境基金

Global Environment Facility,全球环境组织,一个致力于环境保护的NGO组织。

全球环境基金(GEF)是关于生物多样性、气候变化、持久性有机污染物土地荒漠化的国际公约的资金机制。GEF通过其业务规划,支持发展中国家和经济转型国家在生物多样性、气候变化、国家水域、臭氧层损耗、土地退化和持久性有机污染物的重点领域上开展活动,取得全球效益。

自1991年启动以来,GEF已通过1000多个项目,向140多个发展中国家和经济转型国家提供了大约40亿美元赠款,并从各种渠道吸引了120亿美元的项目融资。2002年8月,32个捐资国保证,在随后4年内,向GEF提供近30亿美元,用于GEF活动。

免责声明
隐私政策
用户协议
目录 22
0{{catalogNumber[index]}}. {{item.title}}
{{item.title}}