001package jmri.jmrit.operations.trains.gui; 002 003import java.awt.Color; 004import java.awt.Dimension; 005import java.util.List; 006import java.util.ResourceBundle; 007 008import javax.swing.*; 009 010import jmri.InstanceManager; 011import jmri.jmrit.operations.OperationsFrame; 012import jmri.jmrit.operations.OperationsXml; 013import jmri.jmrit.operations.automation.gui.AutomationsTableFrameAction; 014import jmri.jmrit.operations.locations.Location; 015import jmri.jmrit.operations.locations.LocationManager; 016import jmri.jmrit.operations.setup.Control; 017import jmri.jmrit.operations.setup.Setup; 018import jmri.jmrit.operations.setup.backup.AutoSave; 019import jmri.jmrit.operations.setup.gui.*; 020import jmri.jmrit.operations.trains.Train; 021import jmri.jmrit.operations.trains.TrainManager; 022import jmri.jmrit.operations.trains.excel.SetupExcelProgramFrameAction; 023import jmri.jmrit.operations.trains.excel.TrainCustomManifest; 024import jmri.jmrit.operations.trains.schedules.*; 025import jmri.jmrit.operations.trains.tools.*; 026import jmri.swing.JTablePersistenceManager; 027import jmri.util.swing.JmriJOptionPane; 028 029/** 030 * Frame for adding and editing the train roster for operations. 031 * 032 * @author Bob Jacobsen Copyright (C) 2001 033 * @author Daniel Boudreau Copyright (C) 2008, 2009, 2010, 2011, 2012, 2013, 034 * 2014 035 */ 036public class TrainsTableFrame extends OperationsFrame implements java.beans.PropertyChangeListener { 037 038 public static final String MOVE = Bundle.getMessage("Move"); 039 public static final String TERMINATE = Bundle.getMessage("Terminate"); 040 public static final String RESET = Bundle.getMessage("Reset"); 041 public static final String CONDUCTOR = Bundle.getMessage("Conductor"); 042 043 TrainManager trainManager = InstanceManager.getDefault(TrainManager.class); 044 LocationManager locationManager = InstanceManager.getDefault(LocationManager.class); 045 046 public TrainsTableModel trainsModel; 047 JTable trainsTable; 048 JScrollPane trainsPane; 049 050 // labels 051 JLabel numTrains = new JLabel(); 052 JLabel textTrains = new JLabel(Bundle.getMessage("trains")); 053 JLabel textSep1 = new JLabel(" "); 054 055 // radio buttons 056 JRadioButton showTime = new JRadioButton(Bundle.getMessage("Time")); 057 JRadioButton showId = new JRadioButton(Bundle.getMessage("Id")); 058 059 JRadioButton moveRB = new JRadioButton(MOVE); 060 JRadioButton terminateRB = new JRadioButton(TERMINATE); 061 JRadioButton resetRB = new JRadioButton(RESET); 062 JRadioButton conductorRB = new JRadioButton(CONDUCTOR); 063 064 // major buttons 065 JButton addButton = new JButton(Bundle.getMessage("AddTrain")); 066 JButton buildButton = new JButton(Bundle.getMessage("Build")); 067 JButton printButton = new JButton(Bundle.getMessage("Print")); 068 JButton openFileButton = new JButton(Bundle.getMessage("OpenFile")); 069 JButton runFileButton = new JButton(Bundle.getMessage("RunFile")); 070 JButton switchListsButton = new JButton(Bundle.getMessage("SwitchLists")); 071 JButton terminateButton = new JButton(Bundle.getMessage("Terminate")); 072 JButton resetButton = new JButton(Bundle.getMessage("Reset")); 073 JButton saveButton = new JButton(Bundle.getMessage("SaveBuilds")); 074 075 // check boxes 076 JCheckBox buildMsgBox = new JCheckBox(Bundle.getMessage("BuildMessages")); 077 JCheckBox buildReportBox = new JCheckBox(Bundle.getMessage("BuildReport")); 078 JCheckBox printPreviewBox = new JCheckBox(Bundle.getMessage("Preview")); 079 JCheckBox openFileBox = new JCheckBox(Bundle.getMessage("OpenFile")); 080 JCheckBox runFileBox = new JCheckBox(Bundle.getMessage("RunFile")); 081 public JCheckBox showAllBox = new JCheckBox(Bundle.getMessage("ShowAllTrains")); 082 083 public TrainsTableFrame() { 084 super(); 085 086 updateTitle(); 087 088 // create ShutDownTasks 089 createShutDownTask(); 090 // always check for dirty operations files 091 setModifiedFlag(true); 092 093 // general GUI configuration 094 getContentPane().setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS)); 095 096 // Set up the jtable in a Scroll Pane.. 097 trainsModel = new TrainsTableModel(); 098 trainsTable = new JTable(trainsModel); 099 trainsPane = new JScrollPane(trainsTable); 100 trainsModel.initTable(trainsTable, this); 101 102 // Set up the control panel 103 // row 1 104 JPanel cp1 = new JPanel(); 105 cp1.setLayout(new BoxLayout(cp1, BoxLayout.X_AXIS)); 106 107 JPanel show = new JPanel(); 108 show.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("ShowClickToSort"))); 109 show.add(showTime); 110 show.add(showId); 111 112 JPanel build = new JPanel(); 113 build.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("Build"))); 114 build.add(showAllBox); 115 116 JPanel function = new JPanel(); 117 function.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("Function"))); 118 function.add(printPreviewBox); 119 function.add(openFileBox); 120 function.add(runFileBox); 121 122 JPanel options = new JPanel(); 123 options.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("Options"))); 124 options.add(buildMsgBox); 125 options.add(buildReportBox); 126 127 JPanel action = new JPanel(); 128 action.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("Action"))); 129 action.add(moveRB); 130 action.add(conductorRB); 131 action.add(terminateRB); 132 action.add(resetRB); 133 134 cp1.add(show); 135 cp1.add(build); 136 cp1.add(function); 137 cp1.add(options); 138 cp1.add(action); 139 140 // tool tips, see setPrintButtonText() for more tool tips 141 addButton.setToolTipText(Bundle.getMessage("AddTrainTip")); 142 buildButton.setToolTipText(Bundle.getMessage("BuildSelectedTip")); 143 switchListsButton.setToolTipText(Bundle.getMessage("PreviewPrintSwitchListsTip")); 144 terminateButton.setToolTipText(Bundle.getMessage("TerminateSelectedTip")); 145 resetButton.setToolTipText(Bundle.getMessage("ResetTrainsTip")); 146 saveButton.setToolTipText(Bundle.getMessage("SaveBuildsTip")); 147 openFileButton.setToolTipText(Bundle.getMessage("OpenFileButtonTip")); 148 runFileButton.setToolTipText(Bundle.getMessage("RunFileButtonTip")); 149 buildMsgBox.setToolTipText(Bundle.getMessage("BuildMessagesTip")); 150 printPreviewBox.setToolTipText(Bundle.getMessage("PreviewTip")); 151 openFileBox.setToolTipText(Bundle.getMessage("OpenFileTip")); 152 runFileBox.setToolTipText(Bundle.getMessage("RunFileTip")); 153 showAllBox.setToolTipText(Bundle.getMessage("ShowAllTrainsTip")); 154 155 moveRB.setToolTipText(Bundle.getMessage("MoveTip")); 156 terminateRB.setToolTipText(Bundle.getMessage("TerminateTip")); 157 resetRB.setToolTipText(Bundle.getMessage("ResetTip")); 158 conductorRB.setToolTipText(Bundle.getMessage("ConductorTip")); 159 160 // row 2 161 JPanel addTrain = new JPanel(); 162 addTrain.setBorder(BorderFactory.createTitledBorder("")); 163 addTrain.add(numTrains); 164 addTrain.add(textTrains); 165 addTrain.add(textSep1); 166 addTrain.add(addButton); 167 168 numTrains.setText(Integer.toString(trainManager.getNumEntries())); 169 170 JPanel select = new JPanel(); 171 select.setBorder(BorderFactory.createTitledBorder("")); 172 select.add(buildButton); 173 select.add(printButton); 174 select.add(openFileButton); 175 select.add(runFileButton); 176 select.add(switchListsButton); 177 select.add(terminateButton); 178 select.add(resetButton); 179 180 JPanel save = new JPanel(); 181 save.setBorder(BorderFactory.createTitledBorder("")); 182 save.add(saveButton); 183 184 JPanel cp2 = new JPanel(); 185 cp2.setLayout(new BoxLayout(cp2, BoxLayout.X_AXIS)); 186 cp2.add(addTrain); 187 cp2.add(select); 188 cp2.add(save); 189 190 // place controls in scroll pane 191 JPanel controlPanel = new JPanel(); 192 controlPanel.setLayout(new BoxLayout(controlPanel, BoxLayout.Y_AXIS)); 193 controlPanel.add(cp1); 194 controlPanel.add(cp2); 195 196 JScrollPane controlPane = new JScrollPane(controlPanel); 197 198 getContentPane().add(trainsPane); 199 getContentPane().add(controlPane); 200 201 // setup buttons 202 addButtonAction(addButton); 203 addButtonAction(buildButton); 204 addButtonAction(printButton); 205 addButtonAction(openFileButton); 206 addButtonAction(runFileButton); 207 addButtonAction(switchListsButton); 208 addButtonAction(terminateButton); 209 addButtonAction(resetButton); 210 addButtonAction(saveButton); 211 212 ButtonGroup showGroup = new ButtonGroup(); 213 showGroup.add(showTime); 214 showGroup.add(showId); 215 showTime.setSelected(true); 216 217 ButtonGroup actionGroup = new ButtonGroup(); 218 actionGroup.add(moveRB); 219 actionGroup.add(conductorRB); 220 actionGroup.add(terminateRB); 221 actionGroup.add(resetRB); 222 223 addRadioButtonAction(showTime); 224 addRadioButtonAction(showId); 225 226 addRadioButtonAction(moveRB); 227 addRadioButtonAction(terminateRB); 228 addRadioButtonAction(resetRB); 229 addRadioButtonAction(conductorRB); 230 231 buildMsgBox.setSelected(trainManager.isBuildMessagesEnabled()); 232 buildReportBox.setSelected(trainManager.isBuildReportEnabled()); 233 printPreviewBox.setSelected(trainManager.isPrintPreviewEnabled()); 234 openFileBox.setSelected(trainManager.isOpenFileEnabled()); 235 runFileBox.setSelected(trainManager.isRunFileEnabled()); 236 showAllBox.setSelected(trainsModel.isShowAll()); 237 238 // show open files only if create csv is enabled 239 updateRunAndOpenButtons(); 240 241 addCheckBoxAction(buildMsgBox); 242 addCheckBoxAction(buildReportBox); 243 addCheckBoxAction(printPreviewBox); 244 addCheckBoxAction(showAllBox); 245 addCheckBoxAction(openFileBox); 246 addCheckBoxAction(runFileBox); 247 248 // Set the button text to Print or Preview 249 setPrintButtonText(); 250 // Set the train action button text to Move or Terminate 251 setTrainActionButton(); 252 253 // build menu 254 JMenuBar menuBar = new JMenuBar(); 255 JMenu toolMenu = new JMenu(Bundle.getMessage("MenuTools")); 256 toolMenu.add(new OptionAction()); 257 toolMenu.add(new PrintOptionAction()); 258 toolMenu.add(new BuildReportOptionAction()); 259 toolMenu.addSeparator(); 260 toolMenu.add(new TrainsScheduleAction()); 261 toolMenu.addSeparator(); 262 toolMenu.add(new TrainsByCarTypeAction()); 263 toolMenu.add(new TrainByCarTypeAction(null)); 264 toolMenu.addSeparator(); 265 toolMenu.add(new ChangeDepartureTimesAction()); 266 toolMenu.add(new TrainsTableSetColorAction()); 267 toolMenu.add(new TrainCopyAction()); 268 toolMenu.addSeparator(); 269 toolMenu.add(new TrainsScriptAction(this)); 270 toolMenu.add(new AutomationsTableFrameAction()); 271 toolMenu.add(new SetupExcelProgramFrameAction()); 272 toolMenu.addSeparator(); 273 toolMenu.add(new ExportTrainRosterAction()); 274 toolMenu.add(new ExportTimetableAction()); 275 toolMenu.add(new ExportTrainLineupsAction()); 276 toolMenu.addSeparator(); 277 toolMenu.add(new PrintTrainsAction(false, this)); 278 toolMenu.add(new PrintTrainsAction(true, this)); 279 toolMenu.add(new PrintSavedTrainManifestAction(false, null)); 280 toolMenu.add(new PrintSavedTrainManifestAction(true, null)); 281 282 menuBar.add(toolMenu); 283 menuBar.add(new jmri.jmrit.operations.OperationsMenu()); 284 setJMenuBar(menuBar); 285 286 // add help menu to window 287 addHelpMenu("package.jmri.jmrit.operations.Operations_Trains", true); // NOI18N 288 289 initMinimumSize(new Dimension(Control.panelWidth700, Control.panelHeight250)); 290 291 addHorizontalScrollBarKludgeFix(controlPane, controlPanel); 292 293 // listen for train schedule changes 294 InstanceManager.getDefault(TrainScheduleManager.class).addPropertyChangeListener(this); 295 // listen for changes in the number of trains 296 trainManager.addPropertyChangeListener(this); 297 Setup.getDefault().addPropertyChangeListener(this); 298 // listen for location switch list changes 299 addPropertyChangeLocations(); 300 301 // now load train icons on panels 302 trainManager.loadTrainIcons(); 303 304 // auto save 305 AutoSave.start(); 306 } 307 308 @Override 309 public void radioButtonActionPerformed(java.awt.event.ActionEvent ae) { 310 log.debug("radio button activated"); 311 // clear any sorts by column 312 clearTableSort(trainsTable); 313 if (ae.getSource() == showId) { 314 trainsModel.setSort(trainsModel.SORTBYID); 315 } 316 if (ae.getSource() == showTime) { 317 trainsModel.setSort(trainsModel.SORTBYTIME); 318 } 319 if (ae.getSource() == moveRB) { 320 trainManager.setTrainsFrameTrainAction(MOVE); 321 } 322 if (ae.getSource() == terminateRB) { 323 trainManager.setTrainsFrameTrainAction(TERMINATE); 324 } 325 if (ae.getSource() == resetRB) { 326 trainManager.setTrainsFrameTrainAction(RESET); 327 } 328 if (ae.getSource() == conductorRB) { 329 trainManager.setTrainsFrameTrainAction(CONDUCTOR); 330 } 331 } 332 333 TrainSwitchListEditFrame tslef; 334 335 // add, build, print, switch lists, terminate, and save buttons 336 @Override 337 public void buttonActionPerformed(java.awt.event.ActionEvent ae) { 338 // log.debug("train button activated"); 339 if (ae.getSource() == addButton) { 340 new TrainEditFrame(null); 341 } 342 if (ae.getSource() == buildButton) { 343 runFileButton.setEnabled(false); 344 // uses a thread which allows table updates during build 345 trainManager.buildSelectedTrains(getSortByList()); 346 } 347 if (ae.getSource() == printButton) { 348 trainManager.printSelectedTrains(getSortByList()); 349 } 350 if (ae.getSource() == openFileButton) { 351 openFile(); 352 } 353 if (ae.getSource() == runFileButton) { 354 runExcel(); 355 } 356 if (ae.getSource() == switchListsButton) { 357 if (tslef != null) { 358 tslef.dispose(); 359 } 360 tslef = new TrainSwitchListEditFrame(); 361 tslef.initComponents(); 362 } 363 if (ae.getSource() == terminateButton) { 364 trainManager.terminateSelectedTrains(getSortByList()); 365 } 366 if (ae.getSource() == resetButton) { 367 trainManager.resetTrains(); 368 } 369 if (ae.getSource() == saveButton) { 370 storeValues(); 371 } 372 } 373 374 private void openFile() { 375 // open the csv files 376 List<Train> trains = getSortByList(); 377 for (Train train : trains) { 378 if (train.isBuildEnabled()) { 379 if (!train.isBuilt() && trainManager.isBuildMessagesEnabled()) { 380 int response = JmriJOptionPane.showConfirmDialog(this, 381 Bundle.getMessage("NeedToBuildBeforeOpenFile", 382 train.getName()), 383 Bundle.getMessage("ErrorTitle"), JmriJOptionPane.OK_CANCEL_OPTION); 384 if (response != JmriJOptionPane.OK_OPTION) { 385 break; 386 } 387 } else if (train.isBuilt()) { 388 train.openFile(); 389 } 390 } 391 } 392 } 393 394 private void runExcel() { 395 // Run on thread since addCsvFile(file) can wait for excel program to complete 396 Thread runExcel = jmri.util.ThreadingUtil.newThread(() -> { 397 // Processes the CSV Manifest files using an external custom program. 398 TrainCustomManifest tcm = InstanceManager.getDefault(TrainCustomManifest.class); 399 if (!tcm.doesExcelFileExist()) { 400 log.warn("Manifest creator file not found!, directory path: {}, file name: {}", 401 tcm.getDirectoryPathName(), 402 tcm.getFileName()); 403 JmriJOptionPane.showMessageDialog(this, 404 Bundle.getMessage("LoadDirectoryNameFileName", 405 tcm.getDirectoryPathName(), tcm.getFileName()), 406 Bundle.getMessage("ManifestCreatorNotFound"), JmriJOptionPane.ERROR_MESSAGE); 407 return; 408 } 409 List<Train> trains = getSortByList(); 410 for (Train train : trains) { 411 if (train.isBuildEnabled()) { 412 if (!train.isBuilt() && trainManager.isBuildMessagesEnabled()) { 413 int response = JmriJOptionPane.showConfirmDialog(this, 414 Bundle.getMessage("NeedToBuildBeforeRunFile", 415 train.getName()), 416 Bundle.getMessage("ErrorTitle"), JmriJOptionPane.OK_CANCEL_OPTION); 417 if (response != JmriJOptionPane.OK_OPTION) { 418 break; 419 } 420 } else if (train.isBuilt()) { 421 // Add csv manifest file to our collection to be processed. 422 tcm.addCsvFile(train.createCsvManifestFile()); 423 train.setPrinted(true); 424 } 425 } 426 } 427 // Now run the user specified custom Manifest processor program 428 tcm.process(); 429 }); 430 runExcel.setName("Run Excel program"); // NOI18N 431 runExcel.start(); 432 } 433 434 SortOrder _status = SortOrder.ASCENDING; 435 436 public String getSortBy() { 437 // set the defaults 438 String sortBy = TrainsTableModel.TIMECOLUMNNAME; 439 _status = SortOrder.ASCENDING; 440 // now look to see if a sort is active 441 for (RowSorter.SortKey key : trainsTable.getRowSorter().getSortKeys()) { 442 String name = trainsModel.getColumnName(key.getColumn()); 443 SortOrder status = key.getSortOrder(); 444 // log.debug("Column {} status {}", name, status); 445 if (!status.equals(SortOrder.UNSORTED) && !name.isEmpty()) { 446 sortBy = name; 447 _status = status; 448 break; 449 } 450 } 451 return sortBy; 452 } 453 454 public List<Train> getSortByList() { 455 return getSortByList(getSortBy()); 456 } 457 458 public List<Train> getSortByList(String sortBy) { 459 List<Train> sysList; 460 461 if (sortBy.equals(TrainsTableModel.IDCOLUMNNAME)) { 462 sysList = trainManager.getTrainsByIdList(); 463 } else if (sortBy.equals(TrainsTableModel.TIMECOLUMNNAME)) { 464 sysList = trainManager.getTrainsByTimeList(); 465 } else if (sortBy.equals(TrainsTableModel.DEPARTSCOLUMNNAME)) { 466 sysList = trainManager.getTrainsByDepartureList(); 467 } else if (sortBy.equals(TrainsTableModel.TERMINATESCOLUMNNAME)) { 468 sysList = trainManager.getTrainsByTerminatesList(); 469 } else if (sortBy.equals(TrainsTableModel.ROUTECOLUMNNAME)) { 470 sysList = trainManager.getTrainsByRouteList(); 471 } else if (sortBy.equals(TrainsTableModel.STATUSCOLUMNNAME)) { 472 sysList = trainManager.getTrainsByStatusList(); 473 } else if (sortBy.equals(TrainsTableModel.DESCRIPTIONCOLUMNNAME)) { 474 sysList = trainManager.getTrainsByDescriptionList(); 475 } else { 476 sysList = trainManager.getTrainsByNameList(); 477 } 478 return sysList; 479 } 480 481 // Modifies button text and tool tips 482 private void setPrintButtonText() { 483 if (printPreviewBox.isSelected()) { 484 printButton.setText(Bundle.getMessage("Preview")); 485 printButton.setToolTipText(Bundle.getMessage("PreviewSelectedTip")); 486 buildReportBox.setToolTipText(Bundle.getMessage("BuildReportPreviewTip")); 487 } else { 488 printButton.setText(Bundle.getMessage("Print")); 489 printButton.setToolTipText(Bundle.getMessage("PrintSelectedTip")); 490 buildReportBox.setToolTipText(Bundle.getMessage("BuildReportPrintTip")); 491 } 492 } 493 494 private void setTrainActionButton() { 495 moveRB.setSelected(trainManager.getTrainsFrameTrainAction().equals(TrainsTableFrame.MOVE)); 496 terminateRB.setSelected(trainManager.getTrainsFrameTrainAction().equals(TrainsTableFrame.TERMINATE)); 497 resetRB.setSelected(trainManager.getTrainsFrameTrainAction().equals(TrainsTableFrame.RESET)); 498 conductorRB.setSelected(trainManager.getTrainsFrameTrainAction().equals(TrainsTableFrame.CONDUCTOR)); 499 } 500 501 @Override 502 public void checkBoxActionPerformed(java.awt.event.ActionEvent ae) { 503 if (ae.getSource() == buildMsgBox) { 504 trainManager.setBuildMessagesEnabled(buildMsgBox.isSelected()); 505 } 506 if (ae.getSource() == buildReportBox) { 507 trainManager.setBuildReportEnabled(buildReportBox.isSelected()); 508 } 509 if (ae.getSource() == printPreviewBox) { 510 trainManager.setPrintPreviewEnabled(printPreviewBox.isSelected()); 511 setPrintButtonText(); // set the button text for Print or Preview 512 } 513 if (ae.getSource() == openFileBox) { 514 trainManager.setOpenFileEnabled(openFileBox.isSelected()); 515 runFileBox.setSelected(false); 516 trainManager.setRunFileEnabled(false); 517 } 518 if (ae.getSource() == runFileBox) { 519 trainManager.setRunFileEnabled(runFileBox.isSelected()); 520 openFileBox.setSelected(false); 521 trainManager.setOpenFileEnabled(false); 522 } 523 if (ae.getSource() == showAllBox) { 524 trainsModel.setShowAll(showAllBox.isSelected()); 525 } 526 } 527 528 private void updateTitle() { 529 String title = Bundle.getMessage("TitleTrainsTable"); 530 TrainSchedule sch = InstanceManager.getDefault(TrainScheduleManager.class).getActiveSchedule(); 531 if (sch != null) { 532 title = title + " " + sch.getName(); 533 } 534 setTitle(title); 535 } 536 537 private void updateSwitchListButton() { 538 List<Location> locations = locationManager.getList(); 539 for (Location location : locations) { 540 if (location != null && location.isSwitchListEnabled() && location.getStatus().equals(Location.MODIFIED)) { 541 switchListsButton.setBackground(Color.RED); 542 return; 543 } 544 } 545 switchListsButton.setBackground(Color.GREEN); 546 } 547 548 // show open files only if create csv is enabled 549 private void updateRunAndOpenButtons() { 550 openFileBox.setVisible(Setup.isGenerateCsvManifestEnabled()); 551 openFileButton.setVisible(Setup.isGenerateCsvManifestEnabled()); 552 runFileBox.setVisible(Setup.isGenerateCsvManifestEnabled()); 553 runFileButton.setVisible(Setup.isGenerateCsvManifestEnabled()); 554 } 555 556 private synchronized void addPropertyChangeLocations() { 557 List<Location> locations = locationManager.getList(); 558 for (Location location : locations) { 559 location.addPropertyChangeListener(this); 560 } 561 } 562 563 private synchronized void removePropertyChangeLocations() { 564 List<Location> locations = locationManager.getList(); 565 for (Location location : locations) { 566 location.removePropertyChangeListener(this); 567 } 568 } 569 570 @Override 571 public void dispose() { 572 trainsModel.dispose(); 573 trainManager.runShutDownScripts(); 574 trainManager.removePropertyChangeListener(this); 575 InstanceManager.getDefault(TrainScheduleManager.class).removePropertyChangeListener(this); 576 Setup.getDefault().removePropertyChangeListener(this); 577 removePropertyChangeLocations(); 578 setModifiedFlag(false); 579 InstanceManager.getOptionalDefault(JTablePersistenceManager.class).ifPresent(tpm -> { 580 tpm.stopPersisting(trainsTable); 581 }); 582 super.dispose(); 583 } 584 585 @Override 586 protected void handleModified() { 587 if (!getModifiedFlag()) { 588 return; 589 } 590 if (Setup.isAutoSaveEnabled()) { 591 storeValues(); 592 return; 593 } 594 if (OperationsXml.areFilesDirty()) { 595 int result = JmriJOptionPane.showOptionDialog(this, Bundle.getMessage("PromptQuitWindowNotWritten"), 596 Bundle.getMessage("PromptSaveQuit"), JmriJOptionPane.YES_NO_OPTION, 597 JmriJOptionPane.WARNING_MESSAGE, null, 598 new String[] { ResourceBundle.getBundle("jmri.util.UtilBundle").getString("WarnYesSave"), // NOI18N 599 ResourceBundle.getBundle("jmri.util.UtilBundle").getString("WarnNoClose") }, // NOI18N 600 ResourceBundle.getBundle("jmri.util.UtilBundle").getString("WarnYesSave")); 601 if (result == JmriJOptionPane.YES_OPTION) { 602 // user wants to save 603 storeValues(); 604 } 605 } 606 } 607 608 @Override 609 protected void storeValues() { 610 super.storeValues(); 611 } 612 613 @Override 614 public void propertyChange(java.beans.PropertyChangeEvent e) { 615 if (Control.SHOW_PROPERTY) { 616 log.debug("Property change: ({}) old: ({}) new: ({})", e.getPropertyName(), e.getOldValue(), 617 e.getNewValue()); 618 } 619 if (e.getPropertyName().equals(TrainScheduleManager.SCHEDULE_ID_CHANGED_PROPERTY)) { 620 updateTitle(); 621 } 622 if (e.getPropertyName().equals(Location.STATUS_CHANGED_PROPERTY) || 623 e.getPropertyName().equals(Location.SWITCHLIST_CHANGED_PROPERTY)) { 624 log.debug("update switch list button location ({})", e.getSource()); 625 updateSwitchListButton(); 626 } 627 if (e.getPropertyName().equals(Setup.MANIFEST_CSV_PROPERTY_CHANGE)) { 628 updateRunAndOpenButtons(); 629 } 630 if (e.getPropertyName().equals(TrainManager.LISTLENGTH_CHANGED_PROPERTY)) { 631 numTrains.setText(Integer.toString(trainManager.getNumEntries())); 632 } 633 if (e.getPropertyName().equals(TrainManager.TRAINS_BUILT_CHANGED_PROPERTY)) { 634 runFileButton.setEnabled(true); 635 } 636 } 637 638 private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(TrainsTableFrame.class); 639}