Source of ArrowHead.java


  1: import java.awt.Color;
  2: import java.awt.Graphics2D;
  3: import java.awt.geom.GeneralPath;
  4: import java.awt.geom.Point2D;

  6: /**
  7:    This class defines arrowheads of various shapes.
  8: */
  9: public enum ArrowHead
 10: {
 11:    NONE, TRIANGLE, BLACK_TRIANGLE, V, DIAMOND, BLACK_DIAMOND;

 13:    /**
 14:       Draws the arrowhead.
 15:       @param g2 the graphics context
 16:       @param p a point on the axis of the arrow head
 17:       @param q the end point of the arrow head
 18:    */
 19:    public void draw(Graphics2D g2, Point2D p, Point2D q)
 20:    {
 21:       GeneralPath path = getPath(p, q);
 22:       Color oldColor = g2.getColor();
 23:       if (this == BLACK_DIAMOND || this == BLACK_TRIANGLE)
 24:          g2.setColor(Color.BLACK);
 25:       else
 26:          g2.setColor(Color.WHITE);
 27:       g2.fill(path);
 28:       g2.setColor(oldColor);
 29:       g2.draw(path);
 30:    }

 32:    /**
 33:       Gets the path of the arrowhead
 34:       @param p a point on the axis of the arrow head
 35:       @param q the end point of the arrow head
 36:       @return the path
 37:    */
 38:    public GeneralPath getPath(Point2D p, Point2D q)
 39:    {
 40:       GeneralPath path = new GeneralPath();
 41:       if (this == NONE) return path;
 42:       final double ARROW_ANGLE = Math.PI / 6;
 43:       final double ARROW_LENGTH = 8;

 45:       double dx = q.getX() - p.getX();
 46:       double dy = q.getY() - p.getY();
 47:       double angle = Math.atan2(dy, dx);
 48:       double x1 = q.getX() 
 49:          - ARROW_LENGTH * Math.cos(angle + ARROW_ANGLE);
 50:       double y1 = q.getY() 
 51:          - ARROW_LENGTH * Math.sin(angle + ARROW_ANGLE);
 52:       double x2 = q.getX() 
 53:          - ARROW_LENGTH * Math.cos(angle - ARROW_ANGLE);
 54:       double y2 = q.getY() 
 55:          - ARROW_LENGTH * Math.sin(angle - ARROW_ANGLE);

 57:       path.moveTo((float)q.getX(), (float)q.getY());
 58:       path.lineTo((float)x1, (float)y1);
 59:       if (this == V)
 60:       {
 61:          path.moveTo((float)x2, (float)y2);
 62:          path.lineTo((float)q.getX(), (float)q.getY());
 63:       }
 64:       else if (this == TRIANGLE || this == BLACK_TRIANGLE)
 65:       {
 66:          path.lineTo((float)x2, (float)y2);
 67:          path.closePath();                  
 68:       }
 69:       else if (this == DIAMOND || this == BLACK_DIAMOND)
 70:       {
 71:          double x3 = x2 - ARROW_LENGTH * Math.cos(angle + ARROW_ANGLE);
 72:          double y3 = y2 - ARROW_LENGTH * Math.sin(angle + ARROW_ANGLE);
 73:          path.lineTo((float)x3, (float)y3);
 74:          path.lineTo((float)x2, (float)y2);
 75:          path.closePath();         
 76:       }      
 77:       return path;
 78:    }
 79:    
 80: }