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