001: /*
002: * Copyright (c) 2001-2005, Gaudenz Alder
003: * All rights reserved.
004: *
005: * See LICENSE file in distribution for license details
006: */
007: package com.jgraph.pad.util;
008:
009: import java.awt.geom.Point2D;
010: import java.util.ArrayList;
011: import java.util.List;
012:
013: import org.jgraph.graph.DefaultEdge;
014: import org.jgraph.graph.DefaultGraphModel;
015: import org.jgraph.graph.EdgeView;
016: import org.jgraph.graph.GraphConstants;
017: import org.jgraph.graph.GraphModel;
018: import org.jgraph.graph.PortView;
019:
020: public class JGraphpadParallelSplineRouter extends
021: DefaultEdge.LoopRouting {
022:
023: protected static GraphModel emptyModel = new DefaultGraphModel();
024:
025: public static JGraphpadParallelSplineRouter sharedInstance = new JGraphpadParallelSplineRouter();
026:
027: /**
028: * The distance between the control point and the middle line. A larger
029: * number will lead to a more "bubbly" appearance of the bezier edges.
030: */
031: public double edgeSeparation = 25;
032:
033: private JGraphpadParallelSplineRouter() {
034: // empty
035: }
036:
037: /**
038: * Returns the array of parallel edges.
039: *
040: * @param edge
041: */
042: public Object[] getParallelEdges(EdgeView edge) {
043: // FIXME: The model is stored in the cells only in the default
044: // implementations. Otherwise we must use the real model here.
045: return DefaultGraphModel.getEdgesBetween(emptyModel, edge
046: .getSource().getParentView().getCell(), edge
047: .getTarget().getParentView().getCell(), false);
048: }
049:
050: public List routeEdge(EdgeView edge) {
051: List newPoints = new ArrayList();
052:
053: // Check presence of source/target nodes
054: if ((null == edge.getSource()) || (null == edge.getTarget())
055: || (null == edge.getSource().getParentView())
056: || (null == edge.getTarget().getParentView())) {
057: return null;
058: }
059: newPoints.add(edge.getSource());
060:
061: Object[] edges = getParallelEdges(edge);
062: // Find the position of the current edge that we are currently routing
063: if (edges == null)
064: return null;
065: int position = 0;
066: for (int i = 0; i < edges.length; i++) {
067: Object e = edges[i];
068: if (e == edge.getCell()) {
069: position = i;
070: }
071: }
072:
073: // If there is only 1 edge between the two vertices, we don't need this
074: // special routing
075: if (edges.length >= 2) {
076:
077: // Find the end point positions
078: Point2D from = ((PortView) edge.getSource()).getLocation();
079: Point2D to = ((PortView) edge.getTarget()).getLocation();
080:
081: if (from != null && to != null) {
082: // calculate mid-point of the main edge
083: double midX = Math.min(from.getX(), to.getX())
084: + Math.abs((from.getX() - to.getX()) / 2);
085: double midY = Math.min(from.getY(), to.getY())
086: + Math.abs((from.getY() - to.getY()) / 2);
087:
088: // compute the normal slope. The normal of a slope is the
089: // negative
090: // inverse of the original slope.
091: double m = (from.getY() - to.getY())
092: / (from.getX() - to.getX());
093: double theta = Math.atan(-1 / m);
094:
095: // modify the location of the control point along the axis of
096: // the
097: // normal using the edge position
098: double r = edgeSeparation
099: * (Math.floor(position / 2) + 1);
100: if ((position % 2) == 0) {
101: r = -r;
102: }
103:
104: // convert polar coordinates to cartesian and translate axis to
105: // the
106: // mid-point
107: double ex = r * Math.cos(theta) + midX;
108: double ey = r * Math.sin(theta) + midY;
109: Point2D controlPoint = new Point2D.Double(ex, ey);
110:
111: // add the control point to the points list
112: newPoints.add(controlPoint);
113: }
114: }
115: newPoints.add(edge.getTarget());
116: return newPoints;
117: }
118:
119: public int getEdgeStyle() {
120: return GraphConstants.STYLE_SPLINE;
121: }
122:
123: /**
124: * @return Returns the edgeSeparation.
125: */
126: public double getEdgeSeparation() {
127: return edgeSeparation;
128: }
129:
130: /**
131: * @param edgeSeparation
132: * The edgeSeparation to set.
133: */
134: public void setEdgeSeparation(double edgeSeparation) {
135: this .edgeSeparation = edgeSeparation;
136: }
137:
138: /**
139: * @return Returns the sharedInstance.
140: */
141: public static JGraphpadParallelSplineRouter getSharedInstance() {
142: return sharedInstance;
143: }
144: }
|