View Javadoc
1   package org.opentrafficsim.editor;
2   
3   import java.awt.Container;
4   import java.awt.Dimension;
5   import java.io.File;
6   import java.rmi.RemoteException;
7   import java.util.LinkedHashMap;
8   import java.util.Map;
9   
10  import javax.swing.Box.Filler;
11  import javax.swing.JButton;
12  import javax.swing.JMenu;
13  import javax.swing.JMenuBar;
14  
15  import org.djutils.exceptions.Try;
16  import org.opentrafficsim.animation.data.util.IconUtil;
17  import org.opentrafficsim.base.OtsRuntimeException;
18  import org.opentrafficsim.core.dsol.OtsAnimator;
19  import org.opentrafficsim.core.dsol.OtsSimulatorInterface;
20  import org.opentrafficsim.editor.OtsRunner.OtsRunnerModel;
21  import org.opentrafficsim.road.network.factory.xml.OtsXmlModel;
22  import org.opentrafficsim.swing.gui.AppearanceControlButton;
23  import org.opentrafficsim.swing.gui.OtsSimulationApplication;
24  import org.opentrafficsim.swing.gui.OtsSimulationPanel;
25  
26  import nl.tudelft.simulation.dsol.SimRuntimeException;
27  import nl.tudelft.simulation.language.DsolException;
28  
29  /**
30   * Simulation runner for when running from editor.
31   * <p>
32   * Copyright (c) 2013-2026 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
33   * BSD-style license. See <a href="https://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
34   * </p>
35   * @author Wouter Schakel
36   */
37  public class OtsRunner extends OtsSimulationApplication<OtsRunnerModel>
38  {
39  
40      /** Serialization version UID. */
41      private static final long serialVersionUID = 20231012;
42  
43      /**
44       * Run a simulation.
45       * @param panel the tabbed panel to display
46       * @param model the model
47       */
48      public OtsRunner(final OtsSimulationPanel panel, final OtsRunnerModel model)
49      {
50          // TODO colorer and markers based on user specification
51          super(model, panel);
52      }
53  
54      /**
55       * Run single run from a file.
56       * @param file XML file
57       * @param scenario scenario, may be {@code null}
58       * @param editor editor may be {@code null}
59       */
60      public static void runSingle(final File file, final String scenario, final OtsEditor editor)
61      {
62          try
63          {
64              OtsAnimator simulator = new OtsAnimator("EditorRun");
65              final OtsRunnerModel runnerModel = new OtsRunnerModel(simulator, file, scenario);
66              // TODO: add OtsSimmulationPanelDecorator with contents based on Animation tag to OtsAnimationPanel constructor
67              // TODO: simulationPanel.addConsoleTab() depending on Animation tag
68              OtsSimulationPanel simulationPanel = new OtsSimulationPanel(runnerModel.getNetwork());
69              if (editor == null)
70              {
71                  OtsRunner app = new OtsRunner(simulationPanel, runnerModel);
72                  app.setExitOnClose(false);
73              }
74              else
75              {
76                  // remember editor content and disable menus
77                  Container contentPane = editor.getContentPane();
78                  JMenuBar menuBar = editor.getJMenuBar();
79                  Map<JMenu, Boolean> wasEnabled = new LinkedHashMap<>();
80                  for (int i = 0; i < menuBar.getMenuCount(); i++)
81                  {
82                      wasEnabled.put(menuBar.getMenu(i), menuBar.getMenu(i).isEnabled());
83                      menuBar.getMenu(i).setEnabled(false);
84                  }
85  
86                  // add button to menu to return to the editor
87                  JButton backToEditor = new AppearanceControlButton(IconUtil.of("RoadLayout24.png").imageSize(16, 16).get());
88                  Filler filler = new Filler(new Dimension(0, 0), new Dimension(0, 0), new Dimension(Short.MAX_VALUE, 0));
89                  backToEditor.setText("Back to editor");
90                  backToEditor.setMinimumSize(new Dimension(130, 16));
91                  backToEditor.setPreferredSize(new Dimension(130, 16));
92                  backToEditor.addActionListener((a) ->
93                  {
94                      if (runnerModel.getNetwork().getSimulator().isStartingOrRunning())
95                      {
96                          runnerModel.getNetwork().getSimulator().stop();
97                      }
98                      Try.execute(() -> runnerModel.getNetwork().getSimulator().getContext().destroySubcontext("animation/2D"),
99                              OtsRuntimeException.class, "Unable to destroy simulation context within editor.");
100                     menuBar.remove(filler);
101                     menuBar.remove(backToEditor);
102                     for (int i = 0; i < menuBar.getMenuCount(); i++)
103                     {
104                         menuBar.getMenu(i).setEnabled(wasEnabled.get(menuBar.getMenu(i)));
105                     }
106                     editor.setContentPane(contentPane);
107                     editor.invalidate();
108                     editor.validate();
109                     editor.repaint();
110                 });
111                 menuBar.add(filler);
112                 menuBar.add(backToEditor);
113                 backToEditor.transferFocus();
114 
115                 editor.setContentPane(simulationPanel);
116                 editor.setAppearance(editor.getAppearance());
117                 editor.repaint();
118             }
119             simulationPanel.enableSimulationControlButtons();
120         }
121         catch (SimRuntimeException | RemoteException | DsolException exception)
122         {
123             exception.printStackTrace();
124         }
125     }
126 
127     /**
128      * The simulation model.
129      */
130     public static class OtsRunnerModel extends OtsXmlModel
131     {
132         /**
133          * Constructor.
134          * @param simulator simulator
135          * @param file XML file
136          * @param scenario scenario, may be {@code null}
137          */
138         public OtsRunnerModel(final OtsSimulatorInterface simulator, final File file, final String scenario)
139         {
140             super(simulator, file.toString(), scenario);
141         }
142     }
143 
144 }