1 package org.opentrafficsim.core.animation;
2
3 import java.awt.Color;
4 import java.awt.Dimension;
5 import java.awt.Font;
6 import java.awt.FontMetrics;
7 import java.awt.Graphics2D;
8 import java.awt.geom.Point2D;
9 import java.awt.geom.Rectangle2D;
10 import java.awt.image.ImageObserver;
11 import java.io.Serializable;
12 import java.rmi.RemoteException;
13
14 import javax.media.j3d.Bounds;
15 import javax.naming.NamingException;
16
17 import nl.tudelft.simulation.dsol.animation.Locatable;
18 import nl.tudelft.simulation.dsol.animation.D2.Renderable2D;
19 import nl.tudelft.simulation.dsol.simulators.SimulatorInterface;
20 import nl.tudelft.simulation.language.d3.BoundingBox;
21 import nl.tudelft.simulation.language.d3.DirectedPoint;
22
23
24
25
26
27
28
29
30
31
32
33
34
35 public abstract class TextAnimation implements Locatable, Serializable
36 {
37
38 private static final long serialVersionUID = 20161211L;
39
40
41 private final Locatable source;
42
43
44 private String text;
45
46
47 private final float dx;
48
49
50 private final float dy;
51
52
53 private final TextAlignment textAlignment;
54
55
56 private Color color;
57
58
59 private final float fontSize;
60
61
62 private final AnimationImpl animationImpl;
63
64
65 private Font font;
66
67
68 private Rectangle2D fontRectangle = null;
69
70
71
72
73
74
75
76
77
78
79
80
81
82 @SuppressWarnings("checkstyle:parameternumber")
83 public TextAnimation(final Locatable source, final String text, final float dx, final float dy,
84 final TextAlignment textAlignment, final Color color, final float fontSize,
85 final SimulatorInterface.TimeDoubleUnit simulator) throws RemoteException, NamingException
86 {
87 this.source = source;
88 this.text = text;
89 this.dx = dx;
90 this.dy = dy;
91 this.textAlignment = textAlignment;
92 this.color = color;
93 this.fontSize = fontSize;
94
95 this.font = new Font("SansSerif", Font.PLAIN, 2);
96 if (this.fontSize != 2.0f)
97 {
98 this.font = this.font.deriveFont(this.fontSize);
99 }
100
101 this.animationImpl = new AnimationImpl(this, simulator);
102 }
103
104
105
106
107
108
109
110
111
112
113
114
115 public TextAnimation(final Locatable source, final String text, final float dx, final float dy,
116 final TextAlignment textAlignment, final Color color, final SimulatorInterface.TimeDoubleUnit simulator)
117 throws RemoteException, NamingException
118 {
119 this(source, text, dx, dy, textAlignment, color, 2.0f, simulator);
120 }
121
122
123 @Override
124 @SuppressWarnings("checkstyle:designforextension")
125 public DirectedPoint getLocation() throws RemoteException
126 {
127
128 DirectedPoint p = this.source.getLocation();
129 return new DirectedPoint(p.x, p.y, Double.MAX_VALUE, 0.0, 0.0, p.getRotZ());
130 }
131
132
133 @Override
134 public final Bounds getBounds() throws RemoteException
135 {
136 return new BoundingBox(0.0, 0.0, 0.0);
137 }
138
139
140
141
142
143
144
145 @SuppressWarnings("checkstyle:designforextension")
146 public void paint(final Graphics2D graphics, final ImageObserver observer) throws RemoteException
147 {
148 graphics.setFont(this.font);
149 synchronized (this.font)
150 {
151 if (this.fontRectangle == null)
152 {
153 FontMetrics fm = graphics.getFontMetrics();
154 this.fontRectangle = fm.getStringBounds(this.text, graphics);
155 }
156 graphics.setColor(this.color);
157 float dxText =
158 this.textAlignment.equals(TextAlignment.LEFT) ? 0.0f : this.textAlignment.equals(TextAlignment.CENTER)
159 ? (float) -this.fontRectangle.getWidth() / 2.0f : (float) -this.fontRectangle.getWidth();
160 graphics.drawString(this.text, dxText + this.dx, this.fontSize / 2.0f - this.dy);
161 }
162 }
163
164
165
166
167 public final void destroy()
168 {
169 try
170 {
171 this.animationImpl.destroy();
172 }
173 catch (NamingException exception)
174 {
175 System.err.println("Tried to destroy Text for GTU animation of GTU " + this.source.toString());
176 }
177 }
178
179
180
181
182
183
184
185
186
187 public abstract TextAnimation clone(final Locatable newSource, final SimulatorInterface.TimeDoubleUnit newSimulator)
188 throws RemoteException, NamingException;
189
190
191
192
193
194 protected final Locatable getSource()
195 {
196 return this.source;
197 }
198
199
200
201
202
203 protected final float getDx()
204 {
205 return this.dx;
206 }
207
208
209
210
211
212 protected final float getDy()
213 {
214 return this.dy;
215 }
216
217
218
219
220
221 protected final TextAlignment getTextAlignment()
222 {
223 return this.textAlignment;
224 }
225
226
227
228
229
230 protected final float getFontSize()
231 {
232 return this.fontSize;
233 }
234
235
236
237
238
239 protected final Font getFont()
240 {
241 return this.font;
242 }
243
244
245
246
247
248 protected final String getText()
249 {
250 return this.text;
251 }
252
253
254
255
256
257 protected final void setText(final String text)
258 {
259 this.text = text;
260 synchronized (this.font)
261 {
262 this.fontRectangle = null;
263 }
264 }
265
266
267
268
269
270 protected final Color getColor()
271 {
272 return this.color;
273 }
274
275
276
277
278
279 protected final void setColor(final Color color)
280 {
281 this.color = color;
282 }
283
284
285
286
287
288 public final boolean isFlip()
289 {
290 return this.animationImpl.isFlip();
291 }
292
293
294
295
296
297 public final void setFlip(final boolean flip)
298 {
299 this.animationImpl.setFlip(flip);
300 }
301
302
303
304
305
306 public final boolean isRotate()
307 {
308 return this.animationImpl.isRotate();
309 }
310
311
312
313
314
315 public final void setRotate(final boolean rotate)
316 {
317 this.animationImpl.setRotate(rotate);
318
319 }
320
321
322
323
324
325 public final boolean isScale()
326 {
327 return this.animationImpl.isScale();
328 }
329
330
331
332
333
334 public final void setScale(final boolean scale)
335 {
336 this.animationImpl.setScale(scale);
337 }
338
339
340
341
342
343 public final boolean isTranslate()
344 {
345 return this.animationImpl.isTranslate();
346 }
347
348
349
350
351
352 public final void setTranslate(final boolean translate)
353 {
354 this.animationImpl.setTranslate(translate);
355 }
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370 private static class AnimationImpl extends Renderable2D<Locatable> implements Serializable
371 {
372
373 private static final long serialVersionUID = 20170400L;
374
375
376
377
378
379
380
381
382 AnimationImpl(final Locatable source, final SimulatorInterface.TimeDoubleUnit simulator)
383 throws NamingException, RemoteException
384 {
385 super(source, simulator);
386 }
387
388
389 @Override
390 public final void paint(final Graphics2D graphics, final ImageObserver observer) throws RemoteException
391 {
392 TextAnimation ta = ((TextAnimation) getSource());
393 ta.paint(graphics, observer);
394 }
395
396
397 @Override
398 public boolean contains(final Point2D pointWorldCoordinates, final Rectangle2D extent, final Dimension screen)
399 {
400 return false;
401 }
402
403
404 @Override
405 public final String toString()
406 {
407 return "TextAnimation.AnimationImpl []";
408 }
409
410 }
411 }