sharky的点滴积累

  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  56 随笔 :: 104 文章 :: 10 评论 :: 0 Trackbacks

构造一个GEF应用程序通常分为这么几个步骤:设计模型、设计EditPart和Figure、设计EditPolicy和Command,其中EditPart是最主要的一部分,因为在实现它的时候不可避免的要使用到EditPolicy,而后者又涉及到Command。

现在我们来看个例子,它的功能非常简单,用户可以在画布上增加节点(Node)和节点间的连接,可以直接编辑节点的名称以及改变节点的位置,用户可以撤消/重做任何操作,有一个树状的大纲视图和一个属性页。点此下载,这是一个Eclipse的项目打包文件,在Eclipse里导入后运行Run-time Workbench,新建一个扩展名为"gefpractice"的文件就会打开这个编辑器。

图1 Practice Editor的使用界面

你可以参考着代码来看接下来的内容了,让我们从模型开始说起。模型是根据应用需求来设计的,所以我们的模型包括代表整个图的Diagram、代表节点的Node和代表连接的Connection这些对象。我们知道,模型是要负责把自己的改变通知给EditPart的,为了把这个功能分离出来,我们使用名为Element的抽象类专门来实现通知机制,然后让其他模型类继承它。Element类里包括一个PropertyChangeSupport类型的成员变量,并提供了addPropertyChangeListener()、removePropertyChangeListener()和fireXXX()方法分别用来注册监听器和通知监听器模型改变事件。在GEF里,模型的监听器就是EditPart,在EditPart的active()方法里我们会把它作为监听器注册到模型中。所以,总共有四个类组成了我们的模型部分。

在前面的贴子里说过,大部分GEF应用程序都是实现为Editor的,这个例子也不例外,对应的Editor名为PracticeEditor。这个Editor继承了GraphicalEditorWithPalette类,表示它是一个具有调色板的图形编辑器。最重要的两个方法是configureGraphicalViewer()和initializeGraphicalViewer(),分别用来定制和初始化EditPartViewer(关于EditPartViewer的作用请查看前面的帖子),简单查看一下GEF的代码你会发现,在GraphicalEditor类里会先后调用这两个方法,只是中间插了一个hookGraphicalViewer()方法,其作用是同步选择和把EditPartViewer作为SelectionProvider注册到所在的site(Site是Workbench的概念,请查Eclipse帮助)。所以,与选择无关的初始化操作应该在前者中完成,否则放在后者完成。例子中,在这两个方法里我们配置了RootEditPart、用于创建EditPart的EditPartFactory、Contents即Diagram对象和增加了拖放支持,拖动目标是当前EditPartViewer,后面会看到拖动源就是调色板。

这个Editor是带有调色板的,所以要告诉GEF我们的调色板里都有哪些工具,这是通过覆盖getPaletteRoot()方法来实现的。在这个方法里,我们利用自己写的一个工具类PaletteFactory构造一个PaletteRoot对象并返回,我们的调色板里需要有三种工具:选择工具、节点工具和连接工具。在GEF里,调色板里可以有抽屉(PaletteDrawer)把各种工具归类放置,每个工具都是一个ToolEntry,选择工具(SelectionToolEntry)和连接工具(ConnectionCreationToolEntry)是预先定义好的几种工具中的两个,所以可以直接使用。对于节点工具,要使用CombinedTemplateCreationEntry,并把节点类型作为参数之一传给它,创建节点工具的代码如下所示。

ToolEntry tool = new CombinedTemplateCreationEntry("Node""Create a new Node", Node.class, new SimpleFactory(Node.class), nullnull);

在新的3.0版本GEF里还提供了一种可以自动隐藏调色板的编辑器GraphicalEditorWithFlyoutPalette,对调色板的外观有更多选项可以选择,以后的帖子里可能会提到如何使用。

调色板的初始化操作应该放在initializePaletteViewer()里完成,最主要的任务是为调色板所在的EditPartViewer添加拖动源事件支持,前面我们已经为画布所在EditPartViewer添加了拖动目标事件,所以现在就可以实现完整的拖放操作了。这里稍微讲解一下拖放的实现原理,以用来创建节点对象的节点工具为例,它在调色板里是一个CombinedTemplateCreationEntry,在创建这个PaletteEntry时(见上面的代码)我们指定该对象对应一个Node.class,所以在用户从调色板里拖动这个工具时,内存里有一个TemplateTransfer单例对象会记录下Node.class(称作template),当用户在画布上松开鼠标时,拖放结束的事件被触发,将由画布注册的DiagramTemplateTransferDropTargetListener对象来处理template对象(现在是Node.class),在例子中我们的处理方法是用一个名为ElementFactory的对象负责根据这个template创建一个对应类型的实例。

以上我们建立了模型和用于实现视图的Editor,因为模型的改变都是由Command对象直接修改的,所以下面我们先来看都有哪些Command。由需求可知,我们对模型的操作有增加/删除节点、修改节点名称、改变节点位置和增加/删除连接等,所以对应就有CreateNodeCommand、DeleteNodeCommand、RenameNodeCommand、MoveNodeCommand、CreateConnectionCommand和DeleteConnectionCommand这些对象,它们都放归类在commands包里。一个Command对象里最重要的当然是execute()方法了,也就是执行命令的方法。除此以外,因为要实现撤消/重做功能,所以在Command对象里都有Undo()和Redo()方法,同时在Command对象里要有成员变量负责保留执行该命令时的相关状态,例如RenameNodeCommand里要有oldName和newName两个变量,这样才能正确的执行Undo()和Redo()方法,要记住,每个被执行过的Command对象实例都是被保存在EditDomain的CommandStack中的。

例子里的EditPolicy都放在policies包里,与图形有关的(GraphicalEditPart的子类)有DiagramLayoutEditPolicy、NodeDirectEditPolicy和NodeGraphicalNodeEditPolicy,另外两个则是与图形无关的编辑策略。可以看到,在后一种类型的两个类(ConnectionEditPolicy和NodeEditPolicy)中我们只覆盖了createDeleteCommand()方法,该方法用于创建一个负责"删除"操作的Command对象并返回,要搞清这个方法看似矛盾的名字里create和delete是对不同对象而言的。

有了Command和EditPolicy,现在可以来看看EditPart部分了。每一个模型对象都对应一个EditPart,所以我们的三个模型对象(Element不算)分别对应DiagramPart、ConnectionPart和NodePart。对于含有子元素的EditPart,必须覆盖getModelChildren()方法返回子对象列表,例如DiagramPart里这个方法返回的是Diagram对象包含的Node对象列表。

每个EditPart都有active()和deactive()两个方法,一般我们在前者里注册监听器(因为实现了PropertyChangeListener接口,所以EditPart本身就是监听器)到模型对象,在后者里将监听器从列表里移除。在触发监听器事件的propertyChange()方法里,一般是根据"事件名"称决定使用何种方式刷新视图,例如对于NodePart,如果是节点本身的属性发生变化,则调用refreshVisuals()方法,若是与它相关的连接发生变化,则调用refreshTargetConnections()或refreshSourceConnections()。这里用到的事件名称都是我们自己来规定的,在例子中比如Node.PROP_NAME表示节点的名称属性,Node.PROP_LOCATION表示节点的位置属性,等等。

EditPart(确切的说是AbstractGraphicalEditpart)另外一个需要实现的重要方法是createFigure(),这个方法应该返回模型在视图中的图形表示,是一个IFigure类型对象。一般都把这些图形放在figures包里,例子里只有NodeFigure一个自定义图形,Diagram对象对应的是GEF自带的名为FreeformLayer的图形,它是一个可以在东南西北四个方向任意扩展的层图形;而Connection对应的也是GEF自带的图形,名为PolylineConnection,这个图形缺省是一条用来连接另外两个图形的直线,在例子里我们通过setTargetDecoration()方法让连接的目标端显示一个箭头。

最后,要为EditPart增加适当的EditPolicy,这是通过覆盖EditPart的createEditPolicies()方法来实现的,每一个被"安装"到EditPart中的EditPolicy都对应一个用来表示角色(Role)的字符串。对于在模型中有子元素的EditPart,一般都会安装一个EditPolicy.LAYOUT_ROLE角色的EditPolicy(见下面的代码),后者多为LayoutEditPolicy的子类;对于连接类型的EditPart,一般要安装EditPolicy.CONNECTION_ENDPOINTS_ROLE角色的EditPolicy,后者则多为ConnectionEndpointEditPolicy或其子类,等等。

installEditPolicy(EditPolicy.LAYOUT_ROLE, new DiagramLayoutEditPolicy());

用户的操作会被当前工具(缺省为选择工具SelectionTool)转换为请求(Request),请求根据类型被分发到目标EditPart所安装的EditPolicy,后者根据请求对应的角色来判断是否应该创建命令并执行。

在以前的帖子里说过,Role-EditPolicy-Command这样的设计主要是为了尽量重用代码,例如同一个EditPolicy可以被安装在不同EditPart中,而同一个Command可以被不同的EditPolicy所使用,等等。当然,凡事有利必有弊,我认为这种的设计也有缺点,首先在代码上看来不够直观,你必须对众多Role、EditPolicy有所了解,增加了学习周期;另外大部分不需要重用的代码也要按照这个相对复杂的方式来写,带来了额外工作量。

以上就是一个GEF应用程序里最基本的几个组成部分,例子中还有如Direct Edit、属性表和大纲视图等一些功能没有讲解,下面的帖子里将介绍这些常用功能的实现。

posted on 2005-02-19 13:57 八进制 阅读(8028) 评论(83)  编辑 收藏 收藏至365Key 所属分类: Eclipse

评论

# re: [Eclipse]GEF入门系列(三、应用实例) 2005-02-23 23:59 郭奕
如果我想给Node加入可视或者其他不可视的属性,但是可以在propertyview里面编辑,应该如何做呢?期盼答复! 谢谢。
  

# re: [Eclipse]GEF入门系列(三、应用实例) 2005-02-24 11:58 八进制
应该是这样的:给模型里的Node类增加isVisible变量,当修改它的值时应会触发NodePart的propertyChange()方法,可以在这里根据isVisible的当前值更新视图。注意属性页里要作为布尔值类型来编辑,节点不可见时相关连接应该也不可见。
  

# re: [Eclipse]GEF入门系列(三、应用实例) 2005-02-25 01:46 郭奕
您好,首先谢谢您答复我。因为最近导师让我做流程验证的程序,所以又有几个问题要麻烦您。
1.我给Node类里面增加了 Type 属性,并加入了propertyDescriptor中,代码如下:
String[] comboBoxValues = {"Activity", "Control"};
protected IPropertyDescriptor[] descriptors = new IPropertyDescriptor[] {
new TextPropertyDescriptor(PROP_NAME,"Name"),
new ComboBoxPropertyDescriptor(PROP_TYPE,"Type",comboBoxValues),
};

但是,在propertyViewer里面并没有出现预期的ComboBox的结果,究竟是什么原因呢?
2.如果我有了不同类型的Node,比如正方形的Node和圆形的Node,应该继承Node类新建两个子类还是作为Node的属性呢?是否一个模型可以对应多个IFigure类呢?
由于我本行不是编程,所以用GEF很困难,有些概念还不是那么清楚,请您抽出宝贵时间,帮我解答。万分感谢!
  

# re: [Eclipse]GEF入门系列(三、应用实例) 2005-02-25 11:44 八进制
1、除了改变descriptors以外,还要修改getPropertyValue()和setPropertyValue()方法:前者应该返回Integer类型,代表combobox里的选项序号(从0开始);后者应该将value参数强制转换为Integer类型,得到用户改变的选项序号,根据此值调用你的setType()方法。
2、两种方式应该都能实现,我想用子类的方法更直观一些。一个模型可以对应多个IFigure类,因为可以有多个视图表现。
  

# re: [Eclipse]GEF入门系列(三、应用实例) 2005-02-28 04:32 郭奕
谢谢你的解答。我最近一直在看这个例子。对GEF也有了一些初步的了解。我也对比了另外一个例子epctools,不知道你用过没有?如果需要我可以给你下载的连接地址。
感觉这个例子好的地方在于:
1。Model层中将model的通知机制抽象出来,代码更OO;
2。Node由于实现了IPropertySource,可以在propertyView中即时修改Node的属性。
不好的地方(也可能是很好,但是我不太懂地方)
1。Node节点没有实现IPropertySource的接口;
2。Node没有子类,我试着扩展了Node,NodePart的createfigure也根据类型的不同进行了修改;PartFactory的createEditPart也修改了.具体代码如下:
protected IFigure createFigure() {
try {
switch (m_type) {
case Node.TYPE_ACTIVITY: {
m_figure = new ActivityFigure((ActivityNode) getModel());
break;
}
case Node.TYPE_CONTROL: {
m_figure = new ControlFigure((ControlNode) getModel());
break;
}

default: {
m_figure = new org.eclipse.draw2d.Label();
break;
}
}
} catch (ClassCastException e) {
System.out
.println("[controllers] NodePart.createFigure(): Check epc node type (Cast error)");
}
return m_figure;
}。。。。。
public EditPart createEditPart(EditPart context, Object model) {
EditPart part = null;
if (model instanceof Diagram)
part = new DiagramPart();
else if (model instanceof Connection)
part = new ConnectionPart();
else if (model instanceof ControlNode)
part = new NodePart(Node.TYPE_CONTROL);
// part = new NodePart();
else if (model instanceof ActivityNode)
part = new NodePart(Node.TYPE_ACTIVITY);
else if (model instanceof MultiNode)
part = new NodePart(Node.TYPE_MULTINODE);
else
part = new NodePart(Node.TYPE_NONE);
part.setModel(model);
return part;
}

我要做的程序功能很简单,1.节点分为Activity(方的)、Control(圆的);
2. 通过算法(已经完成)找到图中的arbitary cycle (block),每一个合法cycle用复杂节点表示(可以展开).
我要把epcTools这个例子改一改。
有兴趣的话可以看看这个基于GEF的EpcTools的例子。
http://wwwcs.upb.de/cs/kindler/Forschung/EPCTools/download.html
再次谢谢你给予的无私的帮助!
  

# re: [Eclipse]GEF入门系列(三、应用实例) 2005-02-28 10:38 八进制
“Node由于实现了IPropertySource”和“Node节点没有实现IPropertySource的接口”矛盾哦。
一般应用里Node是应该有子类的,这时让Node作为抽象类更合适些,例如你的Activity和Control都应该继承Node类。
有一些基础以后,一定要看看Eclipse提供的Logic或Flow例子,它们是GEF的开发人员参与编写的,很有代表性。
能给你带来帮助我也很高兴!
  

# re: [Eclipse]GEF入门系列(三、应用实例) 2005-03-01 10:10 郭奕
对不起,写错啦。我想说那个EPCTools的例子的Node节点没有实现IPropertySource的接口。Eclipse的Logic的例子SourceCode,怎么放到Project里面运行啊?我看了一下,好像它提供的plugin.xml不太对
  

# re: [Eclipse]GEF入门系列(三、应用实例) 2005-03-01 14:29 八进制
我只在2.1版本里运行过Logic例子,它现在有了新的版本,外观也稍有不同。你要确定使用的是能在你的Eclipse版本里运行的Logic,应该很容易装的。
  

# re: [Eclipse]GEF入门系列(三、应用实例) 2005-03-02 06:00 郭奕
我在3.0.1里面运行例子也没有问题。:P.我想看它的源代码,并能编译运行。
另外可以知道你的MSN吗?我的是eric_guoyi@hotmail.com
我下载了org.eclipse.gef.examples.source_3.0.1。可是不知道如何放在Eclipse的workbench里面运行.
最近怎么不继续写下去了。。确实对我的帮助很大
  

# re: [Eclipse]GEF入门系列(三、应用实例) 2005-03-02 06:26 郭奕
运行logic的sourceCode那个问题已经解决了。谢谢。要在plugin.xml里面的requires加入如下
<import plugin="org.eclipse.core.runtime.compatibility"/>
<import plugin="org.eclipse.ui.ide"/>
<import plugin="org.eclipse.ui.views"/>
<import plugin="org.eclipse.jface.text"/>
<import plugin="org.eclipse.ui.workbench.texteditor"/>
<import plugin="org.eclipse.ui.editors"/>
<import plugin="org.eclipse.gef"/>
<import plugin="org.eclipse.core.resources"/>
<import plugin="org.eclipse.ui"/>
  

# re: [Eclipse]GEF入门系列(三、应用实例) 2005-03-03 10:46 八进制
抱歉,最近比较忙,接下来的文章得过一段时间再续写了。
  

# re: [Eclipse]GEF入门系列(三、应用实例) 2005-03-07 13:02 howjay
奇怪,我下了你的例子,不过在 PracticeEditor-OutlinePage 有这个错误:

“不能解析类型 org.eclipse.ui.views.contentoutline.IContentOutlinePage。从必需的 .class 文件间
接引用了它”

这个是什么问题?明明 import 了org.eclipse.ui.views.contentoutline.IContentOutlinePage; 啊
  

# re: [Eclipse]GEF入门系列(三、应用实例) 2005-03-07 13:03 howjay
对了,我只安装了 GEF 的 runtime 版本,没有安装 SDK,现在这个错误和我以前说的那个 pt1-pt6 例子的错误会不会有关系啊?我去下个sdk试试
  

# re: [Eclipse]GEF入门系列(三、应用实例) 2005-03-07 13:05 howjay
不好意思,我的意思是说这些例子我运行不起来是不是和我没有安装sdk有关系,不是说那两个错误之间有关系-__-
  

# redbook里面提到的sg246302 的例子如何修改才能在3.0里面运行? 2005-03-12 22:10 郭奕
redbook里面提到的sg246302 的例子如何修改才能在3.0里面运行? 另外你看到过介绍GEF自带的logic和flow例子的文章吗?有点复杂,很多地方看不太懂。

  

# re: [Eclipse]GEF入门系列(三、应用实例) 2005-03-14 10:39 八进制
sg246302和介绍logic/flow的文章我都没看过,我觉得应该有些基础以后再看,最好自己做做简单的应用。我马上要开始用GEF做项目了,到时会把更多心得写下来的。
  

# re: [Eclipse]GEF入门系列(三、应用实例) 2005-05-13 11:38 upcxcf
清问我的是ecilipse2.1和GEF2.1请问对于你的代码我怎么修改呢。我才可以正确地使用呢。谢谢
  

# re: [Eclipse]GEF入门系列(三、应用实例) 2005-05-13 13:38 八进制
是你们的项目要求版本吗,如果不是换成3.0以上是最方便的办法。
Eclipse带了一个Migration Guide文档,里面是从2.1到3.0版本需要修改的地方,你可以参考一下。前面说的pt1~pt6的例子本身就是在2.1下运行的,你也可以先看它们。
我自己做的这些例子都没考虑2.1版本,比如后面帖子里说的Ruler/Guide那些功能就必须GEF3.0以上版本,另外一些功能简单的例子你可以试试放在2.1里看有什么错误,如果只是plugin引用的问题应该可以通过修改plugin.xml文件改好的。
  

# re: [Eclipse]GEF入门系列(三、应用实例) 2005-05-13 15:27 upcxcf
您好,我得是eclipse2.1和GEF2.1。我想问下上面得例子在我导入工程后,出现好多错误。请问我该怎么做?
  

# re: [Eclipse]GEF入门系列(三、应用实例) 2005-05-13 15:36 upcxcf
谢谢八进制 ,我是下载了一个别人做好得GEF插件。我现在用的是GEF2.1的。后来我看他的代码中有<import plugin="org.eclipse.gef" version="2.0.1"/>。而我的版本是gef2.1的。所以那个插件不能用的。我在www.eclispe.org上又没有找到这么低版本的。最少的也是2.1。请问我该怎么办?
后来我看了你的帖子。他的功能和你上面提出的一样的。就是连线和其他的几个图形连接。你看我该怎么修改呢?
因为时间很紧。所以请赐教。QQ61757325.急盼
  

# re: [Eclipse]GEF入门系列(三、应用实例) 2005-05-13 16:20 八进制
把version="2.0.1"去掉看看,我觉得2.1的GEF应该可以运行2.0.1做的程序。
  

# re: [Eclipse]GEF入门系列(三、应用实例) 2005-05-13 16:20 upcxcf
ni好,我换成ECLIPSE3.0和GEF3.0后,导入工程gefpractice.后,怎么还是不可一呢?出现好些错误。
请把在Eclipse里导入后运行Run-time Workbench,新建一个扩展名为"gefpractice"的文件就会打开这个编辑器。 。详细说下。谢谢
  

# re: [Eclipse]GEF入门系列(三、应用实例) 2005-05-13 22:36 八进制
我刚刚得知,GEF第一个版本就是2.1,他代码里的2.0.1是怎么回事……
出现的错误是什么,在Eclipse的Problems视图里应该有错误信息,贴来看一下吧。
  

# re: [Eclipse]GEF入门系列(三、应用实例) 2005-05-23 08:54 upcxcf
你好,我这里有个简单的GEF应用程序源代码。但是我无法让它正常工作。很是着急。功能和你上面的很类似。我的MSN是upcxcf@hotmail.com。在线等。希望赐教
  

# re: [Eclipse]GEF入门系列(三、应用实例) 2005-05-23 22:16 八进制
不好意思,今天一天都没连上这里,现在刚看到你的留言。你可以把那个工程(大小不要超过1M)发到我邮箱里我帮你看看什么问题。
  

# re: [Eclipse]GEF入门系列(三、应用实例) 2005-05-24 09:41 xunix
请问一下您的例子中的NodeFigure这个类似乎没有被其他类用到啊,这个类到底是怎么工作的啊?
  

# re: [Eclipse]GEF入门系列(三、应用实例) 2005-05-24 15:08 八进制
有用到啊,在NodePart的createFigure()方法里返回的就是一个NodeFigure实例。这个Figure的作用没有什么特别,就是表现一个黑框包围的矩形,中间有一个标签。
  

# re: [Eclipse]GEF入门系列(三、应用实例) 2005-05-25 08:41 upcxcf
八进制,您好,谢谢.但是我不知道你的信箱......????谢谢你的帮助.我的这个例子.你和上面的很相似.就是几个图形,然后加上连接线的.急切的等待你的回复
  

# re: [Eclipse]GEF入门系列(三、应用实例) 2005-05-25 13:12 八进制
按网页最上面的“联系”链接可以看到我的邮箱,因为会有垃圾邮件所以不敢发在这里,见谅!
  

# re: [Eclipse]GEF入门系列(三、应用实例) 2005-05-26 10:08 UPCXCF
已经在联系中给你发了一封信,但是还没有得到您的回复,无法将我的一个GEF小的应用程序发给你.请EMAIL回复下吧.谢谢.急
  

# re: [Eclipse]GEF入门系列(三、应用实例) 2005-05-26 13:26 八进制
暂时还没有收到你的信,你把你的程序打包发到“联系”里看到的地址即可。
  

# re: [Eclipse]GEF入门系列(三、应用实例) 2005-05-27 08:45 upcxcf
八进制 ,联系里找了半天没有你的地址.
您先发一份信到我的 信箱吧upcxcfzl@163.com.我再回复你吧.
目前比较着急的.谢谢.等待您的来信.万分感谢
  

# re: [Eclipse]GEF入门系列(三、应用实例) 2005-05-29 17:30 upcxcf
请问最后得到的EMF图形化编辑器它有什么作用.?如下面的网页
http://eclipse.org/emf/docs.php?doc=docs/xlibmod/xlibmod_emf1.1.html
得到文本的描述有什么作用?得到网页最后的一个图有什么作用那?
  

# re: [Eclipse]GEF入门系列(三、应用实例) 2005-05-31 10:04 xunix
请问一下,Node节点画出来的过程是怎样的啊?我的理解是这样的:DiagramPart在收到请求后,将请求发送给DiagramLayoutEditPolicy, DiagramLayoutEditPolicy.java在接到请求后就去调用CreateNodeCommand,然后就创建了Node,但是这样的问题是,为什么NodeFigure是在NodePart里面创建的呢?请解答一下,谢谢!
  

# re: [Eclipse]GEF入门系列(三、应用实例) 2005-05-31 10:40 八进制
CreateNodeCommand负责操作模型,在它的execute()方法里应该有类似diagram.addChild()的语句用来把新建的Node加为diagram的子元素,这个addChild()方法会触发监听器(DiagramPart)的propertyChanged()方法,这里在得知diagram新增了子元素时会调用refreshChildren()方法,在这个方法里将生成新建Node所对应的EditPart(通过你的EditPartFactory),并通过addChild()调用EditPart的createFigure()得到Node的图形,添加在diagram图形的contentPane上。
  

# re: [Eclipse]GEF入门系列(三、应用实例) 2005-05-31 11:09 xunix
谢谢你的解答,但是我还是有点不明白的是,在DiagramLayoutEditPolicy中并没有调用CreateNodeCommand的execute()这个方法啊,那么这个方法是怎么自动执行的呢?谢谢!
  

# re: [Eclipse]GEF入门系列(三、应用实例) 2005-05-31 11:21 xunix
还有请问一下,你提到的EditPartFactory我该怎么来建啊?谢谢
  

# re: [Eclipse]GEF入门系列(三、应用实例) 2005-05-31 13:20 八进制
DiagramLayoutEditPolicy只负责返回command,你从工具栏里拖动一个节点到画布上,当你松开鼠标的时候,Viewer上注册的TemplateTransferDropTargetListener会得到这个command并调用CommandStack.execute(cmd)(这里会调用cmd的execute()方法,用CommandStack主要是为了实现undo和redo)。
EditPartFactory的实现在代码里有,名叫PartFactory,你看一下就知道了,很容易。
  

# re: [Eclipse]GEF入门系列(三、应用实例) 2005-05-31 13:49 xunix
不好意思,今天问您这么多问题。我现在遇到了一个问题是当我新增加了一种Node后,不知道如何通过refreshChildren()方法来新建我这种新Node对应的EditPart,请您详细解答一下这个过程,谢谢!
  

# re: [Eclipse]GEF入门系列(三、应用实例) 2005-05-31 21:40 NetWeaver
请问一下,如果我给Node增加一个属性后怎么给这个属性初始化一个值啊,就像NAME这个属性就有一个初始化的“Node”的值,我看了您的源代码,发现了一个String name="node", 但是不知道这个值是怎么赋到属性中去的,请赐教,谢谢!
  

# re: [Eclipse]GEF入门系列(三、应用实例) 2005-05-31 22:35 八进制
xunix: 只要在DiagramPart的propertyChanged()方法里判断是哪个属性被改变,如果是children有变化,执行refreshChildren()即可。
NetWeaver: String name="Node"就是给name属性初始化值了,比如你新增一个price属性,就写int price=100就可以了,是不是我没明白你的问题?
  

# re: [Eclipse]GEF入门系列(三、应用实例) 2005-06-01 16:53 NetWeaver
我的意思是,Node这个值是怎么传递给属性name的,谢谢!
  

# re: [Eclipse]GEF入门系列(三、应用实例) 2005-06-01 19:50 八进制
还是不太明白……是指如何显示在properties view里吗,只要在descriptions数组里增加这个属性,然后在getPropertyValue()和setPropertyValue()方法里处理一下就可以了。
  

# re: [Eclipse]GEF入门系列(三、应用实例) 2005-06-06 20:26 whatisnew
看了你的照片,又看了你的文章说现在研二,好像是在crl或者csdl实习过,如果方便,请问您是哪个学校的?
  

# re: [Eclipse]GEF入门系列(三、应用实例) 2005-06-06 20:34 whatisnew
your blog is really a big help for these gef beginners, thank u !
  

# re: [Eclipse]GEF入门系列(三、应用实例) 2005-06-06 23:21 八进制
您猜得很对。我在Peking University,欢迎交流,页面左边有我的邮箱。
  

# re: [Eclipse]GEF入门系列(三、应用实例) 2005-07-01 17:20 张俊
八进制,你好。看你的BLOG,是我学习GEF的第1步,但是我觉得你没有讲好基础概念。没有对目录结构进行一下说明。
我在学习时,修改你的例子,增加了一个和NODE同级的activity,费了不少事情。当然,如果我用NODE作为基类,就没那么多麻烦了。但是为了更详细的了解,我抽象了一个FlowElement去保持连接和位置属性,结果遇到了DiagramPart的getChilds的麻烦,activity放不到Diagram中去。呵呵,没办法,谁知道AbstractEditPart的refreshChildren()的做法呢,这个是被隐藏的细节了。
  

# re: [Eclipse]GEF入门系列(三、应用实例) 2005-07-02 10:19 张俊
你的Connection没有使用标准的工厂机制啊。
  

# re: [Eclipse]GEF入门系列(三、应用实例) 2005-07-02 10:43 张俊
能不能单独讲解一个GEF的步骤啊:
创建figure、editPart、editPartFactory、policy、command;
各个步骤的关键要注意什么,怎么让GEF知道各个部件的关系。
最好是能讲一下GEF中,产生一个图形,创建一个connection时,GEF的调用过程,比如基类的AbstractGraphicalEditPart有哪些函数被先后调用了,那些是GEF包装的基本实现,是可以覆盖修改的。
这样,我们才能知道那些函数是可以覆盖的,确切的插入点在哪里。
  

# re: [Eclipse]GEF入门系列(三、应用实例) 2005-07-02 13:51 八进制
张俊,这个系列文章陆陆续续写了四五个月,一开始的时候我对gef的很多机制都不了解,所以有些没搞清楚的概念就没写在上面。gef的东西还是挺多的,一两句说不清(否则我也没必要写这么多了),最关键的还是弄清EditPart、EditPolicy,弄清它们的最好办法是看代码,比如gef自带的和我这里提供的几个。至于调用过程,在代码里设置一些断点可以很方便的观察到。
  

# re: [Eclipse]GEF入门系列(三、应用实例) 2005-07-12 20:35 liuyu
请问八进制如果我想在Connection不是单纯的线段,而是我自己的图片应该怎么做?如果是一般的图形,我可以用ImageFigure,但是Connection我就不会了。
  

# re: [Eclipse]GEF入门系列(三、应用实例) 2005-07-13 20:54 八进制
和普通图形没有区别吧,在你的ConnectionPart里覆盖createFigure()方法不能实现?
  

# re: [Eclipse]GEF入门系列(三、应用实例) 2005-07-14 19:34 liuyu
PolylineConnection conn = new PolylineConnection();

conn.setConnectionRouter(new ManhattanConnectionRouter());
conn.setTargetDecoration(new PolygonDecoration());

这是ConnectionPart里面的createFigure,怎么在conn上加图片呢?举个例子吧,谢谢:)
  

# re: [Eclipse]GEF入门系列(三、应用实例) 2005-07-15 00:17 八进制
你是指用图片作为连接线,还是在连接线上加图片呢?如果是前者,这里不应该用PolylineConnection,可能该用ImageFigure这样的类型;如果是后者,应该用locator实现,就像给连接线加箭头一样。
  

# re: [Eclipse]GEF入门系列(三、应用实例) 2005-07-15 10:45 liuyu
我要的是前者,但是问题是如果用了ImageFigure的话Connection的那些性质不就没有了吗?比如Connection的拉长、缩短,还有Bendpoint、ManhattanConnectionRouter之类的也不能用了咯?是不是这些东西都要自己去实现阿?
  

# re: [Eclipse]GEF入门系列(三、应用实例) 2005-07-15 17:38 八进制
BendPoint和Router肯定不能用了,都不是polyline了啊。
  

# re: [Eclipse]GEF入门系列(三、应用实例) 2005-07-15 20:03 liuyu
哦,那要做出漂亮的线真的是困难了。。。
  

# re: [Eclipse]GEF入门系列(三、应用实例) 2005-07-20 21:15 liuyu
我看到你的例子里面如果node放在连线上面,连线还是会看得到的,而不会被遮掉,是不是因为Connection的Layer总是在Node所在的Layer上面的?我不想要这样,我希望如果node放在Connection上面的话能够把下面的Connection遮掉,就像一个node把另一个node遮掉一样怎么办?
  

# re: [Eclipse]GEF入门系列(三、应用实例) 2005-07-20 22:37 八进制
可以试试覆盖ScalableRootEditPart或FreeformGraphicalRootEditPart类(视你在程序用哪个作为RootEditPart而定)的createPrintableLayers()方法,我觉得把两个layer的顺序颠倒一下应该就可以了。
  

# re: [Eclipse]GEF入门系列(三、应用实例) 2005-07-22 14:05 liuyu
非常感谢,的确换一下顺序就能克服这个问题了,现在还有两个问题想请教:
第一,如果是同一个Layer的part,比如2个Activity,他们的前后顺序好像是按照他们拖放上来的先后顺序所决定的吧,后放上来的肯定会把前面放上来的遮掉,有没有改变这种状态呢?还是说无法改变的?
第二,现在按照你的例子,Activity上的文字都是写在Activity的中央的,如果我想改变这文字的位置,比如放在Activity的下方应该怎么做呢?
  

# re: [Eclipse]GEF入门系列(三、应用实例) 2005-07-23 00:24 八进制
第一个问题,是不是可以给用户一个“把图形提前”的选项,点它后你让layer先remove掉这个图形,再加进来,它就应该在最前面了。
第二个问题,改Activity图形类即可实现。
  

# re: [Eclipse]GEF入门系列(三、应用实例) 2005-07-23 20:42 liuyu
第一个问题的确可以用这个方法解决,第二的问题我还是不会改,现在的代码里就是直接this.add(label);,这样的话肯定会加在中央,但是设置label的location没有用,始终在Activity的中央,到底应该怎么改呢?
  

# re: [Eclipse]GEF入门系列(三、应用实例) 2005-07-23 22:09 八进制
label的位置由它所在图形的layout manager决定
  

# re: [Eclipse]GEF入门系列(三、应用实例) 2005-07-24 15:56 liuyu
我在ActivityFigure里用ToolbarLayout对其进行设置后,刚把Activity放上去的时候成功了,label的确在图形下面,但是问题是一拖动图形label又会跑到图形中间去了,不知道为什么。
  

# re: [Eclipse]GEF入门系列(三、应用实例) 2005-07-30 13:43 xiaodao
感觉楼主谆谆教导~!~!~!~!~!~!~!~!~!~!~
  

# re: [Eclipse]GEF入门系列(三、应用实例) 2005-08-06 17:05 lucia
非常感谢你的文章,是我读的有关gef里写得最好的了。我因为刚刚接触,所以对我现在要编写的东西还有些迷糊,所以请教一下。我的editor要分成两个部分,一边是TreeView, 一边是显示节点和连线,就好像是把大纲视图嵌入到了editor里。因为他们分别显示不同的部分,又一一对应。你有没有这方面的例子?我如何才能实现他们呢?

多谢指教
  

# re: [Eclipse]GEF入门系列(三、应用实例) 2005-08-08 20:15 八进制
应该是继承GraphicalEditorWithFlyoutPalette来实现,覆盖其中的createPartControl()方法把“大纲”加进去,但肯定还有其他工作要做,比如选择的同步等等,感觉会很麻烦。不如利用perspective把大纲加在Editor的旁边,如果允许的话。
  

# re: [Eclipse]GEF入门系列(三、应用实例) 2005-08-10 01:44 lucia
非常感谢,

我试过把大纲通过覆盖createPartControl()的方法加进去,可是没有成功。我不知道错在哪里,因为没有任何出错信息,但也没有任何显示。第二个建议是比较简单,可是我要建立的是一个gantt chart, 大纲显示的是任务,我的理想是把大纲嵌入其中。我现在有个折中的办法,就是任务不用树形结构表示,也是用节点。可问题也不小,如何在浏览的时候,将任务节点保持不动,我还没有一点头绪呢。如果你有什么建议,将感激不尽。


  

# re: [Eclipse]GEF入门系列(三、应用实例) 2005-08-10 18:30 panda
Does it work GefPractice with eclipse 3.1 and gef 3.1?
Thank you.
  

# re: [Eclipse]GEF入门系列(三、应用实例) 2005-08-10 20:39 八进制
lucia:gantt图很麻烦,上一个项目里我们组的大牛花了不少功夫,基本是用draw2d自己实现的。
panda:GefPractice在eclipse 3.1里运行不起来。
  

# re: [Eclipse]GEF入门系列(三、应用实例) 2005-08-10 22:53 lucia
八进制:
可惜是我的毕业论文,没得选择了,必须完成。我就是觉得用draw2d自己实现实在太麻烦,所以才用gef的。原来打算抄写ganttproject的开源码,可是读那些没有注释的code太头痛,要改的东西太多,才开始另起炉灶的。我实在没有把握,能不能在一个月内编完。因为这只是一部分。

  

# re: [Eclipse]GEF入门系列(三、应用实例) 2005-08-11 06:02 lucia
打扰了,我能再提个问题吗?

我才注意到,EditPart里的getModelChildren只能返回一种类型的children吗?如果我的模型有的元素有很多类型的children,那该怎么办呢?多谢指点.
  

# re: [Eclipse]GEF入门系列(三、应用实例) 2005-08-11 11:37 八进制
让这些children继承同一个父类
  

# re: [Eclipse]GEF入门系列(三、应用实例) 2005-08-11 14:26 lucia
谢谢你的解答。
  

# re: [Eclipse]GEF入门系列(三、应用实例) 2005-08-11 17:25 panda
Thx for your answer yesterday.
Now i have eclipse 3.0.1 and gef 3.0.1.
I downloded GefPractice.
I did:
file->import->existingtoworkspace
run as eclipse workbench
in the new eclipse instance
file->new->simple project->"gefprac"
gefprac->new->file->"gefp.gef"

But it doesn't work. So something goes wrong.

Could you advice me how i can run gefpractice?

Thank you.

  

# re: [Eclipse]GEF入门系列(三、应用实例) 2005-08-11 19:26 八进制
Your file should be named "gefp.gefpractice", not "gefp.gef".
  

# re: [Eclipse]GEF入门系列(三、应用实例) 2005-08-11 23:55 panda
Thank you. It works.
  

# 请教一个技术问题 2005-08-15 17:49 freegoldlu
请教八进制,如何给FreeformLayeredPane 加一个居中的背景图片 ,
FreeformLayeredPane中有FreeformLayer
谢谢!
  

# re: [Eclipse]GEF入门系列(三、应用实例) 2005-08-15 20:33 八进制
给FreeformLayeredPane加一个新层,在这个新层上画背景图。
  

# re: [Eclipse]GEF入门系列(三、应用实例) 2005-08-16 02:41 lucia
freegoldlu, 八进制,

另一种可能性,建立一个新的class,继承FreeformLayer,覆盖paintClientArea方法,在这里加入你的背景图案。我就是这么做的。




  

# re: [Eclipse]GEF入门系列(三、应用实例) 2005-08-20 06:54 lucia
有关上次EditPart里的getModelChildren只能返回一种类型的children的问题,想再问一下, 让这些children继承同一个父类,可是如果这些children是用不同editpart控制的,怎么办呢?谢谢
  

# re: [Eclipse]GEF入门系列(三、应用实例) 2005-08-20 15:58 八进制
在你的EditPartFactory里根据不同子类返回需要的EditPart,不知道你问的是不是这个问题呢?
  

# re: [Eclipse]GEF入门系列(三、应用实例) 2005-08-21 01:51 lucia

答案找到了,getModelChildren的时候可以将不同类型的children将入到一个list里,就行了。

我一开始在处理list的时候,没有新建,而是
List list = getModel().getChildBs();
list.addAll(getModel().getChildCs());
糊涂啊,改成
List list =new ArrayList(getModel.getChildBs());
list.addAll(getModel().getChildCs());
就行了。

浪费了大家很多时间帮我找错,真是不安啊。

多谢了
posted on 2005-08-26 17:07 sharky的点滴积累 阅读(2367) 评论(2)  编辑  收藏

评论

# re: GEF入门系列(三、应用实例) [未登录] 2008-12-07 00:06 tiger
你好:
我把你的程序导入之后,为什么运行结果是eclipse的界面,你能把详细运行过程说一下吗  回复  更多评论
  


只有注册用户登录后才能发表评论。


网站导航: