Posted on 2006-10-09 18:55
Dart 阅读(3044)
评论(3) 编辑 收藏 所属分类:
GEF
GEF(Graphical Editing Framework )是
Eclipse旗下的强有力的Tool Project,利用
GEF可以轻松实现类似于Visual Editor的可视化图形编辑应用程序。
我将以如何构建一个数据库编辑工具为力,介绍一下
GEF。
1.什么是GEF。EditPartViewer
上面已经说过了,GEF是Eclipse旗下的Tool Project,为开发者提供了一个图形编辑开发平台。GEF是一个很出色的MVC平台,见下图:
EditPartViewer是用于承载图形的,就像一张画布一样,但是并不是直接讲图像绘制在其之上,而是通过GEF的EditPart来获得的图形,这里只是介绍一下,下面会进行讲解,但是涉及到EditPartViewer本身的东西比较少。
2.Model , EditPart ,View
模型(model)是开发者自己根据自身程序的要求而定制的,它包括了开发者所想在程序中展现的一些信息,比如我们创建数据库编辑工具,那么我们的模型中就会有数据表(DataTable)这么一个模型,一个完整的数据表就会拥有自己的表名(name)、列(Column)、元组(Row)、主键(Key)等属性。这些属性对于一个数据表来说是必须的,只有这些属性才能完整地去描述一个数据表。
此外,在GEF中,模型有时候还需要一些附属属性,我们姑且这些属性为“图形属性”,这些属性和模型本身是没有什么关系的,只是为了反应模型对应的视图(View)的一些变化而设置的,比如坐标、尺寸等。
模型的变化需要反应在视图上,典型的MVC是通过控制器来改变视图的,在GEF中称控制器为“编辑单元”(EditPart),编辑单元和模型是一对一的关系。
编辑单元是架起模型是试图的一道桥梁,模型的改变会触发事件,让EditPart更新目前的视图,视图会根据模型的属性改变而做出响应的调整,当然这些调整都是开发人员自己规定的了。简单的做法是,在模型中设置一个属性更改发起源:java.bean.PropertieSource,然后让编辑单元 (EditPart)实现监听器:java.bean.PropertiesChangeListener,这样一来,每当模型变化的时候,就会发出变化通知,编辑单元得到通知后,刷新视图。但是这种做法不是很好,一般情况下,开发人员都应该利用EMF(Eclipse旗下的另一个 Toolproject)进行建模,然后利用EMF模型的属性通知功能来实现事件通知以及响应。
而当视图发生变化的时呢?广告之后马上回来(我抽根烟先)
3. Request 和 Policy
视图变化发出的事件,其实是开发人员所不能控制的,我这么说并不是指无法控制,而是想引出下一个问题:Request和Policy
费了半天话,我开始进入正题了。各位观众请注意,这一节很重要。
其实GEF的MVC模式中,在利用控制器去改变模型的时候,利用了策略模式(Policy)。这里需要说一下GEF中如何进行对图形变化的事件处理。
在GEF 构架中,图形的变化并不是像通常的控件那样,利用添加监听器来回调函数,它是把这些事件都封装成了一个个的Request向外发送,然后让 EditPart来截获处理。维护这些事件,并将他们封装成Request的是一个叫EditDomain的家伙,在这里不做介绍,只要知道有这么一个东西就行了,在以后的文章里面会慢慢提起它。
EditPart怎么处理Request?很简单,写代码呗!举个例子:当我们在图形上做了一个点击操作,点了一下某一个图形,这时候,EditPartViewer就会截获事件,传给EditDomain,然后将信息封装生成一个Reuqest,传递到EditPart那里,让它处理。下面是事件方向:
怎么处理呢?如果我们点击后要高亮显示这个图片,或者是在图片四周形成一个黑色的边框,那怎么办?写代码吗?不用,有人会去做,它就是Policy。见图:
下面请Policy登场。
Policy 能够对这些Request进行一些基本的处理,比如上述的那样,一些Policy能够处理当我们选中一个图形后所产生的高亮效果等,不仅仅如此,还比如拖动图形、拉伸图形以及绘制图形等等操作,都是由Policy来处理的,可以毫不客气地说,Policy比EditPart有用多了!
Policy 是被EditPart“安装”到自己身上的,利用EditPart的instanllEditPartPolicy方法,将一些相关的Policy“安装”好,好让他们处理Request。EditPart所需要安装的Policy是有不同的,这是由于Request有多种“角色”,不同的角色是不同事件封装的结果,只有对应的Policy才能对他们处理,这里记住,Policy和Request是多-多的关系,不同的Policy能够处理同一个 Request。
但是Policy却又什么都不能做,这是由于很多代码还是需要程序员来写的,Policy 只处理一些基本东西(上面提到的现实黑色边框什么的),然后它又会通过Request“索取”Command,然后再执行Command。好了,我不废话了,这里大家只要了解下就可以了,以后会慢慢讲清楚Policy,记住Policy很重要。
4.Command 和 CommandStack
从上图可以看到有一个名位Command的东东,下面说说它。
Command,顾名思义,方法,它是一个简单的类,需要开发人员去实现它的一些方法,最常用的方法有:excute,redo,undo。这三个方法非别是执行、重新执行、取消执行,Policy索取到Command后会去执行它的excute方法,所以说开发人员必须清楚地去理解Policy所要Command的含义(它是一个什么样的Command?是添加一个模型的,还是更改图形位置的),以及触发的时机。
两个方法redo,undo是为了实现取消、回滚操作而设定的方法。说到Command,就不能提到CommandStack(方法栈),它维护了一系列的Command,从而实现了回滚、前进等操作,而这个方法栈又是由Domain进行维护的。
5. Draw2D 和 Figure
Draw2D是在SWT之上的,GEF的图形实现就是利用了Draw2D。这里不做太多介绍,在以后的文章里面,我会有很多的地方要提到它
关于Figure这里就不废话了,来日方长嘛!睡觉!
6.结束语
这里只是简单介绍了一下GEF的大致情况,下一章我讲会讲一下具体的实现