1
6
7 import java.awt.*;
8 import javax.swing.*;
9 import java.awt.geom.*;
10 import java.io.*;
11 import java.util.*;
12
13
16 public class Arrow extends FileDefaultable implements Serializable {
17
18 private static final long serialVersionUID = Version.getSUID();
19
20
22 public boolean left = true;
23
24
26 public boolean right = true;
27
28
30 public boolean back = true;
31
32
34 public boolean solid = false;
35
36
37 public float aspect = (float)2.0;
38
39
40 public float concavity = (float)0.3;
41
42
43 public float backconcavity = (float)0.3;
44
45
46 public float backjunction = (float)0.3;
47
48
53 public Size size = Size.none;
54
55 public String name;
56 public String getName() {return(name);}
57
58 public Arrow(String name) {
59 this.name = name;
60 }
61
62 public static TreeSet defaults;
63 public static TreeSet mindefaults = new TreeSet();
64 public static TreeSet file = new TreeSet();
65 public static TreeSet fixed = new TreeSet();
66
67 public static Arrow none;
68
69 static {
70 fixed.add(none = new Arrow("None"));
71
72 mindefaults.add(new Arrow("plain",true,true,false,false,Size.arrow,1.4, 0.5,1,1));
73 mindefaults.add(new Arrow("closed",true,true,false,true,Size.arrow,1.4, 0.5,1,1));
74 mindefaults.add(new Arrow("solid",true,true,true,true,Size.arrow,1.4, 0.5,1,1));
75 mindefaults.add(new Arrow("thin",true,true,false,true,Size.arrow,0.8, 0.3,0.9,0.85));
76 mindefaults.add(new Arrow("thinsolid",true,true,true,true,Size.arrow,0.8, 0.3,0.9,0.85));
77 mindefaults.add(new Arrow("left",true,false,true,true,Size.arrow,0.8, 0.3,0.9,0.85));
78 mindefaults.add(new Arrow("right",false,true,true,true,Size.arrow,0.8, 0.3,0.9,0.85));
79
80 defaults = (TreeSet)mindefaults.clone();
81
82 fixedmap.put(Arrow.class,fixed);
83 defmap.put(Arrow.class,defaults);
84 minmap.put(Arrow.class,mindefaults);
85 filemap.put(Arrow.class,file);
86 }
87
88 public Arrow(String name,
89 boolean left, boolean right, boolean solid, boolean back,
90 Size size,double aspect, double concavity,
91 double backjunction, double backconcavity) {
92 this.name = name;
93 this.left=left;
94 this.right=right;
95 this.back = back;
96 this.solid = solid;
97 this.size= size;
98 this.aspect = (float)aspect;
99 this.concavity = (float)concavity;
100 this.backjunction = (float)backjunction;
101 this.backconcavity = (float)backconcavity;
102 }
103
104 public boolean edit(JFrame owner) {
105 JPanel panel = new JPanel();
106 panel.setLayout(new BoxLayout(panel,BoxLayout.Y_AXIS));
107
108 javax.swing.Box row = new javax.swing.Box(BoxLayout.X_AXIS);
109 JComboBox sizefield = new JComboBox(Size.getAll(Size.class));
110 sizefield.setSelectedItem(size);
111 row.add(sizefield);
112 JTextField aspectfield = PrefEditor.addDouble(row,aspect,"Aspect Ratio");
113 JCheckBox solidbox = new JCheckBox("Solid",solid);
114 row.add(solidbox);
115 panel.add(row);
116
117 row = new javax.swing.Box(BoxLayout.X_AXIS);
118 JCheckBox leftbox = new JCheckBox("Left",left);
119 row.add(leftbox);
120 JCheckBox rightbox = new JCheckBox("Right",right);
121 row.add(rightbox);
122 JTextField concavityfield = PrefEditor.addDouble(row,concavity,"Concavity");
123 panel.add(row);
124
125 row = new javax.swing.Box(BoxLayout.X_AXIS);
126
127 JCheckBox backbox = new JCheckBox("Back",back);
128 row.add(backbox);
129
130 JTextField backfield = PrefEditor.addDouble(row,backjunction,"Back Junction point");
131 JTextField backconcavityfield = PrefEditor.addDouble(row,backconcavity,"Back Concavity");
132 panel.add(row);
133
134 if (JOptionPane.showConfirmDialog(owner,panel,"Edit size"+name,JOptionPane.OK_CANCEL_OPTION) ==
135 JOptionPane.OK_OPTION) {
136 left = leftbox.isSelected();
137 right = rightbox.isSelected();
138 back = backbox.isSelected();
139 solid = solidbox.isSelected();
140 aspect = (float)PrefEditor.readDouble(aspectfield);
141 concavity = (float)PrefEditor.readDouble(concavityfield);
142 backjunction = (float)PrefEditor.readDouble(backfield);
143 backconcavity = (float)PrefEditor.readDouble(backconcavityfield);
144 size = (Size)sizefield.getSelectedItem();
145 if (size==Size.none) size = null;
146
147
148 return(true);
149 }
150
151
152 return(false);
153
154 }
155
156 public Object clone() {
157 Arrow res = new Arrow(name);
158 res.copy(this);
159 return((Object)res);
160 }
161
162 public void copy(FileDefaultable thatitem) {
163 Arrow that = (Arrow)thatitem;
164 name = that.name;
165 left = that.left;
166 right = that.right;
167 back = that.back;
168 solid = that.solid;
169 size = that.size;
170 aspect = that.aspect;
171 concavity = that.concavity;
172 backjunction = that.backjunction;
173 backconcavity = that.backconcavity;
174 }
175
176 public Object readResolve() throws ObjectStreamException {
177 return((Object)getGlobal(Arrow.class));
178 }
179
180 public void draw(View view, Anchor point, int direction, CurveAtt props) {
181 point.guideUpdate();
182
183 Color color = view.draw.getColor();
184 view.draw.setColor(props.color);
185
186 double thickness = props.thickness.getSize(view.mapscale);
187 double scale = (size==null?thickness*10:size.getSize(view.mapscale))/view.scale;
188
189 float scalethick = (float)(thickness/(view.scale*scale*aspect));
190 float len = (float)(point.position.distance(point.guide[direction])/scale);
191
192
193
194
195 AffineTransform trans = (AffineTransform)view.trans.clone();
196 trans.concatenate(point.position);
197 trans.rotate(-Math.atan2(point.guidelocal[direction].getX(),point.guidelocal[direction].getY()));
198 trans.scale(scale*aspect/2,scale);
199
200 GeneralPath path = new GeneralPath(GeneralPath.WIND_NON_ZERO);
201
202 if (!solid) {
203 Stroke st = view.draw.getStroke();
204 view.draw.setStroke(new BasicStroke((float)thickness,
205 BasicStroke.CAP_BUTT,
206 BasicStroke.JOIN_MITER,(float)30.0));
207 path.moveTo(0,0);
208 path.lineTo(0,len-backjunction);
209
210 if (left) {
211 if (back) path.quadTo((float)-0.5,len-backconcavity,-1,len-1);
212 else path.moveTo(-1,len-1);
213 path.quadTo(-concavity,(float)(len-0.5),0,len);
214 }
215 else
216 path.lineTo(0,len);
217
218 if (right) {
219 path.quadTo(concavity,(float)(len-0.5),1,len-1);
220 if (back) path.quadTo((float)0.5,len-backconcavity,0,len-backjunction);
221 else path.moveTo(0,len-backjunction);
222 }
223 else
224 path.lineTo(0,len-backjunction);
225
226 if (!back && left && right) path.lineTo(0,len);
227
228 Shape shape = trans.createTransformedShape(path);
229 view.draw.draw(shape);
230
231 view.draw.setStroke(st);
232 }
233 else {
234 float ppos = 0;
235 if (left) ppos += scalethick;
236 if (right) ppos -= scalethick;
237
238 path.moveTo(0,0);
239 path.lineTo(-scalethick,0);
240 path.lineTo(-scalethick,len-backjunction);
241
242 if (left) {
243 path.quadTo((float)-0.5,len-backconcavity,-1,len-1);
244 path.quadTo(-concavity,(float)(len-0.5),ppos,len);
245 }
246 else
247 path.lineTo(ppos,len);
248
249 if (right) {
250 path.quadTo(concavity,(float)(len-0.5),1,len-1);
251 path.quadTo((float)0.5,len-backconcavity,scalethick,len-backjunction);
252 }
253 else
254 path.lineTo(scalethick,len-backjunction);
255
256 path.lineTo(scalethick,0);
257 path.closePath();
258
259 Shape shape = trans.createTransformedShape(path);
260 view.draw.fill(shape);
261 }
262
263 view.draw.setColor(color);
264 }
265
266 }
267