View Javadoc
1   package nl.tudelft.simulation.dsol.swing.gui.control;
2   
3   import java.awt.Dimension;
4   import java.awt.FlowLayout;
5   import java.awt.Font;
6   import java.io.Serializable;
7   import java.util.Timer;
8   import java.util.TimerTask;
9   
10  import javax.swing.JLabel;
11  import javax.swing.JPanel;
12  
13  import org.djunits.value.vdouble.scalar.Duration;
14  import org.djunits.value.vfloat.scalar.FloatDuration;
15  
16  import nl.tudelft.simulation.dsol.simulators.SimulatorInterface;
17  import nl.tudelft.simulation.dsol.swing.gui.appearance.AppearanceControl;
18  import nl.tudelft.simulation.dsol.swing.gui.appearance.AppearanceControlLabel;
19  
20  /**
21   * Panel that displays the simulation speed.
22   * <p>
23   * Copyright (c) 2020-2023 Delft University of Technology, Jaffalaan 5, 2628 BX Delft, the Netherlands. All rights reserved. See
24   * for project information <a href="https://simulation.tudelft.nl/dsol/manual/" target="_blank">DSOL Manual</a>. The DSOL
25   * project is distributed under a three-clause BSD-style license, which can be found at
26   * <a href="https://https://simulation.tudelft.nl/dsol/docs/latest/license.html" target="_blank">DSOL License</a>.
27   * </p>
28   * @author <a href="https://www.tudelft.nl/averbraeck">Alexander Verbraeck</a>
29   * @param <T> the time type
30   */
31  public abstract class SpeedPanel<T extends Number & Comparable<T>> extends JPanel implements AppearanceControl
32  {
33      /** */
34      private static final long serialVersionUID = 20141211L;
35  
36      /** The JLabel that displays the simulation speed. */
37      @SuppressWarnings("checkstyle:visibilitymodifier")
38      public JLabel speedLabel;
39  
40      /** the simulator. */
41      @SuppressWarnings("checkstyle:visibilitymodifier")
42      final SimulatorInterface<T> simulator;
43  
44      /** Font used to display the clock. */
45      private Font timeFont = new Font("SansSerif", Font.BOLD, 18);
46  
47      /** The timer (so we can cancel it). */
48      private Timer timer;
49  
50      /** Timer update interval in msec. */
51      private long updateIntervalMs = 1000;
52  
53      /** Simulation time time. */
54      private T prevSimTime;
55  
56      /**
57       * Construct a clock panel.
58       * @param simulator SimulatorInterface&lt;T&gt;; the simulator
59       */
60      public SpeedPanel(final SimulatorInterface<T> simulator)
61      {
62          this.simulator = simulator;
63          setLayout(new FlowLayout(FlowLayout.LEFT));
64          setFont(getTimeFont());
65  
66          this.speedLabel = new AppearanceControlLabel();
67          this.speedLabel.setFont(getTimeFont());
68          this.speedLabel.setMaximumSize(new Dimension(100, 35));
69          add(this.speedLabel);
70  
71          this.timer = new Timer();
72          this.timer.scheduleAtFixedRate(new TimeUpdateTask(), 0, this.updateIntervalMs);
73      }
74  
75      /**
76       * Cancel the timer task.
77       */
78      public void cancelTimer()
79      {
80          if (this.timer != null)
81          {
82              this.timer.cancel();
83          }
84          this.timer = null;
85      }
86  
87      /** Updater for the clock panel. */
88      protected class TimeUpdateTask extends TimerTask implements Serializable
89      {
90          /** */
91          private static final long serialVersionUID = 20140000L;
92  
93          /** {@inheritDoc} */
94          @Override
95          public void run()
96          {
97              T simulationTime = SpeedPanel.this.getSimulator().getSimulatorTime();
98              getSpeedLabel().setText(formatSpeed(simulationTime));
99              getSpeedLabel().repaint();
100         }
101 
102         /** {@inheritDoc} */
103         @Override
104         public String toString()
105         {
106             return "TimeUpdateTask of SpeedPanel";
107         }
108     }
109 
110     /**
111      * @return speedLabel
112      */
113     public JLabel getSpeedLabel()
114     {
115         return this.speedLabel;
116     }
117 
118     /**
119      * @return simulator
120      */
121     public SimulatorInterface<T> getSimulator()
122     {
123         return this.simulator;
124     }
125 
126     /**
127      * @return timeFont.
128      */
129     public Font getTimeFont()
130     {
131         return this.timeFont;
132     }
133 
134     /**
135      * @return updateInterval
136      */
137     public long getUpdateIntervalMs()
138     {
139         return this.updateIntervalMs;
140     }
141 
142     /**
143      * @return prevSimTime
144      */
145     public T getPrevSimTime()
146     {
147         return this.prevSimTime;
148     }
149 
150     /**
151      * Set the new simulation time to be used in the next calculation for the speed.
152      * @param prevSimTime A; the new simulation time to be used in the next calculation for the speed
153      */
154     protected void setPrevSimTime(final T prevSimTime)
155     {
156         this.prevSimTime = prevSimTime;
157     }
158 
159     /**
160      * Returns the simulation speed as a String.
161      * @param simulationTime A; simulation time
162      * @return simulation speed
163      */
164     protected abstract String formatSpeed(T simulationTime);
165 
166     /** {@inheritDoc} */
167     @Override
168     public boolean isForeground()
169     {
170         return true;
171     }
172 
173     /** {@inheritDoc} */
174     @Override
175     public String toString()
176     {
177         return "SpeedPanel";
178     }
179 
180     /**
181      * SpeedPanel for a double time. The speed calculation can be adjusted.
182      * <p>
183      * Copyright (c) 2020-2023 Delft University of Technology, Jaffalaan 5, 2628 BX Delft, the Netherlands. All rights reserved.
184      * See for project information <a href="https://simulation.tudelft.nl/dsol/manual/" target="_blank">DSOL Manual</a>. The
185      * DSOL project is distributed under a three-clause BSD-style license, which can be found at
186      * <a href="https://https://simulation.tudelft.nl/dsol/docs/latest/license.html" target="_blank">DSOL License</a>.
187      * </p>
188      * @author <a href="https://www.tudelft.nl/averbraeck">Alexander Verbraeck</a>
189      */
190     public static class TimeDouble extends SpeedPanel<Double>
191     {
192         /** */
193         private static final long serialVersionUID = 20201227L;
194 
195         /**
196          * Construct a clock panel with a double time.
197          * @param simulator SimulatorInterface; the simulator
198          */
199         public TimeDouble(final SimulatorInterface<Double> simulator)
200         {
201             super(simulator);
202             setPrevSimTime(0.0);
203         }
204 
205         /** {@inheritDoc} */
206         @Override
207         protected String formatSpeed(final Double simulationTime)
208         {
209             if (simulationTime == null)
210             {
211                 return "0.0";
212             }
213             double speed = (simulationTime - getPrevSimTime()) / (0.001 * getUpdateIntervalMs());
214             setPrevSimTime(simulationTime);
215             return String.format("%6.2f x ", speed);
216         }
217     }
218 
219     /**
220      * SpeedPanel for a float time. The speed calculation can be adjusted.
221      * <p>
222      * Copyright (c) 2020-2023 Delft University of Technology, Jaffalaan 5, 2628 BX Delft, the Netherlands. All rights reserved.
223      * See for project information <a href="https://simulation.tudelft.nl/dsol/manual/" target="_blank">DSOL Manual</a>. The
224      * DSOL project is distributed under a three-clause BSD-style license, which can be found at
225      * <a href="https://https://simulation.tudelft.nl/dsol/docs/latest/license.html" target="_blank">DSOL License</a>.
226      * </p>
227      * @author <a href="https://www.tudelft.nl/averbraeck">Alexander Verbraeck</a>
228      */
229     public static class TimeFloat extends SpeedPanel<Float>
230     {
231         /** */
232         private static final long serialVersionUID = 20201227L;
233 
234         /**
235          * Construct a clock panel with a float time.
236          * @param simulator SimulatorInterface; the simulator
237          */
238         public TimeFloat(final SimulatorInterface<Float> simulator)
239         {
240             super(simulator);
241             setPrevSimTime(0.0f);
242         }
243 
244         /** {@inheritDoc} */
245         @Override
246         protected String formatSpeed(final Float simulationTime)
247         {
248             if (simulationTime == null)
249             {
250                 return "0.0";
251             }
252             double speed = (simulationTime - getPrevSimTime()) / (0.001 * getUpdateIntervalMs());
253             setPrevSimTime(simulationTime);
254             return String.format("%6.2f x ", speed);
255         }
256     }
257 
258     /**
259      * SpeedPanel for a long time. The speed calculation can be adjusted.
260      * <p>
261      * Copyright (c) 2020-2023 Delft University of Technology, Jaffalaan 5, 2628 BX Delft, the Netherlands. All rights reserved.
262      * See for project information <a href="https://simulation.tudelft.nl/dsol/manual/" target="_blank">DSOL Manual</a>. The
263      * DSOL project is distributed under a three-clause BSD-style license, which can be found at
264      * <a href="https://https://simulation.tudelft.nl/dsol/docs/latest/license.html" target="_blank">DSOL License</a>.
265      * </p>
266      * @author <a href="https://www.tudelft.nl/averbraeck">Alexander Verbraeck</a>
267      */
268     public static class TimeLong extends SpeedPanel<Long>
269     {
270         /** */
271         private static final long serialVersionUID = 20201227L;
272 
273         /**
274          * Construct a clock panel with a long time.
275          * @param simulator SimulatorInterface; the simulator
276          */
277         public TimeLong(final SimulatorInterface<Long> simulator)
278         {
279             super(simulator);
280             setPrevSimTime(0L);
281         }
282 
283         /** {@inheritDoc} */
284         @Override
285         protected String formatSpeed(final Long simulationTime)
286         {
287             if (simulationTime == null)
288             {
289                 return "0.0";
290             }
291             double speed = (simulationTime - getPrevSimTime()) / (0.001 * getUpdateIntervalMs());
292             setPrevSimTime(simulationTime);
293             return String.format("%6.2f x ", speed);
294         }
295     }
296 
297     /**
298      * SpeedPanel for a djutils Duration. The speed calculation can be adjusted.
299      * <p>
300      * Copyright (c) 2020-2023 Delft University of Technology, Jaffalaan 5, 2628 BX Delft, the Netherlands. All rights reserved.
301      * See for project information <a href="https://simulation.tudelft.nl/dsol/manual/" target="_blank">DSOL Manual</a>. The
302      * DSOL project is distributed under a three-clause BSD-style license, which can be found at
303      * <a href="https://https://simulation.tudelft.nl/dsol/docs/latest/license.html" target="_blank">DSOL License</a>.
304      * </p>
305      * @author <a href="https://www.tudelft.nl/averbraeck">Alexander Verbraeck</a>
306      */
307     public static class TimeDoubleUnit extends SpeedPanel<Duration>
308     {
309         /** */
310         private static final long serialVersionUID = 20201227L;
311 
312         /**
313          * Construct a clock panel with a djutils Duration.
314          * @param simulator SimulatorInterface; the simulator
315          */
316         public TimeDoubleUnit(final SimulatorInterface<Duration> simulator)
317         {
318             super(simulator);
319             setPrevSimTime(Duration.ZERO);
320         }
321 
322         /** {@inheritDoc} */
323         @Override
324         protected String formatSpeed(final Duration simulationTime)
325         {
326             if (simulationTime == null)
327             {
328                 return "0.0";
329             }
330             double speed = (simulationTime.si - getPrevSimTime().si) / (0.001 * getUpdateIntervalMs());
331             setPrevSimTime(simulationTime);
332             return String.format("%6.2f x ", speed);
333         }
334     }
335 
336     /**
337      * SpeedPanel for a djutils FloatDuration. The speed calculation can be adjusted.
338      * <p>
339      * Copyright (c) 2020-2023 Delft University of Technology, Jaffalaan 5, 2628 BX Delft, the Netherlands. All rights reserved.
340      * See for project information <a href="https://simulation.tudelft.nl/dsol/manual/" target="_blank">DSOL Manual</a>. The
341      * DSOL project is distributed under a three-clause BSD-style license, which can be found at
342      * <a href="https://https://simulation.tudelft.nl/dsol/docs/latest/license.html" target="_blank">DSOL License</a>.
343      * </p>
344      * @author <a href="https://www.tudelft.nl/averbraeck">Alexander Verbraeck</a>
345      */
346     public static class TimeFloatUnit extends SpeedPanel<FloatDuration>
347     {
348         /** */
349         private static final long serialVersionUID = 20201227L;
350 
351         /**
352          * Construct a clock panel with a djutils Duration.
353          * @param simulator SimulatorInterface; the simulator
354          */
355         public TimeFloatUnit(final SimulatorInterface<FloatDuration> simulator)
356         {
357             super(simulator);
358             setPrevSimTime(FloatDuration.ZERO);
359         }
360 
361         /** {@inheritDoc} */
362         @Override
363         protected String formatSpeed(final FloatDuration simulationTime)
364         {
365             if (simulationTime == null)
366             {
367                 return "0.0";
368             }
369             double speed = (simulationTime.si - getPrevSimTime().si) / (0.001 * getUpdateIntervalMs());
370             setPrevSimTime(simulationTime);
371             return String.format("%6.2f x ", speed);
372         }
373     }
374 
375 }