SimulationConfigurator.java 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445
  1. package de.tu_darmstadt.tk.SmartHomeNetworkSim.view.popups;
  2. import java.awt.Color;
  3. import java.awt.Dimension;
  4. import java.awt.Rectangle;
  5. import java.awt.event.WindowAdapter;
  6. import java.awt.event.WindowEvent;
  7. import java.io.File;
  8. import java.util.Observable;
  9. import java.util.Observer;
  10. import javax.swing.JButton;
  11. import javax.swing.JFrame;
  12. import javax.swing.JProgressBar;
  13. import javax.swing.JSeparator;
  14. import javax.swing.JLabel;
  15. import javax.swing.JTextField;
  16. import javax.swing.event.DocumentEvent;
  17. import javax.swing.event.DocumentListener;
  18. import de.tu_darmstadt.tk.SmartHomeNetworkSim.control.Controller;
  19. import de.tu_darmstadt.tk.SmartHomeNetworkSim.control.SimulationController;
  20. import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Model;
  21. import javax.swing.JCheckBox;
  22. import javax.swing.JFileChooser;
  23. /**
  24. * Window for configuring, starting and stopping the Simulation
  25. *
  26. * @author Andreas T. Meyer-Berg
  27. */
  28. @SuppressWarnings("serial")
  29. public class SimulationConfigurator extends JFrame implements Observer{
  30. /**
  31. * Textfield for editing the start time
  32. */
  33. private JTextField tfStartTimeLong;
  34. /**
  35. * Textfield for editing the end time
  36. */
  37. private JTextField tfEndTimeLong;
  38. /**
  39. * Textfield for editing the step duration
  40. */
  41. private JTextField tfStepDuration;
  42. /**
  43. * Checkbox if packets should be printed
  44. */
  45. private JCheckBox chckbxPrintpackets;
  46. /**
  47. * Checkbox if packets should be split into different Files for each link
  48. */
  49. private JCheckBox chckbxSplitLinks;
  50. /**
  51. * Label which shows the name of the export File
  52. */
  53. private JLabel lblExportFileName;
  54. /**
  55. * Label which shows the current Time of the simulation
  56. */
  57. private JLabel lblCurrentTimeShow;
  58. /**
  59. * Button for starting/stopping the simulation
  60. */
  61. private JButton btnStartStop;
  62. /**
  63. * Button for specifying the export file
  64. */
  65. private JButton btnExportFile;
  66. /**
  67. * ProgressionBar which shows the progression. Values are between 0 and
  68. * 10000 where 0 represents the start time, and 10000 represents the end
  69. * time.
  70. */
  71. private JProgressBar progressBar;
  72. /**
  73. * Controller of the Application
  74. */
  75. private Controller controller;
  76. /**
  77. * Simulation controller
  78. */
  79. private SimulationController sim;
  80. /**
  81. * Reference to this instance for inner classes
  82. */
  83. private SimulationConfigurator that = this;
  84. /**
  85. * Mutex to disable
  86. */
  87. private boolean mutex = false;
  88. /**
  89. * Create a new SimulationConfigurator Panel, which controls the given
  90. * SimulationManager
  91. *
  92. * @param control Controller of the program
  93. */
  94. public SimulationConfigurator(Controller control) {
  95. this.controller = control;
  96. this.sim = controller.getSimulationController();
  97. sim.addObserver(this);
  98. this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
  99. this.addWindowListener(new WindowAdapter() {
  100. @Override
  101. public void windowClosing(WindowEvent e) {
  102. sim.removeObserver(that);
  103. }
  104. });
  105. this.getContentPane().setMinimumSize(new Dimension(640, 310));
  106. this.setBounds(new Rectangle(0, 0, 640, 310));
  107. setResizable(false);
  108. getContentPane().setLayout(null);
  109. this.setTitle("Simulation Configuration");
  110. /*Buttons for setting Start/End Dates
  111. * Currently not in use
  112. JButton btnChooseStartDate = new JButton("Choose Start Date");
  113. btnChooseStartDate.setBounds(12, 13, 161, 25);
  114. getContentPane().add(btnChooseStartDate);
  115. JButton btnStartTime = new JButton("Choose End Date");
  116. btnStartTime.setBounds(271, 13, 161, 25);
  117. getContentPane().add(btnStartTime);
  118. */
  119. /*******************************************************************************
  120. * Buttons and labels for simulation Configuration (start, end, duration, steps)
  121. ******************************************************************************/
  122. JLabel lblConfigureParameters = new JLabel("Change Simulation parameters:");
  123. lblConfigureParameters.setBounds(10, 10, 300, 20);
  124. getContentPane().add(lblConfigureParameters);
  125. JLabel lblStarttimeLong = new JLabel("Start Time (in ms):");
  126. lblStarttimeLong.setBounds(10, 40, 160, 20);
  127. getContentPane().add(lblStarttimeLong);
  128. tfStartTimeLong = new JTextField();
  129. tfStartTimeLong.setBounds(160, 40, 130, 20);
  130. getContentPane().add(tfStartTimeLong);
  131. tfStartTimeLong.setColumns(10);
  132. tfStartTimeLong.setText(sim.getStartTime()+"");
  133. JLabel lblEndtimeLong = new JLabel("End Time (in ms):");
  134. lblEndtimeLong.setBounds(300, 40, 160, 20);
  135. getContentPane().add(lblEndtimeLong);
  136. tfEndTimeLong = new JTextField();
  137. tfEndTimeLong.setBounds(450, 40, 130, 20);
  138. getContentPane().add(tfEndTimeLong);
  139. tfEndTimeLong.setColumns(10);
  140. JLabel lblStepDuration = new JLabel("Step Duration(in ms):");
  141. lblStepDuration.setBounds(10, 70, 160, 20);
  142. getContentPane().add(lblStepDuration);
  143. tfStepDuration = new JTextField();
  144. tfStepDuration.setBounds(160, 70, 130, 20);
  145. getContentPane().add(tfStepDuration);
  146. tfStepDuration.setColumns(10);
  147. JSeparator topSeparator = new JSeparator(JSeparator.HORIZONTAL);
  148. topSeparator.setBounds(0, 95, 660, 10);
  149. getContentPane().add(topSeparator);
  150. /*******************************************************************************
  151. * Buttons and labels for simulation Configuration (start, end, duration, steps)
  152. ******************************************************************************/
  153. JLabel lblConfigureExports = new JLabel("Configure Packet export options:");
  154. lblConfigureExports.setBounds(10, 100, 255, 20);
  155. getContentPane().add(lblConfigureExports);
  156. JButton btnEditAlgorithms = new JButton("Edit Algorithms");
  157. btnEditAlgorithms.setBounds(250, 100, 180, 20);
  158. getContentPane().add(btnEditAlgorithms);
  159. btnEditAlgorithms.setToolTipText("Edit which user defined algorithms should run during the simulation.");
  160. btnEditAlgorithms.addActionListener(a->{
  161. new EditAlgorithmsPopUp(controller, that);
  162. });
  163. chckbxPrintpackets = new JCheckBox("Save packets");
  164. chckbxPrintpackets.setBounds(10, 130, 120, 20);
  165. getContentPane().add(chckbxPrintpackets);
  166. chckbxPrintpackets
  167. .setToolTipText("Save packets as human readable Strings to the configured File");
  168. chckbxSplitLinks = new JCheckBox("Split Links");
  169. chckbxSplitLinks.setBounds(130, 130, 100, 20);
  170. getContentPane().add(chckbxSplitLinks);
  171. chckbxSplitLinks
  172. .setToolTipText("Export packets into a different file for each Link.");
  173. btnExportFile = new JButton("Choose Export File");
  174. btnExportFile.setBounds(250, 130, 180, 20);
  175. getContentPane().add(btnExportFile);
  176. lblExportFileName = new JLabel();
  177. lblExportFileName.setBounds(440, 130, 300, 20);
  178. getContentPane().add(lblExportFileName);
  179. JSeparator botSeparator = new JSeparator(JSeparator.HORIZONTAL);
  180. botSeparator.setBounds(0, 155, 660, 5);
  181. getContentPane().add(botSeparator);
  182. /*******************************************************************************
  183. * Buttons and labels for simulation Configuration (start, end, duration, steps)
  184. ******************************************************************************/
  185. JLabel lblSimulationStatus = new JLabel("Running Simulation status:");
  186. lblSimulationStatus.setBounds(10, 160, 300, 20);
  187. getContentPane().add(lblSimulationStatus);
  188. JLabel lblCurrentTime = new JLabel("Current Time:");
  189. lblCurrentTime.setBounds(10, 190, 100, 20);
  190. getContentPane().add(lblCurrentTime);
  191. lblCurrentTimeShow = new JLabel();
  192. lblCurrentTimeShow.setBounds(120, 190, 120, 20);
  193. lblCurrentTimeShow.setAlignmentX(JLabel.RIGHT_ALIGNMENT);
  194. getContentPane().add(lblCurrentTimeShow);
  195. btnStartStop = new JButton("Start Simulation");
  196. btnStartStop.setBounds(10, 220, 150, 40);
  197. getContentPane().add(btnStartStop);
  198. JButton btnReset = new JButton("Reset");
  199. btnReset.setBounds(170, 220, 150, 40);
  200. btnReset.addActionListener(a -> sim.resetSimulation());
  201. getContentPane().add(btnReset);
  202. progressBar = new JProgressBar();
  203. progressBar.setBounds(0, 260, this.getWidth(), 30);
  204. getContentPane().add(progressBar);
  205. progressBar.setMinimum(0);
  206. progressBar.setMaximum(10000);
  207. this.update(null,null);
  208. initializeListener();
  209. }
  210. /**
  211. * Test the GUI
  212. * @param args none specified
  213. */
  214. public static void main(String[] args) {
  215. SimulationConfigurator simConfig = new SimulationConfigurator(new Controller(new Model()));
  216. simConfig.setEnabled(true);
  217. simConfig.setVisible(true);
  218. //Prevent demon threads on close
  219. simConfig.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  220. }
  221. @Override
  222. public void update(Observable o, Object arg) {
  223. long currentTime = sim.getCurrentTime();
  224. long startTime = sim.getStartTime();
  225. long endTime = sim.getEndTime();
  226. long duration = sim.getStepDuration();
  227. if(!mutex){
  228. tfStartTimeLong.setText("" + startTime);
  229. tfStartTimeLong.setBackground(Color.WHITE);
  230. tfEndTimeLong.setText("" + endTime);
  231. tfEndTimeLong.setBackground(Color.WHITE);
  232. tfStepDuration.setText("" + duration);
  233. tfStepDuration.setBackground(Color.WHITE);
  234. }
  235. chckbxPrintpackets.setSelected(sim.getPrintPackets());
  236. chckbxSplitLinks.setSelected(sim.isSplitLinkExportFiles());
  237. lblExportFileName.setText(sim.getExportFile().getName());
  238. lblExportFileName.setToolTipText("Path: "+sim.getExportFile().getPath());
  239. lblCurrentTimeShow.setText(currentTime+" ms");
  240. if(endTime!=startTime)
  241. progressBar.setValue((int) ((currentTime - startTime) * 10000 / (endTime - startTime)));
  242. else
  243. progressBar.setValue(10000);
  244. //Prevent manipulation of parameters during simulation
  245. tfStartTimeLong.setEditable(!sim.isRunning());
  246. tfEndTimeLong.setEditable(!sim.isRunning());
  247. tfStepDuration.setEditable(!sim.isRunning());
  248. //Change Button Text
  249. if (sim.isRunning()) {
  250. btnStartStop.setText("Stop Simulation");
  251. } else if(sim.getCurrentTime()<sim.getEndTime()){
  252. btnStartStop.setText("Start Simulation");
  253. } else{
  254. btnStartStop.setText("Restart Simulation");
  255. }
  256. mutex = false;
  257. }
  258. /**
  259. * Add listeners to the different Textfields, Buttons etc.
  260. */
  261. private void initializeListener(){
  262. /**
  263. * Start Time listener
  264. */
  265. tfStartTimeLong.getDocument().addDocumentListener(new DocumentListener() {
  266. @Override
  267. public void removeUpdate(DocumentEvent e) {update(e);}
  268. @Override
  269. public void insertUpdate(DocumentEvent e) {update(e);}
  270. @Override
  271. public void changedUpdate(DocumentEvent e) {update(e);}
  272. private void update(DocumentEvent e){
  273. if(mutex)return;//Skip if document change in progress
  274. try{
  275. /**
  276. * Parsed Long
  277. */
  278. long l = Long.parseLong(tfStartTimeLong.getText());
  279. if(!sim.isRunning()){
  280. /**
  281. * Set Mutex, to disable document change
  282. */
  283. mutex = true;
  284. try{
  285. /**
  286. * Catch InvalidStateException, change startTime
  287. */
  288. sim.setStartTime(l);
  289. }catch(Exception e1){}
  290. mutex = false;
  291. tfStartTimeLong.setBackground(Color.WHITE);
  292. return;
  293. }
  294. tfStartTimeLong.setBackground(Color.WHITE);
  295. }catch(Exception e1){
  296. /**
  297. * Invalid Long -> Red Background
  298. */
  299. tfStartTimeLong.setBackground(Color.RED);
  300. }
  301. }
  302. });
  303. /**
  304. * End time listener
  305. */
  306. tfEndTimeLong.getDocument().addDocumentListener(new DocumentListener() {
  307. @Override
  308. public void removeUpdate(DocumentEvent e) {update(e);}
  309. @Override
  310. public void insertUpdate(DocumentEvent e) {update(e);}
  311. @Override
  312. public void changedUpdate(DocumentEvent e) {update(e);}
  313. private void update(DocumentEvent e){
  314. if(mutex)return;
  315. try{
  316. long l = Long.parseLong(tfEndTimeLong.getText());
  317. if(!sim.isRunning()){
  318. mutex = true;
  319. try{
  320. sim.setEndTime(l);
  321. }catch(Exception e1){}
  322. mutex = false;
  323. tfEndTimeLong.setBackground(Color.WHITE);
  324. return;
  325. }
  326. tfEndTimeLong.setBackground(Color.WHITE);
  327. }catch(Exception e1){
  328. tfEndTimeLong.setBackground(Color.RED);
  329. }
  330. }
  331. });
  332. /**
  333. * Step duration listener
  334. */
  335. tfStepDuration.getDocument().addDocumentListener(new DocumentListener() {
  336. @Override
  337. public void removeUpdate(DocumentEvent e) {update(e);}
  338. @Override
  339. public void insertUpdate(DocumentEvent e) {update(e);}
  340. @Override
  341. public void changedUpdate(DocumentEvent e) {update(e);}
  342. private void update(DocumentEvent e){
  343. if(mutex)return;
  344. try{
  345. long l = Long.parseLong(tfStepDuration.getText());
  346. if(l<=0)throw new NumberFormatException("Duration shall not be negative");
  347. if(!sim.isRunning()){
  348. mutex = true;
  349. try{
  350. sim.setStepDuration(l);
  351. }catch(Exception e1){}
  352. mutex = false;
  353. tfStepDuration.setBackground(Color.WHITE);
  354. return;
  355. }
  356. tfStepDuration.setBackground(Color.WHITE);
  357. }catch(Exception e1){
  358. tfStepDuration.setBackground(Color.RED);
  359. }
  360. }
  361. });
  362. /**
  363. * Start Stop listener
  364. */
  365. btnStartStop.addActionListener(a -> {
  366. if(sim.isRunning()){
  367. sim.stopSimulation();
  368. }else{
  369. if(sim.getCurrentTime()>=sim.getEndTime()){
  370. //Reset
  371. sim.resetSimulation();
  372. }
  373. sim.startSimulation();
  374. }
  375. });
  376. chckbxPrintpackets.addActionListener(l -> sim.setPrintPackets(chckbxPrintpackets.isSelected()));
  377. chckbxSplitLinks.addActionListener(l -> sim.setSplitLinkExportFiles(chckbxSplitLinks.isSelected()));
  378. /**
  379. * Export location:
  380. */
  381. btnExportFile.addActionListener(a->{
  382. /**
  383. * Open FileChooser, starting from the last File
  384. */
  385. JFileChooser fc = new JFileChooser(sim.getExportFile());
  386. /**
  387. * If File selected
  388. */
  389. if (fc.showSaveDialog(that.getParent()) == JFileChooser.APPROVE_OPTION) {
  390. /**
  391. * and not null -> import
  392. */
  393. File file = fc.getSelectedFile();
  394. if(file!=null)sim.setExportFile(file);
  395. }
  396. });
  397. }
  398. }