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