1 package org.opentrafficsim.demo;
2
3 import java.awt.event.ActionEvent;
4 import java.rmi.RemoteException;
5 import java.util.ArrayList;
6 import java.util.List;
7
8 import javax.naming.NamingException;
9 import javax.swing.Box;
10 import javax.swing.ButtonGroup;
11 import javax.swing.JLabel;
12 import javax.swing.JOptionPane;
13 import javax.swing.JPanel;
14 import javax.swing.JRadioButton;
15
16 import org.djunits.unit.util.UNITS;
17 import org.djunits.value.vdouble.scalar.Duration;
18 import org.opentrafficsim.animation.data.util.GraphLaneUtil;
19 import org.opentrafficsim.animation.graphs.GraphPath;
20 import org.opentrafficsim.animation.graphs.TrajectoryPlot;
21 import org.opentrafficsim.base.OtsRuntimeException;
22 import org.opentrafficsim.core.dsol.OtsAnimator;
23 import org.opentrafficsim.core.network.Network;
24 import org.opentrafficsim.core.network.NetworkException;
25 import org.opentrafficsim.core.perception.HistoryManagerDevs;
26 import org.opentrafficsim.road.network.Lane;
27 import org.opentrafficsim.road.network.RoadNetwork;
28 import org.opentrafficsim.road.network.sampling.LaneDataRoad;
29 import org.opentrafficsim.road.network.sampling.RoadSampler;
30 import org.opentrafficsim.swing.graphs.OtsPlotScheduler;
31 import org.opentrafficsim.swing.graphs.SwingPlot;
32 import org.opentrafficsim.swing.graphs.SwingTrajectoryPlot;
33 import org.opentrafficsim.swing.gui.OtsSimulationApplication;
34 import org.opentrafficsim.swing.gui.OtsSimulationPanel;
35 import org.opentrafficsim.swing.gui.OtsSimulationPanelDecorator;
36
37 import nl.tudelft.simulation.dsol.SimRuntimeException;
38 import nl.tudelft.simulation.dsol.model.inputparameters.InputParameter;
39 import nl.tudelft.simulation.dsol.model.inputparameters.InputParameterMap;
40 import nl.tudelft.simulation.dsol.model.inputparameters.InputParameterSelectionMap;
41 import nl.tudelft.simulation.dsol.swing.gui.TablePanel;
42 import nl.tudelft.simulation.dsol.swing.gui.inputparameters.AbstractInputField;
43 import nl.tudelft.simulation.dsol.swing.gui.inputparameters.InputField;
44 import nl.tudelft.simulation.dsol.swing.gui.inputparameters.TabbedParameterDialog;
45 import nl.tudelft.simulation.language.DsolException;
46
47
48
49
50
51
52
53
54
55 public class NetworksSwing extends OtsSimulationApplication<NetworksModel> implements UNITS
56 {
57
58 private static final long serialVersionUID = 1L;
59
60
61
62
63
64
65
66 public NetworksSwing(final String title, final OtsSimulationPanel panel, final NetworksModel model)
67 {
68 super(model, panel);
69 }
70
71
72
73
74
75 public static void main(final String[] args)
76 {
77 demo(true);
78 }
79
80
81
82
83
84 public static void demo(final boolean exitOnClose)
85 {
86 try
87 {
88 OtsAnimator simulator = new OtsAnimator("NetworksSwing");
89 final NetworksModel otsModel = new NetworksModel(simulator);
90 if (NetworksParameterDialog.process(otsModel.getInputParameterMap()))
91 {
92 simulator.initialize(Duration.ZERO, Duration.ZERO, Duration.ofSI(3600.0), otsModel,
93 HistoryManagerDevs.noHistory(simulator));
94 OtsSimulationPanel simulationPanel =
95 new OtsSimulationPanel(otsModel.getNetwork(), new OtsSimulationPanelDecorator()
96 {
97 @Override
98 public void addTabs(final OtsSimulationPanel simulationPanel, final Network network)
99 {
100 addStatisticsTabs(simulationPanel, network, otsModel.getPaths());
101 }
102 });
103 NetworksSwing app = new NetworksSwing("Networks", simulationPanel, otsModel);
104 app.setExitOnClose(exitOnClose);
105 simulationPanel.enableSimulationControlButtons();
106 }
107 else
108 {
109 if (exitOnClose)
110 {
111 System.exit(0);
112 }
113 }
114 }
115 catch (SimRuntimeException | NamingException | RemoteException | DsolException exception)
116 {
117 exception.printStackTrace();
118 }
119 }
120
121
122
123
124
125
126
127 private static void addStatisticsTabs(final OtsSimulationPanel simulationPanel, final Network network,
128 final List<List<Lane>> paths)
129 {
130 int graphCount = paths.size();
131 int columns = 1;
132 int rows = 0 == columns ? 0 : (int) Math.ceil(graphCount * 1.0 / columns);
133 TablePanel charts = new TablePanel(columns, rows);
134 RoadSampler sampler = new RoadSampler((RoadNetwork) network);
135 Duration updateInterval = Duration.ofSI(10.0);
136 for (int graphIndex = 0; graphIndex < graphCount; graphIndex++)
137 {
138 List<Lane> start = new ArrayList<>();
139 start.add(paths.get(graphIndex).get(0));
140 GraphPath<LaneDataRoad> path;
141 try
142 {
143 path = GraphLaneUtil.createPath("name", start.get(0));
144 }
145 catch (NetworkException exception)
146 {
147 throw new OtsRuntimeException(exception);
148 }
149 GraphPath.initRecording(sampler, path);
150 SwingPlot plot = new SwingTrajectoryPlot(new TrajectoryPlot("Trajectories on lane " + (graphIndex + 1),
151 updateInterval, new OtsPlotScheduler(network.getSimulator()), sampler.getSamplerData(), path));
152 charts.setCell(plot.getContentPane(), graphIndex % columns, graphIndex / columns);
153 }
154
155 simulationPanel.getTabbedPane().addTab(simulationPanel.getTabbedPane().getTabCount(), "statistics ", charts);
156 }
157
158
159 private static class NetworksParameterDialog extends TabbedParameterDialog
160 {
161
162 private static final long serialVersionUID = 1L;
163
164
165
166
167 NetworksParameterDialog(final InputParameterMap inputParameterMap)
168 {
169 super(inputParameterMap);
170 }
171
172 @SuppressWarnings({"rawtypes", "unchecked"})
173 @Override
174 public void addParameterField(final JPanel panel, final InputParameter<?, ?> parameter)
175 {
176 if (parameter instanceof InputParameterSelectionMap<?, ?>)
177 {
178 this.fields.add(new InputFieldSelectionMapRadio(panel, (InputParameterSelectionMap<?, ?>) parameter));
179 }
180 else
181 {
182 super.addParameterField(panel, parameter);
183 }
184 }
185
186 @Override
187 public void actionPerformed(final ActionEvent e)
188 {
189 boolean ok = true;
190 try
191 {
192 for (InputField field : this.fields)
193 {
194 if (field instanceof InputFieldSelectionMapRadio<?, ?>)
195 {
196 InputFieldSelectionMapRadio<?, ?> f = (InputFieldSelectionMapRadio<?, ?>) field;
197 f.getParameter().setObjectValue(f.getValue());
198 }
199 }
200 }
201 catch (Exception exception)
202 {
203 JOptionPane.showMessageDialog(null, exception.getMessage(), "Data Entry Error", JOptionPane.ERROR_MESSAGE);
204 ok = false;
205 }
206 if (ok)
207 {
208 super.actionPerformed(e);
209 }
210 }
211
212
213
214
215
216
217 public static boolean process(final InputParameterMap inputParameterMap)
218 {
219 NetworksParameterDialog dialog = new NetworksParameterDialog(inputParameterMap);
220 return !dialog.stopped;
221 }
222 }
223
224
225
226
227
228
229 public static class InputFieldSelectionMapRadio<K, T> extends AbstractInputField
230 {
231
232 private List<JRadioButton> buttons = new ArrayList<>();
233
234
235 private List<T> values = new ArrayList<>();
236
237
238
239
240
241
242 public InputFieldSelectionMapRadio(final JPanel panel, final InputParameterSelectionMap<K, T> parameter)
243 {
244 super(parameter);
245 Box box = Box.createVerticalBox();
246 box.add(new JLabel(" "));
247 box.add(new JLabel(parameter.getShortName()));
248 ButtonGroup group = new ButtonGroup();
249 for (K option : parameter.getOptions().keySet())
250 {
251 String item = option.toString();
252 T value = parameter.getOptions().get(option);
253 JRadioButton button = new JRadioButton(item);
254 button.setActionCommand(item);
255 if (value.equals(parameter.getDefaultValue()))
256 {
257 button.setSelected(true);
258 }
259 group.add(button);
260 box.add(button);
261 this.buttons.add(button);
262 this.values.add(value);
263 }
264 panel.add(box);
265 }
266
267 @SuppressWarnings("unchecked")
268 @Override
269 public InputParameterSelectionMap<K, T> getParameter()
270 {
271 return (InputParameterSelectionMap<K, T>) super.getParameter();
272 }
273
274
275
276
277
278 public T getValue()
279 {
280 for (JRadioButton button : this.buttons)
281 {
282 if (button.isSelected())
283 {
284 return this.values.get(this.buttons.indexOf(button));
285 }
286 }
287 return this.values.get(0);
288 }
289 }
290 }