[Eclipse]GEF入门系列(四、其他功能)

简介: 最近由于实验室任务繁重,一直没有继续研究GEF,本来已经掌握的一些东西好象又丢掉了不少,真是无奈啊,看来还是要经常碰碰。刚刚接触GEF的朋友大都会有这样的印象:GEF里概念太多,比较绕,一些能直接实现的功能非要拐几个弯到另一个类里做,而且很多类的名字十分相似,加上不知道他们的作用,感觉就好象一团乱麻。

最近由于实验室任务繁重,一直没有继续研究GEF,本来已经掌握的一些东西好象又丢掉了不少,真是无奈啊,看来还是要经常碰碰。刚刚接触GEF的朋友大都会有这样的印象:GEF里概念太多,比较绕,一些能直接实现的功能非要拐几个弯到另一个类里做,而且很多类的名字十分相似,加上不知道他们的作用,感觉就好象一团乱麻。我觉得这种情况是由图形用户界面(GUI)的复杂性所决定的,GUI看似简单,实际上包含了相当多的逻辑,特别是GEF处理的这种图形编辑方式,可以说是最复杂的一种。GEF里每一个类,应该说都有它存在的理由,我们要尽可能了解作者的意图,这就需要多看文档和好的例子。

在Eclipse里查看文档和代码相当便利,比如我们对某个类的用法不清楚,一般首先找它的注释(选中类或方法按F2),其次可以查看它在其他地方用法(选中类或方法按Ctrl+Shift+G),还可以找它的源代码(Ctrl+鼠标左键或F3)来看,另外Ctrl+Shift+T可以按名称查找一个类等等。学GEF是少不了看代码的,当然还需要时间和耐心。

好,闲话少说,下面进入正题。这篇帖子将继续上一篇内容,主要讨论如何实现DirectEdit、属性页和大纲视图,这些都是一个完整GEF应用程序需要提供的基本功能。

实现DirectEdit

所谓DirectEdit(也称In-Place-Edit),就是允许用户在原本显示内容的地方直接对内容进行修改,例如在Windows资源管理器里选中一个文件,然后按F2键就可以开始修改文件名。实现DirectEdit的原理很直接:当用户发出修改请求(REQ_DIRECT_EDIT)时,就在文字内容所在位置覆盖一个文本框(也可以是下拉框,这里我们只讨论文本的情况)作为编辑器,编辑结束后,再将编辑器中的内容应用到模型里即可。(作为类似的功能请参考:给表格的单元格增加编辑功能

directedit.gif
图1 Direct Edit

在GEF里,这个弹出的编辑器由DirectEditManager类负责管理,在我们的NodePart类里,通过覆盖performRequest()方法响应用户的DirectEdit请求,在这个方法里一般要构造一个DirectEditManager类的实例(例子中的NodeDirectEditManager),并传入必要的参数,包括接受请求的EditPart(就是自己,this)、编辑器类型(使用TextCellEditor)以及用来定位编辑器的CellEditorLocator(NodeCellEditorLocator),然后用show()方法使编辑器显示出来,而编辑器中显示的内容已经在构造方法里得到。简单看一下NodeCellEditorLocator类,它的关键方法在relocate()里,当编辑器里的内容改变时,这个方法被调用从而让编辑器始终处于正确的坐标位置。DirectEditManager有一个重要的initCellEditor()方法,它的主要作用是设置编辑器的初始值。在我们的例子里,初始值设置为被编辑NodePart对应模型 (Node)的name属性值;这里还另外完成了设置编辑器字体和选中全部文字(selectAll)的功能,因为这样更符合一般使用习惯。

在NodePart里还要增加一个角色为DIRECT_EDIT_ROLE的EditPolicy,它应该继承自DirectEditPolicy,有两个方法需要实现:getDirectEditCommand()和showCurrentEditValue(),虽然还未遇到过,但前者的作用你不应该感到陌生--在编辑结束时生成一个Command对象将修改结果作用到模型;后者的目的是更新Figure中的显示,虽然我们的编辑器覆盖了Figure中的文本,似乎并不需要管Figure的显示,但在编辑中时刻保持这两个文本的一致才不会出现"盖不住"的情况,例如当编辑器里的文本较短时。

实现属性页

在GEF里实现属性页和普通应用程序基本一样,例如我们希望可以通过属性视图(PropertyView)显示和编辑每个节点的属性,则可以让Node类实现IPropertySource接口,并通过一个IPropertyDescriptor[]类型的成员变量描述要在属性视图里显示的那些属性。有朋友问,要在属性页里增加一个属性都该改哪些地方,主要是三个地方:首先要在你的IPropertyDescriptor[]变量里增加对应的描述,包括属性名和属性编辑方式(比如文本或是下拉框,如果是后者还要指定选项列表),其次是getPropertyValue()和setPropertyValue()里增加读取属性值和将结果写入的代码,这两个方法里一般都是像下面的结构(以前者为例):

public Object getPropertyValue(Object id) {
    
if  (PROP_NAME.equals(id))
        
return  getName();
    
if  (PROP_VISIBLE.equals(id))
        
return  isVisible()  ?   new  Integer( 0 ) :  new  Integer( 1 );
    
return   null ;
}

也就是根据要处理的属性名做不同操作。要注意的是,下拉框类型的编辑器是以Integer类型数据代表选中项序号的,而不是int或String,例如上面的代码根据visible属性返回第零项或第一项,否则会出现ClassCastException。

properties.gif
图2 属性页

实现大纲视图

在Eclipse里,当编辑器(Editor)被激活时,大纲视图自动通过这个编辑器的getAdapter()方法寻找它提供的大纲(大纲实现IcontentOutlinePage接口)。GEF提供了ContentOutlinePage类用来实现大纲视图,我们要做的就是实现一个它的子类,并重点实现createControl()方法。ContentOutlinePage是org.eclipse.ui.part.Page的一个子类,大纲视图则是PageBookView的子类,在大纲视图中有一个PageBook,包含了很多Page并可以在它们之间切换,切换的依据就是当前活动的Editor。因此,我们在createControl()方法里要做的就是构造这个Page,简化后的代码如下所示:

private Control outline;
public OutlinePage() {
    super(
new  TreeViewer());
}
public 
void  createControl(Composite parent) {
    outline 
=  getViewer().createControl(parent);
    getSelectionSynchronizer().addViewer(getViewer());
    getViewer().setEditDomain(getEditDomain());
    getViewer().setEditPartFactory(
new  TreePartFactory());
    getViewer().setContents(getDiagram());
}

由于我们在构造方法里指定了使用树结构显示大纲,所以createControl()里的第一句就会使outline变量得到一个Tree(见org.eclipse.gef.ui.parts.TreeViewer的代码),第二句把TreeViewer加到选择同步器中,从而让用户不论在大纲或编辑区域里选择EditPart时,另一方都能自动做出同样的选择;最后三行的作用在以前的帖子里都有介绍,总体目的是把大纲视图的模型与编辑区域的模型联系在一起,这样,对于同一个模型我们就有了两个视图,体会到MVC的好处了吧。

实现大纲视图最重要的工作基本就是这些,但还没有完,我们要在init()方法里绑定UNDO/REDO/DELETE等命令到Eclipse主窗口,否则当大纲视图处于活动状态时,主工具条上的这些命令就会变为不可用状态;在 getControl()方法里要返回我们的outline成员变量,也就是指定让这个控件出现在大纲视图中;在dispose()方法里应该把这个TreeViewer从选择同步器中移除;最后,必须在PracticeEditor里覆盖getAdapter()方法,前面说过,这个方法是在Editor激活时被大纲视图调用的,所以在这里必须把我们实现好的OutlinePage返回给大纲视图使用,代码如下:

public Object getAdapter(Class type) {
    
if  (type  ==  IContentOutlinePage.class)
        
return   new  OutlinePage();
    
return  super.getAdapter(type);
}

这样,树型大纲视图就完成了,见下图。很多GEF应用程序同时具有树型和缩略图两种大纲,实现的基本思路是一样的,但代码会稍微复杂一些,因为这两种大纲一般要通过一个PageBook进行切换,缩略图一般由org.eclipse.draw2d.parts.ScrollableThumbnail负责实现,这里暂时不讲了(也许以后会详细说),你也可以通过看logic例子的LogicEditor这个类的代码来了解。

outline.gif
图3 大纲视图

P.S.写这篇帖子的时候,我对例子又做了一些修改,都是和这篇帖子所说的内容相关的,所以如果你以前下载过,会发现那时的代码与现在稍有不同(功能还是完全一样的,下载)。另外要说一下,这个例子并不完善,比如删除一个节点的时候,它的连接就没同时删除,一些键盘快捷键不起作用,还存在很多被注释掉的代码等等。如果有兴趣你可以来修改它们,也是不错的学习途径。

本文转自博客园八进制的博客,原文链接:[Eclipse]GEF入门系列(四、其他功能),如需转载请自行联系原博主。

相关文章
|
Android开发
10activiti - 入门demo(Eclipse)
10activiti - 入门demo(Eclipse)
48 0
10activiti - 入门demo(Eclipse)
|
6月前
|
前端开发 Java Maven
Eclipse里使用Servlet实现简单的登录功能
Maven是一款非常方便的Java开发插件,它可以自动管理好开发过程中需要的jar包,提升开发者们的开发效率。在这里,我手把手教给大家如何新建一个Maven项目,并实现简单的用户登录功能。
182 0
|
Java Android开发 Windows
Eclipse代码自动补全功能
Eclipse代码自动补全功能
109 0
|
数据可视化 Java API
【Eclipse设计】Excel表格的读写功能
【Eclipse设计】Excel表格的读写功能
169 0
|
Go Android开发
开心档-软件开发入门之Eclipse 添加书签
Eclipse 中可以在编辑器的任意一行添加书签。 您可以使用书签作为提示信息,或者使用书签快速定位到文件中的指定的行。
|
Java 应用服务中间件 Apache
Java Web入门之开发环境的搭建(包括下载Tomcat和 Eclipse for Java EE)
Java Web入门之开发环境的搭建(包括下载Tomcat和 Eclipse for Java EE)
232 0
Java Web入门之开发环境的搭建(包括下载Tomcat和 Eclipse for Java EE)
|
Java Android开发
STS|Eclipse修改代码补全功能
STS|Eclipse修改代码补全功能
226 0
STS|Eclipse修改代码补全功能
|
Java Android开发
Eclipse自动生成作者、日期注释等功能设置
引自 http://blog.csdn.net/kaivenslove/article/details/45915493   在使用Eclipse 编写Java代码时,自动生成的注释信息都是按照预先设置好的格式生成的。
2025 0
|
XML Java API
Spring框架入门以及Eclipse创建 Spring项目
Spring框架入门以及Eclipse创建 Spring项目
Spring框架入门以及Eclipse创建 Spring项目
|
XML Java Android开发
SpringBoot入门:使用IDEA和Eclipse构建第一个SpringBoot项目
Spring Boot是一个简化Spring开发的框架,用来监护spring应用开发,约定大于配置,去繁就简,just run 就能创建一个独立的,产品级的应用。我们在使用Spring Boot时只需要配置相应的Spring Boot就可以用所有的Spring组件,简单的说,spring boot就是整合了很多优秀的框架,不用我们自己手动的去写一堆xml配置然后进行配置。所以springboot在java开发中也变得越来越重要,这里总结一下如何使用IDEA和Eclipse创建一个简单的springboot项目。
436 0
SpringBoot入门:使用IDEA和Eclipse构建第一个SpringBoot项目