001package jmri.jmrit.operations.trains; 002 003import java.awt.Dimension; 004import java.awt.GridBagLayout; 005import java.awt.event.ActionEvent; 006import java.beans.PropertyChangeEvent; 007import java.io.File; 008import java.util.ArrayList; 009import java.util.List; 010 011import javax.swing.*; 012import javax.swing.filechooser.FileNameExtensionFilter; 013 014import jmri.InstanceManager; 015import jmri.jmrit.operations.*; 016import jmri.jmrit.operations.locations.Location; 017import jmri.jmrit.operations.locations.LocationManager; 018import jmri.jmrit.operations.setup.Control; 019import jmri.jmrit.operations.setup.Setup; 020import jmri.jmrit.operations.trains.excel.SetupExcelProgramSwitchListFrameAction; 021import jmri.jmrit.operations.trains.excel.TrainCustomSwitchList; 022import jmri.util.swing.JmriJOptionPane; 023 024/** 025 * Frame for user selection of switch lists 026 * 027 * @author Dan Boudreau Copyright (C) 2008, 2012, 2013, 2014, 2021 028 */ 029public class TrainSwitchListEditFrame extends OperationsFrame implements java.beans.PropertyChangeListener { 030 031 JScrollPane switchPane; 032 033 // load managers 034 LocationManager locationManager = InstanceManager.getDefault(LocationManager.class); 035 List<JCheckBox> locationCheckBoxes = new ArrayList<>(); 036 List<JComboBox<String>> locationComboBoxes = new ArrayList<>(); 037 JPanel locationPanelCheckBoxes = new JPanel(); 038 039 // checkboxes 040 JCheckBox switchListRealTimeCheckBox = new JCheckBox(Bundle.getMessage("SwitchListRealTime")); 041 JCheckBox switchListAllTrainsCheckBox = new JCheckBox(Bundle.getMessage("SwitchListAllTrains")); 042 043 // major buttons 044 JButton clearButton = new JButton(Bundle.getMessage("ClearAll")); 045 JButton setButton = new JButton(Bundle.getMessage("SelectAll")); 046 JButton printButton = new JButton(Bundle.getMessage("PrintSwitchLists")); 047 JButton previewButton = new JButton(Bundle.getMessage("PreviewSwitchLists")); 048 JButton printChangesButton = new JButton(Bundle.getMessage("PrintChanges")); 049 JButton runButton = new JButton(Bundle.getMessage("RunFile")); 050 JButton runChangeButton = new JButton(Bundle.getMessage("RunFileChanges")); 051 JButton openFileButton = new JButton(Bundle.getMessage("OpenFile")); 052 JButton updateButton = new JButton(Bundle.getMessage("Update")); 053 JButton resetButton = new JButton(Bundle.getMessage("ResetSwitchLists")); 054 JButton saveButton = new JButton(Bundle.getMessage("ButtonSave")); 055 056 JComboBox<String> switchListPageComboBox = Setup.getSwitchListPageFormatComboBox(); 057 058 // panels 059 JPanel customPanel; 060 061 public TrainSwitchListEditFrame() { 062 super(Bundle.getMessage("TitleSwitchLists")); 063 } 064 065 @Override 066 public void initComponents() { 067 // listen for any changes in the number of locations 068 locationManager.addPropertyChangeListener(this); 069 070 // the following code sets the frame's initial state 071 getContentPane().setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS)); 072 073 // tool tips 074 switchListRealTimeCheckBox.setToolTipText(Bundle.getMessage("RealTimeTip")); 075 switchListAllTrainsCheckBox.setToolTipText(Bundle.getMessage("AllTrainsTip")); 076 switchListPageComboBox.setToolTipText(Bundle.getMessage("PageTrainTip")); 077 printChangesButton.setToolTipText(Bundle.getMessage("PrintChangesTip")); 078 resetButton.setToolTipText(Bundle.getMessage("ResetSwitchListTip")); 079 080 switchPane = new JScrollPane(locationPanelCheckBoxes); 081 switchPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED); 082 switchPane.setBorder(BorderFactory.createTitledBorder("")); 083 084 // Layout the panel by rows 085 locationPanelCheckBoxes.setLayout(new GridBagLayout()); 086 updateLocationCheckboxes(); 087 enableSaveButton(false); 088 089 // Clear and set buttons 090 JPanel pButtons = new JPanel(); 091 pButtons.setLayout(new GridBagLayout()); 092 pButtons.setBorder(BorderFactory.createTitledBorder("")); 093 addItem(pButtons, clearButton, 0, 1); 094 addItem(pButtons, setButton, 1, 1); 095 096 // options 097 JPanel pSwitchListOptions = new JPanel(); 098 pSwitchListOptions.setLayout(new GridBagLayout()); 099 pSwitchListOptions 100 .setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("BorderLayoutSwitchListOptions"))); 101 102 JPanel pSwitchListPageFormat = new JPanel(); 103 pSwitchListPageFormat 104 .setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("BorderLayoutSwitchListPageFormat"))); 105 pSwitchListPageFormat.add(switchListPageComboBox); 106 107 addItem(pSwitchListOptions, switchListAllTrainsCheckBox, 1, 0); 108 addItem(pSwitchListOptions, pSwitchListPageFormat, 2, 0); 109 addItem(pSwitchListOptions, switchListRealTimeCheckBox, 3, 0); 110 addItem(pSwitchListOptions, saveButton, 4, 0); 111 112 // buttons 113 JPanel controlPanel = new JPanel(); 114 controlPanel.setLayout(new GridBagLayout()); 115 controlPanel.setBorder(BorderFactory.createTitledBorder("")); 116 117 // row 3 118 addItem(controlPanel, previewButton, 0, 2); 119 addItem(controlPanel, printButton, 1, 2); 120 addItem(controlPanel, printChangesButton, 2, 2); 121 // row 4 122 addItem(controlPanel, updateButton, 0, 3); 123 addItem(controlPanel, resetButton, 1, 3); 124 125 // row 5 126 customPanel = new JPanel(); 127 customPanel.setLayout(new GridBagLayout()); 128 customPanel.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("BorderLayoutCustomSwitchLists"))); 129 130 addItem(customPanel, runButton, 1, 5); 131 addItem(customPanel, runChangeButton, 2, 5); 132 addItem(customPanel, openFileButton, 3, 5); 133 134 getContentPane().add(switchPane); 135 getContentPane().add(pButtons); 136 getContentPane().add(pSwitchListOptions); 137 getContentPane().add(controlPanel); 138 getContentPane().add(customPanel); 139 140 customPanel.setVisible(Setup.isGenerateCsvSwitchListEnabled()); 141 142 // Set the state 143 switchListRealTimeCheckBox.setSelected(Setup.isSwitchListRealTime()); 144 switchListAllTrainsCheckBox.setSelected(Setup.isSwitchListAllTrainsEnabled()); 145 switchListPageComboBox.setSelectedItem(Setup.getSwitchListPageFormat()); 146 147 updateButton.setVisible(!switchListRealTimeCheckBox.isSelected()); 148 resetButton.setVisible(!switchListRealTimeCheckBox.isSelected()); 149 saveButton.setEnabled(false); 150 151 addButtonAction(clearButton); 152 addButtonAction(setButton); 153 addButtonAction(printButton); 154 addButtonAction(previewButton); 155 addButtonAction(printChangesButton); 156 addButtonAction(runButton); 157 addButtonAction(runChangeButton); 158 addButtonAction(openFileButton); 159 addButtonAction(updateButton); 160 addButtonAction(resetButton); 161 addButtonAction(saveButton); 162 163 addCheckBoxAction(switchListRealTimeCheckBox); 164 addCheckBoxAction(switchListAllTrainsCheckBox); 165 166 addComboBoxAction(switchListPageComboBox); 167 168 Setup.getDefault().addPropertyChangeListener(this); 169 170 // build menu 171 JMenuBar menuBar = new JMenuBar(); 172 JMenu toolMenu = new JMenu(Bundle.getMessage("MenuTools")); 173 toolMenu.add(new SetupExcelProgramSwitchListFrameAction()); 174 menuBar.add(toolMenu); 175 setJMenuBar(menuBar); 176 177 // add help menu to window 178 addHelpMenu("package.jmri.jmrit.operations.Operations_SwitchList", true); // NOI18N 179 // set frame size and train for display 180 initMinimumSize(new Dimension(Control.panelWidth500, Control.panelHeight500)); 181 } 182 183 private static final boolean IS_CHANGED = true; 184 private static final boolean IS_PRINT = true; // print or preview 185 private static final boolean IS_PREVIEW = true; 186 187 // Buttons 188 @Override 189 public void buttonActionPerformed(java.awt.event.ActionEvent ae) { 190 if (ae.getSource() == clearButton) { 191 selectCheckboxes(false); 192 } 193 if (ae.getSource() == setButton) { 194 selectCheckboxes(true); 195 } 196 if (ae.getSource() == previewButton) { 197 buildSwitchList(!IS_CHANGED, IS_PRINT, IS_PREVIEW); 198 } 199 if (ae.getSource() == printButton) { 200 buildSwitchList(!IS_CHANGED, IS_PRINT, !IS_PREVIEW); 201 } 202 if (ae.getSource() == printChangesButton) { 203 buildSwitchList(IS_CHANGED, IS_PRINT, !IS_PREVIEW); 204 } 205 if (ae.getSource() == updateButton) { 206 buildSwitchList(!IS_CHANGED, !IS_PRINT, IS_PREVIEW); 207 } 208 if (ae.getSource() == runButton) { 209 runCustomSwitchLists(!IS_CHANGED); 210 } 211 if (ae.getSource() == runChangeButton) { 212 runCustomSwitchLists(IS_CHANGED); 213 } 214 if (ae.getSource() == openFileButton) { 215 buildSwitchList(IS_CHANGED, !IS_PRINT, IS_PREVIEW); 216 openCsvSwitchList(); 217 } 218 if (ae.getSource() == resetButton) { 219 reset(); 220 } 221 if (ae.getSource() == saveButton) { 222 save(); 223 if (Setup.isCloseWindowOnSaveEnabled()) { 224 dispose(); 225 } 226 } 227 } 228 229 @Override 230 public void checkBoxActionPerformed(java.awt.event.ActionEvent ae) { 231 if (ae.getSource() == switchListRealTimeCheckBox) { 232 updateButton.setVisible(!switchListRealTimeCheckBox.isSelected()); 233 resetButton.setVisible(!switchListRealTimeCheckBox.isSelected()); 234 } 235 // enable the save button whenever a checkbox is changed 236 enableSaveButton(true); 237 } 238 239 // Remove all terminated or reset trains from the switch lists for selected 240 // locations 241 private void reset() { 242 // Confirm that user really wants to delete all terminated and reset trains from 243 // the switch lists 244 if (JmriJOptionPane.showConfirmDialog(this, Bundle.getMessage("DoYouReallyWantDeleteSwitchListData"), 245 Bundle.getMessage("ResetSwitchLists"), JmriJOptionPane.YES_NO_OPTION) != JmriJOptionPane.YES_OPTION) { 246 return; 247 } 248 249 // this for loop prevents ConcurrentModificationException when printing and 250 // status changes 251 for (JCheckBox checkbox : new ArrayList<>(locationCheckBoxes)) { 252 String locationName = checkbox.getName(); 253 Location location = locationManager.getLocationByName(locationName); 254 if (location.isSwitchListEnabled()) { 255 // new switch lists will now be created for the location 256 location.setSwitchListState(Location.SW_CREATE); 257 location.setStatus(Location.MODIFIED); 258 } 259 } 260 // set trains switch lists unknown, any built trains should remain on the switch 261 // lists 262 InstanceManager.getDefault(TrainManager.class).setTrainsSwitchListStatus(Train.UNKNOWN); 263 } 264 265 // save printer selection 266 private void save() { 267 // this for loop prevents ConcurrentModificationException when printing and 268 // status changes 269 for (int i = 0; i < locationCheckBoxes.size(); i++) { 270 String locationName = locationCheckBoxes.get(i).getName(); 271 Location location = locationManager.getLocationByName(locationName); 272 JComboBox<String> comboBox = locationComboBoxes.get(i); 273 String printerName = (String) comboBox.getSelectedItem(); 274 if (printerName == null || printerName.equals(TrainPrintUtilities.getDefaultPrinterName())) { 275 location.setDefaultPrinterName(Location.NONE); 276 } else { 277 log.debug("Location {} has selected printer {}", location.getName(), printerName); 278 location.setDefaultPrinterName(printerName); 279 } 280 } 281 // reset if changing to consolidation mode 282 if (Setup.isSwitchListRealTime() && !switchListRealTimeCheckBox.isSelected()) { 283 reset(); 284 } 285 Setup.setSwitchListRealTime(switchListRealTimeCheckBox.isSelected()); 286 Setup.setSwitchListAllTrainsEnabled(switchListAllTrainsCheckBox.isSelected()); 287 Setup.setSwitchListPageFormat((String) switchListPageComboBox.getSelectedItem()); 288 // save location file 289 OperationsXml.save(); 290 enableSaveButton(false); 291 if (Setup.isCloseWindowOnSaveEnabled()) { 292 dispose(); 293 } 294 } 295 296 /** 297 * 298 * @param isPreview true if print preview 299 * @param isChanged true if only print changes was requested 300 * @param isPrint true if printing or preview 301 */ 302 private void buildSwitchList(boolean isChanged, boolean isPrint, boolean isPreview) { 303 TrainSwitchLists trainSwitchLists = new TrainSwitchLists(); 304 TrainCsvSwitchLists trainCsvSwitchLists = new TrainCsvSwitchLists(); 305 // this for loop prevents ConcurrentModificationException when printing and 306 // status changes 307 for (JCheckBox checkbox : new ArrayList<>(locationCheckBoxes)) { 308 String locationName = checkbox.getName(); 309 Location location = locationManager.getLocationByName(locationName); 310 if (location.isSwitchListEnabled() && (!isChanged || location.getStatus().equals(Location.MODIFIED))) { 311 // update switch lists 312 trainCsvSwitchLists.buildSwitchList(location); 313 trainSwitchLists.buildSwitchList(location); 314 // print or only print changes 315 if (isPrint) { 316 trainSwitchLists.printSwitchList(location, isPreview); 317 } 318 } 319 } 320 // set trains switch lists printed 321 InstanceManager.getDefault(TrainManager.class).setTrainsSwitchListStatus(Train.PRINTED); 322 } 323 324 private void selectCheckboxes(boolean enable) { 325 for (JCheckBox checkbox : new ArrayList<>(locationCheckBoxes)) { 326 String locationName = checkbox.getName(); 327 Location location = locationManager.getLocationByName(locationName); 328 location.setSwitchListEnabled(enable); 329 } 330 // enable the save button whenever a checkbox is changed 331 saveButton.setEnabled(true); 332 } 333 334 // TODO there's a ConcurrentModificationException when the printer status 335 // changes 336 // when printing. This routine rebuilds the locationCheckBoxes during the 337 // update. 338 // A better solution would only update the status for a location. 339 // name change or number of locations has changed 340 private void updateLocationCheckboxes() { 341 List<Location> locations = locationManager.getLocationsByNameList(); 342 synchronized (this) { 343 for (Location location : locations) { 344 location.removePropertyChangeListener(this); 345 } 346 } 347 348 locationCheckBoxes.clear(); 349 locationComboBoxes.clear(); // remove printer selection 350 locationPanelCheckBoxes.removeAll(); 351 352 // create header 353 addItem(locationPanelCheckBoxes, new JLabel(Bundle.getMessage("Location")), 0, 0); 354 addItem(locationPanelCheckBoxes, new JLabel(" "), 1, 0); 355 addItem(locationPanelCheckBoxes, new JLabel(Bundle.getMessage("Status")), 2, 0); 356 addItem(locationPanelCheckBoxes, new JLabel(" "), 3, 0); 357 addItem(locationPanelCheckBoxes, new JLabel(Bundle.getMessage("Comment")), 4, 0); 358 addItem(locationPanelCheckBoxes, new JLabel(" "), 5, 0); 359 addItem(locationPanelCheckBoxes, new JLabel(Bundle.getMessage("Printer")), 6, 0); 360 361 int y = 1; // vertical position in panel 362 363 // note that getUniqueLocationsByNameList() method updates the status of 364 // locations with "similar" names. 365 for (Location location : locationManager.getUniqueLocationsByNameList()) { 366 JCheckBox checkBox = new JCheckBox(); 367 locationCheckBoxes.add(checkBox); 368 checkBox.setSelected(location.isSwitchListEnabled()); 369 checkBox.setText(location.getSplitName()); 370 checkBox.setName(location.getName()); 371 addLocationCheckBoxAction(checkBox); 372 addItemLeft(locationPanelCheckBoxes, checkBox, 0, y); 373 374 JLabel status = new JLabel(location.getStatus()); 375 addItem(locationPanelCheckBoxes, status, 2, y); 376 377 JButton button = new JButton(Bundle.getMessage("Add")); 378 if (!location.getSwitchListCommentWithColor().isEmpty()) { 379 button.setText(Bundle.getMessage("ButtonEdit")); 380 } 381 button.setName(location.getName()); 382 addCommentButtonAction(button); 383 addItem(locationPanelCheckBoxes, button, 4, y); 384 385 JComboBox<String> comboBox = TrainPrintUtilities.getPrinterJComboBox(); 386 locationComboBoxes.add(comboBox); 387 comboBox.setSelectedItem(location.getDefaultPrinterName()); 388 addComboBoxAction(comboBox); 389 addItem(locationPanelCheckBoxes, comboBox, 6, y++); 390 } 391 392 // restore listeners 393 synchronized (this) { 394 for (Location location : locations) { 395 location.addPropertyChangeListener(this); 396 } 397 } 398 399 locationPanelCheckBoxes.revalidate(); 400 pack(); 401 repaint(); 402 } 403 404 /** 405 * Creates custom switch lists using an external program like MS Excel. Switch 406 * lists are created for locations that have switch lists enabled. 407 * 408 * @param isChanged when true, only create custom switch list for enabled 409 * locations that have changes. When isChanged is false, create 410 * custom switch lists for all enabled locations. 411 */ 412 private void runCustomSwitchLists(boolean isChanged) { 413 if (!Setup.isGenerateCsvSwitchListEnabled()) { 414 return; 415 } 416 log.debug("run custom switch lists"); 417 TrainSwitchLists trainSwitchLists = new TrainSwitchLists(); 418 TrainCsvSwitchLists trainCsvSwitchLists = new TrainCsvSwitchLists(); 419 // this for loop prevents ConcurrentModificationException when printing and 420 // status changes 421 for (JCheckBox checkbox : new ArrayList<>(locationCheckBoxes)) { 422 String locationName = checkbox.getName(); 423 Location location = locationManager.getLocationByName(locationName); 424 if (location.isSwitchListEnabled() && (!isChanged || location.getStatus().equals(Location.MODIFIED))) { 425 File csvFile = trainCsvSwitchLists.buildSwitchList(location); 426 // also build the regular switch lists so they can be used 427 trainSwitchLists.buildSwitchList(location); 428 if (csvFile == null || !csvFile.exists()) { 429 log.error("CSV switch list file was not created for location {}", locationName); 430 return; 431 } 432 InstanceManager.getDefault(TrainCustomSwitchList.class).addCsvFile(csvFile); 433 } 434 } 435 // Processes the CSV Manifest files using an external custom program. 436 if (!InstanceManager.getDefault(TrainCustomSwitchList.class).excelFileExists()) { 437 log.warn("Manifest creator file not found!, directory path: {}, file name: {}", 438 InstanceManager.getDefault(TrainCustomSwitchList.class).getDirectoryPathName(), 439 InstanceManager.getDefault(TrainCustomSwitchList.class).getFileName()); 440 JmriJOptionPane.showMessageDialog(this, 441 Bundle.getMessage("LoadDirectoryNameFileName", 442 InstanceManager.getDefault(TrainCustomSwitchList.class).getDirectoryPathName(), 443 InstanceManager.getDefault(TrainCustomSwitchList.class).getFileName()), 444 Bundle.getMessage("ManifestCreatorNotFound"), JmriJOptionPane.ERROR_MESSAGE); 445 return; 446 } 447 // Now run the user specified custom Switch List processor program 448 InstanceManager.getDefault(TrainCustomSwitchList.class).process(); 449 // set trains switch lists printed 450 InstanceManager.getDefault(TrainManager.class).setTrainsSwitchListStatus(Train.PRINTED); 451 } 452 453 private void openCsvSwitchList() { 454 File file = selectFile(); 455 if (file != null) { 456 TrainUtilities.openDesktop(file); 457 } 458 } 459 460 /** 461 * We always use the same file chooser in this class, so that the user's 462 * last-accessed directory remains available. 463 */ 464 JFileChooser fc; 465 466 private File selectFile() { 467 if (fc == null) { 468 fc = new jmri.util.swing.JmriJFileChooser( 469 InstanceManager.getDefault(TrainManagerXml.class).getDefaultCsvSwitchListDirectoryName()); 470 fc.setFileFilter(new FileNameExtensionFilter("Comma Separated Values", "csv")); // NOI18N 471 fc.setDialogTitle(Bundle.getMessage("TitleSwitchLists")); 472 } 473 // when reusing the chooser, make sure new files are included 474 fc.rescanCurrentDirectory(); 475 int retVal = fc.showOpenDialog(this); 476 // handle selection or cancel 477 if (retVal == JFileChooser.APPROVE_OPTION) { 478 return fc.getSelectedFile(); 479 } 480 return null; 481 } 482 483 private void enableSaveButton(boolean enable) { 484 saveButton.setEnabled(enable); 485 // these get the inverse 486 previewButton.setEnabled(!enable); 487 printButton 488 .setEnabled(!enable && (!Control.disablePrintingIfCustom || !Setup.isGenerateCsvSwitchListEnabled())); 489 resetButton.setEnabled(!enable); 490 runButton.setEnabled(!enable); 491 openFileButton.setEnabled(!enable); 492 // disable the following, and turn then back on if needed 493 printChangesButton.setEnabled(false); 494 runChangeButton.setEnabled(false); 495 updateButton.setEnabled(false); 496 if (!enable) { 497 enableChangeButtons(); 498 } 499 } 500 501 private void enableChangeButtons() { 502 printChangesButton.setEnabled(false); 503 runChangeButton.setEnabled(false); 504 updateButton.setEnabled(false); 505 for (Location location : locationManager.getLocationsByNameList()) { 506 if (location.getStatus().equals(Location.MODIFIED) && location.isSwitchListEnabled()) { 507 printChangesButton 508 .setEnabled((!Control.disablePrintingIfCustom || !Setup.isGenerateCsvSwitchListEnabled())); 509 runChangeButton.setEnabled(true); 510 updateButton.setEnabled(true); 511 } 512 } 513 } 514 515 // The print switch list for a location has changed 516 private void changeLocationCheckboxes(PropertyChangeEvent e) { 517 Location l = (Location) e.getSource(); 518 for (JCheckBox checkbox : new ArrayList<>(locationCheckBoxes)) { 519 if (checkbox.getName().equals(l.getName())) { 520 checkbox.setSelected(l.isSwitchListEnabled()); 521 break; 522 } 523 } 524 } 525 526 private void addLocationCheckBoxAction(JCheckBox b) { 527 b.addActionListener(new java.awt.event.ActionListener() { 528 @Override 529 public void actionPerformed(ActionEvent e) { 530 locationCheckBoxActionPerformed(e); 531 } 532 }); 533 } 534 535 public void locationCheckBoxActionPerformed(ActionEvent ae) { 536 JCheckBox b = (JCheckBox) ae.getSource(); 537 log.debug("checkbox change {}", b.getName()); 538 Location l = locationManager.getLocationByName(b.getName()); 539 l.setSwitchListEnabled(b.isSelected()); 540 // enable the save button whenever a checkbox is changed 541 saveButton.setEnabled(true); 542 } 543 544 private void addCommentButtonAction(JButton b) { 545 b.addActionListener(new java.awt.event.ActionListener() { 546 @Override 547 public void actionPerformed(java.awt.event.ActionEvent e) { 548 commentButtonActionPerformed(e); 549 } 550 }); 551 } 552 553 public void commentButtonActionPerformed(ActionEvent ae) { 554 JButton b = (JButton) ae.getSource(); 555 log.debug("button action {}", b.getName()); 556 Location l = locationManager.getLocationByName(b.getName()); 557 new TrainSwitchListCommentFrame(l); 558 } 559 560 @Override 561 protected void comboBoxActionPerformed(ActionEvent ae) { 562 log.debug("combo box action"); 563 enableSaveButton(true); 564 } 565 566 @Override 567 public void dispose() { 568 locationManager.removePropertyChangeListener(this); 569 Setup.getDefault().removePropertyChangeListener(this); 570 for (Location location : locationManager.getLocationsByNameList()) { 571 location.removePropertyChangeListener(this); 572 } 573 super.dispose(); 574 } 575 576 @Override 577 public void propertyChange(PropertyChangeEvent e) { 578 if (Control.SHOW_PROPERTY) { 579 log.debug("Property change: ({}) old: ({}) new: ({})", e.getPropertyName(), e.getOldValue(), 580 e.getNewValue()); 581 } 582 if (e.getPropertyName().equals(Location.SWITCHLIST_CHANGED_PROPERTY)) { 583 changeLocationCheckboxes(e); 584 enableChangeButtons(); 585 } 586 if (e.getPropertyName().equals(LocationManager.LISTLENGTH_CHANGED_PROPERTY) || 587 e.getPropertyName().equals(Location.NAME_CHANGED_PROPERTY) || 588 e.getPropertyName().equals(Location.STATUS_CHANGED_PROPERTY) || 589 e.getPropertyName().equals(Location.SWITCHLIST_COMMENT_CHANGED_PROPERTY)) { 590 updateLocationCheckboxes(); 591 enableChangeButtons(); 592 } 593 if (e.getPropertyName().equals(Setup.SWITCH_LIST_CSV_PROPERTY_CHANGE)) { 594 enableSaveButton(false); 595 customPanel.setVisible(Setup.isGenerateCsvSwitchListEnabled()); 596 } 597 } 598 599 public static class TrainSwitchListCommentFrame extends OperationsFrame { 600 601 // text area 602 JTextArea commentTextArea = new JTextArea(10, 90); 603 JScrollPane commentScroller = new JScrollPane(commentTextArea, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, 604 JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); 605 Dimension minScrollerDim = new Dimension(1200, 500); 606 607 // text color chooser 608 JColorChooser commentColorChooser = new JColorChooser(); 609 610 JButton saveButton = new JButton(Bundle.getMessage("ButtonSave")); 611 JButton cancelButton = new JButton(Bundle.getMessage("ButtonCancel")); 612 613 Location _location; 614 615 private TrainSwitchListCommentFrame(Location location) { 616 super(); 617 initComponents(location); 618 } 619 620 private void initComponents(Location location) { 621 _location = location; 622 // the following code sets the frame's initial state 623 getContentPane().setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS)); 624 625 JPanel pC = new JPanel(); 626 pC.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("Comment"))); 627 pC.setLayout(new GridBagLayout()); 628 commentScroller.setMinimumSize(minScrollerDim); 629 addItem(pC, commentScroller, 1, 0); 630 addItem(pC, OperationsPanel.getColorChooserPanel(location.getSwitchListCommentWithColor(), commentColorChooser), 2, 0); 631 JScrollPane panelPane = new JScrollPane(pC); 632 633 commentTextArea.setText(TrainCommon.getTextColorString(location.getSwitchListCommentWithColor())); 634 635 JPanel pB = new JPanel(); 636 pB.setLayout(new GridBagLayout()); 637 addItem(pB, cancelButton, 0, 0); 638 addItem(pB, saveButton, 1, 0); 639 640 getContentPane().add(panelPane); 641 getContentPane().add(pB); 642 643 addButtonAction(saveButton); 644 addButtonAction(cancelButton); 645 646 setTitle(location.getName()); 647 initMinimumSize(new Dimension(Control.panelWidth600, Control.panelHeight200)); 648 } 649 650 // Buttons 651 @Override 652 public void buttonActionPerformed(java.awt.event.ActionEvent ae) { 653 if (ae.getSource() == saveButton) { 654 _location.setSwitchListComment( 655 TrainCommon.formatColorString(commentTextArea.getText(), commentColorChooser.getColor())); 656 // save location file 657 OperationsXml.save(); 658 if (Setup.isCloseWindowOnSaveEnabled()) { 659 super.dispose(); 660 } 661 } 662 if (ae.getSource() == cancelButton) { 663 super.dispose(); 664 } 665 } 666 } 667 668 private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(TrainSwitchListEditFrame.class); 669}