1 package org.opentrafficsim.demo;
2
3 import java.awt.Color;
4 import java.awt.Dimension;
5 import java.awt.Font;
6 import java.awt.HeadlessException;
7 import java.awt.event.ActionEvent;
8 import java.awt.event.ActionListener;
9 import java.lang.reflect.InvocationTargetException;
10 import java.lang.reflect.Method;
11 import java.util.ArrayList;
12 import java.util.List;
13
14 import javax.swing.Box;
15 import javax.swing.JButton;
16 import javax.swing.JComponent;
17 import javax.swing.JFrame;
18 import javax.swing.JLabel;
19 import javax.swing.JOptionPane;
20 import javax.swing.JScrollPane;
21 import javax.swing.JSeparator;
22 import javax.swing.JTextArea;
23 import javax.swing.ScrollPaneConstants;
24 import javax.swing.WindowConstants;
25
26 import org.djutils.reflection.ClassUtil;
27 import org.opentrafficsim.core.dsol.OtsModelInterface;
28 import org.opentrafficsim.demo.conflict.TJunctionDemo;
29 import org.opentrafficsim.demo.conflict.TurboRoundaboutDemo;
30 import org.opentrafficsim.demo.trafficcontrol.TrafCodDemo2;
31 import org.opentrafficsim.swing.gui.OtsSwingApplication;
32
33
34
35
36
37
38
39
40
41 public class SuperDemo extends JFrame
42 {
43
44 private static final long serialVersionUID = 1L;
45
46
47 private List<Demo> demos = new ArrayList<>();
48
49
50
51
52
53 public SuperDemo() throws HeadlessException
54 {
55 super("OTS demo models");
56 setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
57 setMinimumSize(new Dimension(1024, 20));
58 addDemos();
59 setContentPane(makeGUI());
60 pack();
61 setVisible(true);
62 }
63
64
65
66
67 private void addDemos()
68 {
69 this.demos.add(new Demo("Straight", StraightSwing.class, "Single lane road with a blockage for a while.\n"
70 + "The model shows the dissolving of the congestion that occurs as a result."));
71 this.demos.add(new Demo("CircularRoad", CircularRoadSwing.class, "Model of a two-lane circular road with overtaking.\n"
72 + "Users can specify the fraction of cars and trucks, as well as some driving parameters."));
73 this.demos.add(new Demo("ShortMerge", ShortMerge.class, "Short merge on a highway, followed by a destination split,\n"
74 + "forcing cars to change lanes in a relative short distance."));
75 this.demos.add(new Demo("TJunction", TJunctionDemo.class,
76 "Complex crossing traffic on a T-junction with\n" + "automated conflict resolution."));
77 this.demos.add(new Demo("TurboRoundabout", TurboRoundaboutDemo.class,
78 "Turbo Roundabout without traffic lights,\n" + "conflict resolution is fully automated."));
79 this.demos.add(new Demo("Networks", NetworksSwing.class,
80 "A number of different networks with merging and splitting,\n" + "forcing cars to change lanes and to merge."));
81 this.demos.add(new Demo("TrafCODDemoComplex", TrafCodDemo2.class,
82 "Model of a complex crossing with traffic lights.\n" + "using a TrafCOD controller"));
83 }
84
85
86
87
88 private JComponent makeGUI()
89 {
90 Box table = Box.createVerticalBox();
91 table.setBackground(Color.WHITE);
92 table.setOpaque(true);
93 JScrollPane scrollPane = new JScrollPane(table, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
94 ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
95 int maxButtonWidth = 0;
96 table.add(Box.createRigidArea(new Dimension(0, 3)));
97 Box headerBox = Box.createHorizontalBox();
98 JLabel header = new JLabel(" OpenTrafficSim demo's ");
99 header.setFont(new Font(Font.SANS_SERIF, Font.BOLD, 36));
100 headerBox.add(header);
101 headerBox.add(Box.createHorizontalGlue());
102 table.add(headerBox);
103 table.add(Box.createRigidArea(new Dimension(0, 3)));
104 table.add(new JSeparator());
105 for (Demo demo : this.demos)
106 {
107 table.add(Box.createRigidArea(new Dimension(0, 3)));
108 Box row = Box.createHorizontalBox();
109 row.add(new JLabel(" "));
110 row.add(demo.getButton());
111 row.add(new JLabel(" "));
112 JTextArea description = new JTextArea();
113 description.setText(demo.getDescription());
114 description.setFont(new Font(Font.SANS_SERIF, Font.PLAIN, 16));
115 description.setEditable(false);
116 description.setWrapStyleWord(true);
117 description.setLineWrap(true);
118 row.add(description);
119 row.add(Box.createHorizontalGlue());
120 row.add(new JLabel(" "));
121 table.add(row);
122 table.add(Box.createRigidArea(new Dimension(0, 3)));
123 table.add(new JSeparator());
124 maxButtonWidth = Math.max(maxButtonWidth, demo.getButton().getPreferredSize().width);
125 }
126
127 for (Demo demo : this.demos)
128 {
129 demo.getButton().setPreferredSize(new Dimension(maxButtonWidth, demo.getButton().getPreferredSize().height));
130 }
131
132 table.add(Box.createVerticalGlue());
133
134 return scrollPane;
135 }
136
137
138
139
140 public static void main(final String[] args)
141 {
142 new SuperDemo();
143 }
144
145
146 static class NoExitSecurityManager extends SecurityManager
147 {
148 @Override
149 public void checkExit(final int status)
150 {
151 throw new SecurityException();
152 }
153 }
154
155
156 private static class Demo implements ActionListener
157 {
158
159 @SuppressWarnings("checkstyle:visibilitymodifier")
160 protected final String name;
161
162
163 private final JButton button;
164
165
166 @SuppressWarnings("checkstyle:visibilitymodifier")
167 protected final Class<? extends OtsSwingApplication<? extends OtsModelInterface>> clazz;
168
169
170 private final String description;
171
172
173
174
175
176
177 Demo(final String name, final Class<? extends OtsSwingApplication<? extends OtsModelInterface>> clazz,
178 final String description)
179 {
180 this.name = name;
181 this.button = new JButton(name);
182 this.button.addActionListener(this);
183 this.clazz = clazz;
184 this.description = description;
185 }
186
187
188
189
190 public final JButton getButton()
191 {
192 return this.button;
193 }
194
195
196
197
198 public final String getDescription()
199 {
200 return this.description;
201 }
202
203
204 @Override
205 public void actionPerformed(final ActionEvent e)
206 {
207 try
208 {
209 final Method demoMethod = ClassUtil.resolveMethod(this.clazz, "demo", new Class[] {boolean.class});
210 Thread demo = new Thread(new Runnable()
211 {
212 @Override
213 public void run()
214 {
215 try
216 {
217 Class.forName(Demo.this.clazz.getName());
218 demoMethod.invoke(null, new Object[] {false});
219 }
220 catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException
221 | ClassNotFoundException exception)
222 {
223 exception.printStackTrace();
224 JOptionPane
225 .showMessageDialog(null,
226 "Method 'demo' for demo " + Demo.this.name + " cound not be started\n"
227 + exception.getMessage(),
228 "Could not start demo", JOptionPane.ERROR_MESSAGE);
229 }
230 }
231 });
232 demo.start();
233 }
234 catch (NoSuchMethodException exception)
235 {
236 JOptionPane.showMessageDialog(null, "Method 'demo' not found for demo " + this.name, "Could not start demo",
237 JOptionPane.ERROR_MESSAGE);
238 }
239 }
240 }
241 }