/* Violet - A program for editing UML diagrams. Copyright (C) 2002 Cay S. Horstmann (http://horstmann.com) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package com.horstmann.violet; import java.awt.Graphics2D; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import com.horstmann.violet.framework.Edge; import com.horstmann.violet.framework.Graph; import com.horstmann.violet.framework.Grid; import com.horstmann.violet.framework.Node; /** A UML sequence diagram. */ public class SequenceDiagramGraph extends Graph { public boolean add(Node n, Point2D p) { if (n instanceof CallNode) // must be inside an object { Collection nodes = getNodes(); boolean inside = false; Iterator iter = nodes.iterator(); while (!inside && iter.hasNext()) { Node n2 = (Node)iter.next(); if (n2 instanceof ImplicitParameterNode && n2.contains(p)) { inside = true; ((CallNode)n).setImplicitParameter( (ImplicitParameterNode)(n2)); } } if (!inside) return false; } if (!super.add(n, p)) return false; return true; } public void removeEdge(Edge e) { super.removeEdge(e); if (e instanceof CallEdge && e.getEnd().getChildren().size() == 0) removeNode(e.getEnd()); } public void layout(Graphics2D g2, Grid grid) { super.layout(g2, grid); ArrayList topLevelCalls = new ArrayList(); ArrayList objects = new ArrayList(); Collection nodes = getNodes(); Iterator iter = nodes.iterator(); while (iter.hasNext()) { Node n = (Node)iter.next(); if (n instanceof CallNode && n.getParent() == null) topLevelCalls.add(n); else if (n instanceof ImplicitParameterNode) objects.add(n); } Collection edges = getEdges(); iter = edges.iterator(); while (iter.hasNext()) { Edge e = (Edge)iter.next(); if (e instanceof CallEdge) { Node end = e.getEnd(); if (end instanceof CallNode) ((CallNode)end).setSignaled(((CallEdge)e).isSignal()); } } double left = 0; // find the max of the heights of the objects double top = 0; for (int i = 0; i < objects.size(); i++) { ImplicitParameterNode n = (ImplicitParameterNode)objects.get(i); n.translate(0, -n.getBounds().getY()); top = Math.max(top, n.getTopRectangle().getHeight()); } /* // sort topLevelCalls by y position Collections.sort(topLevelCalls, new Comparator() { public int compare(Object o1, Object o2) { CallNode c1 = (CallNode)o1; CallNode c2 = (CallNode)o2; double diff = c1.getBounds().getY() - c2.getBounds().getY(); if (diff < 0) return -1; if (diff > 0) return 1; return 0; } }); for (int i = 0; i < topLevelCalls.size(); i++) { CallNode call = (CallNode)topLevelCalls.get(i); top += CallNode.CALL_YGAP; call.translate(0, top - call.getBounds().getY()); call.layout(this, g2, grid); top += call.getBounds().getHeight(); } */ for (int i = 0; i < topLevelCalls.size(); i++) { CallNode call = (CallNode) topLevelCalls.get(i); call.layout(this, g2, grid); } iter = nodes.iterator(); while (iter.hasNext()) { Node n = (Node)iter.next(); if (n instanceof CallNode) top = Math.max(top, n.getBounds().getY() + n.getBounds().getHeight()); } top += CallNode.CALL_YGAP; for (int i = 0; i < objects.size(); i++) { ImplicitParameterNode n = (ImplicitParameterNode) objects.get(i); Rectangle2D b = n.getBounds(); n.setBounds(new Rectangle2D.Double( b.getX(), b.getY(), b.getWidth(), top - b.getY())); } } public void draw(Graphics2D g2, Grid g) { layout(g2, g); Collection nodes = getNodes(); Iterator iter = nodes.iterator(); while (iter.hasNext()) { Node n = (Node) iter.next(); if (!(n instanceof CallNode)) n.draw(g2); } iter = nodes.iterator(); while (iter.hasNext()) { Node n = (Node) iter.next(); if (n instanceof CallNode) n.draw(g2); } Collection edges = getEdges(); iter = edges.iterator(); while (iter.hasNext()) { Edge e = (Edge) iter.next(); e.draw(g2); } } public Node[] getNodePrototypes() { return NODE_PROTOTYPES; } public Edge[] getEdgePrototypes() { return EDGE_PROTOTYPES; } protected static final Node[] NODE_PROTOTYPES = new Node[3]; protected static final Edge[] EDGE_PROTOTYPES = new Edge[3]; }