001: /*
002: * @(#)DefaultEdge.java 1.0 03-JUL-04
003: *
004: * Copyright (c) 2001-2004 Gaudenz Alder
005: *
006: */
007: package org.jgraph.graph;
008:
009: import java.awt.geom.Point2D;
010: import java.awt.geom.Rectangle2D;
011: import java.util.ArrayList;
012: import java.util.List;
013:
014: /**
015: * A simple implementation for an edge.
016: *
017: * @version 1.0 1/1/02
018: * @author Gaudenz Alder
019: */
020:
021: public class DefaultEdge extends DefaultGraphCell implements Edge {
022:
023: /** Source and target of the edge. */
024: protected Object source, target;
025:
026: /**
027: * Constructs an empty edge.
028: */
029: public DefaultEdge() {
030: this (null);
031: }
032:
033: /**
034: * Constructs an edge that holds a reference to the specified user object.
035: *
036: * @param userObject
037: * reference to the user object
038: */
039: public DefaultEdge(Object userObject) {
040: this (userObject, null);
041: }
042:
043: /**
044: * Constructs an edge that holds a reference to the specified user object
045: * and sets default values for points and the label position.
046: *
047: * @param userObject
048: * reference to the user object
049: */
050: public DefaultEdge(Object userObject, AttributeMap storageMap) {
051: super (userObject, storageMap);
052: }
053:
054: /**
055: * Returns the source of the edge.
056: */
057: public Object getSource() {
058: return source;
059: }
060:
061: /**
062: * Returns the target of the edge.
063: */
064: public Object getTarget() {
065: return target;
066: }
067:
068: /**
069: * Sets the source of the edge.
070: */
071: public void setSource(Object port) {
072: source = port;
073: }
074:
075: /**
076: * Returns the target of <code>edge</code>.
077: */
078: public void setTarget(Object port) {
079: target = port;
080: }
081:
082: /**
083: * Create a clone of the cell. The cloning of the user object is deferred to
084: * the cloneUserObject() method. The source and target references are set to
085: * null.
086: *
087: * @return Object a clone of this object.
088: */
089: public Object clone() {
090: DefaultEdge edge = (DefaultEdge) super .clone();
091: edge.source = null;
092: edge.target = null;
093: return edge;
094: }
095:
096: //
097: // Default Routing
098: //
099:
100: public static class LoopRouting implements Edge.Routing {
101:
102: public List route(GraphLayoutCache cache, EdgeView edge) {
103: if (edge.isLoop()) {
104: return routeLoop(cache, edge);
105: }
106: return routeEdge(cache, edge);
107: }
108:
109: protected List routeLoop(GraphLayoutCache cache, EdgeView edge) {
110: List newPoints = new ArrayList();
111: newPoints.add(edge.getSource());
112: CellView sourceParent = (edge.getSource() != null) ? edge
113: .getSource().getParentView() : edge
114: .getSourceParentView();
115: if (sourceParent != null) {
116: Point2D from = AbstractCellView
117: .getCenterPoint(sourceParent);
118: Rectangle2D rect = sourceParent.getBounds();
119: double width = rect.getWidth();
120: double height2 = rect.getHeight() / 2;
121: double loopWidth = Math
122: .min(20, Math.max(10, width / 8));
123: double loopHeight = Math.min(30, Math.max(12, Math.max(
124: loopWidth + 4, height2 / 2)));
125: newPoints.add(edge.getAttributes().createPoint(
126: from.getX() - loopWidth,
127: from.getY() - height2 - loopHeight * 1.2));
128: newPoints.add(edge.getAttributes().createPoint(
129: from.getX(),
130: from.getY() - height2 - 1.5 * loopHeight));
131: newPoints.add(edge.getAttributes().createPoint(
132: from.getX() + loopWidth,
133: from.getY() - height2 - loopHeight * 1.2));
134: newPoints.add(edge.getTarget());
135: return newPoints;
136: }
137: return null;
138: }
139:
140: protected List routeEdge(GraphLayoutCache cache, EdgeView edge) {
141: return null;
142: }
143:
144: public int getPreferredLineStyle(EdgeView edge) {
145: if (edge.isLoop()) {
146: return getLoopStyle();
147: }
148: return getEdgeStyle();
149: }
150:
151: protected int getLoopStyle() {
152: return GraphConstants.STYLE_BEZIER;
153: }
154:
155: protected int getEdgeStyle() {
156: return NO_PREFERENCE;
157: }
158:
159: }
160:
161: public static class DefaultRouting extends LoopRouting {
162:
163: protected List routeEdge(GraphLayoutCache cache, EdgeView edge) {
164: List newPoints = new ArrayList();
165: int n = edge.getPointCount();
166: Point2D from = edge.getPoint(0);
167: newPoints.add(from);
168: if (edge.getSource() instanceof PortView) {
169: newPoints.set(0, edge.getSource());
170: from = ((PortView) edge.getSource()).getLocation();
171: } else if (edge.getSource() != null) {
172: Rectangle2D b = edge.getSource().getBounds();
173: from = edge.getAttributes().createPoint(b.getCenterX(),
174: b.getCenterY());
175: }
176: Point2D to = edge.getPoint(n - 1);
177: CellView target = edge.getTarget();
178: if (target instanceof PortView)
179: to = ((PortView) target).getLocation();
180: else if (target != null) {
181: Rectangle2D b = target.getBounds();
182: to = edge.getAttributes().createPoint(b.getCenterX(),
183: b.getCenterY());
184: }
185: if (from != null && to != null) {
186: Point2D[] routed;
187: double dx = Math.abs(from.getX() - to.getX());
188: double dy = Math.abs(from.getY() - to.getY());
189: double x2 = from.getX()
190: + ((to.getX() - from.getX()) / 2);
191: double y2 = from.getY()
192: + ((to.getY() - from.getY()) / 2);
193: routed = new Point2D[2];
194: if (dx > dy) {
195: routed[0] = edge.getAttributes().createPoint(x2,
196: from.getY());
197: routed[1] = edge.getAttributes().createPoint(x2,
198: to.getY());
199: } else {
200: routed[0] = edge.getAttributes().createPoint(
201: from.getX(), y2);
202: routed[1] = edge.getAttributes().createPoint(
203: to.getX(), y2);
204: }
205: // Set/Add Points
206: for (int i = 0; i < routed.length; i++) {
207: if ((edge.getTarget() == null
208: || edge.getTarget().getParentView() == null || !edge
209: .getTarget().getParentView().getBounds()
210: .contains(routed[i]))
211: && (edge.getSource() == null
212: || edge.getSource().getParentView() == null || !edge
213: .getSource().getParentView()
214: .getBounds().contains(routed[i]))) {
215: newPoints.add(routed[i]);
216: }
217: }
218:
219: // Add target point
220: if (target != null)
221: newPoints.add(target);
222: else
223: newPoints.add(to);
224: return newPoints;
225: }
226: return null;
227: }
228:
229: }
230:
231: }
|