1 package org.opentrafficsim.trafficcontrol.trafcod;
2
3 import java.awt.BorderLayout;
4 import java.awt.Color;
5 import java.awt.Component;
6 import java.awt.Dimension;
7 import java.awt.Graphics2D;
8 import java.awt.event.ActionEvent;
9 import java.awt.event.ActionListener;
10 import java.awt.image.BufferedImage;
11 import java.util.ArrayList;
12 import java.util.Comparator;
13 import java.util.LinkedHashMap;
14 import java.util.LinkedHashSet;
15 import java.util.List;
16 import java.util.Map;
17 import java.util.Set;
18
19 import javax.swing.BoxLayout;
20 import javax.swing.ImageIcon;
21 import javax.swing.JCheckBox;
22 import javax.swing.JFrame;
23 import javax.swing.JLabel;
24 import javax.swing.JPanel;
25 import javax.swing.JScrollPane;
26 import javax.swing.SwingUtilities;
27
28 import org.djutils.exceptions.Throw;
29 import org.opentrafficsim.road.network.lane.object.trafficlight.TrafficLightException;
30 import org.opentrafficsim.trafficcontrol.TrafficController;
31
32
33
34
35
36
37
38
39
40
41
42
43
44 public class Diagram
45 {
46
47
48 static final int DIVIDER_1 = 0;
49
50
51 static final int CAR_ROUNDABOUT_LEFT = 1;
52
53
54 static final int PT_DIV_L = 3;
55
56
57 static final int DIVIDER_2 = 4;
58
59
60 static final int CAR_LEFT = 5;
61
62
63 static final int CAR_CENTER = 7;
64
65
66 static final int CAR_RIGHT = 9;
67
68
69 static final int DIVIDER_3 = 10;
70
71
72 static final int PT_RIGHT_BICYCLE = 11;
73
74
75 static final int DIVIDER_4 = 12;
76
77
78 static final int BICYCLE = 13;
79
80
81 static final int DIVIDER_5 = 14;
82
83
84 static final int PT_BICYCLE_SIDEWALK = 15;
85
86
87 static final int DIVIDER_6 = 16;
88
89
90 static final int SIDEWALK = 17;
91
92
93 static final int DIVIDER_7 = 18;
94
95
96 static final int PT_SIDEWALK_SHOULDER = 19;
97
98
99 static final int SHOULDER = 20;
100
101
102 static final int BOUNDARY = 21;
103
104
105 private final List<Short> streams;
106
107
108 private final Map<Short, XYPair[]> routes = new LinkedHashMap<>();
109
110
111
112
113
114
115 public Diagram(final Set<Short> streams) throws TrafficLightException
116 {
117 this.streams = new ArrayList<Short>(streams);
118 this.streams.sort(new Comparator<Short>()
119 {
120
121 @Override
122 public int compare(final Short o1, final Short o2)
123 {
124 return o1 - o2;
125 }
126 });
127
128
129
130
131
132
133
134
135
136 for (short stream = 1; stream <= 12; stream += 3)
137 {
138 int quadrant = (stream - 1) / 3;
139 this.routes.put(stream, rotateRoute(quadrant, assembleRoute(
140 new RouteStep(-BOUNDARY, CAR_RIGHT),
141 new RouteStep(-SHOULDER, CAR_RIGHT, Command.STOP_LINE_AND_ICON),
142 new RouteStep(-CAR_CENTER, CAR_RIGHT),
143 new RouteStep(-CAR_CENTER, BOUNDARY))));
144 this.routes.put((short) (stream + 1), rotateRoute(quadrant, assembleRoute(
145 new RouteStep(-BOUNDARY, CAR_CENTER),
146 new RouteStep(-SHOULDER, CAR_CENTER, Command.STOP_LINE_AND_ICON),
147 new RouteStep(Command.IF, stream + 1 + 60),
148 new RouteStep(-CAR_ROUNDABOUT_LEFT, CAR_CENTER),
149 new RouteStep(Command.ELSE),
150 new RouteStep(BOUNDARY, CAR_CENTER),
151 new RouteStep(Command.END_IF))));
152 this.routes.put((short) (stream + 2), rotateRoute(quadrant, assembleRoute(
153 new RouteStep(-BOUNDARY, CAR_LEFT),
154 new RouteStep(-SHOULDER, CAR_LEFT, Command.STOP_LINE_AND_ICON),
155 new RouteStep(Command.IF, stream + 2 + 60),
156 new RouteStep(-CAR_ROUNDABOUT_LEFT, CAR_LEFT),
157 new RouteStep(Command.ELSE_IF, (stream + 10) % 12 + 60),
158 new RouteStep(CAR_CENTER, CAR_LEFT),
159 new RouteStep(CAR_CENTER, CAR_ROUNDABOUT_LEFT),
160 new RouteStep(Command.ELSE),
161 new RouteStep(-CAR_LEFT, CAR_LEFT),
162 new RouteStep(-CAR_LEFT, PT_DIV_L),
163 new RouteStep(-CAR_ROUNDABOUT_LEFT, PT_DIV_L),
164 new RouteStep(-CAR_ROUNDABOUT_LEFT, -CAR_LEFT),
165 new RouteStep(PT_DIV_L, -CAR_LEFT),
166 new RouteStep(PT_DIV_L, -CAR_CENTER),
167 new RouteStep(CAR_CENTER, -CAR_CENTER),
168 new RouteStep(CAR_CENTER, -BOUNDARY),
169 new RouteStep(Command.END_IF))));
170 }
171
172 for (short stream = 21; stream <= 28; stream += 2)
173 {
174 int quadrant = (stream - 19) / 2 % 4;
175 this.routes.put(stream, rotateRoute(quadrant, assembleRoute(
176 new RouteStep(DIVIDER_1, BICYCLE, Command.ICON),
177 new RouteStep(SHOULDER, BICYCLE),
178 new RouteStep(BOUNDARY, BICYCLE, Command.ICON))));
179 this.routes.put((short) (stream + 1), rotateRoute(quadrant, assembleRoute(
180 new RouteStep(-BOUNDARY, BICYCLE),
181 new RouteStep(-DIVIDER_3, BICYCLE, Command.ICON),
182 new RouteStep(Command.IF, stream),
183 new RouteStep(-DIVIDER_1, BICYCLE, Command.ICON),
184 new RouteStep(Command.ELSE),
185 new RouteStep(SHOULDER, BICYCLE),
186 new RouteStep(BOUNDARY, BICYCLE, Command.ICON),
187 new RouteStep(Command.END_IF))));
188 }
189
190 for (short stream = 31; stream <= 38; stream += 2)
191 {
192 int quadrant = (stream - 29) / 2 % 4;
193 this.routes.put(stream, rotateRoute(quadrant, assembleRoute(
194 new RouteStep(DIVIDER_1, SIDEWALK),
195 new RouteStep(BOUNDARY, SIDEWALK))));
196 this.routes.put((short) (stream + 1), rotateRoute(quadrant, assembleRoute(
197 new RouteStep(-BOUNDARY, SIDEWALK),
198 new RouteStep(Command.IF, stream),
199 new RouteStep(-DIVIDER_1, SIDEWALK),
200 new RouteStep(Command.ELSE),
201 new RouteStep(BOUNDARY, SIDEWALK),
202 new RouteStep(Command.END_IF))));
203 }
204
205 for (short stream = 41; stream <= 52; stream += 3)
206 {
207 int quadrant = (stream - 41) / 3;
208 this.routes.put(stream, rotateRoute(quadrant, assembleRoute(
209 new RouteStep(-BOUNDARY, PT_DIV_L),
210 new RouteStep(-SHOULDER, PT_DIV_L, Command.STOP_LINE),
211 new RouteStep(-PT_SIDEWALK_SHOULDER, PT_DIV_L, Command.ICON),
212 new RouteStep(-CAR_RIGHT, PT_DIV_L),
213 new RouteStep(-CAR_RIGHT, CAR_LEFT),
214 new RouteStep(-PT_DIV_L, CAR_LEFT),
215 new RouteStep(-PT_DIV_L, SHOULDER),
216 new RouteStep(-PT_DIV_L, BOUNDARY, Command.ICON))));
217 this.routes.put((short) (stream + 1), rotateRoute(quadrant, assembleRoute(
218 new RouteStep(-BOUNDARY, PT_DIV_L),
219 new RouteStep(-SHOULDER, PT_DIV_L, Command.STOP_LINE),
220 new RouteStep(-PT_SIDEWALK_SHOULDER, PT_DIV_L, Command.ICON),
221 new RouteStep(SHOULDER, PT_DIV_L),
222 new RouteStep(BOUNDARY, PT_DIV_L))));
223 this.routes.put((short) (stream + 2), rotateRoute(quadrant, assembleRoute(
224 new RouteStep(-BOUNDARY, PT_DIV_L),
225 new RouteStep(-SHOULDER, PT_DIV_L, Command.STOP_LINE),
226 new RouteStep(-PT_SIDEWALK_SHOULDER, PT_DIV_L, Command.ICON),
227 new RouteStep(-CAR_RIGHT, PT_DIV_L),
228 new RouteStep(-CAR_RIGHT, CAR_ROUNDABOUT_LEFT),
229 new RouteStep(-PT_DIV_L, CAR_ROUNDABOUT_LEFT),
230 new RouteStep(Command.IF, (stream + 2 - 40) % 12 + 60),
231 new RouteStep(-PT_DIV_L, -PT_DIV_L),
232 new RouteStep(PT_DIV_L, -PT_DIV_L),
233 new RouteStep(Command.ELSE),
234 new RouteStep(-PT_DIV_L, -CAR_CENTER),
235 new RouteStep(CAR_ROUNDABOUT_LEFT, -CAR_CENTER),
236 new RouteStep(CAR_ROUNDABOUT_LEFT, -CAR_RIGHT),
237 new RouteStep(PT_DIV_L, -CAR_RIGHT),
238 new RouteStep(Command.END_IF),
239 new RouteStep(PT_DIV_L, -SHOULDER),
240 new RouteStep(PT_DIV_L, -BOUNDARY, Command.ICON))));
241 }
242
243 for (short stream = 62; stream <= 72; stream += 3)
244 {
245 int quadrant = (stream - 61) / 3;
246 this.routes.put(stream, rotateRoute(quadrant, assembleRoute(
247 new RouteStep(-CAR_ROUNDABOUT_LEFT, CAR_CENTER),
248 new RouteStep(CAR_ROUNDABOUT_LEFT, CAR_CENTER, Command.STOP_LINE_AND_ICON),
249 new RouteStep(BOUNDARY, CAR_CENTER))));
250 this.routes.put((short) (stream + 1), rotateRoute(quadrant, assembleRoute(
251 new RouteStep(-CAR_ROUNDABOUT_LEFT, CAR_LEFT),
252 new RouteStep(CAR_ROUNDABOUT_LEFT, CAR_LEFT, Command.STOP_LINE_AND_ICON),
253 new RouteStep(CAR_CENTER, CAR_LEFT),
254 new RouteStep(Command.IF, ((stream - 61) + 11) % 12 + 60),
255 new RouteStep(CAR_CENTER, CAR_ROUNDABOUT_LEFT),
256 new RouteStep(Command.ELSE),
257 new RouteStep(CAR_CENTER, -BOUNDARY),
258 new RouteStep(Command.END_IF))));
259 }
260
261 }
262
263
264
265
266
267
268 private boolean streamExists(final short stream)
269 {
270 return this.streams.contains(stream);
271 }
272
273
274
275
276
277
278 public static final boolean isGrass(final int i)
279 {
280 return i == DIVIDER_1 || i == DIVIDER_2 || i == DIVIDER_3 || i == DIVIDER_4 || i == DIVIDER_5 || i == DIVIDER_6
281 || i == DIVIDER_7 || i == SHOULDER;
282 }
283
284
285
286
287
288
289 final LaneType laneType(final int streamNumber)
290 {
291 if (streamNumber < 20 || streamNumber > 60 && streamNumber <= 80)
292 {
293 return LaneType.CAR_LANE;
294 }
295 if (streamNumber >= 20 && streamNumber < 30)
296 {
297 return LaneType.BICYCLE_LANE;
298 }
299 if (streamNumber >= 30 && streamNumber < 40)
300 {
301 return LaneType.PEDESTRIAN_LANE;
302 }
303 if (streamNumber > 40 && streamNumber <= 52 || streamNumber >= 81 && streamNumber <= 92)
304 {
305 return LaneType.PUBLIC_TRANSIT_LANE;
306 }
307 return null;
308 }
309
310
311
312
313 enum LaneType
314 {
315
316 CAR_LANE,
317
318 BICYCLE_LANE,
319
320 PUBLIC_TRANSIT_LANE,
321
322 PEDESTRIAN_LANE,
323 }
324
325
326
327
328
329
330
331 final int rotatedX(final XYPair xyPair, final int rotation)
332 {
333 switch (rotation % 4)
334 {
335 case 0:
336 return xyPair.getX();
337 case 1:
338 return -xyPair.getY();
339 case 2:
340 return -xyPair.getX();
341 case 3:
342 return xyPair.getY();
343 default:
344 break;
345 }
346 return 0;
347 }
348
349
350
351
352
353
354
355 final int rotatedY(final XYPair xyPair, final int rotation)
356 {
357 switch (rotation % 4)
358 {
359 case 0:
360 return xyPair.getY();
361 case 1:
362 return xyPair.getX();
363 case 2:
364 return -xyPair.getY();
365 case 3:
366 return -xyPair.getX();
367 default:
368 break;
369 }
370 return 0;
371 }
372
373
374
375
376 enum Command
377 {
378
379 NO_OP,
380
381 IF,
382
383 ELSE,
384
385 ELSE_IF,
386
387 END_IF,
388
389 STOP_LINE,
390
391 ICON,
392
393 STOP_LINE_AND_ICON,
394 }
395
396
397
398
399 class RouteStep
400 {
401
402 private final int x;
403
404
405 private final int y;
406
407
408 private final Command command;
409
410
411 private final int streamCondition;
412
413
414
415
416
417
418 RouteStep(final int x, final int y)
419 {
420 this.x = x;
421 this.y = y;
422 this.command = Command.NO_OP;
423 this.streamCondition = TrafficController.NO_STREAM;
424 }
425
426
427
428
429
430
431
432
433
434 RouteStep(final int x, final int y, final Command command) throws TrafficLightException
435 {
436 Throw.when(
437 Command.STOP_LINE != command && Command.NO_OP != command && Command.ICON != command
438 && Command.STOP_LINE_AND_ICON != command,
439 TrafficLightException.class,
440 "X and Y should only be provided with a NO_OP, STOP_LINE, ICON, or STOP_LINE_AND_ICON command; not with "
441 + command);
442 this.x = x;
443 this.y = y;
444 this.command = command;
445 this.streamCondition = TrafficController.NO_STREAM;
446 }
447
448
449
450
451
452
453
454
455 RouteStep(final Command command, final int streamCondition) throws TrafficLightException
456 {
457 Throw.when(Command.IF != command && Command.ELSE_IF != command, TrafficLightException.class,
458 "RouteStep constructor with stream condition must use command IF or ELSE_IF");
459 this.x = TrafficController.NO_STREAM;
460 this.y = TrafficController.NO_STREAM;
461 this.command = command;
462 Throw.when(streamCondition == TrafficController.NO_STREAM, TrafficLightException.class,
463 "IF or ELSE_IF need a valid traffic stream number");
464 this.streamCondition = streamCondition;
465 }
466
467
468
469
470
471
472 RouteStep(final Command command) throws TrafficLightException
473 {
474 Throw.when(Command.ELSE != command && Command.END_IF != command, TrafficLightException.class,
475 "RouteStep constructor with single command parameter requires ELSE or END_IF command");
476 this.x = TrafficController.NO_STREAM;
477 this.y = TrafficController.NO_STREAM;
478 this.command = command;
479 this.streamCondition = TrafficController.NO_STREAM;
480 }
481
482
483
484
485
486 public int getX()
487 {
488 return this.x;
489 }
490
491
492
493
494
495 public int getY()
496 {
497 return this.y;
498 }
499
500
501
502
503
504 public Command getCommand()
505 {
506 return this.command;
507 }
508
509
510
511
512
513 public int getStreamCondition()
514 {
515 return this.streamCondition;
516 }
517
518
519 @Override
520 public String toString()
521 {
522 return "RouteStep [x=" + this.x + ", y=" + this.y + ", command=" + this.command + ", streamCondition="
523 + this.streamCondition + "]";
524 }
525
526 }
527
528
529
530
531 class XYPair
532 {
533
534 private final int x;
535
536
537 private final int y;
538
539
540
541
542
543
544 XYPair(final int x, final int y)
545 {
546 this.x = x;
547 this.y = y;
548 }
549
550
551
552
553
554 XYPair(final RouteStep routeStep)
555 {
556 this.x = routeStep.getX();
557 this.y = routeStep.getY();
558 }
559
560
561
562
563
564
565 XYPair(final XYPair in, final int quadrant)
566 {
567 this.x = rotatedX(in, quadrant);
568 this.y = rotatedY(in, quadrant);
569 }
570
571
572
573
574
575 public int getX()
576 {
577 return this.x;
578 }
579
580
581
582
583
584 public int getY()
585 {
586 return this.y;
587 }
588
589
590 @Override
591 public String toString()
592 {
593 return "XYPair [x=" + this.x + ", y=" + this.y + "]";
594 }
595
596 }
597
598
599
600
601
602
603
604
605 private XYPair[] rotateRoute(final int quadrant, final RouteStep... steps) throws TrafficLightException
606 {
607 List<XYPair> route = new ArrayList<>();
608 boolean on = true;
609
610 for (RouteStep step : steps)
611 {
612 switch (step.getCommand())
613 {
614 case NO_OP:
615 case STOP_LINE:
616 case ICON:
617 case STOP_LINE_AND_ICON:
618 if (on)
619 {
620 route.add(new XYPair(new XYPair(step), quadrant));
621 }
622 break;
623
624 default:
625 throw new TrafficLightException("Bad command in rotateRoute: " + step.getCommand());
626
627 }
628 }
629 return route.toArray(new XYPair[route.size()]);
630 }
631
632
633
634
635
636
637
638 private RouteStep[] assembleRoute(final RouteStep... steps) throws TrafficLightException
639 {
640 List<RouteStep> result = new ArrayList<>();
641 RouteStep step;
642 for (int pointNo = 0; null != (step = routePoint(pointNo, steps)); pointNo++)
643 {
644 result.add(step);
645 }
646 return result.toArray(new RouteStep[result.size()]);
647 }
648
649
650
651
652
653
654
655
656 private RouteStep routePoint(final int pointNo, final RouteStep... steps) throws TrafficLightException
657 {
658 boolean active = true;
659 boolean beenActive = false;
660 int index = 0;
661
662 for (RouteStep routeStep : steps)
663 {
664 switch (routeStep.getCommand())
665 {
666 case NO_OP:
667 case STOP_LINE:
668 case ICON:
669 case STOP_LINE_AND_ICON:
670 if (active)
671 {
672 if (index++ == pointNo)
673 {
674 return routeStep;
675 }
676 }
677 break;
678
679 case IF:
680 active = streamExists((short) routeStep.getStreamCondition());
681 beenActive = active;
682 break;
683
684 case ELSE_IF:
685 if (active)
686 {
687 active = false;
688 }
689 else if (!beenActive)
690 {
691 active = this.streams.contains(routeStep.getStreamCondition());
692 }
693 if (active)
694 {
695 beenActive = true;
696 }
697 break;
698
699 case ELSE:
700 active = !beenActive;
701 break;
702
703 case END_IF:
704 active = true;
705 break;
706
707 default:
708 throw new TrafficLightException("Bad switch: " + routeStep);
709
710 }
711 }
712 return null;
713 }
714
715
716
717
718
719 public BufferedImage render()
720 {
721 int range = 2 * BOUNDARY + 1;
722 int cellSize = 10;
723 BufferedImage result = new BufferedImage(range * cellSize, range * cellSize, BufferedImage.TYPE_INT_RGB);
724 Graphics2D graphics = (Graphics2D) result.getGraphics();
725 graphics.setColor(Color.GREEN);
726 graphics.fillRect(0, 0, result.getWidth(), result.getHeight());
727 for (Short stream : this.streams)
728 {
729 switch (laneType(stream))
730 {
731 case BICYCLE_LANE:
732 graphics.setColor(Color.RED);
733 break;
734
735 case CAR_LANE:
736 graphics.setColor(Color.BLACK);
737 break;
738
739 case PEDESTRIAN_LANE:
740 graphics.setColor(Color.BLUE);
741 break;
742
743 case PUBLIC_TRANSIT_LANE:
744 graphics.setColor(Color.BLACK);
745 break;
746
747 default:
748 graphics.setColor(Color.WHITE);
749 break;
750
751 }
752 XYPair[] path = this.routes.get(stream);
753 if (null == path)
754 {
755 System.err.println("Cannot find path for stream " + stream);
756 continue;
757 }
758 XYPair prevPair = null;
759 for (XYPair xyPair : path)
760 {
761 if (null != prevPair)
762 {
763 int dx = (int) Math.signum(xyPair.getX() - prevPair.getX());
764 int dy = (int) Math.signum(xyPair.getY() - prevPair.getY());
765 int x = prevPair.getX() + dx;
766 int y = prevPair.getY() + dy;
767 while (x != xyPair.getX() || y != xyPair.getY())
768 {
769 fillXYPair(graphics, new XYPair(x, y));
770 if (x != xyPair.getX())
771 {
772 x += dx;
773 }
774 if (y != xyPair.getY())
775 {
776 y += dy;
777 }
778 }
779
780 }
781 fillXYPair(graphics, xyPair);
782 prevPair = xyPair;
783 }
784 }
785 return result;
786 }
787
788
789
790
791
792
793 private void fillXYPair(final Graphics2D graphics, final XYPair xyPair)
794 {
795 int cellSize = 10;
796 graphics.fillRect(cellSize * (BOUNDARY - xyPair.getX()), cellSize * (BOUNDARY - xyPair.getY()), cellSize, cellSize);
797 }
798
799
800
801
802
803 public static void main(final String[] args)
804 {
805 SwingUtilities.invokeLater(new Runnable()
806 {
807 @Override
808 public void run()
809 {
810 JFrame frame = new JFrame("Diagram test");
811 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
812 frame.setMinimumSize(new Dimension(1000, 1000));
813 JPanel mainPanel = new JPanel(new BorderLayout());
814 frame.add(mainPanel);
815 checkBoxPanel = new JPanel();
816 checkBoxPanel.setLayout(new BoxLayout(checkBoxPanel, BoxLayout.Y_AXIS));
817 JScrollPane scrollPane = new JScrollPane(checkBoxPanel);
818 scrollPane.setPreferredSize(new Dimension(150, 1000));
819 mainPanel.add(scrollPane, BorderLayout.LINE_START);
820 for (int stream = 1; stream <= 12; stream++)
821 {
822 checkBoxPanel.add(makeCheckBox(stream, stream % 3 == 2));
823 }
824 for (int stream = 21; stream <= 28; stream++)
825 {
826 checkBoxPanel.add(makeCheckBox(stream, false));
827 }
828 for (int stream = 31; stream <= 38; stream++)
829 {
830 checkBoxPanel.add(makeCheckBox(stream, false));
831 }
832 for (int stream = 41; stream <= 52; stream++)
833 {
834 checkBoxPanel.add(makeCheckBox(stream, false));
835 }
836 for (int stream = 61; stream <= 72; stream++)
837 {
838 if (stream % 3 == 1)
839 {
840 continue;
841 }
842 checkBoxPanel.add(makeCheckBox(stream, false));
843 }
844 testPanel = new JPanel();
845 rebuildTestPanel();
846 mainPanel.add(testPanel, BorderLayout.CENTER);
847 frame.setVisible(true);
848 }
849 });
850
851 }
852
853
854
855
856
857
858
859 public static JCheckBox makeCheckBox(final int stream, final boolean initialState)
860 {
861 JCheckBox result = new JCheckBox(String.format("Stream %02d", stream));
862 result.setSelected(initialState);
863 result.addActionListener(new ActionListener()
864 {
865
866 @Override
867 public void actionPerformed(final ActionEvent e)
868 {
869 rebuildTestPanel();
870 }
871 });
872 return result;
873 }
874
875
876 private static JPanel testPanel = null;
877
878
879 private static JPanel checkBoxPanel = null;
880
881
882
883
884 static void rebuildTestPanel()
885 {
886 testPanel.removeAll();
887 Set<Short> streamList = new LinkedHashSet<>();
888 for (Component c : checkBoxPanel.getComponents())
889 {
890 if (c instanceof JCheckBox)
891 {
892 JCheckBox checkBox = (JCheckBox) c;
893 if (checkBox.isSelected())
894 {
895 String caption = checkBox.getText();
896 String streamText = caption.substring(caption.length() - 2);
897 Short stream = Short.parseShort(streamText);
898 streamList.add(stream);
899 }
900 }
901 }
902 try
903 {
904 Diagram diagram = new Diagram(streamList);
905 testPanel.add(new JLabel(new ImageIcon(diagram.render())));
906 }
907 catch (TrafficLightException exception)
908 {
909 exception.printStackTrace();
910 }
911 testPanel.repaint();
912 testPanel.revalidate();
913 }
914
915 }