001package horstmann.ch08_umleditor; 002import java.awt.Color; 003import java.awt.Graphics2D; 004import java.awt.geom.GeneralPath; 005import java.awt.geom.Point2D; 006 007/** 008 This class defines arrowheads of various shapes. 009 */ 010public enum ArrowHead 011{ 012 NONE, TRIANGLE, BLACK_TRIANGLE, V, DIAMOND, BLACK_DIAMOND; 013 014 /** 015 Draws the arrowhead. 016 @param g2 the graphics context 017 @param p a point on the axis of the arrow head 018 @param q the end point of the arrow head 019 */ 020 public void draw(Graphics2D g2, Point2D p, Point2D q) 021 { 022 GeneralPath path = getPath(p, q); 023 Color oldColor = g2.getColor(); 024 if (this == BLACK_DIAMOND || this == BLACK_TRIANGLE) 025 g2.setColor(Color.BLACK); 026 else 027 g2.setColor(Color.WHITE); 028 g2.fill(path); 029 g2.setColor(oldColor); 030 g2.draw(path); 031 } 032 033 /** 034 Gets the path of the arrowhead 035 @param p a point on the axis of the arrow head 036 @param q the end point of the arrow head 037 @return the path 038 */ 039 public GeneralPath getPath(Point2D p, Point2D q) 040 { 041 GeneralPath path = new GeneralPath(); 042 if (this == NONE) return path; 043 final double ARROW_ANGLE = Math.PI / 6; 044 final double ARROW_LENGTH = 8; 045 046 double dx = q.getX() - p.getX(); 047 double dy = q.getY() - p.getY(); 048 double angle = Math.atan2(dy, dx); 049 double x1 = q.getX() 050 - ARROW_LENGTH * Math.cos(angle + ARROW_ANGLE); 051 double y1 = q.getY() 052 - ARROW_LENGTH * Math.sin(angle + ARROW_ANGLE); 053 double x2 = q.getX() 054 - ARROW_LENGTH * Math.cos(angle - ARROW_ANGLE); 055 double y2 = q.getY() 056 - ARROW_LENGTH * Math.sin(angle - ARROW_ANGLE); 057 058 path.moveTo((float)q.getX(), (float)q.getY()); 059 path.lineTo((float)x1, (float)y1); 060 if (this == V) 061 { 062 path.moveTo((float)x2, (float)y2); 063 path.lineTo((float)q.getX(), (float)q.getY()); 064 } 065 else if (this == TRIANGLE || this == BLACK_TRIANGLE) 066 { 067 path.lineTo((float)x2, (float)y2); 068 path.closePath(); 069 } 070 else if (this == DIAMOND || this == BLACK_DIAMOND) 071 { 072 double x3 = x2 - ARROW_LENGTH * Math.cos(angle + ARROW_ANGLE); 073 double y3 = y2 - ARROW_LENGTH * Math.sin(angle + ARROW_ANGLE); 074 path.lineTo((float)x3, (float)y3); 075 path.lineTo((float)x2, (float)y2); 076 path.closePath(); 077 } 078 return path; 079 } 080 081}