Index: graph/examples/src/test/graphlayout/TreeGraphLayoutTest.java =================================================================== RCS file: /cvs/graph/examples/src/test/graphlayout/TreeGraphLayoutTest.java,v retrieving revision 1.3 diff -u -r1.3 TreeGraphLayoutTest.java --- graph/examples/src/test/graphlayout/TreeGraphLayoutTest.java 14 Nov 2006 10:04:04 -0000 1.3 +++ graph/examples/src/test/graphlayout/TreeGraphLayoutTest.java 1 Jun 2007 10:29:28 -0000 @@ -20,8 +20,12 @@ import org.netbeans.api.visual.action.ActionFactory; import org.netbeans.api.visual.action.EditProvider; -import org.netbeans.api.visual.graph.layout.TreeGraphLayout; +import org.netbeans.api.visual.graph.layout.GraphLayout; +import org.netbeans.api.visual.graph.layout.GraphLayoutFactory; +import org.netbeans.api.visual.graph.layout.GraphLayoutSupport; import org.netbeans.api.visual.widget.Widget; +import org.netbeans.api.visual.layout.LayoutFactory; +import org.netbeans.api.visual.layout.SceneLayout; import test.SceneSupport; import test.general.StringGraphScene; @@ -31,9 +35,17 @@ public class TreeGraphLayoutTest extends StringGraphScene { public TreeGraphLayoutTest () { + // new implementation + GraphLayout graphLayout = GraphLayoutFactory.createTreeGraphLayout (100, 100, 50, 50, true); + GraphLayoutSupport.setTreeGraphLayoutRootNode (graphLayout, "root"); + final SceneLayout sceneGraphLayout = LayoutFactory.createSceneGraphLayout (this, graphLayout); + getActions ().addAction (ActionFactory.createEditAction (new EditProvider() { public void edit (Widget widget) { - new TreeGraphLayout (TreeGraphLayoutTest.this, 100, 100, 50, 50, true).layout ("root"); + // new implementation + sceneGraphLayout.invokeLayoutImmediately (); + // old implementation +// new TreeGraphLayout (TreeGraphLayoutTest.this, 100, 100, 50, 50, true).layout ("root"); } })); } Index: graph/lib/apichanges.xml =================================================================== RCS file: /cvs/graph/lib/apichanges.xml,v retrieving revision 1.10 diff -u -r1.10 apichanges.xml --- graph/lib/apichanges.xml 25 May 2007 21:20:27 -0000 1.10 +++ graph/lib/apichanges.xml 1 Jun 2007 10:29:28 -0000 @@ -168,6 +168,20 @@ + + + + GraphLayoutFactory.createTreeGraphLayout added + + + + + + TreeGraphLayout added. + + + + Index: graph/lib/manifest.mf =================================================================== RCS file: /cvs/graph/lib/manifest.mf,v retrieving revision 1.10 diff -u -r1.10 manifest.mf --- graph/lib/manifest.mf 25 May 2007 21:20:27 -0000 1.10 +++ graph/lib/manifest.mf 1 Jun 2007 10:29:28 -0000 @@ -1,4 +1,4 @@ Manifest-Version: 1.0 OpenIDE-Module: org.netbeans.api.visual OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/visual/resources/Bundle.properties -OpenIDE-Module-Specification-Version: 2.2 +OpenIDE-Module-Specification-Version: 2.4 Index: graph/lib/src/org/netbeans/api/visual/graph/layout/GraphLayoutFactory.java =================================================================== RCS file: graph/lib/src/org/netbeans/api/visual/graph/layout/GraphLayoutFactory.java diff -N graph/lib/src/org/netbeans/api/visual/graph/layout/GraphLayoutFactory.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ graph/lib/src/org/netbeans/api/visual/graph/layout/GraphLayoutFactory.java 1 Jun 2007 10:29:28 -0000 @@ -0,0 +1,47 @@ +/* + * The contents of this file are subject to the terms of the Common Development + * and Distribution License (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the License at http://www.netbeans.org/cddl.html + * or http://www.netbeans.org/cddl.txt. + * + * When distributing Covered Code, include this CDDL Header Notice in each file + * and include the License file at http://www.netbeans.org/cddl.txt. + * If applicable, add the following below the CDDL Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun + * Microsystems, Inc. All Rights Reserved. + */ +package org.netbeans.api.visual.graph.layout; + +import org.netbeans.modules.visual.graph.layout.TreeGraphLayout; + +/** + * The factory class of all built-in GraphLayout based implementations. + * + * @author David Kaspar + * @since 2.4 + */ +public class GraphLayoutFactory { + + /** + * Creates a tree graph layout. + * Use GraphLayoutSupport.setTreeGraphLayoutRootNode method to set the root node of the graph. + * If not set/found, then layout is not executed. + * @param originX the x-axis origin + * @param originY the y-axis origin + * @param verticalGap the vertical gap between cells + * @param horizontalGap the horizontal gap between cells + * @param vertical if true, then layout organizes the graph vertically; if false, then horizontally + * @return the tree graph layout + * @since 2.4 + */ + public static GraphLayout createTreeGraphLayout (int originX, int originY, int verticalGap, int horizontalGap, boolean vertical) { + return new TreeGraphLayout (originX, originY, verticalGap, horizontalGap, vertical); + } + +} Index: graph/lib/src/org/netbeans/api/visual/graph/layout/GraphLayoutSupport.java =================================================================== RCS file: graph/lib/src/org/netbeans/api/visual/graph/layout/GraphLayoutSupport.java diff -N graph/lib/src/org/netbeans/api/visual/graph/layout/GraphLayoutSupport.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ graph/lib/src/org/netbeans/api/visual/graph/layout/GraphLayoutSupport.java 1 Jun 2007 10:29:28 -0000 @@ -0,0 +1,40 @@ +/* + * The contents of this file are subject to the terms of the Common Development + * and Distribution License (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the License at http://www.netbeans.org/cddl.html + * or http://www.netbeans.org/cddl.txt. + * + * When distributing Covered Code, include this CDDL Header Notice in each file + * and include the License file at http://www.netbeans.org/cddl.txt. + * If applicable, add the following below the CDDL Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun + * Microsystems, Inc. All Rights Reserved. + */ +package org.netbeans.api.visual.graph.layout; + +import org.netbeans.modules.visual.graph.layout.TreeGraphLayout; + +/** + * @author David Kaspar + * @since 2.4 + */ +public class GraphLayoutSupport { + + /** + * Sets a root node to a tree graph layout. + * @param graph the tree graph layout + * @param rootNode the root node + * @since 2.4 + */ + public static void setTreeGraphLayoutRootNode (GraphLayout graph, N rootNode) { + if (graph instanceof TreeGraphLayout) + ((TreeGraphLayout) graph).setRootNode (rootNode); + } + +} Index: graph/lib/src/org/netbeans/api/visual/widget/doc-files/documentation.html =================================================================== RCS file: /cvs/graph/lib/src/org/netbeans/api/visual/widget/doc-files/documentation.html,v retrieving revision 1.11 diff -u -r1.11 documentation.html --- graph/lib/src/org/netbeans/api/visual/widget/doc-files/documentation.html 31 May 2007 08:12:47 -0000 1.11 +++ graph/lib/src/org/netbeans/api/visual/widget/doc-files/documentation.html 1 Jun 2007 10:29:28 -0000 @@ -167,6 +167,7 @@
  • Universal Graph
  • Graph-oriented Layout
  • GraphLayoutListener +
  • TreeGraphLayout
  • GridGraphLayout
  • ComponentWidget @@ -1728,10 +1729,19 @@

    The GraphLayout has possibility to attach a GraphLayoutListener which allows notification about: graphLayoutStarted (called when graph layout is started), nodeLocationChanged (called when a node location is changed, graphLayoutFinished (called when graph layout is finished). +

    TreeGraphLayout

    + +

    +The algotihm organizes nodes in to a tree. Nodes that are not in the tree (defined by a root node and connecting edges) are resolved at [0,0] location. + +

    +The layout can be created using GraphLayoutFactory.createTreeGraphLayout factory method. +For proper work, you have to specify a root node using GraphLayoutSupport.createTreeGraphLayoutRootNode method. See test.graphlayout.TreeGraphLayoutTest example for usages. +

    GridGraphLayout

    -For now there is only one graph-oriented layout implemented by the GridGraphLayout class. The algorithm organizes nodes in to a grid. +The algorithm organizes nodes in to a grid.

    You can call setChecker method to enable checker style. If a parameter is true, that the layout uses only half of nodes on a grid like single color on a chess board. Index: graph/lib/src/org/netbeans/modules/visual/graph/layout/TreeGraphLayout.java =================================================================== RCS file: graph/lib/src/org/netbeans/modules/visual/graph/layout/TreeGraphLayout.java diff -N graph/lib/src/org/netbeans/modules/visual/graph/layout/TreeGraphLayout.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ graph/lib/src/org/netbeans/modules/visual/graph/layout/TreeGraphLayout.java 1 Jun 2007 10:29:28 -0000 @@ -0,0 +1,164 @@ +/* + * The contents of this file are subject to the terms of the Common Development + * and Distribution License (the License). You may not use this file except in + * compliance with the License. + * + * You can obtain a copy of the License at http://www.netbeans.org/cddl.html + * or http://www.netbeans.org/cddl.txt. + * + * When distributing Covered Code, include this CDDL Header Notice in each file + * and include the License file at http://www.netbeans.org/cddl.txt. + * If applicable, add the following below the CDDL Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun + * Microsystems, Inc. All Rights Reserved. + */ +package org.netbeans.modules.visual.graph.layout; + +import org.netbeans.api.visual.graph.layout.GraphLayout; +import org.netbeans.api.visual.graph.layout.UniversalGraph; +import org.netbeans.api.visual.widget.Widget; + +import java.awt.*; +import java.util.*; + +/** + * @author David Kaspar + */ +public final class TreeGraphLayout extends GraphLayout { + + private int originX; + private int originY; + private int verticalGap; + private int horizontalGap; + private boolean vertical; + + private N rootNode; + + public TreeGraphLayout (int originX, int originY, int verticalGap, int horizontalGap, boolean vertical) { + this.originX = originX; + this.originY = originY; + this.verticalGap = verticalGap; + this.horizontalGap = horizontalGap; + this.vertical = vertical; + } + + public void setRootNode (N rootNode) { + this.rootNode = rootNode; + } + + protected void performGraphLayout (UniversalGraph graph) { + if (rootNode == null) + return; + Collection allNodes = graph.getNodes (); + ArrayList nodesToResolve = new ArrayList (allNodes); + + HashSet loadedSet = new HashSet (); + Node root = new Node (graph, rootNode, loadedSet); + nodesToResolve.removeAll (loadedSet); + if (vertical) { + root.allocateHorizontally (graph); + root.resolveVertically (originX, originY); + } else { + root.allocateVertically (graph); + root.resolveHorizontally (originX, originY); + } + + final HashMap resultPosition = new HashMap (); + root.upload (resultPosition); + + for (N node : nodesToResolve) { + Point position = new Point (); + // TODO - resolve others + resultPosition.put (node, position); + } + + for (Map.Entry entry : resultPosition.entrySet ()) + setResolvedNodeLocation (graph, entry.getKey (), entry.getValue ()); + } + + protected void performNodesLayout (UniversalGraph universalGraph, Collection nodes) { + throw new UnsupportedOperationException (); // TODO + } + + private class Node { + + private N node; + private ArrayList children; + + private Rectangle relativeBounds; + private int space; + private int totalSpace; + private Point point; + + private Node (UniversalGraph graph, N node, HashSet loadedSet) { + this.node = node; + loadedSet.add (node); + + children = new ArrayList (); + for (E edge: graph.findNodeEdges (node, true, false)) { + N child = graph.getEdgeTarget (edge); + if (child != null && ! loadedSet.contains (child)) + children.add (new Node (graph, child, loadedSet)); + } + } + + private int allocateHorizontally (UniversalGraph graph) { + Widget widget = graph.getScene ().findWidget (node); + widget.getLayout ().layout (widget); + relativeBounds = widget.getPreferredBounds (); + space = 0; + for (int i = 0; i < children.size (); i++) { + if (i > 0) + space += horizontalGap; + space += children.get (i).allocateHorizontally (graph); + } + totalSpace = Math.max (space, relativeBounds.width); + return totalSpace; + } + + private void resolveVertically (int x, int y) { + point = new Point (x + totalSpace / 2, y - relativeBounds.y); + x += (totalSpace - space) / 2; + y += relativeBounds.height + verticalGap; + for (Node child : children) { + child.resolveVertically (x, y); + x += child.totalSpace + horizontalGap; + } + } + + private int allocateVertically (UniversalGraph graph) { + Widget widget = graph.getScene ().findWidget (node); + widget.getLayout ().layout (widget); + relativeBounds = widget.getPreferredBounds (); + space = 0; + for (int i = 0; i < children.size (); i++) { + if (i > 0) + space += verticalGap; + space += children.get (i).allocateVertically (graph); + } + totalSpace = Math.max (space, relativeBounds.height); + return totalSpace; + } + + private void resolveHorizontally (int x, int y) { + point = new Point (x - relativeBounds.x, y + totalSpace / 2); + x += relativeBounds.width + horizontalGap; + y += (totalSpace - space) / 2; + for (Node child : children) { + child.resolveHorizontally (x, y); + y += child.totalSpace + verticalGap; + } + } + + private void upload (HashMap result) { + result.put (node, point); + for (Node child : children) + child.upload (result); + } + } + +}