读书人

gef编辑器胪陈

发布时间: 2012-08-14 10:39:57 作者: rapoo

gef编辑器详述

工作以来一直都在做IDE,写篇文章记录下自己对gef的理解,再粗糙也是自己的理解,呵呵!

?

gef主要是用于实现图形化编辑器的一个框架,尽管它主要用于实现编辑器,但是它还是可以做其它的东西的,例如官方提供的tree节点的大纲视图,就是建立在gef框架基础之上的。

?

?

?

1.Tool

EditDomain:

对于一个gef应用来说,EditDomain对象是全局唯一的,对于一个gef应用来说,EditDomain基本上是顶层控制器。它管理者EditPartViewer,PaletteViewer,CommandStack,activeTool。这里觉得奇怪的是为啥要有PaletteViewer,PaletteViewer至少应该在子类里面存在才是合适的吧,个人觉得PaletteViewer并不是一个gef应用必须的。

在EditDomain里面,EditDomain会转发来自EditPartViewer,PaletteViewer的请求,把它们转发给当前的activeTool,让activeTool处理这些事件。CommandStack命令栈,这个就不说了,不知道的别玩了,洗洗睡算了。

EditDomain自己是不构建Tool的,它都是从响应的Viewer里面获取的,也就是说Viewer提供了事件以为,还提供了处理事件的tool。

?

?

Tool:

想理解Tool是干嘛的,Tool接口上有一段详细的英文说明。Tool具备以下功能:

(1)获取EditDomain和EditPartViewer的事件,并把这些事件转换成请求,让相应的EditPart进行响应和处理。

(2)它自己本身也可以处理一些事件,例如切换选中状态,让viewer滚动,执行一个命令之类的。

说白了,Tool就是对界面事件的第一道处理工序,至于是自己直接处理,还是转发给EditPart,完全在于此事件的复杂度。

注意:官方说明,不要直接实现Tool接口,而是继承其AbstractTool,这是个建议。

?

Tool的继承关系,可以直接通过F4查看,整个结构比较简洁清晰,基本上gef所有的行为都能找到对应的Tool。eclipse最大的特点就是见文识意,基本上当你需要的时候,直接看实现类的名字就能找到地方了。具体的我自己也没研究。

?

常见Tool:

DragTracker:一个继承自Tool的接口,主要是用于响应拖拽操作的。

MarqueeSelectionTool:MarqueeToolEntry用的,选中编辑器里面的多个组件

ConnectionBendpointTracker:移动或创建连线上面的拐点的Tool

ResizeTracker:改变组件size的tool

RulerDragTracker:移动游标的,这个跟编辑器的Ruler效果相关

TargetingTool:是所有需要把事件请求转发给Editpart执行的tool的基类。

ConnectionCreationTool:用于连线的tool,ConnectionDragCreationTool与其功能相仿

?

SelectEditPartTracker:操作EditPart的,只是响应选中,编辑,打开等操作,拖拽由其子类实现。

DragEditPartsTracker:在父的基础上实现了移动的能力

DragTreeItemsTracker:拖拽树节点,大纲视图用到

?

SelectionTool:这个tool是很关键的一个tool,它是EditDomain默认提供的一个tool,我们说过EditDomain会把事件给相应的tool进行处理。但是事实上PaletteViewer获取当前活动的tool是有一个方法的:paletteViewer.getActiveTool(),但是EditPartViewer却没有这样的方法,而且EditDomain也没有什么调用特殊的方法获取EditPartViewer的tool。最后发现其实SelectionTool这个默认的tool会到EditPart里面获取相应的tool。

?

?

?

2.PaletteViewer

PaletteViewer:

在编辑器里面除了EditPartViewer以外还有PaletteViewer。PaletteViewer就是我们看到的面板,它也是用gef实现的。在PaletteViewer中有一套数据模型,其根类是PaletteEntry,它相当于gef里面的模型层,记录这界面的显示信息,以及实体的操作信息。

PaletteEntry的子类:

PaletteContainer:所有继承此类的类,都表示的是palette上的容器节点,例如?PaletteDrawer 就是我们常用的可折叠容器,PaletteRoot代表着palette的根节点,也是继承这个类。

ToolEntry:这个类的含义是,所有继承了它的类,都能够在编辑器中使用。例如gef默认提供的SelectionToolEntry:选中节点的那个tool,MarqueeToolEntry:画一个矩形框选中多个组件的tool,CreationToolEntry:以及我们创建一个界面元素常用的tool

其他:PaletteSeparator:分隔符,PaletteTemplateEntry:模板(这个没用过)

?

刚才提到ToolEntry可以在编辑器使用,也就是说它能够在编辑器上做一些行为,例如拖拽创建,点击选中,拖拽选中之类的操作。之所以能有这些能力,主要是因为在构造一个ToolEntry的时候同事会传一个Tool类型进去,之后使用的时候会创建一个Tool。

?

CreationToolEntry构造方法里面的代码:它会传一个CreationTool类型的tool进去,它会把基本的拖拽事件转换为创建请求,传递给EditPart处理

?

?

protected boolean handleButtonDown(int button) {if (!stateTransition(STATE_INITIAL, STATE_DRAG)) {resetHover();return true;}resetHover();EditPartViewer viewer = getCurrentViewer();Point p = getLocation();if (getDragTracker() != null)getDragTracker().deactivate();if (viewer instanceof GraphicalViewer) {Handle handle = ((GraphicalViewer) viewer).findHandleAt(p);if (handle != null) {setDragTracker(handle.getDragTracker());return true;}}updateTargetRequest();((SelectionRequest) getTargetRequest()).setLastButtonPressed(button);updateTargetUnderMouse();EditPart editpart = getTargetEditPart();if (editpart != null) {setDragTracker(editpart.getDragTracker(getTargetRequest()));lockTargetEditPart(editpart);return true;}return false;}
?

其中最关键的一步:setDragTracker,然后其他相应事件的方法就调用这个Tool来对事件进行处理了。

?

?

附:

?

我们在刚入门的时候,通常只会关注如何扩展EditPart,以及它里面的东西,很少关注EditPart由谁管理,如何管理。这篇文章很浅,因为作者很浅,但是希望对不清楚的人有点帮助。

?

读书人网 >开源软件

热点推荐