博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
GMF树形布局 2 实现展开/折叠
阅读量:5906 次
发布时间:2019-06-19

本文共 3465 字,大约阅读时间需要 11 分钟。

hot3.png

这一篇博客在上一篇的基础上,实现展开/折叠功能。期待的最终效果是,双击某一Node,其后面的Node与连线都隐藏;再双击时显示回来。并且折叠之后,保存关闭,下次打开时还处于折叠状态,可以正确展开。

有一个细节应当注意,如下图:

比如折叠了节点1之后再折叠节点0,之后再展开节点0的时候,节点1应当还是处于折叠状态。

具体步骤如下:

1、为了实现这个展开/折叠操作,并且方便以后实现图标的更换,可以在节点的模型文件中添加一个布尔型的变量expanded,用于标识展开状态。可以在模型文件中修改,然后重新生成Model Code以及Edit Code,具体操作可以参考的步骤1、2。注意,将expanded的默认值设为true。

2、创建一个Command,用于实现折叠或者展开。先在diagram工程下的src目录下新建一个package,名为org.eclipse.gmf.examples.mindmap.diagram.edit.commands.custom,在其中新建一个class文件,名为ExpandOrCollapseCommand,继承自RecordingCommand。

3、ExpandOrCollapseCommand的构造函数如下,获取

public ExpandOrCollapseCommand(        TransactionalEditingDomain transactionalEditingDomain,        TopicEditPart topicEditPart) {    super(transactionalEditingDomain);    this.sourceEdgeList = ((View) topicEditPart.getModel()).getSourceEdges();    this.setLabel("Expand Or Collapse");    this.topicModel = (Topic) ((View) topicEditPart.getModel()).getElement();    this.isExpanded = topicModel.isExpanded();    this.topicEditPart = topicEditPart;}

4、重写doExecute()方法:

@Overrideprotected void doExecute() {    if (this.sourceEdgeList.size() > 0) {        this.topicModel.setExpanded(!this.isExpanded);        this.doExpandOrCollapse(this.topicModel, this.sourceEdgeList, !this.isExpanded);    }}
5、最关键的doExpandOrCollapse方法代码:
/** * 执行展开或者折叠功能,并且将子节点的元素也要相应地展开或者折叠 */private void doExpandOrCollapse(Topic model, List edgeList, boolean visible) {    Iterator
iter = edgeList.iterator(); while (iter.hasNext()) { Edge conn = iter.next(); conn.getTarget().setVisible(visible); Topic targetModel = (Topic) conn.getTarget().getElement(); List targetSourceEdgeList = conn.getTarget().getSourceEdges(); if (this.isExpanded) { // 如果将要折叠,则应将子节点全部隐藏 doExpandOrCollapse(targetModel, targetSourceEdgeList, false); } else if (!this.isExpanded && targetModel.isExpanded()) { // 如果将要展开,则应将子节点中,在折叠之前处于展开状态的展开 doExpandOrCollapse(targetModel, targetSourceEdgeList, true); } }}

6、接下来则要使用这个命令。由于是双击,所以先要捕获对节点的双击事件。在TopicEditPart类中重写超类中的performRequest(Request request)方法:

/** * 捕获各种事件,如双击 */@Overridepublic void performRequest(Request request) {    if (request.getType() == (RequestConstants.REQ_OPEN)) {        // 双击时展开或者隐藏后面的节点        Topic model = (Topic) ((View) this.getModel()).getElement();        TransactionalEditingDomain domain = TransactionUtil                .getEditingDomain(this.getModel());        ExpandOrCollapseCommand command = new ExpandOrCollapseCommand(                domain, this);        domain.getCommandStack().execute(command);    }    super.performRequest(request);}

7、现在运行,会发现已经可以展开/折叠了,但是,存在一个问题:当把某一节点折叠,保存关闭后,再打开图,然后再展开这个节点,与它直接相连的节点并不会马上显示,需要保存、关闭之后再打开才会显示,如下图:

8、解决上面的问题,需要在TopicEditPart中重写getModelSourceConnections()方法。如果在超类ShapeNodeEditPart中查看原始的getModelSourceConnections()方法,最终找到ViewUtil中的getSourceConnectionsConnectingVisibleViews(View view)方法,会发现其中有一个判断:

if (edge.isVisible() && isVisible(target)){    sourceConnections.add(edge);}

而我们是要得到所有的edge,不管是否可见。我们虽然没有手动调用getModelSourceConnections(),但是在内部它是被调用的,所以,在TopicEditPart中重写getModelSourceConnections()方法如下:

/** * 重写getModelSourceConnections()方法 */@Overrideprotected List getModelSourceConnections() {    View view = (View) this.getModel();    if (!view.eIsSet(NotationPackage.Literals.VIEW__SOURCE_EDGES))        return Collections.EMPTY_LIST;    return view.getSourceEdges();}

9、此时再运行,则不会出现上述问题。

最终代码在

转载于:https://my.oschina.net/plumsoft/blog/153377

你可能感兴趣的文章
API 菜单函数
查看>>
设置当前日期前几天或者后几天
查看>>
博客作业01-抽象数据类型
查看>>
领域模型(DomainModel)与视图模型(ViewModel)
查看>>
C# DataRow的扩展
查看>>
同步(Sync)/异步(Async),阻塞(Block)/非阻塞(Unblock)四种调用方式
查看>>
java中的重载和重写
查看>>
ref out 区别
查看>>
VS2005 创建Windows服务程序,打包成安装文件
查看>>
php get_magic_quotes_gpc() addslashes()
查看>>
react列表中,当key改变后发生的事情
查看>>
LOJ #6183 看无可看
查看>>
Bzoj4556: [Tjoi2016&Heoi2016]字符串 后缀数组
查看>>
VS2010 MFC对话框程序用CButtonST给按钮添加图标
查看>>
访问修饰符
查看>>
大型企业服务器的自动化运维(转载)
查看>>
js基本类型和常量 ,比较运算符,逻辑运算符
查看>>
办公室局域网访问共享文件夹
查看>>
常用模块random/os/sys/time/datatime/hashlib/pymysql等
查看>>
CSS定位
查看>>