1 /** ************************************************************************* */ 2 // Eclipse SUMO, LisumSimulation of Urban MObility; see https://eclipse.org/sumo 3 // Copyright (C) 2016-2018 German Aerospace Center (DLR) and others. 4 // This program and the accompanying materials 5 // are made available under the terms of the Eclipse Public License v2.0 6 // which accompanies this distribution, and is available at 7 // http://www.eclipse.org/legal/epl-v20.html 8 // SPDX-License-Identifier: EPL-2.0 9 /** ************************************************************************* */ 10 /// @file Constants.java 11 /// @author Maximiliano Bottazzi 12 /// @date 2016 13 /// @version $Id$ 14 /// 15 // 16 /** ************************************************************************* */ 17 package de.dlr.ts.lisum.gui; 18 19 import de.dlr.ts.commons.javafx.messages.ConfirmationMessage; 20 import de.dlr.ts.commons.javafx.messages.ExceptionMessage; 21 import de.dlr.ts.commons.javafx.messages.InformationMessage; 22 import de.dlr.ts.commons.logger.DLRLogger; 23 import de.dlr.ts.lisum.simulation.LisumSimulation; 24 import de.dlr.ts.lisum.exceptions.LisumException; 25 import de.dlr.ts.lisum.gui.options.LisaControlUnitPreferences; 26 import de.dlr.ts.lisum.gui.options.SystemPreferencesWindow; 27 import de.dlr.ts.lisum.gui.options.WorkspaceWindow; 28 import java.io.File; 29 import java.util.ArrayList; 30 import java.util.List; 31 import java.util.Optional; 32 import javafx.event.EventHandler; 33 import javafx.scene.control.Alert; 34 import javafx.scene.control.Button; 35 import javafx.scene.control.ButtonType; 36 import javafx.scene.control.MenuItem; 37 import javafx.stage.FileChooser; 38 import javafx.stage.Modality; 39 import javafx.stage.Stage; 40 import javafx.stage.WindowEvent; 41 42 /** 43 * 44 * @author @author <a href="mailto:maximiliano.bottazzi@dlr.de">Maximiliano 45 * Bottazzi</a> 46 */ 47 public class Actions { 48 49 private static final Actions INSTANCE = new Actions(); 50 private final List<EventHandler> onCloseListeners = new ArrayList<>(); 51 52 /** 53 * 54 * @return 55 */ getInstance()56 public static Actions getInstance() { 57 return INSTANCE; 58 } 59 60 /** 61 * 62 * @param eventHandler 63 */ addOnCloseListener(EventHandler eventHandler)64 public void addOnCloseListener(EventHandler eventHandler) { 65 onCloseListeners.add(eventHandler); 66 } 67 68 /** 69 * 70 */ openLastSimulation()71 public void openLastSimulation() { 72 SystemProperties.getInstance().setCurrentSimulation(null); 73 74 MenuItem[] lastOpenFiles = MainProgram.getInstance().getMenuAdmin().getMainMenuBar().getFileMenu().getLastOpenFiles(); 75 76 if (lastOpenFiles != null && lastOpenFiles.length > 0) { 77 File selectedFile = new File(lastOpenFiles[0].getText()); 78 openSimulation(selectedFile); 79 } else { 80 InformationMessage im = new InformationMessage("List of recent opened files is empty."); 81 im.show(); 82 } 83 } 84 85 /** 86 * 87 * @return 88 */ openSimulationSelectingFile()89 public File openSimulationSelectingFile() { 90 SystemProperties.getInstance().setCurrentSimulation(null); 91 92 //DirectoryChooser dch = new DirectoryChooser(); 93 FileChooser fch = new FileChooser(); 94 fch.setTitle("Select simulation file"); 95 FileChooser.ExtensionFilter extf = new FileChooser.ExtensionFilter("LiSuM Config File", "lisum.xml"); 96 fch.getExtensionFilters().add(extf); 97 98 File file = new File(GlobalConfig.getInstance().getWorkspace()); 99 if (!file.exists()) { 100 file.mkdirs(); 101 } 102 103 fch.setInitialDirectory(file); 104 105 File selectedFile = fch.showOpenDialog(MainProgram.getInstance().getScene().getWindow()); 106 openSimulation(selectedFile); 107 108 return selectedFile; 109 } 110 111 /** 112 * 113 * @param selectedFile 114 */ openSimulation(File selectedFile)115 public void openSimulation(File selectedFile) { 116 if (selectedFile != null && selectedFile.exists()) { 117 try { 118 DLRLogger.info(this, "Opening simulation " + selectedFile.getAbsolutePath()); 119 120 GlobalConfig g = GlobalConfig.getInstance(); 121 122 LisumSimulation simulation = new LisumSimulation(g.getSumoExec(), g.getSumoPort(), 123 g.getLisaServerAddress(), g.getLisaServerPort()); 124 simulation.load(selectedFile); 125 126 SystemProperties.getInstance().setCurrentSimulation(simulation); 127 } catch (LisumException ex) { 128 ExceptionMessage em = new ExceptionMessage(null, "Error reading configuration file", ex); 129 em.show(); 130 //DLRLogger.severe(this, ex); 131 } catch (Exception ex) { 132 DLRLogger.severe(this, ex); 133 //Actions.getInstance().lisaServerNotFoundMessage(); 134 } 135 } 136 } 137 138 /** 139 * 140 */ openControlUnitPreferences()141 public void openControlUnitPreferences() { 142 LisaControlUnitPreferences.justDoIt(); 143 } 144 145 /** 146 * 147 */ closeCurrentproject()148 public void closeCurrentproject() { 149 LisumSimulation cs = SystemProperties.getInstance().getCurrentSimulation(); 150 if (cs != null) { 151 DLRLogger.info("Actions", "Closing simulation " + cs.getSimulationFiles().getSimulationDirectory()); 152 } 153 154 SystemProperties.getInstance().setCurrentSimulation(null); 155 } 156 157 /** 158 * 159 */ lisaServerNotFoundMessage()160 private void lisaServerNotFoundMessage() { 161 GlobalConfig g = GlobalConfig.getInstance(); 162 String dd = g.getLisaServerAddress() + ":" + g.getLisaServerPort(); 163 164 ConfirmationMessage cm = new ConfirmationMessage("Do you want to start a new instance?"); 165 cm.setHeader("No Lisa+ RESTful Server could be found in " + dd); 166 Optional<ButtonType> result = cm.showAndWait(); 167 168 if (result.get() == ButtonType.OK) { 169 Tools.startLisaRESTfulServer(g.getLisaRESTfulServerPath(), g.getLisaServerPort()); 170 } 171 } 172 173 /** 174 * 175 */ noSumoExecMessage()176 private void noSumoExecMessage() { 177 ConfirmationMessage cm = new ConfirmationMessage("Do you want to fix this now?"); 178 cm.setHeader("No SumoGUI executable could be found."); 179 Optional<ButtonType> result = cm.showAndWait(); 180 181 if (result.get() == ButtonType.OK) { 182 new SystemPreferencesWindow().show(1); 183 } 184 } 185 186 /** 187 * 188 */ execCurrentSimulation()189 public void execCurrentSimulation() { 190 191 String sumoExec = GlobalConfig.getInstance().getSumoExec(); 192 193 if (sumoExec.isEmpty()) { 194 noSumoExecMessage(); 195 return; 196 } 197 198 /** 199 * Init before play 200 */ 201 LisumSimulation.InitBeforePlayResponse initBeforePlay = SystemProperties.getInstance().getCurrentSimulation().initBeforePlay(); 202 203 if (initBeforePlay == LisumSimulation.InitBeforePlayResponse.LisaRESTfulServerNotFound) { 204 Actions.getInstance().lisaServerNotFoundMessage(); 205 } else { 206 Runnable r = SystemProperties.getInstance().getCurrentSimulation().getRunnable(); 207 Thread worker = new Thread(r); 208 worker.start(); 209 210 Thread thread = new Thread(() 211 -> { 212 try { 213 worker.join(); 214 215 SystemProperties.getInstance().simulationStartedProperty().set(false); 216 } catch (InterruptedException ex) { 217 ex.printStackTrace(System.out); 218 } 219 }); 220 thread.start(); 221 222 SystemProperties.getInstance().simulationStartedProperty().set(true); 223 } 224 } 225 226 /** 227 * 228 * @return True if workspace changed 229 */ switchWorkspace()230 public boolean switchWorkspace() { 231 File workspace = WorkspaceWindow.getWorkspace(); 232 new WorkspaceWindow().show(MainProgram.getInstance().getScene().getWindow()); 233 234 boolean aa = WorkspaceWindow.getWorkspace().compareTo(workspace) != 0; 235 236 if (aa) { 237 GlobalConfig.getInstance().setWorkspace(WorkspaceWindow.getWorkspace().getAbsolutePath()); 238 } 239 240 return aa; 241 } 242 243 /** 244 * 245 * @param event 246 * @param stage 247 */ exitSystem(WindowEvent event, Stage stage)248 public void exitSystem(WindowEvent event, Stage stage) { 249 if (SystemProperties.getInstance().simulationStartedProperty().get()) { 250 StringBuilder sb = new StringBuilder("A simulation is currently running.").append("\n"); 251 sb.append("Do you really want to exit?"); 252 253 ConfirmationMessage cm = new ConfirmationMessage(sb.toString()); 254 255 Optional<ButtonType> showAndWait = cm.showAndWait(); 256 257 if (event == null) { 258 if (showAndWait.get() == ButtonType.OK) { 259 for (EventHandler onCloseListener : onCloseListeners) { 260 onCloseListener.handle(null); 261 } 262 263 closeCurrentproject(); 264 GlobalConfig.getInstance().saveProps(); 265 event.consume(); 266 } 267 } else { 268 if (showAndWait.get() == ButtonType.CANCEL) { 269 event.consume(); 270 } else { 271 closeCurrentproject(); 272 GlobalConfig.getInstance().saveProps(); 273 } 274 } 275 } else { 276 Alert closeConfirmation = new Alert(Alert.AlertType.CONFIRMATION, ""); 277 closeConfirmation.setTitle(SystemProperties.getInstance().getSystemName()); 278 279 Button exitButton = (Button) closeConfirmation.getDialogPane().lookupButton(ButtonType.OK); 280 exitButton.setText("Exit"); 281 282 Button cancelButton = (Button) closeConfirmation.getDialogPane().lookupButton(ButtonType.CANCEL); 283 cancelButton.setText("Cancel"); 284 285 closeConfirmation.setHeaderText("Are you sure you want to exit?"); 286 closeConfirmation.initModality(Modality.APPLICATION_MODAL); 287 closeConfirmation.initOwner(stage); 288 289 Optional<ButtonType> closeResponse = closeConfirmation.showAndWait(); 290 if (!ButtonType.OK.equals(closeResponse.get())) { 291 event.consume(); 292 } else { 293 closeCurrentproject(); 294 GlobalConfig.getInstance().saveProps(); 295 } 296 } 297 } 298 } 299