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: }