package iiuf.swing.graph; import java.awt.Dimension; import java.awt.Component; import java.util.ArrayList; import iiuf.util.graph.GraphModel; import iiuf.util.graph.GraphNode; import iiuf.awt.Awt; /** Node layouter implementation that orderes the node in a tree starting from a start node. (c) 2000, 2001, IIUF, DIUF<p> @author $Author: ohitz $ @version $Name: $ $Revision: 1.1 $ */ public class TreeNL implements NodeLayouter { public static final int NORTH = 0; public static final int EAST = 1; public static final int SOUTH = 2; public static final int WEST = 3; private static final int OFF = 10; private static final int IOFF = 4; private GraphNode start; private int direction; private boolean bottomUp; public TreeNL() { this(null, EAST); } public TreeNL(GraphNode start, int direction) { this(start, direction, false); } public TreeNL(GraphNode start, int direction, boolean bottomUp_) { setStart(start); setDirection(direction); bottomUp = bottomUp_; } public boolean allowsNodeLocationChange() { return false; } public void setDirection(int direction_) { direction = direction_; } public void setStart(GraphNode start_) { start = start_; } class TreeNode { Component cmp; ArrayList children; Dimension cmpsz; TreeNode() { cmp = iiuf.awt.Awt.newComponent(); cmpsz = new Dimension(); } TreeNode(GraphNode node, int COMPONENT) { node.setColor(node.BLACK); if(bottomUp) { iiuf.util.graph.GraphEdge[] in = node.getIn(); cmp = (Component)node.get(COMPONENT); cmpsz = cmp.getPreferredSize(); for(int i = 0; i < in.length; i++) { GraphNode from = in[i].getNodes()[in[i].FROM]; if(from.getColor() == from.WHITE) add(new TreeNode(from, COMPONENT)); } } else { iiuf.util.graph.GraphEdge[] out = node.getOut(); cmp = (Component)node.get(COMPONENT); cmpsz = cmp.getPreferredSize(); for(int i = 0; i < out.length; i++) { GraphNode to = out[i].getNodes()[out[i].TO]; if(to.getColor() == to.WHITE) add(new TreeNode(to, COMPONENT)); } } } void add(TreeNode n) { if(children == null) children = new ArrayList(); children.add(n); } Dimension getSize() { if(children == null) return cmpsz; int width = 0; int height = 0; TreeNode[] tns = (TreeNode[])children.toArray(new TreeNode[children.size()]); for(int i = 0; i < tns.length; i++) { tns[i].cmp.setBounds(cmp.getX() + OFF + cmpsz.width, cmp.getY() + height, tns[i].cmpsz.width, tns[i].cmpsz.height); Dimension d = tns[i].getSize(); width = d.width > width ? d.width : width; height += d.height + (i < tns.length - 1 ? IOFF : 0); } height = height > cmpsz.height ? height : cmpsz.height; cmp.setLocation(cmp.getX(), cmp.getY() + (height - cmpsz.height - IOFF) / 2); width += cmpsz.width + OFF; if(tns.length > 1) height += OFF; return new Dimension(width, height); } } private GraphNode getRoot(GraphNode node) { if(node == null) return null; if(bottomUp) { iiuf.util.graph.GraphEdge[] out = node.getOut(); if(out.length == 0) return node; for(GraphNode n = out[0].getToNode(); n != node; n = out[0].getToNode()) { out = n.getOut(); if(out.length == 0) return n; } } else { iiuf.util.graph.GraphEdge[] in = node.getIn(); if(in.length == 0) return node; for(GraphNode n = in[0].getFromNode(); n != node; n = in[0].getFromNode()) { in = n.getIn(); if(in.length == 0) return n; } } return node; } public Dimension layout(GraphPanel panel, GraphModel graph) { if(graph == null) return new Dimension(1, 1); synchronized(graph) { GraphNode[] nodes = graph.nodesArray(); if(start == null) { if(nodes.length == 0) return new Dimension(1,1); for(int i = 0; i < nodes.length; i++) if(nodes[i] instanceof ConnectingNode) continue; else { setStart(getRoot(nodes[i])); break; } } if(start == null) return new Dimension(1, 1); for(int i = 0; i < nodes.length; i++) { GraphNode gn = nodes[i]; gn.setColor(gn instanceof ConnectingNode ? gn.BLACK : gn.WHITE); } TreeNode result = new TreeNode(); GraphNode top = start; do { result.add(new TreeNode(top, panel.COMPONENT)); top = null; for(int i = 0; i < nodes.length; i++) { if(nodes[i].getColor() == GraphNode.WHITE) { top = getRoot(nodes[i]); break; } } } while(top != null); return result.getSize(); } } public void activate() {} public void deactivate() {} } /* $Log: TreeNL.java,v $ Revision 1.1 2002/07/11 12:09:52 ohitz Initial checkin Revision 1.3 2001/05/01 18:08:56 schubige webcom demo beta Revision 1.2 2001/04/30 07:33:17 schubige added webcom to cvstree Revision 1.1 2001/02/17 09:54:22 schubige moved graph stuff to iiuf.swing.graph, started work on rotatable GraphNodeComponents Revision 1.6 2001/01/04 16:28:39 schubige Header update for 2001 and DIUF Revision 1.5 2000/12/28 09:29:10 schubige SourceWatch beta Revision 1.4 2000/12/18 12:39:09 schubige Added ports to iiuf.util.graph Revision 1.3 2000/11/10 10:46:53 schubige iiuf tree cleanup iter 3 Revision 1.2 2000/10/03 08:39:39 schubige Added tree view and contect menu stuff Revision 1.1 2000/08/17 16:22:15 schubige Swing cleanup & TreeView added Revision 1.2 2000/07/28 12:06:54 schubige Graph stuff update Revision 1.1 2000/07/14 13:56:20 schubige Added graph view stuff */