f@0
|
1 /*
|
f@0
|
2 CCmI Editor - A Collaborative Cross-Modal Diagram Editing Tool
|
f@0
|
3
|
f@0
|
4 Copyright (C) 2002 Cay S. Horstmann (http://horstmann.com)
|
f@0
|
5 Copyright (C) 2011 Queen Mary University of London (http://ccmi.eecs.qmul.ac.uk/)
|
f@0
|
6
|
f@0
|
7 This program is free software: you can redistribute it and/or modify
|
f@0
|
8 it under the terms of the GNU General Public License as published by
|
f@0
|
9 the Free Software Foundation, either version 3 of the License, or
|
f@0
|
10 (at your option) any later version.
|
f@0
|
11
|
f@0
|
12 This program is distributed in the hope that it will be useful,
|
f@0
|
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
|
f@0
|
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
f@0
|
15 GNU General Public License for more details.
|
f@0
|
16
|
f@0
|
17 You should have received a copy of the GNU General Public License
|
f@0
|
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
|
f@0
|
19 */
|
f@0
|
20
|
f@0
|
21 package uk.ac.qmul.eecs.ccmi.simpletemplate;
|
f@0
|
22
|
f@0
|
23 import java.awt.BasicStroke;
|
f@0
|
24 import java.awt.Color;
|
f@0
|
25 import java.awt.Graphics2D;
|
f@0
|
26 import java.awt.Stroke;
|
f@0
|
27 import java.awt.geom.GeneralPath;
|
f@0
|
28 import java.awt.geom.Point2D;
|
f@0
|
29 import java.io.IOException;
|
f@0
|
30
|
f@0
|
31 /**
|
f@0
|
32 This class defines arrowheads of diverse shapes.
|
f@0
|
33 */
|
f@0
|
34 public enum ArrowHead {
|
f@0
|
35 TAIL("Tail"),
|
f@0
|
36 TRIANGLE("Triangle"),
|
f@0
|
37 BLACK_TRIANGLE("Black Triangle"),
|
f@0
|
38 V("V"),
|
f@0
|
39 HALF_V("Half V"),
|
f@0
|
40 DIAMOND("Diamond"),
|
f@0
|
41 BLACK_DIAMOND("Black Diamond");
|
f@0
|
42
|
f@0
|
43 private ArrowHead(String name) {
|
f@0
|
44 this.lowerCaseName = name;
|
f@0
|
45 }
|
f@0
|
46
|
f@0
|
47 public static ArrowHead getArrowHeadFromString(String arrowHeadName) throws IOException{
|
f@0
|
48 ArrowHead h;
|
f@0
|
49 String name = arrowHeadName.toUpperCase().replace(" ", "_");
|
f@0
|
50 try {
|
f@0
|
51 h = ArrowHead.valueOf(name);
|
f@0
|
52 }catch (IllegalArgumentException e){
|
f@0
|
53 throw new IOException(e);
|
f@0
|
54 }
|
f@0
|
55 return h;
|
f@0
|
56 }
|
f@0
|
57
|
f@0
|
58 @Override
|
f@0
|
59 public String toString(){
|
f@0
|
60 return lowerCaseName;
|
f@0
|
61 }
|
f@0
|
62
|
f@0
|
63 /**
|
f@0
|
64 Draws the arrowhead.
|
f@0
|
65 @param g2 the graphics context
|
f@0
|
66 @param p a point on the axis of the arrow head
|
f@0
|
67 @param q the end point of the arrow head
|
f@0
|
68 */
|
f@0
|
69 public void draw(Graphics2D g2, Point2D p, Point2D q){
|
f@0
|
70 GeneralPath path = getPath(p, q);
|
f@0
|
71 Color oldColor = g2.getColor();
|
f@0
|
72 if (this == BLACK_DIAMOND || this == BLACK_TRIANGLE)
|
f@0
|
73 g2.setColor(Color.BLACK);
|
f@0
|
74 else
|
f@0
|
75 g2.setColor(Color.WHITE);
|
f@0
|
76 g2.fill(path);
|
f@0
|
77 g2.setColor(oldColor);
|
f@0
|
78 Stroke oldStroke = g2.getStroke();
|
f@0
|
79 g2.setStroke(new BasicStroke());
|
f@0
|
80 g2.draw(path);
|
f@0
|
81 g2.setStroke(oldStroke);
|
f@0
|
82 }
|
f@0
|
83
|
f@0
|
84 /**
|
f@0
|
85 Gets the path of the arrowhead
|
f@0
|
86 @param p a point on the axis of the arrow head
|
f@0
|
87 @param q the end point of the arrow head
|
f@0
|
88 @return the path
|
f@0
|
89 */
|
f@0
|
90 public GeneralPath getPath(Point2D p, Point2D q){
|
f@0
|
91 GeneralPath path = new GeneralPath();
|
f@0
|
92 final double ARROW_ANGLE = Math.PI / 6;
|
f@0
|
93 final double ARROW_LENGTH = 10;
|
f@0
|
94
|
f@0
|
95 double dx = q.getX() - p.getX();
|
f@0
|
96 double dy = q.getY() - p.getY();
|
f@0
|
97 double angle = Math.atan2(dy, dx);
|
f@0
|
98 double x1 = q.getX()
|
f@0
|
99 - ARROW_LENGTH * Math.cos(angle + ARROW_ANGLE);
|
f@0
|
100 double y1 = q.getY()
|
f@0
|
101 - ARROW_LENGTH * Math.sin(angle + ARROW_ANGLE);
|
f@0
|
102 double x2 = q.getX()
|
f@0
|
103 - ARROW_LENGTH * Math.cos(angle - ARROW_ANGLE);
|
f@0
|
104 double y2 = q.getY()
|
f@0
|
105 - ARROW_LENGTH * Math.sin(angle - ARROW_ANGLE);
|
f@0
|
106
|
f@0
|
107 path.moveTo((float)q.getX(), (float)q.getY());
|
f@0
|
108 path.lineTo((float)x1, (float)y1);
|
f@0
|
109 if (this == V)
|
f@0
|
110 {
|
f@0
|
111 path.moveTo((float)x2, (float)y2);
|
f@0
|
112 path.lineTo((float)q.getX(), (float)q.getY());
|
f@0
|
113 }
|
f@0
|
114 else if (this == TRIANGLE || this == BLACK_TRIANGLE)
|
f@0
|
115 {
|
f@0
|
116 path.lineTo((float)x2, (float)y2);
|
f@0
|
117 path.closePath();
|
f@0
|
118 }
|
f@0
|
119 else if (this == DIAMOND || this == BLACK_DIAMOND)
|
f@0
|
120 {
|
f@0
|
121 double x3 = x2 - ARROW_LENGTH * Math.cos(angle + ARROW_ANGLE);
|
f@0
|
122 double y3 = y2 - ARROW_LENGTH * Math.sin(angle + ARROW_ANGLE);
|
f@0
|
123 path.lineTo((float)x3, (float)y3);
|
f@0
|
124 path.lineTo((float)x2, (float)y2);
|
f@0
|
125 path.closePath();
|
f@0
|
126 }
|
f@0
|
127 return path;
|
f@0
|
128 }
|
f@0
|
129
|
f@0
|
130 private String lowerCaseName;
|
f@0
|
131 }
|