001package jmri.jmrit.operations.trains.gui; 002 003import java.awt.*; 004import java.util.ArrayList; 005import java.util.List; 006 007import javax.swing.*; 008 009import jmri.InstanceManager; 010import jmri.jmrit.operations.*; 011import jmri.jmrit.operations.locations.Location; 012import jmri.jmrit.operations.locations.LocationManager; 013import jmri.jmrit.operations.rollingstock.RollingStock; 014import jmri.jmrit.operations.rollingstock.cars.*; 015import jmri.jmrit.operations.rollingstock.engines.*; 016import jmri.jmrit.operations.routes.*; 017import jmri.jmrit.operations.routes.gui.RouteEditFrame; 018import jmri.jmrit.operations.setup.Control; 019import jmri.jmrit.operations.setup.Setup; 020import jmri.jmrit.operations.trains.Train; 021import jmri.jmrit.operations.trains.TrainManager; 022import jmri.jmrit.operations.trains.manualtrainbuilder.gui.TrainManualBuildAction; 023import jmri.jmrit.operations.trains.tools.*; 024import jmri.jmrit.operations.trains.trainbuilder.TrainCommon; 025import jmri.util.swing.JmriJOptionPane; 026 027/** 028 * Frame for user edit of a train 029 * 030 * @author Dan Boudreau Copyright (C) 2008, 2011, 2012, 2013, 2014 031 */ 032public class TrainEditFrame extends OperationsFrame implements java.beans.PropertyChangeListener { 033 034 TrainManager trainManager = InstanceManager.getDefault(TrainManager.class); 035 RouteManager routeManager = InstanceManager.getDefault(RouteManager.class); 036 037 public Train _train = null; 038 List<JCheckBox> typeCarCheckBoxes = new ArrayList<>(); 039 List<JCheckBox> typeEngineCheckBoxes = new ArrayList<>(); 040 List<JCheckBox> locationCheckBoxes = new ArrayList<>(); 041 JPanel typeCarPanelCheckBoxes = new JPanel(); 042 JPanel typeEnginePanelCheckBoxes = new JPanel(); 043 JPanel roadAndLoadStatusPanel = new JPanel(); 044 JPanel locationPanelCheckBoxes = new JPanel(); 045 JScrollPane typeCarPane; 046 JScrollPane typeEnginePane; 047 JScrollPane locationsPane; 048 049 // labels 050 JLabel textRouteStatus = new JLabel(); 051 JLabel textModel = new JLabel(Bundle.getMessage("Model")); 052 JLabel textRoad2 = new JLabel(Bundle.getMessage("Road")); 053 JLabel textRoad3 = new JLabel(Bundle.getMessage("Road")); 054 JLabel textEngine = new JLabel(Bundle.getMessage("Engines")); 055 056 // major buttons 057 JButton editButton = new JButton(Bundle.getMessage("ButtonEdit")); // edit route 058 JButton clearButton = new JButton(Bundle.getMessage("ClearAll")); 059 JButton setButton = new JButton(Bundle.getMessage("SelectAll")); 060 JButton autoSelectButton = new JButton(Bundle.getMessage("AutoSelect")); 061 JButton resetButton = new JButton(Bundle.getMessage("ResetTrain")); 062 JButton saveTrainButton = new JButton(Bundle.getMessage("SaveTrain")); 063 JButton deleteTrainButton = new JButton(Bundle.getMessage("DeleteTrain")); 064 JButton addTrainButton = new JButton(Bundle.getMessage("AddTrain")); 065 066 // alternate buttons 067 JButton loadOptionButton = new JButton(Bundle.getMessage("AcceptAll")); 068 JButton roadOptionButton = new JButton(Bundle.getMessage("AcceptAll")); 069 070 // radio buttons 071 JRadioButton noneRadioButton = new JRadioButton(Bundle.getMessage("None")); 072 JRadioButton cabooseRadioButton = new JRadioButton(Bundle.getMessage("Caboose")); 073 JRadioButton fredRadioButton = new JRadioButton(Bundle.getMessage("FRED")); 074 ButtonGroup group = new ButtonGroup(); 075 076 // text field 077 JTextField trainNameTextField = new JTextField(Control.max_len_string_train_name); 078 JTextField trainDescriptionTextField = new JTextField(30); 079 080 // text area 081 JTextArea commentTextArea = new JTextArea(4, 70); 082 JScrollPane commentScroller = new JScrollPane(commentTextArea); 083 JColorChooser commentColorChooser = new JColorChooser(Color.black); 084 JCheckBox boldCheckBox = new JCheckBox(); 085 086 // for padding out panel 087 JLabel space0 = new JLabel(" "); // before day 088 JLabel space1 = new JLabel(" "); // between day and hour 089 JLabel space2 = new JLabel(" "); // between hour and minute 090 JLabel space3 = new JLabel(" "); // after minute 091 JLabel space4 = new JLabel(" "); // between route and edit 092 JLabel space5 = new JLabel(" "); // after edit 093 094 // combo boxes 095 JComboBox<String> dayBox = new JComboBox<>(); 096 JComboBox<String> hourBox = new JComboBox<>(); 097 JComboBox<String> minuteBox = new JComboBox<>(); 098 JComboBox<Route> routeBox = routeManager.getComboBox(); 099 JComboBox<String> roadCabooseBox = new JComboBox<>(); 100 JComboBox<String> roadEngineBox = new JComboBox<>(); 101 JComboBox<String> modelEngineBox = InstanceManager.getDefault(EngineModels.class).getComboBox(); 102 JComboBox<String> numEnginesBox = new JComboBox<>(); 103 104 JMenu toolMenu = new JMenu(Bundle.getMessage("MenuTools")); 105 106 public static final String DISPOSE = "dispose"; // NOI18N 107 108 public TrainEditFrame(Train train) { 109 super(Bundle.getMessage("TitleTrainEdit")); 110 // Set up the jtable in a Scroll Pane.. 111 locationsPane = new JScrollPane(locationPanelCheckBoxes); 112 locationsPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED); 113 locationsPane.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("Stops"))); 114 115 typeCarPane = new JScrollPane(typeCarPanelCheckBoxes); 116 typeCarPane.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("TypesCar"))); 117 typeCarPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED); 118 119 typeEnginePane = new JScrollPane(typeEnginePanelCheckBoxes); 120 typeEnginePane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED); 121 typeEnginePane.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("TypesEngine"))); 122 123 _train = train; 124 125 getContentPane().setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS)); 126 127 // Set up the panels 128 JPanel p = new JPanel(); 129 p.setLayout(new BoxLayout(p, BoxLayout.Y_AXIS)); 130 JScrollPane pPane = new JScrollPane(p); 131 pPane.setMinimumSize(new Dimension(300, 5 * trainNameTextField.getPreferredSize().height)); 132 pPane.setBorder(BorderFactory.createTitledBorder("")); 133 134 // Layout the panel by rows 135 // row 1 136 JPanel p1 = new JPanel(); 137 p1.setLayout(new BoxLayout(p1, BoxLayout.X_AXIS)); 138 // row 1a 139 JPanel pName = new JPanel(); 140 pName.setLayout(new GridBagLayout()); 141 pName.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("Name"))); 142 addItem(pName, trainNameTextField, 0, 0); 143 // row 1b 144 JPanel pDesc = new JPanel(); 145 pDesc.setLayout(new GridBagLayout()); 146 pDesc.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("Description"))); 147 trainDescriptionTextField.setToolTipText(Bundle.getMessage("TipTrainDescription")); 148 addItem(pDesc, trainDescriptionTextField, 0, 0); 149 150 p1.add(pName); 151 p1.add(pDesc); 152 153 // row 2 154 JPanel p2 = new JPanel(); 155 p2.setLayout(new BoxLayout(p2, BoxLayout.X_AXIS)); 156 // row 2a 157 JPanel pdt = new JPanel(); 158 pdt.setLayout(new GridBagLayout()); 159 pdt.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("DepartTime"))); 160 161 // build hour and minute menus 162 dayBox.setPrototypeDisplayValue("0000"); // needed for font size 9 163 hourBox.setPrototypeDisplayValue("0000"); 164 minuteBox.setPrototypeDisplayValue("0000"); 165 for (int i = 0; i < Control.numberOfDays; i++) { 166 dayBox.addItem(Integer.toString(i)); 167 } 168 for (int i = 0; i < 24; i++) { 169 if (i < 10) { 170 hourBox.addItem("0" + Integer.toString(i)); 171 } else { 172 hourBox.addItem(Integer.toString(i)); 173 } 174 } 175 for (int i = 0; i < 60; i += 1) { 176 if (i < 10) { 177 minuteBox.addItem("0" + Integer.toString(i)); 178 } else { 179 minuteBox.addItem(Integer.toString(i)); 180 } 181 } 182 183 addItem(pdt, space0, 0, 5); 184 addItem(pdt, dayBox, 1, 5); 185 addItem(pdt, space1, 2, 5); 186 addItem(pdt, hourBox, 3, 5); 187 addItem(pdt, space2, 4, 5); 188 addItem(pdt, minuteBox, 5, 5); 189 addItem(pdt, space3, 6, 5); 190 // time tips 191 dayBox.setToolTipText(Bundle.getMessage("DepartureDayTip")); 192 hourBox.setToolTipText(Bundle.getMessage("DepartureHourTip")); 193 minuteBox.setToolTipText(Bundle.getMessage("DepartureMinuteTip")); 194 195 // row 2b 196 // BUG! routeBox needs its own panel when resizing frame! 197 JPanel pr = new JPanel(); 198 pr.setLayout(new GridBagLayout()); 199 pr.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("Route"))); 200 addItem(pr, routeBox, 0, 5); 201 addItem(pr, space4, 1, 5); 202 addItem(pr, editButton, 2, 5); 203 addItem(pr, space5, 3, 5); 204 addItem(pr, textRouteStatus, 4, 5); 205 206 p2.add(pdt); 207 p2.add(pr); 208 209 p.add(p1); 210 p.add(p2); 211 212 // row 5 213 locationPanelCheckBoxes.setLayout(new GridBagLayout()); 214 215 // row 6 216 typeCarPanelCheckBoxes.setLayout(new GridBagLayout()); 217 218 // row 8 219 typeEnginePanelCheckBoxes.setLayout(new GridBagLayout()); 220 221 // status panel for roads and loads 222 roadAndLoadStatusPanel.setLayout(new BoxLayout(roadAndLoadStatusPanel, BoxLayout.X_AXIS)); 223 JPanel pRoadOption = new JPanel(); 224 pRoadOption.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("RoadOption"))); 225 pRoadOption.add(roadOptionButton); 226 roadOptionButton.addActionListener(new TrainRoadOptionsAction(this)); 227 228 JPanel pLoadOption = new JPanel(); 229 pLoadOption.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("LoadOption"))); 230 pLoadOption.add(loadOptionButton); 231 loadOptionButton.addActionListener(new TrainLoadOptionsAction(this)); 232 233 roadAndLoadStatusPanel.add(pRoadOption); 234 roadAndLoadStatusPanel.add(pLoadOption); 235 roadAndLoadStatusPanel.setVisible(false); // don't show unless there's a restriction 236 237 // row 10 238 JPanel trainReq = new JPanel(); 239 trainReq.setLayout(new GridBagLayout()); 240 trainReq.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("TrainRequires"))); 241 242 for (int i = 0; i < Setup.getMaxNumberEngines() + 1; i++) { 243 numEnginesBox.addItem(Integer.toString(i)); 244 } 245 numEnginesBox.addItem(Train.AUTO); 246 numEnginesBox.setMinimumSize(new Dimension(100, 20)); 247 numEnginesBox.setToolTipText(Bundle.getMessage("TipNumberOfLocos")); 248 addItem(trainReq, textEngine, 1, 1); 249 addItem(trainReq, numEnginesBox, 2, 1); 250 addItem(trainReq, textModel, 3, 1); 251 modelEngineBox.insertItemAt(NONE, 0); 252 modelEngineBox.setSelectedIndex(0); 253 modelEngineBox.setMinimumSize(new Dimension(120, 20)); 254 modelEngineBox.setToolTipText(Bundle.getMessage("ModelEngineTip")); 255 addItem(trainReq, modelEngineBox, 4, 1); 256 addItem(trainReq, textRoad2, 5, 1); 257 roadEngineBox.insertItemAt(NONE, 0); 258 roadEngineBox.setSelectedIndex(0); 259 roadEngineBox.setMinimumSize(new Dimension(120, 20)); 260 roadEngineBox.setToolTipText(Bundle.getMessage("RoadEngineTip")); 261 addItem(trainReq, roadEngineBox, 6, 1); 262 263 JPanel trainLastCar = new JPanel(); 264 trainLastCar.setLayout(new GridBagLayout()); 265 trainLastCar.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("TrainLastCar"))); 266 267 addItem(trainLastCar, noneRadioButton, 2, 2); 268 noneRadioButton.setToolTipText(Bundle.getMessage("TipNoCabooseOrFRED")); 269 addItem(trainLastCar, fredRadioButton, 3, 2); 270 fredRadioButton.setToolTipText(Bundle.getMessage("TipFRED")); 271 addItem(trainLastCar, cabooseRadioButton, 4, 2); 272 cabooseRadioButton.setToolTipText(Bundle.getMessage("TipCaboose")); 273 addItem(trainLastCar, textRoad3, 5, 2); 274 roadCabooseBox.setMinimumSize(new Dimension(120, 20)); 275 roadCabooseBox.setToolTipText(Bundle.getMessage("RoadCabooseTip")); 276 addItem(trainLastCar, roadCabooseBox, 6, 2); 277 group.add(noneRadioButton); 278 group.add(cabooseRadioButton); 279 group.add(fredRadioButton); 280 noneRadioButton.setSelected(true); 281 282 // row 13 comment 283 JPanel pC = new JPanel(); 284 pC.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("Comment"))); 285 pC.setLayout(new GridBagLayout()); 286 addItem(pC, commentScroller, 1, 0); 287 if (_train != null) { 288 addItem(pC, getColorChooserPanel(_train.getCommentWithColor(), commentColorChooser, boldCheckBox), 2, 0); 289 boldCheckBox.setSelected(TrainCommon.isTextBold(_train.getCommentWithColor())); 290 } else { 291 addItem(pC, getColorChooserPanel("", commentColorChooser, boldCheckBox), 2, 0); 292 } 293 294 // adjust text area width based on window size less color chooser 295 Dimension d = new Dimension(getPreferredSize().width - 100, getPreferredSize().height); 296 adjustTextAreaColumnWidth(commentScroller, commentTextArea, d); 297 298 // row 15 buttons 299 JPanel pB = new JPanel(); 300 pB.setLayout(new GridBagLayout()); 301 addItem(pB, deleteTrainButton, 0, 0); 302 addItem(pB, resetButton, 1, 0); 303 addItem(pB, addTrainButton, 2, 0); 304 addItem(pB, saveTrainButton, 3, 0); 305 306 getContentPane().add(pPane); 307 getContentPane().add(locationsPane); 308 getContentPane().add(typeCarPane); 309 getContentPane().add(typeEnginePane); 310 getContentPane().add(roadAndLoadStatusPanel); 311 getContentPane().add(trainReq); 312 getContentPane().add(trainLastCar); 313 getContentPane().add(pC); 314 getContentPane().add(pB); 315 316 // setup buttons 317 addButtonAction(editButton); 318 addButtonAction(setButton); 319 addButtonAction(clearButton); 320 addButtonAction(autoSelectButton); 321 addButtonAction(resetButton); 322 addButtonAction(deleteTrainButton); 323 addButtonAction(addTrainButton); 324 addButtonAction(saveTrainButton); 325 326 addRadioButtonAction(noneRadioButton); 327 addRadioButtonAction(cabooseRadioButton); 328 addRadioButtonAction(fredRadioButton); 329 330 // tool tips 331 resetButton.setToolTipText(Bundle.getMessage("TipTrainReset")); 332 autoSelectButton.setToolTipText(Bundle.getMessage("AutoSelectTip")); 333 334 // build menu 335 JMenuBar menuBar = new JMenuBar(); 336 menuBar.add(toolMenu); 337 loadToolMenu(toolMenu); 338 setJMenuBar(menuBar); 339 addHelpMenu("package.jmri.jmrit.operations.Operations_TrainEdit", true); // NOI18N 340 341 if (_train != null) { 342 trainNameTextField.setText(_train.getName()); 343 trainDescriptionTextField.setText(_train.getRawDescription()); 344 routeBox.setSelectedItem(_train.getRoute()); 345 modelEngineBox.setSelectedItem(_train.getEngineModel()); 346 commentTextArea.setText(TrainCommon.isTextUserModified(_train.getCommentWithColor()) 347 ? _train.getCommentWithColor() : _train.getComment()); 348 cabooseRadioButton.setSelected(_train.isCabooseNeeded()); 349 fredRadioButton.setSelected(_train.isFredNeeded()); 350 updateDepartureTime(); 351 enableButtons(true); 352 // listen for train changes 353 _train.addPropertyChangeListener(this); 354 355 Route route = _train.getRoute(); 356 if (route != null) { 357 if (_train.getTrainDepartsRouteLocation() != null && 358 _train.getTrainDepartsRouteLocation().getLocation() != null && 359 !_train.getTrainDepartsRouteLocation().getLocation().isStaging()) 360 numEnginesBox.addItem(Train.AUTO_HPT); 361 } 362 numEnginesBox.setSelectedItem(_train.getNumberEngines()); 363 } else { 364 setTitle(Bundle.getMessage("TitleTrainAdd")); 365 enableButtons(false); 366 } 367 368 modelEngineBox.setEnabled(!numEnginesBox.getSelectedItem().equals("0")); 369 roadEngineBox.setEnabled(!numEnginesBox.getSelectedItem().equals("0")); 370 371 // load route location checkboxes 372 updateLocationCheckboxes(); 373 updateCarTypeCheckboxes(); 374 updateEngineTypeCheckboxes(); 375 updateRoadAndLoadStatus(); 376 updateCabooseRoadComboBox(); 377 updateEngineRoadComboBox(); 378 379 // setup combobox 380 addComboBoxAction(numEnginesBox); 381 addComboBoxAction(routeBox); 382 addComboBoxAction(modelEngineBox); 383 384 // get notified if combo box gets modified 385 routeManager.addPropertyChangeListener(this); 386 // get notified if car types or roads gets modified 387 InstanceManager.getDefault(CarTypes.class).addPropertyChangeListener(this); 388 InstanceManager.getDefault(CarRoads.class).addPropertyChangeListener(this); 389 InstanceManager.getDefault(EngineTypes.class).addPropertyChangeListener(this); 390 InstanceManager.getDefault(EngineModels.class).addPropertyChangeListener(this); 391 InstanceManager.getDefault(LocationManager.class).addPropertyChangeListener(this); 392 393 initMinimumSize(new Dimension(Control.panelWidth600, Control.panelHeight600)); 394 } 395 396 private void loadToolMenu(JMenu toolMenu) { 397 toolMenu.removeAll(); 398 // first 4 menu items will also close when the edit train window closes 399 toolMenu.add(new TrainEditBuildOptionsAction(this)); 400 toolMenu.add(new TrainLoadOptionsAction(this)); 401 toolMenu.add(new TrainRoadOptionsAction(this)); 402 toolMenu.add(new TrainManifestOptionAction(this)); 403 toolMenu.addSeparator(); 404 toolMenu.add(new TrainManualBuildAction(_train)); 405 toolMenu.addSeparator(); 406 toolMenu.add(new TrainCopyAction(_train)); 407 toolMenu.addSeparator(); 408 // scripts window closes when the edit train window closes 409 toolMenu.add(new TrainScriptAction(this)); 410 toolMenu.addSeparator(); 411 toolMenu.add(new TrainConductorAction(_train)); 412 toolMenu.addSeparator(); 413 toolMenu.add(new TrainByCarTypeAction(_train)); 414 toolMenu.addSeparator(); 415 toolMenu.add(new PrintTrainAction(false, _train)); 416 toolMenu.add(new PrintTrainAction(true, _train)); 417 toolMenu.add(new PrintTrainManifestAction(false, _train)); 418 toolMenu.add(new PrintTrainManifestAction(true, _train)); 419 toolMenu.add(new PrintShowCarsInTrainRouteAction(false, _train)); 420 toolMenu.add(new PrintShowCarsInTrainRouteAction(true, _train)); 421 toolMenu.add(new PrintTrainBuildReportAction(false, _train)); 422 toolMenu.add(new PrintTrainBuildReportAction(true, _train)); 423 toolMenu.add(new PrintSavedTrainManifestAction(false, _train)); 424 toolMenu.add(new PrintSavedTrainManifestAction(true, _train)); 425 toolMenu.add(new PrintSavedBuildReportAction(false, _train)); 426 toolMenu.add(new PrintSavedBuildReportAction(true, _train)); 427 } 428 429 // Save, Delete, Add, Edit, Reset, Set, Clear 430 @Override 431 public void buttonActionPerformed(java.awt.event.ActionEvent ae) { 432 Train train = trainManager.getTrainByName(trainNameTextField.getText().trim()); 433 if (ae.getSource() == saveTrainButton) { 434 log.debug("train save button activated"); 435 if (_train == null && train == null) { 436 saveNewTrain(); // this can't happen, Save button is disabled 437 } else { 438 if (train != null && train != _train) { 439 reportTrainExists(Bundle.getMessage("save")); 440 return; 441 } 442 // check to see if user supplied a route 443 if (!checkRoute() || !saveTrain()) { 444 return; 445 } 446 } 447 if (Setup.isCloseWindowOnSaveEnabled()) { 448 dispose(); 449 } 450 } 451 if (ae.getSource() == deleteTrainButton) { 452 log.debug("train delete button activated"); 453 if (train == null) { 454 return; 455 } 456 if (train.isBuilt()) { 457 JmriJOptionPane.showMessageDialog(this, 458 Bundle.getMessage("BuiltTrain"), 459 Bundle.getMessage("CanNotDeleteTrain"), JmriJOptionPane.ERROR_MESSAGE); 460 return; 461 } 462 if (!_train.reset()) { 463 JmriJOptionPane.showMessageDialog(this, 464 Bundle.getMessage("TrainIsInRoute", 465 train.getTrainTerminatesName()), 466 Bundle.getMessage("CanNotDeleteTrain"), JmriJOptionPane.ERROR_MESSAGE); 467 return; 468 } 469 if (JmriJOptionPane.showConfirmDialog(this, 470 Bundle.getMessage("deleteMsg", train.getName()), 471 Bundle.getMessage("deleteTrain"), JmriJOptionPane.YES_NO_OPTION) != JmriJOptionPane.YES_OPTION) { 472 return; 473 } 474 routeBox.setSelectedItem(null); 475 trainManager.deregister(train); 476 for (Frame frame : children) { 477 frame.dispose(); 478 } 479 _train = null; 480 enableButtons(false); 481 // save train file 482 OperationsXml.save(); 483 } 484 if (ae.getSource() == addTrainButton) { 485 if (train != null) { 486 reportTrainExists(Bundle.getMessage("add")); 487 return; 488 } 489 saveNewTrain(); 490 } 491 if (ae.getSource() == editButton) { 492 editAddRoute(); 493 } 494 if (ae.getSource() == setButton) { 495 selectCheckboxes(true); 496 } 497 if (ae.getSource() == clearButton) { 498 selectCheckboxes(false); 499 } 500 if (ae.getSource() == autoSelectButton) { 501 autoSelect(); 502 } 503 if (ae.getSource() == resetButton) { 504 if (_train != null) { 505 if (_train.checkDepartureTrack()) { 506 int results = JmriJOptionPane.showConfirmDialog(null, 507 Bundle.getMessage("StagingTrackUsed", 508 _train.getDepartureTrack().getName()), 509 Bundle.getMessage("ShouldNotResetTrain"), JmriJOptionPane.OK_CANCEL_OPTION); 510 if (results == JmriJOptionPane.OK_CANCEL_OPTION) { 511 return; 512 } 513 } 514 Train t = trainManager.getTrainBuiltAfter(train); 515 if (Setup.isBuildOnTime() && t != null) { 516 JmriJOptionPane.showMessageDialog(null, 517 Bundle.getMessage("TrainAfterBuilt", t, train), Bundle.getMessage("CanNotResetTrain"), 518 JmriJOptionPane.WARNING_MESSAGE); 519 } else if (!_train.reset()) { 520 JmriJOptionPane.showMessageDialog(this, 521 Bundle.getMessage("TrainIsInRoute", 522 _train.getTrainTerminatesName()), 523 Bundle.getMessage("CanNotResetTrain"), JmriJOptionPane.ERROR_MESSAGE); 524 } 525 } 526 } 527 } 528 529 @Override 530 public void radioButtonActionPerformed(java.awt.event.ActionEvent ae) { 531 log.debug("radio button activated"); 532 if (_train != null) { 533 if (ae.getSource() == noneRadioButton || 534 ae.getSource() == cabooseRadioButton || 535 ae.getSource() == fredRadioButton) { 536 updateCabooseRoadComboBox(); 537 } 538 } 539 } 540 541 private void saveNewTrain() { 542 if (!checkName(Bundle.getMessage("add"))) { 543 return; 544 } 545 Train train = trainManager.newTrain(trainNameTextField.getText()); 546 _train = train; 547 _train.addPropertyChangeListener(this); 548 549 // update check boxes 550 updateCarTypeCheckboxes(); 551 updateEngineTypeCheckboxes(); 552 // enable check boxes and buttons 553 enableButtons(true); 554 saveTrain(); 555 loadToolMenu(toolMenu); 556 } 557 558 private boolean saveTrain() { 559 if (!checkName(Bundle.getMessage("save"))) { 560 return false; 561 } 562 if (!checkModel() || !checkEngineRoad() || !checkCabooseRoad()) { 563 return false; 564 } 565 if (!_train.getName().equals(trainNameTextField.getText().trim()) || 566 !_train.getRawDescription().equals(trainDescriptionTextField.getText()) || 567 !_train.getCommentWithColor().equals( 568 TrainCommon.formatColorString(commentTextArea.getText(), commentColorChooser.getColor(), 569 boldCheckBox.isSelected()))) { 570 _train.setModified(true); 571 } 572 _train.setDepartureTime(dayBox.getSelectedItem().toString(), hourBox.getSelectedItem().toString(), 573 minuteBox.getSelectedItem().toString()); 574 _train.setNumberEngines((String) numEnginesBox.getSelectedItem()); 575 if (_train.getNumberEngines().equals("0")) { 576 modelEngineBox.setSelectedIndex(0); 577 roadEngineBox.setSelectedIndex(0); 578 } 579 _train.setEngineRoad((String) roadEngineBox.getSelectedItem()); 580 _train.setEngineModel((String) modelEngineBox.getSelectedItem()); 581 if (cabooseRadioButton.isSelected()) { 582 _train.setRequirements(Train.CABOOSE); 583 } 584 if (fredRadioButton.isSelected()) { 585 _train.setRequirements(Train.FRED); 586 } 587 if (noneRadioButton.isSelected()) { 588 _train.setRequirements(Train.NO_CABOOSE_OR_FRED); 589 } 590 _train.setCabooseRoad((String) roadCabooseBox.getSelectedItem()); 591 _train.setName(trainNameTextField.getText().trim()); 592 _train.setDescription(trainDescriptionTextField.getText()); 593 _train.setComment(TrainCommon.formatColorString(commentTextArea.getText(), commentColorChooser.getColor(), 594 boldCheckBox.isSelected())); 595 // save train file 596 OperationsXml.save(); 597 return true; 598 } 599 600 /** 601 * @return true if name isn't too long and is at least one character 602 */ 603 private boolean checkName(String s) { 604 String trainName = trainNameTextField.getText().trim(); 605 if (trainName.isEmpty()) { 606 log.debug("Must enter a train name"); 607 JmriJOptionPane.showMessageDialog(this, Bundle.getMessage("MustEnterName"), 608 Bundle.getMessage("CanNot", s), JmriJOptionPane.ERROR_MESSAGE); 609 return false; 610 } 611 if (trainName.length() > Control.max_len_string_train_name) { 612 JmriJOptionPane.showMessageDialog(this, 613 Bundle.getMessage("TrainNameLess", 614 Control.max_len_string_train_name + 1), 615 Bundle.getMessage("CanNot", s), JmriJOptionPane.ERROR_MESSAGE); 616 return false; 617 } 618 if (!OperationsXml.checkFileName(trainName)) { // NOI18N 619 log.error("Train name must not contain reserved characters"); 620 JmriJOptionPane.showMessageDialog(this, 621 Bundle.getMessage("NameResChar") + NEW_LINE + Bundle.getMessage("ReservedChar"), 622 Bundle.getMessage("CanNot", s), JmriJOptionPane.ERROR_MESSAGE); 623 return false; 624 } 625 626 return true; 627 } 628 629 private boolean checkModel() { 630 String model = (String) modelEngineBox.getSelectedItem(); 631 if (numEnginesBox.getSelectedItem().equals("0") || model.equals(NONE)) { 632 return true; 633 } 634 String type = InstanceManager.getDefault(EngineModels.class).getModelType(model); 635 if (!_train.isTypeNameAccepted(type)) { 636 JmriJOptionPane.showMessageDialog(this, 637 Bundle.getMessage("TrainModelService", model, type), 638 Bundle.getMessage("CanNot", Bundle.getMessage("save")), 639 JmriJOptionPane.ERROR_MESSAGE); 640 return false; 641 } 642 if (roadEngineBox.getItemCount() == 1) { 643 log.debug("No locos available that match the model selected!"); 644 JmriJOptionPane.showMessageDialog(this, 645 Bundle.getMessage("NoLocosModel", model), 646 Bundle.getMessage("TrainWillNotBuild", _train.getName()), 647 JmriJOptionPane.WARNING_MESSAGE); 648 } 649 return true; 650 } 651 652 private boolean checkEngineRoad() { 653 String road = (String) roadEngineBox.getSelectedItem(); 654 if (numEnginesBox.getSelectedItem().equals("0") || road.equals(NONE)) { 655 return true; 656 } 657 if (!road.equals(NONE) && !_train.isLocoRoadNameAccepted(road)) { 658 JmriJOptionPane.showMessageDialog(this, 659 Bundle.getMessage("TrainNotThisRoad", _train.getName(), road), 660 Bundle.getMessage("TrainWillNotBuild", _train.getName()), 661 JmriJOptionPane.WARNING_MESSAGE); 662 return false; 663 } 664 for (RollingStock rs : InstanceManager.getDefault(EngineManager.class).getList()) { 665 if (!_train.isTypeNameAccepted(rs.getTypeName())) { 666 continue; 667 } 668 if (rs.getRoadName().equals(road)) { 669 return true; 670 } 671 } 672 JmriJOptionPane.showMessageDialog(this, 673 Bundle.getMessage("NoLocoRoad", road), 674 Bundle.getMessage("TrainWillNotBuild", _train.getName()), 675 JmriJOptionPane.WARNING_MESSAGE); 676 return false; // couldn't find a loco with the selected road 677 } 678 679 private boolean checkCabooseRoad() { 680 String road = (String) roadCabooseBox.getSelectedItem(); 681 if (!road.equals(NONE) && cabooseRadioButton.isSelected() && !_train.isCabooseRoadNameAccepted(road)) { 682 JmriJOptionPane.showMessageDialog(this, 683 Bundle.getMessage("TrainNotCabooseRoad", _train.getName(), road), 684 Bundle.getMessage("TrainWillNotBuild", _train.getName()), 685 JmriJOptionPane.WARNING_MESSAGE); 686 return false; 687 } 688 return true; 689 } 690 691 private boolean checkRoute() { 692 if (_train.getRoute() == null) { 693 JmriJOptionPane.showMessageDialog(this, Bundle.getMessage("TrainNeedsRoute"), 694 Bundle.getMessage("TrainNoRoute"), 695 JmriJOptionPane.WARNING_MESSAGE); 696 return false; 697 } 698 return true; 699 700 } 701 702 private void reportTrainExists(String s) { 703 log.debug("Can not {}, train already exists", s); 704 JmriJOptionPane.showMessageDialog(this, Bundle.getMessage("TrainNameExists"), 705 Bundle.getMessage("CanNot", s), JmriJOptionPane.ERROR_MESSAGE); 706 } 707 708 private void enableButtons(boolean enabled) { 709 toolMenu.setEnabled(enabled); 710 editButton.setEnabled(enabled); 711 routeBox.setEnabled(enabled && _train != null && !_train.isBuilt()); 712 clearButton.setEnabled(enabled); 713 resetButton.setEnabled(enabled); 714 autoSelectButton.setEnabled(enabled); 715 setButton.setEnabled(enabled); 716 saveTrainButton.setEnabled(enabled); 717 deleteTrainButton.setEnabled(enabled); 718 numEnginesBox.setEnabled(enabled); 719 enableCheckboxes(enabled); 720 noneRadioButton.setEnabled(enabled); 721 fredRadioButton.setEnabled(enabled); 722 cabooseRadioButton.setEnabled(enabled); 723 roadOptionButton.setEnabled(enabled); 724 loadOptionButton.setEnabled(enabled); 725 // the inverse! 726 addTrainButton.setEnabled(!enabled); 727 } 728 729 private void selectCheckboxes(boolean enable) { 730 for (int i = 0; i < typeCarCheckBoxes.size(); i++) { 731 JCheckBox checkBox = typeCarCheckBoxes.get(i); 732 checkBox.setSelected(enable); 733 if (_train != null) { 734 _train.removePropertyChangeListener(this); 735 if (enable) { 736 _train.addTypeName(checkBox.getText()); 737 } else { 738 _train.deleteTypeName(checkBox.getText()); 739 } 740 _train.addPropertyChangeListener(this); 741 } 742 } 743 } 744 745 private void autoSelect() { 746 if (_train != null) { 747 Route route = _train.getRoute(); 748 if (route != null) { 749 typeLoop: for (String type : InstanceManager.getDefault(CarTypes.class).getNames()) { 750 for (RouteLocation rl : route.getLocationsBySequenceList()) { 751 if (rl.getMaxCarMoves() > 0 && (rl.isDropAllowed() || rl.isLocalMovesAllowed())) { 752 if (!_train.isLocationSkipped(rl) && rl.getLocation().acceptsTypeName(type)) { 753 continue typeLoop; 754 } 755 } 756 } 757 _train.deleteTypeName(type); 758 } 759 } 760 } 761 } 762 763 @Override 764 public void comboBoxActionPerformed(java.awt.event.ActionEvent ae) { 765 if (_train == null) { 766 return; 767 } 768 if (ae.getSource() == numEnginesBox) { 769 modelEngineBox.setEnabled(!numEnginesBox.getSelectedItem().equals("0")); 770 roadEngineBox.setEnabled(!numEnginesBox.getSelectedItem().equals("0")); 771 } 772 if (ae.getSource() == modelEngineBox) { 773 updateEngineRoadComboBox(); 774 } 775 if (ae.getSource() == routeBox) { 776 if (routeBox.isEnabled()) { 777 Route route = _train.getRoute(); 778 if (route != null) { 779 route.removePropertyChangeListener(this); 780 } 781 Object selected = routeBox.getSelectedItem(); 782 if (selected != null) { 783 route = (Route) selected; 784 _train.setRoute(route); 785 route.addPropertyChangeListener(this); 786 } else { 787 _train.setRoute(null); 788 } 789 updateLocationCheckboxes(); 790 updateDepartureTime(); 791 pack(); 792 repaint(); 793 } 794 } 795 } 796 797 private void enableCheckboxes(boolean enable) { 798 for (int i = 0; i < typeCarCheckBoxes.size(); i++) { 799 typeCarCheckBoxes.get(i).setEnabled(enable); 800 } 801 for (int i = 0; i < typeEngineCheckBoxes.size(); i++) { 802 typeEngineCheckBoxes.get(i).setEnabled(enable); 803 } 804 } 805 806 private void addLocationCheckBoxAction(JCheckBox b) { 807 b.addActionListener(new java.awt.event.ActionListener() { 808 @Override 809 public void actionPerformed(java.awt.event.ActionEvent e) { 810 locationCheckBoxActionPerformed(e); 811 } 812 }); 813 } 814 815 public void locationCheckBoxActionPerformed(java.awt.event.ActionEvent ae) { 816 JCheckBox b = (JCheckBox) ae.getSource(); 817 log.debug("checkbox change {}", b.getText()); 818 if (_train == null) { 819 return; 820 } 821 String id = b.getName(); 822 RouteLocation rl = _train.getRoute().getRouteLocationById(id); 823 if (b.isSelected()) { 824 _train.deleteTrainSkipsLocation(rl); 825 } else { 826 // check to see if skipped location is staging 827 if (_train.getRoute().getRouteLocationById(id).getLocation().isStaging()) { 828 int result = JmriJOptionPane.showConfirmDialog(this, 829 Bundle.getMessage("TrainRouteStaging", 830 _train.getName(), _train.getRoute().getRouteLocationById(id).getName()), 831 Bundle.getMessage("TrainRouteNotStaging"), JmriJOptionPane.OK_CANCEL_OPTION); 832 if (result != JmriJOptionPane.OK_OPTION) { 833 b.setSelected(true); 834 return; // don't skip staging 835 } 836 } 837 _train.addTrainSkipsLocation(rl); 838 } 839 } 840 841 private void updateRouteComboBox() { 842 routeBox.setEnabled(false); 843 routeManager.updateComboBox(routeBox); 844 if (_train != null) { 845 routeBox.setSelectedItem(_train.getRoute()); 846 } 847 routeBox.setEnabled(true); 848 } 849 850 private void updateCarTypeCheckboxes() { 851 typeCarCheckBoxes.clear(); 852 typeCarPanelCheckBoxes.removeAll(); 853 loadCarTypes(); 854 enableCheckboxes(_train != null); 855 typeCarPanelCheckBoxes.revalidate(); 856 repaint(); 857 } 858 859 private void loadCarTypes() { 860 int numberOfCheckboxes = getNumberOfCheckboxesPerLine(); // number per line 861 int x = 0; 862 int y = 1; // vertical position in panel 863 for (String type : InstanceManager.getDefault(CarTypes.class).getNames()) { 864 JCheckBox checkBox = new javax.swing.JCheckBox(); 865 typeCarCheckBoxes.add(checkBox); 866 checkBox.setText(type); 867 addTypeCheckBoxAction(checkBox); 868 addItemLeft(typeCarPanelCheckBoxes, checkBox, x++, y); 869 if (_train != null && _train.isTypeNameAccepted(type)) { 870 checkBox.setSelected(true); 871 } 872 if (x > numberOfCheckboxes) { 873 y++; 874 x = 0; 875 } 876 } 877 878 JPanel p = new JPanel(); 879 p.add(clearButton); 880 p.add(setButton); 881 p.add(autoSelectButton); 882 GridBagConstraints gc = new GridBagConstraints(); 883 gc.gridwidth = getNumberOfCheckboxesPerLine() + 1; 884 gc.gridy = ++y; 885 typeCarPanelCheckBoxes.add(p, gc); 886 887 } 888 889 private void updateEngineTypeCheckboxes() { 890 typeEngineCheckBoxes.clear(); 891 typeEnginePanelCheckBoxes.removeAll(); 892 loadEngineTypes(); 893 enableCheckboxes(_train != null); 894 typeEnginePanelCheckBoxes.revalidate(); 895 repaint(); 896 } 897 898 private void loadEngineTypes() { 899 int numberOfCheckboxes = getNumberOfCheckboxesPerLine(); // number per line 900 int x = 0; 901 int y = 1; 902 for (String type : InstanceManager.getDefault(EngineTypes.class).getNames()) { 903 JCheckBox checkBox = new javax.swing.JCheckBox(); 904 typeEngineCheckBoxes.add(checkBox); 905 checkBox.setText(type); 906 addTypeCheckBoxAction(checkBox); 907 addItemLeft(typeEnginePanelCheckBoxes, checkBox, x++, y); 908 if (_train != null && _train.isTypeNameAccepted(type)) { 909 checkBox.setSelected(true); 910 } 911 if (x > numberOfCheckboxes) { 912 y++; 913 x = 0; 914 } 915 } 916 } 917 918 private void updateRoadComboBoxes() { 919 updateCabooseRoadComboBox(); 920 updateEngineRoadComboBox(); 921 } 922 923 // update caboose road box based on radio selection 924 private void updateCabooseRoadComboBox() { 925 roadCabooseBox.removeAllItems(); 926 roadCabooseBox.addItem(NONE); 927 if (noneRadioButton.isSelected()) { 928 roadCabooseBox.setEnabled(false); 929 return; 930 } 931 roadCabooseBox.setEnabled(true); 932 List<String> roads; 933 if (cabooseRadioButton.isSelected()) { 934 roads = InstanceManager.getDefault(CarManager.class).getCabooseRoadNames(); 935 } else { 936 roads = InstanceManager.getDefault(CarManager.class).getFredRoadNames(); 937 } 938 for (String road : roads) { 939 roadCabooseBox.addItem(road); 940 } 941 if (_train != null) { 942 roadCabooseBox.setSelectedItem(_train.getCabooseRoad()); 943 } 944 OperationsPanel.padComboBox(roadCabooseBox); 945 } 946 947 private void updateEngineRoadComboBox() { 948 String engineModel = (String) modelEngineBox.getSelectedItem(); 949 if (engineModel == null) { 950 return; 951 } 952 InstanceManager.getDefault(EngineManager.class).updateEngineRoadComboBox(engineModel, roadEngineBox); 953 if (_train != null) { 954 roadEngineBox.setSelectedItem(_train.getEngineRoad()); 955 } 956 } 957 958 private void addTypeCheckBoxAction(JCheckBox b) { 959 b.addActionListener(new java.awt.event.ActionListener() { 960 @Override 961 public void actionPerformed(java.awt.event.ActionEvent e) { 962 typeCheckBoxActionPerformed(e); 963 } 964 }); 965 } 966 967 public void typeCheckBoxActionPerformed(java.awt.event.ActionEvent ae) { 968 JCheckBox b = (JCheckBox) ae.getSource(); 969 log.debug("checkbox change {}", b.getText()); 970 if (_train == null) { 971 return; 972 } 973 if (b.isSelected()) { 974 _train.addTypeName(b.getText()); 975 } else { 976 _train.deleteTypeName(b.getText()); 977 } 978 } 979 980 // the train's route shown as locations with checkboxes 981 private void updateLocationCheckboxes() { 982 updateRouteStatus(); 983 locationCheckBoxes.clear(); 984 locationPanelCheckBoxes.removeAll(); 985 int y = 0; // vertical position in panel 986 Route route = null; 987 if (_train != null) { 988 route = _train.getRoute(); 989 } 990 if (route != null) { 991 List<RouteLocation> routeList = route.getLocationsBySequenceList(); 992 for (RouteLocation rl : routeList) { 993 JCheckBox checkBox = new javax.swing.JCheckBox(); 994 locationCheckBoxes.add(checkBox); 995 checkBox.setText(rl.toString()); 996 checkBox.setName(rl.getId()); 997 addItemLeft(locationPanelCheckBoxes, checkBox, 0, y++); 998 Location loc = InstanceManager.getDefault(LocationManager.class).getLocationByName(rl.getName()); 999 // does the location exist? 1000 if (loc != null) { 1001 // need to listen for name and direction changes 1002 loc.removePropertyChangeListener(this); 1003 loc.addPropertyChangeListener(this); 1004 boolean services = false; 1005 // does train direction service location? 1006 if ((rl.getTrainDirection() & loc.getTrainDirections()) != 0) { 1007 services = true; 1008 } // train must service last location or single location 1009 else if (_train.isLocalSwitcher() || rl == _train.getTrainTerminatesRouteLocation()) { 1010 services = true; 1011 } 1012 // check can drop and pick up, and moves > 0 1013 if (services && 1014 (rl.isDropAllowed() || rl.isPickUpAllowed() || rl.isLocalMovesAllowed()) && 1015 rl.getMaxCarMoves() > 0) { 1016 checkBox.setSelected(!_train.isLocationSkipped(rl)); 1017 } else { 1018 checkBox.setEnabled(false); 1019 } 1020 addLocationCheckBoxAction(checkBox); 1021 } else { 1022 checkBox.setEnabled(false); 1023 } 1024 } 1025 } 1026 locationPanelCheckBoxes.revalidate(); 1027 } 1028 1029 private void updateRouteStatus() { 1030 Route route = null; 1031 textRouteStatus.setText(NONE); // clear out previous status 1032 if (_train != null) { 1033 route = _train.getRoute(); 1034 } 1035 if (route != null) { 1036 if (!route.getStatus().equals(Route.OKAY)) { 1037 textRouteStatus.setText(route.getStatus()); 1038 textRouteStatus.setForeground(Color.RED); 1039 } 1040 } 1041 } 1042 1043 RouteEditFrame ref; 1044 1045 private void editAddRoute() { 1046 log.debug("Edit/add route"); 1047 if (ref != null) { 1048 ref.dispose(); 1049 } 1050 ref = new RouteEditFrame(); 1051 setChildFrame(ref); 1052 Route route = (Route) routeBox.getSelectedItem(); 1053 ref.initComponents(route, _train); 1054 } 1055 1056 private void updateDepartureTime() { 1057 dayBox.setSelectedItem(_train.getDepartureTimeDay()); 1058 hourBox.setSelectedItem(_train.getDepartureTimeHour()); 1059 minuteBox.setSelectedItem(_train.getDepartureTimeMinute()); 1060 // check to see if route has a departure time from the 1st location 1061 RouteLocation rl = _train.getTrainDepartsRouteLocation(); 1062 if (rl != null && !rl.getDepartureTimeHourMinutes().equals(NONE)) { 1063 dayBox.setEnabled(false); 1064 hourBox.setEnabled(false); 1065 minuteBox.setEnabled(false); 1066 } else { 1067 dayBox.setEnabled(!_train.isBuilt()); 1068 hourBox.setEnabled(!_train.isBuilt()); 1069 minuteBox.setEnabled(!_train.isBuilt()); 1070 } 1071 } 1072 1073 private void updateRoadAndLoadStatus() { 1074 if (_train != null) { 1075 // road options 1076 if (_train.getCarRoadOption().equals(Train.INCLUDE_ROADS)) { 1077 roadOptionButton.setText(Bundle.getMessage( 1078 "AcceptOnly") + " " + _train.getCarRoadNames().length + " " + Bundle.getMessage("RoadsCar")); 1079 } else if (_train.getCarRoadOption().equals(Train.EXCLUDE_ROADS)) { 1080 roadOptionButton.setText(Bundle.getMessage( 1081 "Exclude") + " " + _train.getCarRoadNames().length + " " + Bundle.getMessage("RoadsCar")); 1082 } else if (_train.getCabooseRoadOption().equals(Train.INCLUDE_ROADS)) { 1083 roadOptionButton.setText(Bundle.getMessage( 1084 "AcceptOnly") + 1085 " " + 1086 _train.getCabooseRoadNames().length + 1087 " " + 1088 Bundle.getMessage("RoadsCaboose")); 1089 } else if (_train.getCabooseRoadOption().equals(Train.EXCLUDE_ROADS)) { 1090 roadOptionButton.setText(Bundle.getMessage( 1091 "Exclude") + 1092 " " + 1093 _train.getCabooseRoadNames().length + 1094 " " + 1095 Bundle.getMessage("RoadsCaboose")); 1096 } else if (_train.getLocoRoadOption().equals(Train.INCLUDE_ROADS)) { 1097 roadOptionButton.setText(Bundle.getMessage( 1098 "AcceptOnly") + " " + _train.getLocoRoadNames().length + " " + Bundle.getMessage("RoadsLoco")); 1099 } else if (_train.getLocoRoadOption().equals(Train.EXCLUDE_ROADS)) { 1100 roadOptionButton.setText(Bundle.getMessage( 1101 "Exclude") + " " + _train.getLocoRoadNames().length + " " + Bundle.getMessage("RoadsLoco")); 1102 } else { 1103 roadOptionButton.setText(Bundle.getMessage("AcceptAll")); 1104 } 1105 // load options 1106 if (_train.getLoadOption().equals(Train.ALL_LOADS)) { 1107 loadOptionButton.setText(Bundle.getMessage("AcceptAll")); 1108 } else if (_train.getLoadOption().equals(Train.INCLUDE_LOADS)) { 1109 loadOptionButton.setText(Bundle.getMessage( 1110 "AcceptOnly") + " " + _train.getLoadNames().length + " " + Bundle.getMessage("Loads")); 1111 } else { 1112 loadOptionButton.setText(Bundle.getMessage( 1113 "Exclude") + " " + _train.getLoadNames().length + " " + Bundle.getMessage("Loads")); 1114 } 1115 if (!_train.getCarRoadOption().equals(Train.ALL_ROADS) || 1116 !_train.getCabooseRoadOption().equals(Train.ALL_ROADS) || 1117 !_train.getLocoRoadOption().equals(Train.ALL_ROADS) || 1118 !_train.getLoadOption().equals(Train.ALL_LOADS)) { 1119 roadAndLoadStatusPanel.setVisible(true); 1120 } 1121 } 1122 } 1123 1124 List<Frame> children = new ArrayList<>(); 1125 1126 public void setChildFrame(Frame frame) { 1127 if (children.contains(frame)) { 1128 return; 1129 } 1130 children.add(frame); 1131 } 1132 1133 @Override 1134 public void dispose() { 1135 InstanceManager.getDefault(LocationManager.class).removePropertyChangeListener(this); 1136 InstanceManager.getDefault(EngineTypes.class).removePropertyChangeListener(this); 1137 InstanceManager.getDefault(EngineModels.class).removePropertyChangeListener(this); 1138 InstanceManager.getDefault(CarTypes.class).removePropertyChangeListener(this); 1139 InstanceManager.getDefault(CarRoads.class).removePropertyChangeListener(this); 1140 routeManager.removePropertyChangeListener(this); 1141 for (Frame frame : children) { 1142 frame.dispose(); 1143 } 1144 if (_train != null) { 1145 _train.removePropertyChangeListener(this); 1146 Route route = _train.getRoute(); 1147 if (route != null) { 1148 for (RouteLocation rl : route.getLocationsBySequenceList()) { 1149 Location loc = rl.getLocation(); 1150 if (loc != null) { 1151 loc.removePropertyChangeListener(this); 1152 } 1153 } 1154 } 1155 } 1156 super.dispose(); 1157 } 1158 1159 @Override 1160 public void propertyChange(java.beans.PropertyChangeEvent e) { 1161 if (Control.SHOW_PROPERTY) { 1162 log.debug("Property change ({}) old: ({}) new: ({})", e.getPropertyName(), e.getOldValue(), 1163 e.getNewValue()); // NOI18N 1164 } 1165 if (e.getPropertyName().equals(CarTypes.CARTYPES_CHANGED_PROPERTY) || 1166 e.getPropertyName().equals(Train.TYPES_CHANGED_PROPERTY)) { 1167 updateCarTypeCheckboxes(); 1168 } 1169 if (e.getPropertyName().equals(EngineTypes.ENGINETYPES_CHANGED_PROPERTY)) { 1170 updateEngineTypeCheckboxes(); 1171 } 1172 if (e.getPropertyName().equals(RouteManager.LISTLENGTH_CHANGED_PROPERTY)) { 1173 updateRouteComboBox(); 1174 } 1175 if (e.getPropertyName().equals(Route.LISTCHANGE_CHANGED_PROPERTY) || 1176 e.getPropertyName().equals(LocationManager.LISTLENGTH_CHANGED_PROPERTY) || 1177 e.getPropertyName().equals(Location.NAME_CHANGED_PROPERTY) || 1178 e.getPropertyName().equals(Location.TRAIN_DIRECTION_CHANGED_PROPERTY)) { 1179 updateLocationCheckboxes(); 1180 pack(); 1181 repaint(); 1182 } 1183 if (e.getPropertyName().equals(CarRoads.CARROADS_CHANGED_PROPERTY)) { 1184 updateRoadComboBoxes(); 1185 } 1186 if (e.getPropertyName().equals(EngineModels.ENGINEMODELS_CHANGED_PROPERTY)) { 1187 InstanceManager.getDefault(EngineModels.class).updateComboBox(modelEngineBox); 1188 modelEngineBox.insertItemAt(NONE, 0); 1189 modelEngineBox.setSelectedIndex(0); 1190 if (_train != null) { 1191 modelEngineBox.setSelectedItem(_train.getEngineModel()); 1192 } 1193 } 1194 if (e.getPropertyName().equals(Train.DEPARTURETIME_CHANGED_PROPERTY)) { 1195 updateDepartureTime(); 1196 } 1197 if (e.getPropertyName().equals(Train.TRAIN_ROUTE_CHANGED_PROPERTY) && _train != null) { 1198 routeBox.setSelectedItem(_train.getRoute()); 1199 } 1200 if (e.getPropertyName().equals(Route.ROUTE_STATUS_CHANGED_PROPERTY)) { 1201 updateDepartureTime(); 1202 enableButtons(_train != null); 1203 updateRouteStatus(); 1204 } 1205 if (e.getPropertyName().equals(Train.ROADS_CHANGED_PROPERTY) || 1206 e.getPropertyName().equals(Train.LOADS_CHANGED_PROPERTY)) { 1207 updateRoadAndLoadStatus(); 1208 } 1209 } 1210 1211 private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(TrainEditFrame.class); 1212}