`
qq123zhz
  • 浏览: 536036 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

GEF 自动布局

阅读更多

利用自动布局功能,我们可以把本来不包含图形信息的文件以图形化的方式展示出来,典型的例子比如将一组Java接口反向工程为类图,那么图中每个图元的坐标应该必须都是自动生成的。GEF里提供了DirectedGraphLayout类用来实现自动布局功能,下面介绍一下怎样在程序里使用它。

DirectedGraphLayout提供的visit()方法接受一个org.eclipse.draw2d.graph.DirectedGraph实例,它遍历这个有向图的所有节点和边,并按照它自己的算法计算出每个节点布局后的新位置。所以在使用它布局画布上的图元分为两个步骤:1、构造有向图,2、将布局信息应用到图元。

还是以gefpractice为基础,我们在主工具条上增加了一个自动布局按钮,当用户按下它时自动布局编辑器里的图形,再次按下时恢复以前的布局。为了完成步骤1,我们要在DiagramPart里添加以下两个方法:

/**
 * 
将图元(NodePart)转换为节点(Node)到有向图

 * @param graph
 * @param map
 */
public void contributeNodesToGraph(DirectedGraph graph, Map map) {
    for (int i = 0; i < getChildren().size(); i++) {
        NodePart node = (NodePart)getChildren().get(i);
        org.eclipse.draw2d.graph.Node n = new org.eclipse.draw2d.graph.Node(node);
        n.width = node.getFigure().getPreferredSize().width;
        n.height = node.getFigure().getPreferredSize().height;
        n.setPadding(new Insets(10,8,10,12));
        map.put(node, n);
        graph.nodes.add(n);
    }
}

/**
 * 
将连接(ConnectionPart)转换为边(Edge)添加到有向图
 * @param graph
 * @param map
 */
public void contributeEdgesToGraph(DirectedGraph graph, Map map) {
    for (int i = 0; i < getChildren().size(); i++) {
        NodePart node = (NodePart)children.get(i);
        List outgoing = node.getSourceConnections();
        for (int j = 0; j < outgoing.size(); j++) {
            ConnectionPart conn = (ConnectionPart)outgoing.get(j);
            Node source = (Node)map.get(conn.getSource());
            Node target = (Node)map.get(conn.getTarget());
            Edge e = new Edge(conn, source, target);
            e.weight = 2;
            graph.edges.add(e);
            map.put(conn, e);
        }
    }
}

要实现步骤2,在DiagramPart里添加下面这个方法:

/**
 * 
利用布局后的有向图里节点的位置信息重新定位画布上的图元

 * @param graph
 * @param map
 */
protected void applyGraphResults(DirectedGraph graph, Map map) {
    for (int i = 0; i < getChildren().size(); i++) {
        NodePart node = (NodePart)getChildren().get(i);
        Node n = (Node)map.get(node);
        node.getFigure().setBounds(new Rectangle(n.x, n.y, n.width, n.height));
    }
}

为了以最少的代码说明问题,上面的方法里只是简单的移动了图形,而没有改变模型里Node的属性值,在大多情况下这里使用一个CompoundCommand对模型进行修改更为合适,这样用户不仅可以撤消(Undo)这个自动布局操作,还可以在重新打开文件时看到关闭前的样子。注意,DirectedGraphLayout是不保证每次布局都得到完全相同的结果的。

因为Draw2D里是用LayoutManager管理布局的,而DirectedGraphLayout只是对布局算法的一个包装,所以我们还要创建一个布局类。GraphLayoutManager调用我们在上面已经添加的那几个方法生成有向图(partsToNodes变量维护了编辑器图元到有向图图元的映射),利用DirectedGraphLayout对这个有向图布局,再把结果应用到编辑器里图元。如下所示:

class GraphLayoutManager extends AbstractLayout {

    private DiagramPart diagram;

    GraphLayoutManager(DiagramPart diagram) {
        this.diagram = diagram;
    }

    protected Dimension calculatePreferredSize(IFigure container, int wHint, int hHint) {
        container.validate();
        List children = container.getChildren();
        Rectangle result = new Rectangle().setLocation(container.getClientArea().getLocation());
        for (int i = 0; i < children.size(); i++)
            result.union(((IFigure) children.get(i)).getBounds());
        result.resize(container.getInsets().getWidth(), container.getInsets().getHeight());
        return result.getSize();
    }

    public void layout(IFigure container) {
        DirectedGraph graph = new DirectedGraph();
        Map partsToNodes = new HashMap();
        diagram.contributeNodesToGraph(graph, partsToNodes);
        diagram.contributeEdgesToGraph(graph, partsToNodes);
        new DirectedGraphLayout().visit(graph);
        diagram.applyGraphResults(graph, partsToNodes);
    }

}

当用户按下自动布局按钮时,只要设置DiagramPart对应的图形的布局管理器为GraphLayoutManager就可以实现自动布局了,布局的结果如图所示。


自动布局的结果

点此下载工程,此工程修改自GEF应用实例中的GefPractice,目标文件的扩展名改为.gefpracticeal。最后有几点需要说明:

1DirectedGraphLayout只能对连通的有向图进行布局,否则会产生异常“graph is not fully connected”,参考Eclipse.org文章Building a Database Schema Diagram Editor中使用的NodeJoiningDirectedGraphLayout可以解决这个问题;

2、如果要对具有嵌套关系的有向图自动布局,应使用SubGraphCompoundDirectedGraphLayout

3、这个版本的gefpractice在自动布局后,没有对连接线进行处理,所以可能会出现连接线穿过图元的情况,这个问题和上一个问题都可以参考GEF提供的flow例子解决。

Update(2007/4/9):如果diagram是放在ScrollPane里的,则要修改一下applyGraphResults()方法,增加container作为参数以使整个diagram能正确滚动。

protected void applyGraphResults(DirectedGraph graph, Map map, IFigure container) {
    for (Iterator iterator = this.nodeParts.iterator(); iterator.hasNext();) {
        NodePart element = (NodePart) iterator.next();
        Node n = (Node) map.get(element);
        Rectangle containerBounds=container.getBounds();
        Rectangle elementBounds=new Rectangle(n.x, n.y, n.width, n.height);
        element.getFigure().setBounds(elementBounds.translate(containerBounds.getLocation()));
    }
}

 

 

分享到:
评论
2 楼 qq123zhz 2015-07-24  
这个要在eclipse的插件环境下运行的,你不懂eclipse插件的话,是运行不了的
1 楼 dxmqp123456 2015-06-05  
你好,我下载下来了,没有主函数,没法运行是怎么回事呢?希望解答,谢谢

相关推荐

    gef框架的自动布局的一个例子

    point="org.eclipse.ui.editors"&gt; class="com.example.ui.PracticeEditor" icon="logo.gif" default="true" contributorClass=... name="Practice Editor" ... extensions="gefpracticeal"/&gt; &lt;/extension&gt;

    gef布局显示学习

    Gef是一款强大的GDB插件,提供了丰富的命令集、颜色高亮、自动完成以及更友好的交互界面,使得程序员在调试C、C++等语言的程序时能够更加高效。 首先,我们需要了解GDB的基础知识。GDB是一款开源的调试器,广泛应用...

    GEF-SDK-3.6.2 jar

    5. **自动生成代码**:通过GEF,开发者可以定义图形化的编辑域,然后自动生成对应的Java代码,减少了手动编码的工作量。 6. **可扩展性**:GEF的插件体系结构允许开发者通过扩展点定制编辑器功能,满足不同项目的...

    GEF Example Source Code

    - **连接线(Connectors)**:掌握如何绘制和管理图元之间的连接线,包括动态连接和自动布局。 - **模型-视图-控制器(MVC)**:理解GEF如何实现MVC设计模式,以及如何将数据模型与图形视图绑定。 - **事件处理**:...

    GEF-SDK-3.7.0

    2. **图形绘制与布局**:GEF提供了一套图形绘制API,支持基本形状、连接线、自定义图形等,并包含了多种自动布局算法,帮助用户自动排列图形元素。 3. **手势与命令**:通过定义手势和命令,GEF支持用户通过鼠标或...

    GEF 3.10 eclipse 插件

    8. **布局管理器**:提供了各种布局策略,如树状布局、网格布局等,可以根据需要自动调整图形元素的位置。 **四、Eclipse集成与使用** 1. **安装插件**:在Eclipse中,可以通过“Help” -&gt; “Install New Software...

    GEF理解系列三

    此外,`XYLayoutEditPolicy`还可能涉及其他的布局相关方法,如`layout()`,用于在需要时自动调整图形元素的布局,确保图形界面的整洁有序。 总之,GEF通过将图形操作分解为请求、Policy和Command,实现了灵活且可...

    GEF简易教程-学习GEF的入门教程

    在RCP项目中,**Editor**是最常见的GEF承载对象,它继承自`EditorPart`,提供了图形修改后的自动保存机制,这是View不具备的功能。 为了构建GEF编辑器,需要创建以下三个核心组件: 1. **模型(Model)**:定义数据...

    IBM GEF 推广资料

    5. **布局**:自动调整图形元素的位置和大小,以保持视觉清晰度。 6. **缩放**:支持用户放大或缩小视图,以便更好地查看细节。 7. **SWT层**:使用Eclipse的SWT库来实现与操作系统底层的交互,提供高效的图形绘制...

    eclipse3.4的可视化开发GEF

    GEF提供了多种布局管理器,如FixedLayout、GridLayout、TreeLayout等,可以根据需求选择合适的布局方式来自动调整图形元素的位置和大小。 **六、GEF的扩展性** GEF的设计充分考虑了扩展性,可以通过插件机制添加新...

    GEF连接线Node之间连接

    6. **布局和约束**:为了保持画布的整洁和合理布局,`GEF`支持多种布局策略,如树形布局、网格布局等。同时,还可以为节点和连接线设置约束条件,限制它们的移动范围和方向。 7. **FecatGEF10**:这个文件名可能是...

    gef入门学习项目源码

    - **布局管理器(Layout Managers)**:负责图元的自动排列和更新。 通过这个项目,你将学习到如何创建一个新的GEF编辑器,包括定义模型,创建图元和编辑领域,实现绘图功能,以及添加用户交互。同时,它也是一个很...

    eclipse gef ve gmf

    GMF的强项在于它的自动化能力,可以自动生成编辑器的大部分代码,包括图形表示、编辑操作以及与模型的交互。 这三者的关系是:GEF提供基础的图形编辑支持,VE是在GEF基础上构建的一个特定领域的可视化编辑器,主要...

    Eclipse的GEF插件

    7. **Layouts**:布局管理器负责图形元素的自动布局,比如网格布局、树状布局等,使得图形界面看起来更加整洁。 8. **DirectEdit**:直接编辑功能允许用户直接在图形元素上进行文本输入,增强了图形界面的交互性。 ...

    GEF学习资料

    此外,"dudu"可能还会涉及图形布局算法,这是图形界面设计中的重要一环,因为它们决定了图形元素在屏幕上的自动排列方式。 PDF和Word文档分别提供了两种不同的格式,以满足不同学习习惯的需求。PDF文件通常用于保持...

    gef-step3.zip_3gef_GEF eclipse_GEF-step2_gef_gef-st

    通过研究这个源代码,学习者可以深入理解GEF的编程模型,学习如何定义图形元素、处理用户事件、以及实现图形的绘制和布局。 总的来说,这个压缩包提供了一个学习和实践GEF的绝佳机会,涵盖了一个完整的图形编辑器...

    eclipse emf&gef

    GEF提供了创建复杂图形化编辑器所需的所有基本组件,包括绘图工具、布局管理器和事件处理器等。 **3.2 GEF与EMF结合使用** 通过将GEF与EMF结合使用,可以轻松创建高度可定制的图形化编辑器,用于编辑由EMF生成的...

    一个GEF的简单例子

    6. **Connection Manager(连接管理器)**: 用于处理图形元素之间的连线,支持自动布局和调整。 **GEF的工作流程** 1. 用户在图形界面上进行操作,例如点击或拖动。 2. 编辑部件(Edit Part)接收到这些事件并进行...

    GEF实现拷贝粘贴

    3. **注册Command到CommandStack**:将CopyCommand和PasteCommand添加到EditDomain的CommandStack,这样当用户执行拷贝和粘贴操作时,框架会自动调用这些命令。 4. **EditPolicy的实现**:在图形元素的EditPolicy中...

    EMF_GEF_入门系列

    GEF支持基本的绘图操作,如线条、形状的绘制,以及更复杂的图形布局算法。此外,GEF还提供了拖放、连接、缩放、旋转等图形交互功能。开发者可以通过实现GEF提供的接口和回调方法,轻松地定制自己的图形编辑器,用于...

Global site tag (gtag.js) - Google Analytics