001: /*
002: * $Header: /cvs/j3dfly/J3dEditor/src/org/jdesktop/j3dedit/treelayout/SimpleTreeLayout.java,v 1.1 2005/04/20 22:21:32 paulby Exp $
003: *
004: * Sun Public License Notice
005: *
006: * The contents of this file are subject to the Sun Public License Version
007: * 1.0 (the "License"). You may not use this file except in compliance with
008: * the License. A copy of the License is available at http://www.sun.com/
009: *
010: * The Original Code is the Java 3D(tm) Scene Graph Editor.
011: * The Initial Developer of the Original Code is Paul Byrne.
012: * Portions created by Paul Byrne are Copyright (C) 2002.
013: * All Rights Reserved.
014: *
015: * Contributor(s): Paul Byrne.
016: *
017: **/
018: package org.jdesktop.j3dedit.treelayout;
019:
020: import java.awt.*;
021:
022: /**
023: * Generic algorithm for computing the layout of a tree who's nodes
024: * implement the @see TreeNode interface
025: *
026: * @author Paul Byrne
027: * @version $Id: SimpleTreeLayout.java,v 1.1 2005/04/20 22:21:32 paulby Exp $
028: */
029: public class SimpleTreeLayout extends TreeLayout {
030:
031: private int START_Y = 10;
032:
033: private int sizeCount = 0;
034: private int layoutCount = 0;
035:
036: private void computeSubtreeSize(TreeNode node) {
037: TreeNode child;
038: Rectangle subtreeSize = node.getSubtreeSize();
039:
040: if (!(node.getLink() instanceof SimpleTreeLink))
041: node.setLink(new SimpleTreeLink(node, 30));
042:
043: sizeCount++;
044: //if (sizeCount % 100 == 0) System.out.println("Sized "+sizeCount);
045:
046: if (node.numChildren() == 0)
047: subtreeSize = new Rectangle(0, 0,
048: node.getPreferredSize().width, node
049: .getPreferredSize().height);
050: else {
051: int biggestChild = 0;
052: subtreeSize.height = node.getPreferredSize().height;
053: subtreeSize.width = 0;
054: for (int i = 0; i < node.numChildren(); i++) {
055: child = node.getChild(i);
056: computeSubtreeSize(child);
057: subtreeSize.width += child.getSubtreeSize().width;
058: biggestChild = Math.max(biggestChild, child
059: .getSubtreeSize().height
060: + child.getLink().getSpacing());
061: }
062: subtreeSize.height += biggestChild;
063: }
064:
065: //System.out.println( node.hashCode() +" size "+subtreeSize );
066: node.setSubtreeSize(subtreeSize);
067:
068: }
069:
070: /**
071: * Traverse the tree and set the computedPosition of each node
072: * according to the area that their subtree occupies
073: */
074: private void layoutSubtree(TreeNode subtreeRoot, TreeNode parent,
075: int xOffset) {
076: layoutCount++;
077: //if (layoutCount % 100 == 0) System.out.println("Layout "+layoutCount);
078:
079: Point computedPos = new Point();
080:
081: if (subtreeRoot.getParent() == null)
082: computedPos.y = START_Y;
083: else {
084: computedPos.y = parent.getComputedPosition().y
085: + parent.getLink().getSpacing()
086: + subtreeRoot.getPreferredSize().height;
087: //System.out.println( computedPos +" "+parent.getComputedPosition()+ " "+parent.getLink() );
088: }
089:
090: // Set the position of the node
091: computedPos.x = xOffset + subtreeRoot.getSubtreeSize().width
092: / 2;
093: //System.out.println( "Node pos "+computedPos );
094:
095: // Set the position of the subtree bounds
096: Rectangle subBounds = subtreeRoot.getSubtreeSize();
097: subBounds.x = xOffset + subtreeRoot.getPreferredSize().width
098: / 2;
099: subBounds.y = computedPos.y;
100: subtreeRoot.setSubtreeSize(subBounds);
101:
102: subtreeRoot.setComputedPosition(computedPos);
103:
104: int leftOffset = xOffset;
105: for (int i = 0; i < subtreeRoot.numChildren(); i++) {
106: layoutSubtree(subtreeRoot.getChild(i), subtreeRoot,
107: leftOffset);
108: leftOffset += subtreeRoot.getChild(i).getSubtreeSize().width;
109: }
110: }
111:
112: public void doLayout(TreeNode root) {
113: computeSubtreeSize(root);
114: layoutSubtree(root, null, 0);
115: ((SimpleTreeLink) root.getLink()).updateAllLinks();
116: }
117:
118: /**
119: * Return the picked node, searching from the starting point node
120: */
121: public TreeNode doPick(TreeNode node, int x, int y) {
122: TreeNode ret = null;
123:
124: if (node.getSubtreeSize().contains(x, y)) {
125: if (node.picked(x, y))
126: ret = node;
127: else {
128: for (int i = 0; i < node.numChildren() && ret == null; i++) {
129: ret = doPick(node.getChild(i), x, y);
130: }
131: }
132: } else
133: ret = null;
134:
135: return ret;
136: }
137: }
|