工作以来一直都在做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处理
super(label, shortDesc, iconSmall, iconLarge, CreationTool.class);
SelectionToolEntry的构造方法里面的代码类似,不同的是它给的是一个SelectionTool用于选中的。
super(label, shortDesc, SharedImages.DESC_SELECTION_TOOL_16,
SharedImages.DESC_SELECTION_TOOL_24, SelectionTool.class);
3.EditPartViewer
ISelectionProvider:
ISelectionProvider是一个jface的接口,EditPartViewer继承于ISelectionProvider,ISelectionProvider主要用于管理选中节点的,这套机制并不属于gef或者编辑器的,而是eclipse的内部机制,也可以说是SWT的选中节点的管理机制。
EditPartViewer:
EditPartViewer继承了ISelectionProvider,标志着所有的EditPartViewer都可以作为一个ISelection源在eclipse内部进行流转。一个gef架构的图形化编辑器是,建立在一套EditPartViewer的基础之上的,用我的理解称EditPartViewer为一个业务单元。EditPartViewer接口里面的方法很多,大致分为几个方向:操作(菜单,快捷键,光标之类),事件(拖拽之类的),对EditPart的管理(EditDomain,EditPartFactory,提供根据鼠标位置获得EditPart的接口,flush),createControl方法提供对原始的SWT组件界面的支持(验证了在大纲视图中使用的能力)。
可以说EditPartViewer就像gef的脸,它是直接面对用户的,用户所有的操作和请求,都是从它这里进行转发的。
EditPartViewer接口也是不建议自己直接实现的,而是继承此类AbstractEditPartViewer,在AbstractEditPartViewer里面有一个SelectionManager对象,用于管理当前Viewer的选中模型,在SelectionManager里面有一个appendSelection(EditPart editpart)方法,从参数名就可以看出。我们在Viewer上选中的是一个个EditPart 对象,这也是为啥,我们在属性视图会获取到EditPart 而不是Viewer的原因。
4.上述三者之间的联系
上述三者肯定是由EditDomain组织起来的,而最终的结果肯定是:Viewer监听事件,并响应事件,把事件传递给EditDomain,EditDomain找到相应的tool来进行处理,而这个tool又是Viewer自己提供的。EditDomain起到了一个中枢的作用。那么整个过程是怎样的呢?
PaletteViewer:
PaletteViewer提供了获取ActiveTool的方法,所以对于PaletteViewer来说,处理方式很简单。
private void handlePaletteToolChanged() {
PaletteViewer paletteViewer = getPaletteViewer();
if (paletteViewer != null) {
ToolEntry entry = paletteViewer.getActiveTool();
if (entry != null)
setActiveTool(entry.createTool());
else
setActiveTool(getDefaultTool());
}
}
在EditDomain里面有一个handlePaletteToolChanged方法,在选中面板上的节点的时候会进入到这个方法。它会把获取当前的PaletteTool,当面板上的选中失去的时候,又会进入到这个方法。但执行的是setActiveTool(getDefaultTool());
EditPartViewer:
上面也说道了一点,EditPartViewer是不直接提供tool的,在EditDomain里面所有跟EditPartViewer相关的操作都会给SelectionTool(默认提供的tool),然后在SelectionTool里面会找到EditPartViewer相应的EditPart,EditPart会提供可用的ActiveTool。
SelectionTool这整个类就是想办法获取EditPart里面的那个可用的Tool,针对同步的事件类型,选择不同的获取方式,这里贴出其中一个方法,其他的方法与其类似:
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由谁管理,如何管理。这篇文章很浅,因为作者很浅,但是希望对不清楚的人有点帮助。
分享到:
相关推荐
对gef中相关内容的描述,这里面我只是个人的理解,描述gef的最基本的功能,若需深入研究,可以从网上查询更多资料,我个人也在继续研究中。
与 其他一些MVC编辑框架相比,GEF的一个主要设计目标是尽量减少模型和视图之间的依赖,好处是可以根据需要选择任意模型和视图的组合,而不必受开发框架 的局限(不过实际上还是很少有脱离Draw2D的实现)。
GEF入门系列,八进制 的GEF入门系列教程, 由社区经作者授权后整理而成GEF(Graphical Editor Framework)是一个图形化编辑框架,它允许开发人员以图形化的方式展示和编辑模型,从而提升用户体验。这样的应用程序有很...
GEF: Graphical Editing Framework <br>GEF是一套MVC Framework,它能帮你比较容易的建立图形化的编辑器,V(View)的部分常常是基于SWT的Draw2D,因此Draw2D也看作是GEF的一部分。依赖:org.eclipse.gef***, org...
用视图显示在GEF编辑器编辑好的图形 在视图里加入GraphicalViewer viewer = new ScrollingGraphicalViewer(); viewer.createControl(parent);
GEF(Graphical Editor Framework)是一个图形化编辑框架,它允许开发人员以图形化的方式展示和编辑模型,从而提升用户体验。这样的应用程序有很多,例如:UML类图编辑器、图形化XML编辑器、界面设计工具以及图形化...
Xtext 的 GEF 编辑器集成示例项目将 Xtext 集成到基于 GEF 的编辑器中,为的演示而。 org.xtext.example.statemachine :所述的statemachine的Xtext语言(一个例子的Xtext语言的变型)和运行时代码(解析器,串行化...
GEF入门必读 GEF入门系列 GEF-whole-upload 感谢八进制
我下的资源的打包,希望有帮助,包括:GEF_Tutorial,GEF实例,入门教程,GEF-whole-upload
由于工作的需要,最近开始研究GEF(Graphical Editor Framework)这个框架,它可以用来给用户提供图形化编辑模型的功能,从而提升用户体验,典型的应用如图形化的流程设计器、UML类图编辑器等等。
GEF简易教程-学习GEF的入门教程,不错的gef入门教程
GEF eclipse 插件
gef 绘图折线的实现方法。 gef API chm 格式
3. 节点内容的编辑功能 4. 删除连线 5. 删除节点 6. 对节点的拖动以改变位置 运行这个例子的方法: 0. 必须要有一个Eclipse RCP的开发环境 1. 在你的Eclipse中要有GEF, Draw2d的包 2. 将此压缩包中的eclipse ...
GEF图形编辑框架使用指南,从新手到入门,详细的讲解了如何使用GEF进行图形编辑
GEF.rar GEF.rar GEF.rar
Agenda Start things off What is GEF? GEF Demo Draw2d Overview Example GEF Overview Break Hands-on Activity: Shapes Example
GEF理解之第三部分,学习gef必备文档资料啊,值得下载
GEF理解之第一部分,学习gef必备文档资料啊,值得下载
Eclipse插件GEF的介绍,对于学习GEF有很大帮助