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