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