public void draw(Graphics2D g) {
    update();

    g.setStroke(new BasicStroke(penSize));

    if (color != null) link.setColor(color);
    else link.setColor(Color.black);

    link.draw(g);
  }
  public void update() {
    initializeLink(0);

    source.updateAnchors();
    target.updateAnchors();

    link.setStartAnchor(source.getAnchor(sourceAnchorKey));
    link.setEndAnchor(target.getAnchor(targetAnchorKey));
    link.setLabel(pattern);
    link.setSelfLoop(source == target);

    link.update();
  }
  public void toggleShape() {
    switch (shape) {
      case SHAPE_ARC:
        shape = SHAPE_ELBOW;
        break;
      case SHAPE_ELBOW:
        shape = SHAPE_ARC;
        break;
      case SHAPE_BEZIER:
        // Cannot toggle a bezier link
        return;
    }
    double flateness = link.getFlateness();
    Vector2D direction = link.getDirection();

    link = createLinkInstance();
    link.setFlateness(flateness);
    link.setDirection(direction);
  }
 public GLink(
     GElement source,
     String sourceAnchorKey,
     GElement target,
     String targetAnchorKey,
     int shape,
     String pattern,
     double flateness) {
   this.source = source;
   this.target = target;
   this.sourceAnchorKey = sourceAnchorKey;
   this.targetAnchorKey = targetAnchorKey;
   this.shape = shape;
   this.pattern = pattern;
   initializeLink(flateness);
   if (source == target) link.setDirection(new Vector2D(0, 1));
   else link.setDirection(source.getPosition().sub(target.getPosition()));
   setSourceTangentOffset(source.getDefaultAnchorOffset(sourceAnchorKey));
   setTargetTangentOffset(target.getDefaultAnchorOffset(targetAnchorKey));
 }
 public void drawShape(Graphics2D g) {
   link.drawShape(g);
 }
 public boolean isInside(Point p) {
   if (link == null) return false;
   else return link.contains(p.x, p.y);
 }
 public Rect getFrame() {
   update();
   return link.getFrame();
 }
 public void setMousePosition(Point mouse) {
   link.setDirection(Vector2D.vector(mouse).sub(target.getPosition()));
   link.setMousePosition(Vector2D.vector(mouse));
 }
 public boolean isLabelVisible() {
   if (link == null) return false;
   else return link.isLabelVisible();
 }
 public void setLabelColor(Color color) {
   link.setLabelColor(color);
 }
 public void setLabelVisible(boolean flag) {
   if (link != null) link.setLabelVisible(flag);
 }
 public void setTargetOffset(Vector2D offset) {
   link.setEndOffset(offset);
 }
 public void setSourceOffset(Vector2D offset) {
   link.setStartOffset(offset);
 }
 public void setTargetTangentOffset(double offset) {
   link.setEndTangentOffset(offset);
 }
 public void setSourceTangentOffset(double offset) {
   link.setStartTangentOffset(offset);
 }
 protected void initializeLink(double flateness) {
   if (link == null) {
     link = createLinkInstance();
     link.setFlateness(flateness);
   }
 }