diff --git a/src/org/ntlab/deltaViewer/DeltaViewer.java b/src/org/ntlab/deltaViewer/DeltaViewer.java index 06b5a1e..6781893 100644 --- a/src/org/ntlab/deltaViewer/DeltaViewer.java +++ b/src/org/ntlab/deltaViewer/DeltaViewer.java @@ -2,7 +2,9 @@ import java.awt.BorderLayout; import java.awt.Dimension; +import java.awt.Graphics2D; import java.awt.Point; +import java.awt.geom.Path2D; import java.awt.geom.Point2D; import java.util.AbstractMap.SimpleEntry; import java.util.ArrayList; @@ -34,11 +36,17 @@ import org.ntlab.trace.Reference; import org.ntlab.trace.Statement; +import com.mxgraph.canvas.mxGraphics2DCanvas; import com.mxgraph.model.mxCell; import com.mxgraph.model.mxICell; +import com.mxgraph.shape.mxConnectorShape; +import com.mxgraph.shape.mxIShape; import com.mxgraph.swing.mxGraphComponent; +import com.mxgraph.swing.view.mxInteractiveCanvas; import com.mxgraph.util.mxConstants; import com.mxgraph.util.mxPoint; +import com.mxgraph.util.mxUtils; +import com.mxgraph.view.mxCellState; import com.mxgraph.view.mxGraphView; /** @@ -85,7 +93,11 @@ public DeltaViewer() { mxgraph = new DeltaGraphAdapter(new DirectedWeightedPseudograph(DefaultEdge.class)); mxDefaultParent = (mxCell)mxgraph.getDefaultParent(); - mxgraphComponent = new mxGraphComponent(mxgraph); + mxgraphComponent = new mxGraphComponent(mxgraph) { + public mxInteractiveCanvas createCanvas() { + return new CurvedCanvas(this); + } + }; deltaAnimation = new DeltaAnimation(mxgraph, mxgraphComponent); } @@ -1543,4 +1555,90 @@ System.out.println(" " + ((mxICell)e.getCell()).getParent().getId()); } } + + private class CurvedCanvas extends mxInteractiveCanvas { + mxIShape shape = new CurvedConnector(); + + public CurvedCanvas(mxGraphComponent mxGraphComponent) { + super(mxGraphComponent); + } + + public Object drawCell(mxCellState state) { + if (!(state.getCell() instanceof mxCell) || !((mxCell)state.getCell()).isEdge() || state.getAbsolutePointCount() == 2) { + return super.drawCell(state); + } + Map style = state.getStyle(); + + if (g != null) { + // Creates a temporary graphics instance for drawing this shape + float opacity = mxUtils.getFloat(style, mxConstants.STYLE_OPACITY, 100); + Graphics2D previousGraphics = g; + g = createTemporaryGraphics(style, opacity, state); + shape.paintShape(this, state); + g.dispose(); + g = previousGraphics; + } + + return shape; + } + } + + private class CurvedConnector extends mxConnectorShape { + public void paintShape(mxGraphics2DCanvas canvas, mxCellState state) { + if (state.getAbsolutePointCount() > 1 + && configureGraphics(canvas, state, false)) { + List pts = new ArrayList( + state.getAbsolutePoints()); + Map style = state.getStyle(); + + // Paints the markers and updates the points + // Switch off any dash pattern for markers + boolean dashed = mxUtils.isTrue(style, mxConstants.STYLE_DASHED); + Object dashedValue = style.get(mxConstants.STYLE_DASHED); + + if (dashed) { + style.remove(mxConstants.STYLE_DASHED); + canvas.getGraphics().setStroke(canvas.createStroke(style)); + } + + translatePoint(pts, 0, + paintMarker(canvas, state, true)); + translatePoint( + pts, + pts.size() - 1, + paintMarker(canvas, state, false)); + + if (dashed) { + // Replace the dash pattern + style.put(mxConstants.STYLE_DASHED, dashedValue); + canvas.getGraphics().setStroke(canvas.createStroke(style)); + } + + // Paints the shape and restores the graphics object + if (state.getAbsolutePointCount() == 4) { + double sx = state.getAbsolutePoint(0).getX(); + double sy = state.getAbsolutePoint(0).getY(); + double tx1 = state.getAbsolutePoint(1).getX(); + double ty1 = state.getAbsolutePoint(1).getY(); + double tx2 = state.getAbsolutePoint(2).getX(); + double ty2 = state.getAbsolutePoint(2).getY(); + double ex = state.getAbsolutePoint(3).getX(); + double ey = state.getAbsolutePoint(3).getY(); + Path2D.Double p = new Path2D.Double(); + p.moveTo((int) sx, (int) sy); + p.curveTo((int) tx1, (int) sy, (int) tx2, (int) ty2, (int) ex, (int) ey); + canvas.getGraphics().draw(p); + } + } + } + + private void translatePoint(List points, int index, mxPoint offset) { + if (offset != null) { + mxPoint pt = (mxPoint) points.get(index).clone(); + pt.setX(pt.getX() + offset.getX()); + pt.setY(pt.getY() + offset.getY()); + points.set(index, pt); + } + } + } }