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