/* * Copyright (c) 2001-2005, Gaudenz Alder All rights reserved. See LICENSE file * in distribution for license details */ package de.unisiegen.gtitool.ui.jgraph; import java.awt.geom.Point2D; import java.util.ArrayList; import java.util.List; import org.jgraph.graph.DefaultGraphModel; import org.jgraph.graph.EdgeView; import org.jgraph.graph.GraphConstants; import org.jgraph.graph.GraphLayoutCache; import org.jgraph.graph.GraphModel; import org.jgraph.graph.PortView; import de.unisiegen.gtitool.core.entities.State; @SuppressWarnings ( "all" ) public class JGraphpadParallelSplineRouter extends DefaultEdge.LoopRouting { protected static GraphModel emptyModel = new DefaultGraphModel (); public static JGraphpadParallelSplineRouter sharedInstance = new JGraphpadParallelSplineRouter (); /** * @return Returns the sharedInstance. */ public static JGraphpadParallelSplineRouter getSharedInstance () { return sharedInstance; } /** * The distance between the control point and the middle line. A larger number * will lead to a more "bubbly" appearance of the bezier edges. */ public double edgeSeparation = 25; private JGraphpadParallelSplineRouter () { // empty } /** * @return Returns the edgeSeparation. */ public double getEdgeSeparation () { return this.edgeSeparation; } public int getEdgeStyle () { return GraphConstants.STYLE_SPLINE; } /** * Returns the array of parallel edges. * * @param edge */ public Object [] getParallelEdges ( EdgeView edge ) { return DefaultGraphModel.getEdgesBetween ( emptyModel, edge.getSource () .getParentView ().getCell (), edge.getTarget ().getParentView () .getCell (), false ); } public List routeEdge ( GraphLayoutCache cache, EdgeView edge ) { List newPoints = new ArrayList (); // Check presence of source/target nodes if ( ( null == edge.getSource () ) || ( null == edge.getTarget () ) || ( null == edge.getSource ().getParentView () ) || ( null == edge.getTarget ().getParentView () ) ) { return null; } newPoints.add ( edge.getSource () ); Object [] edges = getParallelEdges ( edge ); // Find the position of the current edge that we are currently routing if ( edges == null ) { return null; } int position = 0; for ( int i = 0 ; i < edges.length ; i++ ) { Object e = edges [ i ]; if ( e == edge.getCell () ) { position = i; } } // If there is only 1 edge between the two vertices, we don't need this // special routing if ( edges.length >= 2 ) { // MODIFYBEGIN // Find the end point positions Point2D from = ( ( PortView ) edge.getSource () ).getLocation (); Point2D to = ( ( PortView ) edge.getTarget () ).getLocation (); if ( ( from != null ) && ( to != null ) ) { double fromX = from.getX (); double fromY = from.getY (); double toX = to.getX (); double toY = to.getY (); StateView stateView = ( StateView ) ( ( PortView ) edge.getSource () ) .getParentView (); if ( stateView.getCell () instanceof DefaultStateView ) { DefaultStateView defaultStateView = ( DefaultStateView ) stateView .getCell (); State state = defaultStateView.getState (); if ( state.isStartState () ) { fromX += StateView.START_OFFSET / 2; } if ( state.isLoopTransition () ) { fromY += StateView.LOOP_TRANSITION_OFFSET / 2; } } StateView stateViewTo = ( StateView ) ( ( PortView ) edge.getTarget () ) .getParentView (); if ( stateViewTo.getCell () instanceof DefaultStateView ) { DefaultStateView defaultStateView = ( DefaultStateView ) stateViewTo .getCell (); State state = defaultStateView.getState (); if ( state.isStartState () ) { toX += StateView.START_OFFSET / 2; } if ( state.isLoopTransition () ) { toY += StateView.LOOP_TRANSITION_OFFSET / 2; } } // calculate mid-point of the main edge double midX = Math.min ( fromX, toX ) + Math.abs ( ( fromX - toX ) / 2 ); double midY = Math.min ( fromY, toY ) + Math.abs ( ( fromY - toY ) / 2 ); // compute the normal slope. The normal of a slope is the // negative // inverse of the original slope. double m = ( fromY - toY ) / ( fromX - toX ); // bug fix if ( m == 0 ) { // System.err.println ("bugfix"); m = -0.0000000001; } double theta = Math.atan ( -1 / m ); // modify the location of the control point along the axis of // the // normal using the edge position double r = this.edgeSeparation * ( Math.floor ( position / 2 ) + 1 ); if ( ( position % 2 ) == 0 ) { r = -r; } // convert polar coordinates to cartesian and translate axis to // the // mid-point double ex = r * Math.cos ( theta ) + midX; double ey = r * Math.sin ( theta ) + midY; Point2D controlPoint = new Point2D.Double ( ex, ey ); // add the control point to the points list newPoints.add ( controlPoint ); // MODIFYEND } } newPoints.add ( edge.getTarget () ); return newPoints; } /** * @param edgeSeparation The edgeSeparation to set. */ public void setEdgeSeparation ( double edgeSeparation ) { this.edgeSeparation = edgeSeparation; } }