How to create and augment custom arrow styles |
| Applies to: yFiles 2.4 |
Type: Tips & Tricks
Categories this article belongs to:
| yFiles for Java | > yFiles Viewer | > Displaying and Editing Graphs | > Realizer-Related Features |
This article demonstrates how to create new custom arrow styles or augment existing ones.
Class y.view.Arrow
already defines some predefined arrow types that should suffice for most basic needs. Of course, creating custom arrows is also possible.
To change the appearance of the arrow completely, it is possible to register an own Shape or Drawable
with several variants of the static methods Arrow.addCustomArrow
. The following snippet changes the arrow to a red circle:
If you just want to augment the appearance of an (existing or custom) arrow, you need a bit more work. Since class y.view.Arrow
is final, it is not possible to overwrite its paint
method. However, it is possible to delegate the painting of the base arrow to a Drawable
, which can be decorated at will and registered with Arrow.addCustomArrow
. The following snippet outlines this approach, where a predefined arrow is decorated with a green circle:
Graph2D g = new Graph2D(); // Take a default PolyLineEdgeRealizer... EdgeRealizer er = new PolyLineEdgeRealizer(); //the head of the shape should be at (0,0), the tail should be at (x, 0), where x < 0 //for a circle with diameter 10, this leads to the following coordinates Drawable redCircle = new ShapeDrawable( new Ellipse2D.Double( -10, -5, 10, 10 ), Color.RED ); //add custom arrow Arrow.addCustomArrow( "red circle", redCircle); //set this custom arrow as target arrow for the realizer ger.setTargetArrow( Arrow.getCustomArrow( "red circle")); g.setDefaultEdgeRealizer( er ); |
public DecoratingEdgeRealizerDemo() { super(); Graph2D g = new Graph2D(); // Take a default PolyLineEdgeRealizer... EdgeRealizer ger = new PolyLineEdgeRealizer(); Arrow baseArrow = Arrow.DELTA; //the location of the drawable is calculated like in the first example Drawable decoration = new ShapeDrawable( new Ellipse2D.Double( -baseArrow.getArrowLength() - 10 - 1, -5, 10, 10 ), Color.GREEN ); //create new drawable that augments the original arrow with the decoration Drawable drawable = new DecoratedArrowDrawable( baseArrow, decoration, false ); Arrow.addCustomArrow( "decorated", drawable, drawable.getBounds().getWidth(), 0 ); ger.setTargetArrow( Arrow.getCustomArrow( "decorated") ); g.setDefaultEdgeRealizer( ger ); } public static class DecoratedArrowDrawable implements Drawable { private Arrow delegateArrow; private Drawable decoration; private boolean drawDecorationFirst; /** Create a new drawable object that wraps an existing arrow. * * @param delegateArrow The base arrow that is decorated * @param decoration the decoration that is drawn additionally * @param drawDecorationFirst true iff decoration should be drawn first (below) the delegate arrow */ public DecoratedArrowDrawable( Arrow delegateArrow, Drawable decoration, boolean drawDecorationFirst ) { this.delegateArrow = delegateArrow; this.decoration = decoration; this.drawDecorationFirst = drawDecorationFirst; } public void paint( Graphics2D g ) { if ( drawDecorationFirst ) { decoration.paint( g ); //dx and dy are measured in "arrow length" dimensions delegateArrow.paint( g, 0, 0, 1, 0 ); } else { delegateArrow.paint( g, 0, 0, 1, 0 ); decoration.paint( g ); } } public Rectangle getBounds() { Rectangle unionRect = decoration.getBounds().union( new Rectangle(-1, -1, 1,1)); return unionRect; } } |
| Resources: |
| Keywords: | EdgeRealizer - Arrow |


