八进制

少年壮志无烟抽

  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  244 随笔 :: 0 文章 :: 3241 评论 :: 14 引用

两天前GEF发布了3.1M7版本,但使用下来发现和M6没有什么区别,是不是主要为了和Eclipse版本相配套?希望3.1正式版早日发布,应该会新增不少内容。上一篇帖子介绍了如何实现表格功能,在开发过程中,另一个经常用到的功能就是树,虽然SWT提供了标准的树控件,但使用它完成如组织结构图这样的应用还是不够直观和方便。在目前版本(3.1M7)的GEF中虽然没有直接支持树的实现,但Draw2D提供的例子程序里却有我们可以利用的代码(org.eclipse.draw2d.examples.tree.TreeExample,运行界面见下图),通过它可以节约不少工作量。

treeexample.gif
图1 Draw2D例子中的TreeExample

记得数年前曾用Swing做过一个组织结构图的编辑工具,当时的实现方式是让画布使用XYLayout,在适当的时候计算和刷新每个树节点的位置,算法的思想则是深度优先搜索,非树叶节点的位置由其子节点的数目和位置决定。我想这应该是比较直观的方法吧,但是这次看了Draw2D例子里的实现觉得也很有道理,以前没想到过。在这个例子里树节点图形称为TreeBranch,它包含一个PageNode(表现为带有折角的矩形)和一个透明容器contentsPane,(一个Layer,用来放置子节点)。在一般情况下,TreeBranch本身使用名为NormalLayout的布局管理器将PageNode放在子节点的正上方,而contentsPane则使用名为TreeLayout的布局管理器计算每个子节点应在的位置。所以我们看到的整个树实际上是由很多层子树叠加而成的,任何一个非叶节点对应的图形的尺寸都等于以它为根节点的子树所占区域的大小。

从这个例子里我们还看到,用户可以选择使用横向或纵向组织树(见图2),可以压缩各节点之间的空隙,每个节点可以横向或纵向排列子节点,还可以展开或收起子节点,等等,这为我们实现一个方便好用的树编辑器提供了良好的基础(视图部分的工作大大简化了)。

treevertical.gif
图2 纵向组织的树

这里要插一句,Draw2D例子中提供的这些类的具体内容我没有仔细研究,相当于把它们当作Draw2D API的一部分来用了(包括TreeRoot、TreeBranch、TreeLayout、BranchLayout、NormalLayout、HangingLayout、PageNode等几个类,把代码拷到你的项目中即可使用),因为按照GEF 3.1的计划表,它们很有可能以某种形式出现在正式版的GEF 3.1里。下面介绍一下我是如何把它们转换为GEF应用程序的视图部分从而实现树编辑器的。

首先从模型部分开始。因为树是由一个个节点构成的,所以模型中最主要的就是节点类(我称为TreeNode),它和例子里的TreeBranch图形相对应,它应该至少包含nodes(子节点列表)和text(显示文本)这两个属性;例子里有一个TreeRoot是TreeBranch的子类,用来表示根节点,在TreeRoot里多了一些属性,如horizontal、majorSpacing等等用来控制整个树的外观,所以模型里也应该有一个继承TreeNode的子类,而实际上这个类就应该是编辑器的contents,它对应的图形TreeRoot也就是一般GEF应用程序里的画布,这个地方要想想清楚。同时,虽然看起来节点间有线连接,但这里我们并不需要Connection对象,这些线是由布局管理器绘制的,毕竟我们并不需要手动改变线的走向。所以,模型部分就是这么简单,当然别忘了要实现通知机制,下面看看都有哪些EditPart。

与模型相对应,我们有TreeNodePart和TreeRootPart,后者和前者之间也是继承关系。在getContentPane()方法里,要返回TreeBranch图形所包含的contentsPane部分;在getModelChildren()方法里,要返回TreeNode的nodes属性;在createFigure()方法里,TreeNodePart应返回TreeBranch实例,而TreeRootPart要覆盖这个方法,返回TreeRoot实例;另外要注意在refreshVisuals()方法里,要把模型的当前属性正确反映到图形中,例如TreeNode里有反映节点当前是否展开的布尔变量expanded,则refreshVisuals()方法里一定要把这个属性的当前值赋给图形才可以。以下是TreeNodePart的部分代码:

public IFigure getContentPane() {
    
return ((TreeBranch) getFigure()).getContentsPane();
}


protected List getModelChildren() {
    
return ((TreeNode) getModel()).getNodes();
}


protected IFigure createFigure() {
    
return new TreeBranch();
}


protected void createEditPolicies() {
    installEditPolicy(EditPolicy.COMPONENT_ROLE, 
new TreeNodeEditPolicy());
    installEditPolicy(EditPolicy.LAYOUT_ROLE, 
new TreeNodeLayoutEditPolicy());
    installEditPolicy(EditPolicy.SELECTION_FEEDBACK_ROLE, 
new ContainerHighlightEditPolicy());
}

上面代码中用到了几个EditPolicy,这里说一下它们各自的用途。实际上,从Role中已经可以看出来,TreeNodeEditPolicy是用来负责节点的删除,没有什么特别;TreeNodeLayoutEditPolicy则复杂一些,我把它实现为ConstrainedLayoutEditPolicy的一个子类,并实现createAddCommand()和getCreateCommand()方法,分别返回改变节点的父节点和创建新节点的命令,另外我让createChildEditPolicy()方法返回NonResizableEditPolicy的实例,并覆盖其createSelectionHandles()方法如下,以便在用户选中一个节点时用一个控制点表示选中状态,不用缺省边框的原因是,边框会将整个子树包住,不够美观,并且在多选的时候界面比较混乱。

protected List createSelectionHandles() {
    List list
=new ArrayList();
    list.add(
new ResizeHandle((GraphicalEditPart)getHost(), PositionConstants.NORTH));
    
return list;
}

选中节点的效果如下图,我根据需要改变了树节点的显示(修改PageNode类):

treeselection.gif
图3 同时选中三个节点(Node2、Node3和Node8)

最后一个ContainerHighlightEditPolicy的唯一作用是当用户拖动节点到另一个节点区域中时,加亮显示后者,方便用户做出是否应该放开鼠标的选择。它是GraphicalEditPolicy的子类,部分代码如下,如果你看过Logic例子的话,应该不难发现这个类就是我从那里拿过来然后修改一下得到的。

protected void showHighlight() {
    ((TreeBranch) getContainerFigure()).setSelected(
true);
}


public void eraseTargetFeedback(Request request) {
    ((TreeBranch) getContainerFigure()).setSelected(
false);
}

好了,现在树编辑器应该已经能够工作了。为了让用户使用更方便,你可以实现展开/收起子节点、横向/纵向排列子节点等等功能,在视图部分Draw2D的例子代码已经内置了这些功能,你要做的就是给模型增加适当的属性。我这里的一个截图如下所示,其中Node1是收起状态,Node6纵向排列子节点(以节省横向空间)。

treeeditor.gif
图4 树编辑器的运行界面

这个编辑器我花一天时间就完成了,但如果不是利用Draw2D的例子,相信至少要四至六天,而且缺陷会比较多,功能上也不会这么完善。我感觉在GEF中遇到没有实现过的功能前最好先找一找有没有可以利用的资源,比如GEF提供的几个例子就很好,当然首先要理解它们才谈得上利用。

posted on 2005-05-27 00:09 八进制 阅读(8563) 评论(74)  编辑 收藏 网摘 所属分类: EclipseGEF

评论

#1楼  2005-06-21 20:00 freegoldlu      
请问 这里例子的代码 能mail给我吗freegoldlu@sohu.com
不方便的话 能不能把draw2d的例子代码发一份 非常感谢 :)

  回复  引用  查看    

#2楼 [楼主] 2005-06-22 20:30 八进制      
例子代码确实不方便外传,否则我都会提供下载链接的,见谅。
draw2d例子已发邮箱,请查收。

  回复  引用  查看    

#3楼  2005-06-23 14:42 freegoldlu      
非常感谢你的答复,请教一个技术问题 按照你的文档
整个这个画布的figure应该是roottree,我的画布是merlin 自动generate 的 EDiagramEditPart, 我在里面
protected IFigure createFigure() {
//FigureCanvas treeroot=new FigureCanvas(this.getViewer().getControl().getShell());
//treeroot.setBounds(0,0,200,200);
//treeroot.setBackground(ColorConstants.white);
TreeRoot root=new TreeRoot(createPageNode("Graph Root"));
root.setBounds(new Rectangle(100,100,100,100));
//treeroot.setContents(root);
return root;
}
总是 出异常,请问 画布 的figure应该怎么设置 谢谢

  回复  引用  查看    

#4楼 [楼主] 2005-06-23 18:23 八进制      
不好说,最好把异常信息贴一下,并且说明在哪句出的异常。
  回复  引用  查看    

#5楼  2005-07-05 13:59 vicstart      
能否给个draw2d的例子代码?
vicstart@gmail.com
谢谢

  回复  引用  查看    

#6楼  2005-07-05 17:30 dorothy      
Could you send me the draw2d example too as fast as possible?
Thank you so much! ^_^

Regards,
dorothyhelene@hotmail.fr

  回复  引用  查看    

#7楼  2005-07-05 21:49 八进制      
vicstart&dorothy:Draw2D的例子可以从eclipse的cvs里获得。
  回复  引用  查看    

#8楼  2005-07-06 17:08 dorothy      
Thank you for the information, in fact, I've found the example in eclipse cvs, I just wonder that we will have to download all the files in the directories of cvsviewer one by one by hand? or there is a better and simpler way to download the whole directory in the very same time? you see, how precious our time is! Maybe ask from you directly is a better choice, that's I did yesterday. :)

Thanks a lot for answering to the silly question.

have a good day.

  回复  引用  查看    

#9楼  2005-07-06 17:15 dorothy      
sorry I forgot, good evening. :)
  回复  引用  查看    

#10楼  2005-07-06 21:48 八进制      
dorothy:不客气。可以下载整个目录,不知道你用的是什么工具,我是用eclipse自带的cvs客户端,选中要下载的目录再check out即可。
  回复  引用  查看    

#11楼  2005-07-07 15:22 dorothy [未注册用户]
呵呵,终于装了中文输入法了,还是这样讲话比较亲切。:)

我刚用了一个月零几天的eclipse,还不知道用cvs呢. :P

多谢八进制了,以后还请多多指教!^_^

  回复  引用    

#12楼  2005-07-13 20:14 Bankey [未注册用户]
也发个例子给我好吗
fengbinhua@163.com
谢谢

  回复  引用    

#13楼  2005-08-03 11:53 fkpwolf [未注册用户]
看了你的很多文章,问个问题下,如何把GEF的图存为XML文件格式?我都没有找到相关方面的文档。
另:不知楼主用过jgraph没有,能不能比较下,哈哈

  回复  引用    

#14楼 [楼主] 2005-08-03 21:33 八进制      
是指把GEF的模型保存为XML格式吧,用dom自己实现就可以了,或者如果你用EMF做模型,它提供了缺省的XML方式。还有很多工具可以实现。
  回复  引用  查看    

#15楼  2005-08-04 11:14 fkpwolf [未注册用户]
怎么把图的所有信息存在XML文件中呢?这样GEF就可以打开一个XML文件格式的图。GEF带的shape example做法是序列化为二进制了。EMF好像很复杂,有方便的工具吗?
多谢

  回复  引用    

#16楼 [楼主] 2005-08-04 21:23 八进制      
保存的工作不是gef负责,在editor的dosave里由你自己实现,序列化是一种方式,想存为xml用dom或其他工具重写dosave方法。
  回复  引用  查看    

#17楼  2005-08-08 09:15 fkpwolf [未注册用户]
多谢提醒,现在利用eclopse.org上面的EMF + GEF已经可以存为XML了。但是当我后来在MODEL中加了一个类Action,并在Shape中引用它(多个),编辑完Shape后,保存,报异常:
org.eclipse.emf.ecore.xmi.DanglingHREFException: The object 'org.eclipse.gef.examples.shapes.emf.model.impl.ActionImpl@1a503f (description: wokao)' is not contained in a resource. at org.eclipse.emf.ecore.xmi.impl.XMLHelperImpl.handleDanglingHREF(XMLHelperImpl.java:644)
对EMF不熟悉,不知道如何处理。
多谢

  回复  引用    

#18楼 [楼主] 2005-08-08 20:37 八进制      
在Shape中是怎样引用Action类的?
  回复  引用  查看    

#19楼  2005-08-09 08:51 fkpwolf [未注册用户]
我是在“Sample Ecore Model Editor”中打开modle.ecore文件(原来例子的),在其中添加一个EClass:Action,然后在Shape中引用它(跟引用Connection一样),然后产生出类出来,没有作其他处理。
  回复  引用    

#20楼  2005-08-12 09:00 fkpwolf [未注册用户]
弄了半天是引用的containment熟悉应该设置为true,55555
  回复  引用    

#21楼  2005-09-21 20:58 张波 [未注册用户]
Draw2D的例子能否也给我1份? 麻烦了!
zhangbo198294@yahoo.com.cn

  回复  引用    

#22楼 [楼主] 2005-09-22 10:15 八进制      
下载draw2d例子的cvs配置:
Connection Type: pserver
Host: dev.eclipse.org
Repository Path: /home/tools
User: anonymous
Password: anonymous

  回复  引用  查看    

#23楼  2005-10-08 16:07 胡访贤 [未注册用户]
把例子也给我一份吧?我太需要了!
hufangxian@163.com

  回复  引用    

#24楼  2005-10-10 15:32 天马 [未注册用户]
八进制,你好,首先向你表示感谢,是你的贴子让我真正进入了GEF世界.原来学起来太费劲了,呵呵.
我现在有个小问题,麻烦你给看一下:我们公司做的一个GEF程序里,各Figure是用小图标,而且每个figure加了12个ConnectionAnchor,diagram的ConnectionRouter用的是ManhattanConnectionRouter。整体效果还不错,只是有一个非常意外的毛病,拖动某figure时,连到它上面的链接端点不能自动活动,以至于链接经常会“穿过”figure,变得很难看。就像GEFpractice那个小例子中,我把它的router换成ManhattanConnectionRouter时,移动NODE,链接端点就能自动移动,使链接保持最短。其实我试着把这个例子改成公司程序那样的链接锁定,也没成功。呵呵。在程序里同时加上ShortestPathConnectionRouter,也没有效果。我想了一下,公司的程序跟GEFpractice例子的不同点在于,前者的figure用的是图标,后者用的是Draw2D中的图形。是这个区别在作怪吗?请你给我些建议。怎样能解决这个链接锁定问题。再次谢谢你。

  回复  引用    

#25楼 [楼主] 2005-10-10 23:06 八进制      
链接端点不能自动活动是什么情况,能具体描述一下吗?移动图形后连线会增加一个转折点?还是线不动与图形脱离?
  回复  引用  查看    

#26楼  2005-10-11 09:11 天马 [未注册用户]
没想到你这么快就看贴子了,呵呵.谢谢八进制.
是这样的,假设有两个figure甲乙, 一开始是这样的链接:甲------->乙(connection原本是有转折点的,因为用了ManhattanConnectionRouter,在这里我就不画那么像了),但当把它们的位置换成 : 乙 甲
时,链接的源、目标端点都没动,源还是从甲的右侧出发,目标是指向乙的左侧,也就是链接的那条线在figure上穿了过去,其实也增加了转折点。而不是我们想要的这种样子:乙------->甲.总体说来就是,链接的源,目标端点都锁定在figure的某个Anchor上.我把ManhattanConnectionRouter用到gefpractice例子里时,链接也能自动变动它源、目标的定位,就像它原本用的ShortestPathConnectionRouter一样灵活。使链接不会绕圈子,或者说是穿过某figure。

大体情况就是这样,请你给分析一下。谢谢八进制。

  回复  引用    

#27楼 [楼主] 2005-10-11 10:40 八进制      
原因应该是你的那些anchor,在gefpractice里用的是chopboxanchor,两个图形的相对位置改变后会重新计算连接线的起止点。你移动图形后,用的anchor可能没变,造成router不得不这样走。
  回复  引用  查看    

#28楼  2005-10-11 13:13 天马 [未注册用户]
哦。这样啊,好,谢谢你,麻烦你了,八进制!
  回复  引用    

#29楼  2005-10-18 15:52 fubin [未注册用户]
八进制你好,谢谢你的文章,对我帮助太大了。
有个问题,gef对一些方法的调用封装得实在太严密了,很难搞懂这些方法的调用原理,比如在XYLayoutEditPolicy 中有方法
createAddCommand(EditPart child, Object constraint),能否讲一下gef是如何调用这个方法来创建command的,如何实现这个方法,能否给点示例代码,谢谢!:)
还有一个问题,呵呵!在你前面的一个例子中有ModelCreationFactory类,里面有方法public Object getNewObject() ,方法里面有这样一段代码:
Map registry = EPackage.Registry.INSTANCE;
String uri = ModelPackage.eNS_URI;
ModelPackage modelPackage = (ModelPackage) registry.get(uri);
ModelFactory factory = modelPackage.getModelFactory();
这段代码是做什么用的呢?

  回复  引用    

#30楼 [楼主] 2005-10-18 18:01 八进制      
深入了解gef的最好方法是多看源代码,
那段代码是emf生成的,是为读入/取出资源做准备吧。

  回复  引用  查看    

#31楼  2005-10-19 10:54 fubin [未注册用户]
谢谢八进制!
没错,看代码是最直接的学习方法。
还有一个问题,由于刚刚学习gef和emf,感觉很难调试,因此编程效率很低。
能否提点一下调试gef和emf程序的技巧或经验。

  回复  引用    

#32楼 [楼主] 2005-10-19 12:15 八进制      
比如想知道editpart的createFigure()在什么时候被调用,就在这里设置一个断点,然后观察debug view里的信息,结合代码就能看到gef的运行机制。一开始是比较痛苦的,否则学会了也没什么成就感不是吗。
  回复  引用  查看    

#33楼  2005-10-19 17:46 fubin [未注册用户]
总是遇到下面的异常,调了一天了,一步一步的跟踪,是从Workbench的runEventLoop里面抛出的,由于信息太少,找不到异常的源头。
Unhandled event loop exception
Reason:
java.lang.NullPointerException

我想问一下,这个异常怎么解释,凭你的经验可能的原因是什么,
发出这个异常的根本源头可能在那里,part或者command里面?

郁闷呀!好长时间了都搞不定。

  回复  引用    

#34楼 [楼主] 2005-10-19 20:51 八进制      
只看这个空指针异常我判断不出来,你至少要说一下执行什么操作时出现这个异常的,而且为什么会没有完整的stacktrace呢。
  回复  引用  查看    

#35楼  2005-10-20 10:15 fubin [未注册用户]
我的模型是emf生成的,其中一个是Screen表示一个屏幕容器,里面可以放Button,Text等widget。我从Palette里面托出一个Screen到画板上,虽然Screen已经画上去了,但是同时也抛出了上面的异常,跟踪时感觉没发现什么问题,也可能是对系统里面的一些类不太了解,总之跟踪到Workbench类里面
private void runEventLoop(Window.IExceptionHandler handler, Display display) {
runEventLoop = true;
while (runEventLoop) {
try {
if (!display.readAndDispatch()) {
getAdvisor().eventLoopIdle(display);
}
} catch (Throwable t) {
handler.handleException(t);
}
}
}
出了异常。我怀疑在EditPart里面的refreshChildren()里面除了问题,可是找不出来!

  回复  引用    

#36楼 [楼主] 2005-10-21 17:55 八进制      
你应该看在你写的代码里哪里出了异常,而不是workbench里。
  回复  引用  查看    

我和上面那位大哥碰到的問題一樣

困擾我好久了

幫我看看,謝謝

http://www.eclipseworld.org/bbs/read.php?tid=1378&keyword=

  回复  引用    

#38楼 [楼主] 2006-01-20 14:35 八进制      
这个链接似乎不存在……
  回复  引用  查看    

有个问题。gefparctice里面的connection选中以后会出现两个点,可是问什么我的connection选中以后出现了矩形框?就像选中node一样。 反复对比两个程序都看不出问题。请指点。
  回复  引用    

#40楼 [楼主] 2006-02-01 19:08 八进制      
应该检查你的Connection的editpart是否继承自AbstractConnectionEditPart;或者是你错误的覆盖了它的getDragTracker()方法。
  回复  引用  查看    

#41楼  2006-02-25 15:10 powlliu [未注册用户]
@freegoldlu
@freegoldlu
draw2d的例子能给我一份吗?cman_powlliu@hotmail.com

  回复  引用    

#42楼  2006-03-08 17:20 lazycat [未注册用户]
汗,能够具体说一下吗?
偶太菜,模仿了n天了都搞不定:(
问题:1。关于figure 的问题,如何修改每个节点的样式?是修改pageNode类嘛?看不懂,好烦
2。关于TreeNodeLayoutPolicy 的createAddCommand()怎么改变当前节点的父亲节点?
3。还有ContainerHighlightEditPolicy 具体说一下吧

不方便公开的话,可以发个mail给我吗?
woaixh51@126.com
3ks

  回复  引用    

#43楼 [楼主] 2006-03-08 22:25 八进制      
1、修改figure就是修改treebranch类,treebranch包含了pagenode。
2、createAddCommand()的返回值应该是一个Command吧,这个command的功能是改变某个节点的父节点,至于改变哪个节点以及新的的父节点是谁则可以由构造方法的参数传入。
3、ContainerHighlightEditPolicy这个editpolicy不是很重要的,没有它只是无法在拖动时看出鼠标下的节点而已。

程序是公司项目里的一部分,很抱歉不能把代码给你。其实没有什么特别的地方,只要熟悉了GEF这些都能自己想出来的,我这个也只是“树的一种实现”,你也可以用其他方法实现自己的树。。

  回复  引用  查看    

#44楼  2006-03-08 22:43 lazycat [未注册用户]
那位有做出这个例子来发一份给偶看看吧,实在不行了,过两天交不出来,会被老板狂k的 :(
救命啊woaixh51@126.com

  回复  引用    

#45楼  2006-03-13 16:00 小徐 [未注册用户]
怎样屏蔽节点多选的功能呢?
  回复  引用    

#46楼  2006-03-20 14:51 小徐 [未注册用户]
八进制好象不怎么回答GEF的问题了哦~~~强烈郁闷中
  回复  引用    

#47楼  2007-01-11 23:42 xalix [未注册用户]
八进制,你好,

我需要建立一个树,但是与GEF的TreeViewer有些不一样,
1.它只需要建立一次就好,不会给用户移动(程序本身则可以),也不会再增加或减少Node
2.树的node是可以被连接到其他Figure的
3.树不能扩张或者收缩

请问我该从哪里开始?
谢谢

  回复  引用    

#48楼 [楼主] 2007-01-14 21:07 八进制      
to 小徐:可以在SelectionEditPolicy子类(如ResizableEditPolicy)里覆盖addSelectionListener()方法。
to xalix:直接修改Draw2d的例子就可以了,因为你不需要图形化的编辑这棵树。

  回复  引用  查看    

#49楼  2007-01-15 23:32 xalix [未注册用户]
谢谢八进制的回答,

其实,我是需要两棵树,虽然不能移动或修改,但是用户却可以用connection来连接两棵树种的任何node 类似 xml mapping
http://www.stylusstudio.com/images/screenshots/xml_mapper_big.gif
而这些连接不是建立一棵树。
现在我去下载例子,谢谢。

  回复  引用    

@xalix
怎么实现的?求教

  回复  引用    

#51楼  2007-08-24 11:51 auranja [未注册用户]
cvs上下载draw2d例子的path需要改成: /cvsroot/tools才可以
费了好大劲儿才找到,希望也需要下载的省些力气

  回复  引用    

#52楼  2007-10-10 11:24 UI [未注册用户]
八进制,你好,
这句话不是很明白,麻烦讲解一下吧!!
""而实际上这个类就应该是编辑器的contents,它对应的图形TreeRoot也就是一般GEF应用程序里的画布"".

  回复  引用    

#53楼  2007-11-05 15:09 jiezi [未注册用户]
请问八进制大大,如果要实现一个子节点从一个父节点拖动到另一个父节点下是不是加上ContainerHighlightEditPolicy就行?是新父节点先高亮然后子节点自动连上去掉效果么?
  回复  引用    

#54楼 [楼主] 2007-11-05 22:43 八进制      
ContainerHighlightEditPolicy只负责高亮父节点,LAYOUT_ROLE对应的policy负责父节点的改变。
  回复  引用  查看    

#55楼  2007-11-06 10:39 jiezi [未注册用户]
拖动的动画是不是都是底层实现的,看了个叫XMIND的产品,它做的树的拖动,线是跟着节点一起走,挺好看的.
能给发一份TreeNodeLayoutEditPolicy的类么?如果不涉及到你们公司业务部分的话?
bit506@163.com
谢谢啊

  回复  引用    

#56楼  2007-11-12 18:20 jiezi [未注册用户]
大大有没有接触用Eclipse+GEF做到类似free mind的脑图那种,xmind实在不错,就是不知道怎么实现那种布局的
  回复  引用    

#57楼  2007-12-07 08:57 jiezi [未注册用户]
请问下,选中某个树节点的时候触发的代码是哪块,我想实现选中某个节点的时候就单单选中那个节点,修改createSelectionHandles好像也仅仅是UI上看起来像只选中某个节点,实际上也把这个节点的子节点一起选中了
  回复  引用    

#58楼 [楼主] 2007-12-09 16:24 八进制      
我记得是在TreeBranch.java里,在UI上是可以实现只选中某个节点的,我后来也按这个方式改成过,效果是点一个节点后加粗其边框。
  回复  引用  查看    

#59楼  2007-12-09 16:57 jiezi [未注册用户]
一个节点拖到另外一个节点,鼠标放下的动作触发的是哪段代码?想实现一个放下鼠标弹出对话框的功能.话说这种鼠标事件真不好调
  回复  引用    

#60楼 [楼主] 2007-12-09 23:18 八进制      
在节点对应的editpart里处理,具体是由安装在这个editpart上的某个editpolicy处理的,这里应该是某个layouteditpolicy。
  回复  引用  查看    

#61楼  2008-03-18 11:42 renjf [未注册用户]
博主,您好。。不知道您还会不会回复提问。还是碰碰运气吧。。

公司里让实现一个试验结构图的东西,我之前是做c#的。对java不熟,对gef就更不熟了。有幸看到你的这个教程,我试着实现了一下。。只做了model,editpart,editer部分,只是想做个demo。可是一直没有成功,已经绕在这个问题上好几天了。。现在去看gef的代码也不现实,只能现学现卖。

不知道您能不能把例子参考一下,我的email:linglingtianshi5@163.com

如果您现在还是不方便传,那我说一下我的做法,请您指点一下好吗?
1.模型:treenode,treenoderoot两个模型,treenode只有一个list,一个string。然后treenoderoot继承,没有任何其他的方法和属性。
2.控制器:treenodepart,treenoderootpart。后者继承前者,然后安装您上面的介绍,覆盖了几个方法,然后就是自己实现refreshVisual():
if(getModel() instanceof TreeNodeRoot){
return;
}else{
//TreeBranch node = (TreeBranch)getModel();
TreeBranch node = new TreeBranch(new PageNode("childsd"));
getContentPane().add(node);
}
3.视图。没有做什么改变。
4.editor。setContents()的时候传的是treenoderoot的实例。

希望您能指导一下。或者把您的代码的业务逻辑部分去掉?。。
再次说下我的email:linglingtianshi5@163.com

  回复  引用    

#62楼 [楼主] 2008-03-18 13:34 八进制      
正常情况下按文里所说的进行修改就可以了,你现在遇到什么问题呢?
  回复  引用  查看    

#63楼  2008-03-19 09:09 renjf [未注册用户]
首先,谢谢八进制的回复!您有qq或者msn吗?您方便发到我的邮箱里吗?..希望能跟您近一步交流。。

我自己想这样测试一下,可是在编辑器里看不到添加的节点,是不是我这样测试是错的?

protected void initializeGraphicalViewer() {
//getGraphicalViewer().setContents(this.diagram);
TreeNode t1 = new TreeNode();
TreeNode t2 = new TreeNode();
treeRoot.addNodes(t1);
treeRoot.addNodes(t2);
getGraphicalViewer().setContents(this.treeRoot);
getGraphicalViewer().addDropTargetListener(new DiagramTemplateTransferDropTargetListener(getGraphicalViewer()));
}

  回复  引用    

#64楼  2008-03-20 17:50 renjf [未注册用户]
八进制,您好。。按照您的教程,我自己终于做出来了。。

不过,还是有些问题,希望您能帮忙:
1.就是选择根节点的时候,下面的子节点都被选中了。这个需要修改什么地方呢?
2.可以把模型的属性存储到数据库里吗?。。应该在哪个方法里面?

再次衷心谢谢您!

  回复  引用    

#65楼  2008-03-24 15:56 peonest [未注册用户]
renjf, 你好

我也正在做这样一个demo,但是有些问题不知道怎么描述,你能把代码发给我看看吗?谢谢!

peonest@gmail.com

  回复  引用    

#66楼 [楼主] 2008-03-30 17:05 八进制      
to renjf: 1. 子节点应该只是看起来被选中了,如果是这样,改一下节点被选中时hightlight的外观代码即可(注意每个节点的bounds是包含所有子节点的) 2.这完全取决于你,很可能在editor的doSave()方法里。
  回复  引用  查看    

#67楼  2008-06-02 17:17 lengxf [未注册用户]
请问一下getGraphicalViewer().addDropTargetListener的具体含义,谢谢!
  回复  引用    

#68楼  2008-06-06 15:03 羽毛1 [未注册用户]
renjf 你好,我最近在学习GEF,我碰到的问题和你的一模一样,你是怎么解决呢?能吧代码发给我参考一下吗? EMAIL:featherafeather@163.com.谢谢
  回复  引用    

#69楼  2008-06-06 15:21 羽毛1 [未注册用户]
八进制麻烦也帮我看下我问题出在那里,谢谢.
treebranch对应的MODEL类:ChildNode
public static final String PROP_NAME = "ChildNode";
public static final String PROP_PROPERTY = "ChildName";
private List nodes = new ArrayList();
private String name;

public List getNodes() {
return nodes;
}

public void addNode(ChildNode cn) {
nodes.add(cn);
fireStructureChange(PROP_NAME, nodes);
}

public void removeNode(ChildNode cn) {
nodes.remove(cn);
fireStructureChange(PROP_NAME, nodes);
}

public String getName() {
return name;
}

public void setName(String name) {
if (this.name == name)
return;
this.name = name;
firePropertyChange(PROP_PROPERTY, null, name);
}

treeRoot对应的MODEL类:ParentNode
public class ParentNode extends ChildNode {

}
ChildNodePart:
public class ChildNodePart extends AbstractGraphicalEditPart implements
PropertyChangeListener {

@Override
protected IFigure createFigure() {
// TODO Auto-generated method stub
return new TreeBranch(new PageNode(""));
}

@Override
protected void createEditPolicies() {
// TODO Auto-generated method stub

}

@Override
protected List getModelChildren() {
// TODO Auto-generated method stub
return ((ChildNode) getModel()).getNodes();
}

@Override
public void activate() {
// TODO Auto-generated method stub
super.activate();
((ChildNode) getModel()).addPropertyChangeListener(this);
}

@Override
public void deactivate() {
// TODO Auto-generated method stub
super.deactivate();
((ChildNode) getModel()).removePropertyChangeListener(this);
}

public void propertyChange(PropertyChangeEvent evt) {
// TODO Auto-generated method stub
refreshChildren();
}

@Override
public IFigure getContentPane() {
// TODO Auto-generated method stub
return ((TreeBranch) getFigure()).getContentsPane();
}

protected void refreshVisuals() {
if(getModel() instanceof ParentNode){
return;
}else{
//TreeBranch node = (TreeBranch)getModel();
TreeBranch node = new TreeBranch(new PageNode("childsd"));
getContentPane().add(node);
}
}
ParentNodePart:
protected IFigure createFigure() {
// TODO Auto-generated method stub
return new TreeRoot(new PageNode(""));
}
现在碰到的问题是:在editor中:
ParentNode diagram = new ParentNode();
ChildNode cn;
diagram.addNode(cn = new ChildNode());
cn.addNode(new ChildNode());
diagram.addNode(new ChildNode());
setcontents(diagram);在editor区域没有图形显示.

  回复  引用    

#70楼 [楼主] 2008-06-12 20:44 八进制      
@lengxf
作用是为editpartviewer增加鼠标放开的响应,使得它可以作为drop的目标。

  回复  引用  查看    

#71楼 [楼主] 2008-06-12 20:53 八进制      
@羽毛1
setContents()是EditPartViewer里的方法,在editor里怎么能直接调用呢?另外一点,setContents()接受的应该是业务对象或editpart对象,而不是figure对象,你的参数diagram是一个figure吧?

  回复  引用  查看    

#72楼  2008-07-02 22:30 羽毛1 [未注册用户]
可能我说的简约了点:
setcontents方法是在initializeGraphicalViewer方法中调用的.而addnode方法是在setinput方法中调用的.后来我证实,不是不显示,是"太小"看不到显示.需要把diagram模型对应的figure设置一个固定大小即可.不过设定估计大小比较死板,不知道怎么让他自适应子节点动态调整大小呢?

  回复  引用    

#73楼  2008-08-28 19:42 karelun [未注册用户]
八进制:
你好!我想用GEF做一个状态机的流程图,两个状态之间的连线需要用到弧线,我现在只会直线的连接,请问画弧线是那个函数或接口?大致是怎样的?

  回复  引用    

#74楼 [楼主] 2008-09-27 16:14 八进制      
@karelun
如果两个节点间的连线是水平或垂直的,弧线可以用半个椭圆代替。

  回复  引用  查看    


发表评论
姓名 [登录] [注册] 
主页
Email (仅博主可见) 
验证码 *  验证码看不清,换一张
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论   新用户注册   返回页首      

导航: 网站首页 社区 新闻 博问 闪存 网摘 招聘 .NET频道 知识库 找找看 Google站内搜索


相关文章:

相关链接: