1 package org.opentrafficsim.trafficcontrol.trafcod;
2
3 import java.awt.Color;
4 import java.awt.Dimension;
5 import java.awt.Graphics;
6 import java.awt.Graphics2D;
7 import java.awt.event.MouseEvent;
8 import java.awt.event.MouseListener;
9 import java.awt.event.MouseMotionListener;
10 import java.awt.geom.Point2D;
11 import java.awt.image.BufferedImage;
12 import java.rmi.RemoteException;
13 import java.util.HashSet;
14 import java.util.Set;
15
16 import javax.media.j3d.Bounds;
17 import javax.swing.JPanel;
18 import javax.swing.ToolTipManager;
19
20 import nl.tudelft.simulation.event.EventInterface;
21 import nl.tudelft.simulation.event.EventListenerInterface;
22 import nl.tudelft.simulation.event.EventType;
23 import nl.tudelft.simulation.language.d3.DirectedPoint;
24
25 import org.djunits.value.vdouble.scalar.Length;
26 import org.opentrafficsim.core.geometry.OTSLine3D;
27 import org.opentrafficsim.road.network.lane.Lane;
28 import org.opentrafficsim.road.network.lane.object.sensor.NonDirectionalOccupancySensor;
29 import org.opentrafficsim.road.network.lane.object.trafficlight.TrafficLight;
30 import org.opentrafficsim.road.network.lane.object.trafficlight.TrafficLightColor;
31
32
33
34
35
36
37
38
39
40
41 public class TrafCODDisplay extends JPanel implements MouseMotionListener, MouseListener
42 {
43
44 private static final long serialVersionUID = 20161115L;
45
46
47 private final BufferedImage image;
48
49
50 private Set<TrafCODObject> trafCODObjects = new HashSet<>();
51
52
53 final int defaultInitialDelay = ToolTipManager.sharedInstance().getInitialDelay();
54
55
56
57
58
59
60 public TrafCODDisplay(final BufferedImage image)
61 {
62 this.image = image;
63 super.setPreferredSize(new Dimension(this.image.getWidth(), this.image.getHeight()));
64 addMouseMotionListener(this);
65 }
66
67 @Override
68 protected void paintComponent(final Graphics g)
69 {
70 super.paintComponent(g);
71 g.drawImage(this.image, 0, 0, null);
72 for (TrafCODObject tco : this.trafCODObjects)
73 {
74 tco.draw((Graphics2D) g);
75 }
76 }
77
78
79
80
81
82 void addTrafCODObject(final TrafCODObject trafCODObject)
83 {
84 this.trafCODObjects.add(trafCODObject);
85 }
86
87
88 @Override
89 public void mouseDragged(MouseEvent e)
90 {
91 mouseMoved(e);
92 }
93
94
95 @Override
96 public void mouseMoved(MouseEvent e)
97 {
98 String toolTipText = null;
99 for (TrafCODObject tco : this.trafCODObjects)
100 {
101 toolTipText = tco.toolTipHit(e.getX(), e.getY());
102 if (null != toolTipText)
103 {
104 break;
105 }
106 }
107
108 setToolTipText(toolTipText);
109 }
110
111
112 @Override
113 public void mouseClicked(MouseEvent e)
114 {
115
116 }
117
118
119 @Override
120 public void mousePressed(MouseEvent e)
121 {
122
123 }
124
125
126 @Override
127 public void mouseReleased(MouseEvent e)
128 {
129
130 }
131
132
133 @Override
134 public void mouseEntered(MouseEvent e)
135 {
136 ToolTipManager.sharedInstance().setInitialDelay(0);
137 }
138
139
140 @Override
141 public void mouseExited(MouseEvent e)
142 {
143 ToolTipManager.sharedInstance().setInitialDelay(this.defaultInitialDelay);
144 }
145
146 }
147
148
149
150
151
152 interface TrafCODObject
153 {
154
155
156
157
158 void draw(Graphics2D g2);
159
160
161
162
163
164
165
166
167 String toolTipHit(int testX, int testY);
168
169 }
170
171
172
173
174 class DetectorImage implements TrafCODObject, EventListenerInterface
175 {
176
177 private final TrafCODDisplay display;
178
179
180 private final int x;
181
182
183 private final int y;
184
185
186 private final String description;
187
188
189 private Color fillColor = Color.WHITE;
190
191
192 private static final int BOX_SIZE = 13;
193
194
195 private static final int xOffset = 5;
196
197
198 private static final int yOffset = 5;
199
200
201
202
203
204
205
206 public DetectorImage(final TrafCODDisplay display, Point2D center, String description)
207 {
208 this.display = display;
209 this.x = (int) center.getX();
210 this.y = (int) center.getY();
211 this.description = description;
212 display.addTrafCODObject(this);
213 }
214
215
216 @Override
217 public void draw(Graphics2D g2)
218 {
219 g2.setColor(this.fillColor);
220 g2.fillRect(xOffset + this.x - BOX_SIZE / 2, yOffset + this.y - BOX_SIZE / 2, BOX_SIZE, BOX_SIZE);
221 g2.setColor(Color.BLACK);
222 g2.drawRect(xOffset + this.x - BOX_SIZE / 2, yOffset + this.y - BOX_SIZE / 2, BOX_SIZE, BOX_SIZE);
223 }
224
225
226 @Override
227 public void notify(EventInterface event) throws RemoteException
228 {
229 if (event.getType().equals(NonDirectionalOccupancySensor.NON_DIRECTIONAL_OCCUPANCY_SENSOR_TRIGGER_ENTRY_EVENT))
230 {
231 this.fillColor = Color.BLUE;
232 }
233 else if (event.getType().equals(NonDirectionalOccupancySensor.NON_DIRECTIONAL_OCCUPANCY_SENSOR_TRIGGER_EXIT_EVENT))
234 {
235 this.fillColor = Color.WHITE;
236 }
237 this.display.repaint();
238 }
239
240
241 @Override
242 public String toolTipHit(final int testX, final int testY)
243 {
244 if (testX < xOffset + this.x - BOX_SIZE / 2 || testX >= xOffset + this.x + BOX_SIZE / 2
245 || testY < yOffset - BOX_SIZE / 2 + this.y || testY >= yOffset + this.y + BOX_SIZE / 2)
246 {
247 return null;
248 }
249 return this.description;
250 }
251
252 }
253
254
255
256
257
258 class TrafficLightImage implements TrafficLight, TrafCODObject
259 {
260
261 private final TrafCODDisplay display;
262
263
264 private final int x;
265
266
267 private final int y;
268
269
270 private final String description;
271
272
273 private TrafficLightColor color = TrafficLightColor.BLACK;
274
275
276
277
278
279
280
281 public TrafficLightImage(final TrafCODDisplay display, final Point2D center, final String description)
282 {
283 this.display = display;
284 this.x = (int) center.getX();
285 this.y = (int) center.getY();
286 this.description = description;
287 display.addTrafCODObject(this);
288 }
289
290
291 @Override
292 public String toolTipHit(int testX, int testY)
293 {
294 if (testX < this.x - DISC_SIZE / 2 || testX >= this.x + DISC_SIZE / 2 || testY < this.y - DISC_SIZE / 2
295 || testY >= this.y + DISC_SIZE / 2)
296 {
297 return null;
298 }
299 return this.description;
300 }
301
302
303 @Override
304 public DirectedPoint getLocation()
305 {
306 return null;
307 }
308
309
310 @Override
311 public Bounds getBounds()
312 {
313 return null;
314 }
315
316
317 @Override
318 public Lane getLane()
319 {
320 return null;
321 }
322
323
324 @Override
325 public Length getLongitudinalPosition()
326 {
327 return null;
328 }
329
330
331 @Override
332 public OTSLine3D getGeometry()
333 {
334 return null;
335 }
336
337
338 @Override
339 public Length getHeight()
340 {
341 return null;
342 }
343
344
345 @Override
346 public String getId()
347 {
348 return null;
349 }
350
351
352 @Override
353 public boolean addListener(EventListenerInterface listener, EventType eventType) throws RemoteException
354 {
355 return false;
356 }
357
358
359 @Override
360 public boolean addListener(EventListenerInterface listener, EventType eventType, boolean weak) throws RemoteException
361 {
362 return false;
363 }
364
365
366 @Override
367 public boolean addListener(EventListenerInterface listener, EventType eventType, short position) throws RemoteException
368 {
369 return false;
370 }
371
372
373 @Override
374 public boolean addListener(EventListenerInterface listener, EventType eventType, short position, boolean weak)
375 throws RemoteException
376 {
377 return false;
378 }
379
380
381 @Override
382 public boolean removeListener(EventListenerInterface listener, EventType eventType) throws RemoteException
383 {
384 return false;
385 }
386
387
388 @Override
389 public TrafficLightColor getTrafficLightColor()
390 {
391 return null;
392 }
393
394
395 @Override
396 public void setTrafficLightColor(TrafficLightColor trafficLightColor)
397 {
398 this.color = trafficLightColor;
399 this.display.repaint();
400 }
401
402
403 private static final int DISC_SIZE = 11;
404
405
406 @Override
407 public void draw(Graphics2D g2)
408 {
409 Color lightColor;
410 switch (this.color)
411 {
412 case BLACK:
413 lightColor = Color.BLACK;
414 break;
415
416 case GREEN:
417 lightColor = Color.green;
418 break;
419
420 case YELLOW:
421 lightColor = Color.YELLOW;
422 break;
423
424 case RED:
425 lightColor = Color.RED;
426 break;
427
428 default:
429 System.err.println("Unhandled TrafficLightColor: " + this.color);
430 return;
431 }
432 g2.setColor(lightColor);
433 g2.fillOval(this.x - DISC_SIZE / 2, this.y - DISC_SIZE / 2, DISC_SIZE, DISC_SIZE);
434
435 }
436
437 }