1 package org.opentrafficsim.simulationengine;
2
3 import java.awt.Container;
4 import java.awt.Dimension;
5 import java.awt.Frame;
6 import java.awt.Rectangle;
7 import java.awt.geom.Rectangle2D;
8 import java.io.Serializable;
9 import java.rmi.RemoteException;
10 import java.util.ArrayList;
11 import java.util.List;
12
13 import javax.naming.NamingException;
14 import javax.swing.WindowConstants;
15 import javax.vecmath.Point3d;
16
17 import org.djunits.value.vdouble.scalar.Duration;
18 import org.djunits.value.vdouble.scalar.Time;
19 import org.opentrafficsim.base.modelproperties.Property;
20 import org.opentrafficsim.base.modelproperties.PropertyException;
21 import org.opentrafficsim.core.dsol.OTSModelInterface;
22 import org.opentrafficsim.core.gtu.animation.DefaultSwitchableGTUColorer;
23 import org.opentrafficsim.core.gtu.animation.GTUColorer;
24 import org.opentrafficsim.core.network.Link;
25 import org.opentrafficsim.core.network.NetworkException;
26 import org.opentrafficsim.gui.OTSAnimationPanel;
27 import org.opentrafficsim.gui.SimulatorFrame;
28
29 import nl.tudelft.simulation.dsol.SimRuntimeException;
30 import nl.tudelft.simulation.dsol.animation.Locatable;
31 import nl.tudelft.simulation.language.d3.BoundingBox;
32 import nl.tudelft.simulation.language.d3.DirectedPoint;
33
34
35
36
37
38
39
40
41
42
43
44 public abstract class AbstractWrappableAnimation implements WrappableAnimation, Serializable
45 {
46
47 private static final long serialVersionUID = 20150000L;
48
49
50 @SuppressWarnings("checkstyle:visibilitymodifier")
51 protected List<Property<?>> properties = new ArrayList<>();
52
53
54 @SuppressWarnings("checkstyle:visibilitymodifier")
55 protected List<Property<?>> savedUserModifiedProperties;
56
57
58 @SuppressWarnings("checkstyle:visibilitymodifier")
59 protected boolean exitOnClose;
60
61
62 @SuppressWarnings("checkstyle:visibilitymodifier")
63 protected OTSAnimationPanel panel;
64
65
66 private Time savedStartTime;
67
68
69 private Duration savedWarmupPeriod;
70
71
72 private Duration savedRunLength;
73
74
75 private OTSModelInterface model;
76
77
78
79
80
81
82
83
84
85
86
87
88 @SuppressWarnings("checkstyle:designforextension")
89 protected SimpleAnimator buildSimpleAnimator(final Time startTime, final Duration warmupPeriod, final Duration runLength,
90 final OTSModelInterface otsModel) throws SimRuntimeException, NamingException, PropertyException
91 {
92 return new SimpleAnimator(startTime, warmupPeriod, runLength, otsModel);
93 }
94
95
96 @Override
97 @SuppressWarnings("checkstyle:designforextension")
98 public SimpleAnimator buildAnimator(final Time startTime, final Duration warmupPeriod, final Duration runLength,
99 final List<Property<?>> userModifiedProperties, final Rectangle rect, final boolean eoc)
100 throws SimRuntimeException, NamingException, OTSSimulationException, PropertyException
101 {
102 this.savedUserModifiedProperties = userModifiedProperties;
103 this.exitOnClose = eoc;
104
105 this.savedStartTime = startTime;
106 this.savedWarmupPeriod = warmupPeriod;
107 this.savedRunLength = runLength;
108
109 GTUColorer colorer = new DefaultSwitchableGTUColorer();
110 this.model = makeModel(colorer);
111
112 if (null == this.model)
113 {
114 return null;
115 }
116
117 final SimpleAnimator simulator = buildSimpleAnimator(startTime, warmupPeriod, runLength, this.model);
118 try
119 {
120 this.panel = new OTSAnimationPanel(makeAnimationRectangle(), new Dimension(1024, 768), simulator, this, colorer);
121 }
122 catch (RemoteException exception)
123 {
124 throw new SimRuntimeException(exception);
125 }
126
127 addAnimationToggles();
128 addTabs(simulator);
129
130 SimulatorFrame frame = new SimulatorFrame(shortName(), this.panel);
131 if (rect != null)
132 {
133 frame.setBounds(rect);
134 }
135 else
136 {
137 frame.setExtendedState(Frame.MAXIMIZED_BOTH);
138 }
139
140 frame.setDefaultCloseOperation(this.exitOnClose ? WindowConstants.EXIT_ON_CLOSE : WindowConstants.DISPOSE_ON_CLOSE);
141
142 return simulator;
143 }
144
145
146
147
148
149
150
151 protected void addTabs(final SimpleSimulatorInterface simulator) throws OTSSimulationException, PropertyException
152 {
153
154 }
155
156
157
158
159 @SuppressWarnings("checkstyle:designforextension")
160 protected void addAnimationToggles()
161 {
162
163 }
164
165
166
167
168
169
170
171
172
173
174
175
176 public final void addToggleAnimationButtonIcon(final String name, final Class<? extends Locatable> locatableClass,
177 final String iconPath, final String toolTipText, final boolean initiallyVisible, final boolean idButton)
178 {
179 this.panel.addToggleAnimationButtonIcon(name, locatableClass, iconPath, toolTipText, initiallyVisible, idButton);
180 }
181
182
183
184
185
186
187
188
189 public final void addToggleAnimationButtonText(final String name, final Class<? extends Locatable> locatableClass,
190 final String toolTipText, final boolean initiallyVisible)
191 {
192 this.panel.addToggleAnimationButtonText(name, locatableClass, toolTipText, initiallyVisible);
193 }
194
195
196
197
198
199 public final void showAnimationClass(final Class<? extends Locatable> locatableClass)
200 {
201 this.panel.getAnimationPanel().showClass(locatableClass);
202 }
203
204
205
206
207
208 public final void hideAnimationClass(final Class<? extends Locatable> locatableClass)
209 {
210 this.panel.getAnimationPanel().hideClass(locatableClass);
211 }
212
213
214
215
216
217 public final void toggleAnimationClass(final Class<? extends Locatable> locatableClass)
218 {
219 this.panel.getAnimationPanel().toggleClass(locatableClass);
220 }
221
222
223
224
225
226
227 protected abstract OTSModelInterface makeModel(GTUColorer colorer) throws OTSSimulationException;
228
229
230
231
232
233
234 @SuppressWarnings("checkstyle:designforextension")
235 protected Rectangle2D makeAnimationRectangle()
236 {
237 double minX = Double.MAX_VALUE;
238 double maxX = -Double.MAX_VALUE;
239 double minY = Double.MAX_VALUE;
240 double maxY = -Double.MAX_VALUE;
241 Point3d p3dL = new Point3d();
242 Point3d p3dU = new Point3d();
243 try
244 {
245 for (Link link : this.model.getNetwork().getLinkMap().values())
246 {
247 DirectedPoint l = link.getLocation();
248 BoundingBox b = new BoundingBox(link.getBounds());
249 b.getLower(p3dL);
250 b.getUpper(p3dU);
251 minX = Math.min(minX, l.x + Math.min(p3dL.x, p3dU.x));
252 minY = Math.min(minY, l.y + Math.min(p3dL.y, p3dU.y));
253 maxX = Math.max(maxX, l.x + Math.max(p3dL.x, p3dU.x));
254 maxY = Math.max(maxY, l.y + Math.max(p3dL.y, p3dU.y));
255 }
256 }
257 catch (Exception e)
258 {
259
260 }
261
262 minX = minX - 0.05 * Math.abs(minX);
263 minY = minY - 0.05 * Math.abs(minY);
264 maxX = maxX + 0.05 * Math.abs(maxX);
265 maxY = maxY + 0.05 * Math.abs(maxY);
266
267 return new Rectangle2D.Double(minX, minY, maxX - minX, maxY - minY);
268 }
269
270
271 @Override
272 public final ArrayList<Property<?>> getProperties()
273 {
274 return new ArrayList<Property<?>>(this.properties);
275 }
276
277
278 @Override
279 public final SimpleSimulatorInterface rebuildSimulator(final Rectangle rect)
280 throws SimRuntimeException, NetworkException, NamingException, OTSSimulationException, PropertyException
281 {
282 return buildAnimator(this.savedStartTime, this.savedWarmupPeriod, this.savedRunLength, this.savedUserModifiedProperties,
283 rect, this.exitOnClose);
284 }
285
286
287 @Override
288 public final List<Property<?>> getUserModifiedProperties()
289 {
290 return this.savedUserModifiedProperties;
291 }
292
293
294 @Override
295 @SuppressWarnings("checkstyle:designforextension")
296 public void stopTimersThreads()
297 {
298 if (this.panel != null && this.panel.getStatusBar() != null)
299 {
300 this.panel.getStatusBar().cancelTimer();
301 }
302 this.panel = null;
303 }
304
305
306
307
308 public final OTSAnimationPanel getPanel()
309 {
310 return this.panel;
311 }
312
313
314
315
316
317
318
319
320 public final void addTab(final int index, final String caption, final Container container)
321 {
322 this.panel.getTabbedPane().addTab(index, caption, container);
323 }
324
325
326
327
328
329
330 public final int getTabCount()
331 {
332 return this.panel.getTabbedPane().getTabCount();
333 }
334
335 }