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.getOnlyText(_train.getCommentWithColor())); 347 cabooseRadioButton.setSelected(_train.isCabooseNeeded()); 348 fredRadioButton.setSelected(_train.isFredNeeded()); 349 updateDepartureTime(); 350 enableButtons(true); 351 // listen for train changes 352 _train.addPropertyChangeListener(this); 353 354 Route route = _train.getRoute(); 355 if (route != null) { 356 if (_train.getTrainDepartsRouteLocation() != null && 357 _train.getTrainDepartsRouteLocation().getLocation() != null && 358 !_train.getTrainDepartsRouteLocation().getLocation().isStaging()) 359 numEnginesBox.addItem(Train.AUTO_HPT); 360 } 361 numEnginesBox.setSelectedItem(_train.getNumberEngines()); 362 } else { 363 setTitle(Bundle.getMessage("TitleTrainAdd")); 364 enableButtons(false); 365 } 366 367 modelEngineBox.setEnabled(!numEnginesBox.getSelectedItem().equals("0")); 368 roadEngineBox.setEnabled(!numEnginesBox.getSelectedItem().equals("0")); 369 370 // load route location checkboxes 371 updateLocationCheckboxes(); 372 updateCarTypeCheckboxes(); 373 updateEngineTypeCheckboxes(); 374 updateRoadAndLoadStatus(); 375 updateCabooseRoadComboBox(); 376 updateEngineRoadComboBox(); 377 378 // setup combobox 379 addComboBoxAction(numEnginesBox); 380 addComboBoxAction(routeBox); 381 addComboBoxAction(modelEngineBox); 382 383 // get notified if combo box gets modified 384 routeManager.addPropertyChangeListener(this); 385 // get notified if car types or roads gets modified 386 InstanceManager.getDefault(CarTypes.class).addPropertyChangeListener(this); 387 InstanceManager.getDefault(CarRoads.class).addPropertyChangeListener(this); 388 InstanceManager.getDefault(EngineTypes.class).addPropertyChangeListener(this); 389 InstanceManager.getDefault(EngineModels.class).addPropertyChangeListener(this); 390 InstanceManager.getDefault(LocationManager.class).addPropertyChangeListener(this); 391 392 initMinimumSize(new Dimension(Control.panelWidth600, Control.panelHeight600)); 393 } 394 395 private void loadToolMenu(JMenu toolMenu) { 396 toolMenu.removeAll(); 397 // first 4 menu items will also close when the edit train window closes 398 toolMenu.add(new TrainEditBuildOptionsAction(this)); 399 toolMenu.add(new TrainLoadOptionsAction(this)); 400 toolMenu.add(new TrainRoadOptionsAction(this)); 401 toolMenu.add(new TrainManifestOptionAction(this)); 402 toolMenu.addSeparator(); 403 toolMenu.add(new TrainManualBuildAction(_train)); 404 toolMenu.addSeparator(); 405 toolMenu.add(new TrainCopyAction(_train)); 406 toolMenu.addSeparator(); 407 // scripts window closes when the edit train window closes 408 toolMenu.add(new TrainScriptAction(this)); 409 toolMenu.addSeparator(); 410 toolMenu.add(new TrainConductorAction(_train)); 411 toolMenu.addSeparator(); 412 toolMenu.add(new TrainByCarTypeAction(_train)); 413 toolMenu.addSeparator(); 414 toolMenu.add(new PrintTrainAction(false, _train)); 415 toolMenu.add(new PrintTrainAction(true, _train)); 416 toolMenu.add(new PrintTrainManifestAction(false, _train)); 417 toolMenu.add(new PrintTrainManifestAction(true, _train)); 418 toolMenu.add(new PrintShowCarsInTrainRouteAction(false, _train)); 419 toolMenu.add(new PrintShowCarsInTrainRouteAction(true, _train)); 420 toolMenu.add(new PrintTrainBuildReportAction(false, _train)); 421 toolMenu.add(new PrintTrainBuildReportAction(true, _train)); 422 toolMenu.add(new PrintSavedTrainManifestAction(false, _train)); 423 toolMenu.add(new PrintSavedTrainManifestAction(true, _train)); 424 toolMenu.add(new PrintSavedBuildReportAction(false, _train)); 425 toolMenu.add(new PrintSavedBuildReportAction(true, _train)); 426 } 427 428 // Save, Delete, Add, Edit, Reset, Set, Clear 429 @Override 430 public void buttonActionPerformed(java.awt.event.ActionEvent ae) { 431 Train train = trainManager.getTrainByName(trainNameTextField.getText().trim()); 432 if (ae.getSource() == saveTrainButton) { 433 log.debug("train save button activated"); 434 if (_train == null && train == null) { 435 saveNewTrain(); // this can't happen, Save button is disabled 436 } else { 437 if (train != null && train != _train) { 438 reportTrainExists(Bundle.getMessage("save")); 439 return; 440 } 441 // check to see if user supplied a route 442 if (!checkRoute() || !saveTrain()) { 443 return; 444 } 445 } 446 if (Setup.isCloseWindowOnSaveEnabled()) { 447 dispose(); 448 } 449 } 450 if (ae.getSource() == deleteTrainButton) { 451 log.debug("train delete button activated"); 452 if (train == null) { 453 return; 454 } 455 if (train.isBuilt()) { 456 JmriJOptionPane.showMessageDialog(this, 457 Bundle.getMessage("BuiltTrain"), 458 Bundle.getMessage("CanNotDeleteTrain"), JmriJOptionPane.ERROR_MESSAGE); 459 return; 460 } 461 if (!_train.reset()) { 462 JmriJOptionPane.showMessageDialog(this, 463 Bundle.getMessage("TrainIsInRoute", 464 train.getTrainTerminatesName()), 465 Bundle.getMessage("CanNotDeleteTrain"), JmriJOptionPane.ERROR_MESSAGE); 466 return; 467 } 468 if (JmriJOptionPane.showConfirmDialog(this, 469 Bundle.getMessage("deleteMsg", train.getName()), 470 Bundle.getMessage("deleteTrain"), JmriJOptionPane.YES_NO_OPTION) != JmriJOptionPane.YES_OPTION) { 471 return; 472 } 473 routeBox.setSelectedItem(null); 474 trainManager.deregister(train); 475 for (Frame frame : children) { 476 frame.dispose(); 477 } 478 _train = null; 479 enableButtons(false); 480 // save train file 481 OperationsXml.save(); 482 } 483 if (ae.getSource() == addTrainButton) { 484 if (train != null) { 485 reportTrainExists(Bundle.getMessage("add")); 486 return; 487 } 488 saveNewTrain(); 489 } 490 if (ae.getSource() == editButton) { 491 editAddRoute(); 492 } 493 if (ae.getSource() == setButton) { 494 selectCheckboxes(true); 495 } 496 if (ae.getSource() == clearButton) { 497 selectCheckboxes(false); 498 } 499 if (ae.getSource() == autoSelectButton) { 500 autoSelect(); 501 } 502 if (ae.getSource() == resetButton) { 503 if (_train != null) { 504 if (_train.checkDepartureTrack()) { 505 int results = JmriJOptionPane.showConfirmDialog(null, 506 Bundle.getMessage("StagingTrackUsed", 507 _train.getDepartureTrack().getName()), 508 Bundle.getMessage("ShouldNotResetTrain"), JmriJOptionPane.OK_CANCEL_OPTION); 509 if (results == JmriJOptionPane.OK_CANCEL_OPTION) { 510 return; 511 } 512 } 513 Train t = trainManager.getTrainBuiltAfter(train); 514 if (Setup.isBuildOnTime() && t != null) { 515 JmriJOptionPane.showMessageDialog(null, 516 Bundle.getMessage("TrainAfterBuilt", t, train), Bundle.getMessage("CanNotResetTrain"), 517 JmriJOptionPane.WARNING_MESSAGE); 518 } else if (!_train.reset()) { 519 JmriJOptionPane.showMessageDialog(this, 520 Bundle.getMessage("TrainIsInRoute", 521 _train.getTrainTerminatesName()), 522 Bundle.getMessage("CanNotResetTrain"), JmriJOptionPane.ERROR_MESSAGE); 523 } 524 } 525 } 526 } 527 528 @Override 529 public void radioButtonActionPerformed(java.awt.event.ActionEvent ae) { 530 log.debug("radio button activated"); 531 if (_train != null) { 532 if (ae.getSource() == noneRadioButton || 533 ae.getSource() == cabooseRadioButton || 534 ae.getSource() == fredRadioButton) { 535 updateCabooseRoadComboBox(); 536 } 537 } 538 } 539 540 private void saveNewTrain() { 541 if (!checkName(Bundle.getMessage("add"))) { 542 return; 543 } 544 Train train = trainManager.newTrain(trainNameTextField.getText()); 545 _train = train; 546 _train.addPropertyChangeListener(this); 547 548 // update check boxes 549 updateCarTypeCheckboxes(); 550 updateEngineTypeCheckboxes(); 551 // enable check boxes and buttons 552 enableButtons(true); 553 saveTrain(); 554 loadToolMenu(toolMenu); 555 } 556 557 private boolean saveTrain() { 558 if (!checkName(Bundle.getMessage("save"))) { 559 return false; 560 } 561 if (!checkModel() || !checkEngineRoad() || !checkCabooseRoad()) { 562 return false; 563 } 564 if (!_train.getName().equals(trainNameTextField.getText().trim()) || 565 !_train.getRawDescription().equals(trainDescriptionTextField.getText()) || 566 !_train.getCommentWithColor().equals( 567 TrainCommon.formatColorString(commentTextArea.getText(), commentColorChooser.getColor(), 568 boldCheckBox.isSelected()))) { 569 _train.setModified(true); 570 } 571 _train.setDepartureTime(dayBox.getSelectedItem().toString(), hourBox.getSelectedItem().toString(), 572 minuteBox.getSelectedItem().toString()); 573 _train.setNumberEngines((String) numEnginesBox.getSelectedItem()); 574 if (_train.getNumberEngines().equals("0")) { 575 modelEngineBox.setSelectedIndex(0); 576 roadEngineBox.setSelectedIndex(0); 577 } 578 _train.setEngineRoad((String) roadEngineBox.getSelectedItem()); 579 _train.setEngineModel((String) modelEngineBox.getSelectedItem()); 580 if (cabooseRadioButton.isSelected()) { 581 _train.setRequirements(Train.CABOOSE); 582 } 583 if (fredRadioButton.isSelected()) { 584 _train.setRequirements(Train.FRED); 585 } 586 if (noneRadioButton.isSelected()) { 587 _train.setRequirements(Train.NO_CABOOSE_OR_FRED); 588 } 589 _train.setCabooseRoad((String) roadCabooseBox.getSelectedItem()); 590 _train.setName(trainNameTextField.getText().trim()); 591 _train.setDescription(trainDescriptionTextField.getText()); 592 _train.setComment(TrainCommon.formatColorString(commentTextArea.getText(), commentColorChooser.getColor(), 593 boldCheckBox.isSelected())); 594 // save train file 595 OperationsXml.save(); 596 return true; 597 } 598 599 /** 600 * @return true if name isn't too long and is at least one character 601 */ 602 private boolean checkName(String s) { 603 String trainName = trainNameTextField.getText().trim(); 604 if (trainName.isEmpty()) { 605 log.debug("Must enter a train name"); 606 JmriJOptionPane.showMessageDialog(this, Bundle.getMessage("MustEnterName"), 607 Bundle.getMessage("CanNot", s), JmriJOptionPane.ERROR_MESSAGE); 608 return false; 609 } 610 if (trainName.length() > Control.max_len_string_train_name) { 611 JmriJOptionPane.showMessageDialog(this, 612 Bundle.getMessage("TrainNameLess", 613 Control.max_len_string_train_name + 1), 614 Bundle.getMessage("CanNot", s), JmriJOptionPane.ERROR_MESSAGE); 615 return false; 616 } 617 if (!OperationsXml.checkFileName(trainName)) { // NOI18N 618 log.error("Train name must not contain reserved characters"); 619 JmriJOptionPane.showMessageDialog(this, 620 Bundle.getMessage("NameResChar") + NEW_LINE + Bundle.getMessage("ReservedChar"), 621 Bundle.getMessage("CanNot", s), JmriJOptionPane.ERROR_MESSAGE); 622 return false; 623 } 624 625 return true; 626 } 627 628 private boolean checkModel() { 629 String model = (String) modelEngineBox.getSelectedItem(); 630 if (numEnginesBox.getSelectedItem().equals("0") || model.equals(NONE)) { 631 return true; 632 } 633 String type = InstanceManager.getDefault(EngineModels.class).getModelType(model); 634 if (!_train.isTypeNameAccepted(type)) { 635 JmriJOptionPane.showMessageDialog(this, 636 Bundle.getMessage("TrainModelService", model, type), 637 Bundle.getMessage("CanNot", Bundle.getMessage("save")), 638 JmriJOptionPane.ERROR_MESSAGE); 639 return false; 640 } 641 if (roadEngineBox.getItemCount() == 1) { 642 log.debug("No locos available that match the model selected!"); 643 JmriJOptionPane.showMessageDialog(this, 644 Bundle.getMessage("NoLocosModel", model), 645 Bundle.getMessage("TrainWillNotBuild", _train.getName()), 646 JmriJOptionPane.WARNING_MESSAGE); 647 } 648 return true; 649 } 650 651 private boolean checkEngineRoad() { 652 String road = (String) roadEngineBox.getSelectedItem(); 653 if (numEnginesBox.getSelectedItem().equals("0") || road.equals(NONE)) { 654 return true; 655 } 656 if (!road.equals(NONE) && !_train.isLocoRoadNameAccepted(road)) { 657 JmriJOptionPane.showMessageDialog(this, 658 Bundle.getMessage("TrainNotThisRoad", _train.getName(), road), 659 Bundle.getMessage("TrainWillNotBuild", _train.getName()), 660 JmriJOptionPane.WARNING_MESSAGE); 661 return false; 662 } 663 for (RollingStock rs : InstanceManager.getDefault(EngineManager.class).getList()) { 664 if (!_train.isTypeNameAccepted(rs.getTypeName())) { 665 continue; 666 } 667 if (rs.getRoadName().equals(road)) { 668 return true; 669 } 670 } 671 JmriJOptionPane.showMessageDialog(this, 672 Bundle.getMessage("NoLocoRoad", road), 673 Bundle.getMessage("TrainWillNotBuild", _train.getName()), 674 JmriJOptionPane.WARNING_MESSAGE); 675 return false; // couldn't find a loco with the selected road 676 } 677 678 private boolean checkCabooseRoad() { 679 String road = (String) roadCabooseBox.getSelectedItem(); 680 if (!road.equals(NONE) && cabooseRadioButton.isSelected() && !_train.isCabooseRoadNameAccepted(road)) { 681 JmriJOptionPane.showMessageDialog(this, 682 Bundle.getMessage("TrainNotCabooseRoad", _train.getName(), road), 683 Bundle.getMessage("TrainWillNotBuild", _train.getName()), 684 JmriJOptionPane.WARNING_MESSAGE); 685 return false; 686 } 687 return true; 688 } 689 690 private boolean checkRoute() { 691 if (_train.getRoute() == null) { 692 JmriJOptionPane.showMessageDialog(this, Bundle.getMessage("TrainNeedsRoute"), 693 Bundle.getMessage("TrainNoRoute"), 694 JmriJOptionPane.WARNING_MESSAGE); 695 return false; 696 } 697 return true; 698 699 } 700 701 private void reportTrainExists(String s) { 702 log.debug("Can not {}, train already exists", s); 703 JmriJOptionPane.showMessageDialog(this, Bundle.getMessage("TrainNameExists"), 704 Bundle.getMessage("CanNot", s), JmriJOptionPane.ERROR_MESSAGE); 705 } 706 707 private void enableButtons(boolean enabled) { 708 toolMenu.setEnabled(enabled); 709 editButton.setEnabled(enabled); 710 routeBox.setEnabled(enabled && _train != null && !_train.isBuilt()); 711 clearButton.setEnabled(enabled); 712 resetButton.setEnabled(enabled); 713 autoSelectButton.setEnabled(enabled); 714 setButton.setEnabled(enabled); 715 saveTrainButton.setEnabled(enabled); 716 deleteTrainButton.setEnabled(enabled); 717 numEnginesBox.setEnabled(enabled); 718 enableCheckboxes(enabled); 719 noneRadioButton.setEnabled(enabled); 720 fredRadioButton.setEnabled(enabled); 721 cabooseRadioButton.setEnabled(enabled); 722 roadOptionButton.setEnabled(enabled); 723 loadOptionButton.setEnabled(enabled); 724 // the inverse! 725 addTrainButton.setEnabled(!enabled); 726 } 727 728 private void selectCheckboxes(boolean enable) { 729 for (int i = 0; i < typeCarCheckBoxes.size(); i++) { 730 JCheckBox checkBox = typeCarCheckBoxes.get(i); 731 checkBox.setSelected(enable); 732 if (_train != null) { 733 _train.removePropertyChangeListener(this); 734 if (enable) { 735 _train.addTypeName(checkBox.getText()); 736 } else { 737 _train.deleteTypeName(checkBox.getText()); 738 } 739 _train.addPropertyChangeListener(this); 740 } 741 } 742 } 743 744 private void autoSelect() { 745 if (_train != null) { 746 Route route = _train.getRoute(); 747 if (route != null) { 748 typeLoop: for (String type : InstanceManager.getDefault(CarTypes.class).getNames()) { 749 for (RouteLocation rl : route.getLocationsBySequenceList()) { 750 if (rl.getMaxCarMoves() > 0 && (rl.isDropAllowed() || rl.isLocalMovesAllowed())) { 751 if (!_train.isLocationSkipped(rl) && rl.getLocation().acceptsTypeName(type)) { 752 continue typeLoop; 753 } 754 } 755 } 756 _train.deleteTypeName(type); 757 } 758 } 759 } 760 } 761 762 @Override 763 public void comboBoxActionPerformed(java.awt.event.ActionEvent ae) { 764 if (_train == null) { 765 return; 766 } 767 if (ae.getSource() == numEnginesBox) { 768 modelEngineBox.setEnabled(!numEnginesBox.getSelectedItem().equals("0")); 769 roadEngineBox.setEnabled(!numEnginesBox.getSelectedItem().equals("0")); 770 } 771 if (ae.getSource() == modelEngineBox) { 772 updateEngineRoadComboBox(); 773 } 774 if (ae.getSource() == routeBox) { 775 if (routeBox.isEnabled()) { 776 Route route = _train.getRoute(); 777 if (route != null) { 778 route.removePropertyChangeListener(this); 779 } 780 Object selected = routeBox.getSelectedItem(); 781 if (selected != null) { 782 route = (Route) selected; 783 _train.setRoute(route); 784 route.addPropertyChangeListener(this); 785 } else { 786 _train.setRoute(null); 787 } 788 updateLocationCheckboxes(); 789 updateDepartureTime(); 790 pack(); 791 repaint(); 792 } 793 } 794 } 795 796 private void enableCheckboxes(boolean enable) { 797 for (int i = 0; i < typeCarCheckBoxes.size(); i++) { 798 typeCarCheckBoxes.get(i).setEnabled(enable); 799 } 800 for (int i = 0; i < typeEngineCheckBoxes.size(); i++) { 801 typeEngineCheckBoxes.get(i).setEnabled(enable); 802 } 803 } 804 805 private void addLocationCheckBoxAction(JCheckBox b) { 806 b.addActionListener(new java.awt.event.ActionListener() { 807 @Override 808 public void actionPerformed(java.awt.event.ActionEvent e) { 809 locationCheckBoxActionPerformed(e); 810 } 811 }); 812 } 813 814 public void locationCheckBoxActionPerformed(java.awt.event.ActionEvent ae) { 815 JCheckBox b = (JCheckBox) ae.getSource(); 816 log.debug("checkbox change {}", b.getText()); 817 if (_train == null) { 818 return; 819 } 820 String id = b.getName(); 821 RouteLocation rl = _train.getRoute().getRouteLocationById(id); 822 if (b.isSelected()) { 823 _train.deleteTrainSkipsLocation(rl); 824 } else { 825 // check to see if skipped location is staging 826 if (_train.getRoute().getRouteLocationById(id).getLocation().isStaging()) { 827 int result = JmriJOptionPane.showConfirmDialog(this, 828 Bundle.getMessage("TrainRouteStaging", 829 _train.getName(), _train.getRoute().getRouteLocationById(id).getName()), 830 Bundle.getMessage("TrainRouteNotStaging"), JmriJOptionPane.OK_CANCEL_OPTION); 831 if (result != JmriJOptionPane.OK_OPTION) { 832 b.setSelected(true); 833 return; // don't skip staging 834 } 835 } 836 _train.addTrainSkipsLocation(rl); 837 } 838 } 839 840 private void updateRouteComboBox() { 841 routeBox.setEnabled(false); 842 routeManager.updateComboBox(routeBox); 843 if (_train != null) { 844 routeBox.setSelectedItem(_train.getRoute()); 845 } 846 routeBox.setEnabled(true); 847 } 848 849 private void updateCarTypeCheckboxes() { 850 typeCarCheckBoxes.clear(); 851 typeCarPanelCheckBoxes.removeAll(); 852 loadCarTypes(); 853 enableCheckboxes(_train != null); 854 typeCarPanelCheckBoxes.revalidate(); 855 repaint(); 856 } 857 858 private void loadCarTypes() { 859 int numberOfCheckboxes = getNumberOfCheckboxesPerLine(); // number per line 860 int x = 0; 861 int y = 1; // vertical position in panel 862 for (String type : InstanceManager.getDefault(CarTypes.class).getNames()) { 863 JCheckBox checkBox = new javax.swing.JCheckBox(); 864 typeCarCheckBoxes.add(checkBox); 865 checkBox.setText(type); 866 addTypeCheckBoxAction(checkBox); 867 addItemLeft(typeCarPanelCheckBoxes, checkBox, x++, y); 868 if (_train != null && _train.isTypeNameAccepted(type)) { 869 checkBox.setSelected(true); 870 } 871 if (x > numberOfCheckboxes) { 872 y++; 873 x = 0; 874 } 875 } 876 877 JPanel p = new JPanel(); 878 p.add(clearButton); 879 p.add(setButton); 880 p.add(autoSelectButton); 881 GridBagConstraints gc = new GridBagConstraints(); 882 gc.gridwidth = getNumberOfCheckboxesPerLine() + 1; 883 gc.gridy = ++y; 884 typeCarPanelCheckBoxes.add(p, gc); 885 886 } 887 888 private void updateEngineTypeCheckboxes() { 889 typeEngineCheckBoxes.clear(); 890 typeEnginePanelCheckBoxes.removeAll(); 891 loadEngineTypes(); 892 enableCheckboxes(_train != null); 893 typeEnginePanelCheckBoxes.revalidate(); 894 repaint(); 895 } 896 897 private void loadEngineTypes() { 898 int numberOfCheckboxes = getNumberOfCheckboxesPerLine(); // number per line 899 int x = 0; 900 int y = 1; 901 for (String type : InstanceManager.getDefault(EngineTypes.class).getNames()) { 902 JCheckBox checkBox = new javax.swing.JCheckBox(); 903 typeEngineCheckBoxes.add(checkBox); 904 checkBox.setText(type); 905 addTypeCheckBoxAction(checkBox); 906 addItemLeft(typeEnginePanelCheckBoxes, checkBox, x++, y); 907 if (_train != null && _train.isTypeNameAccepted(type)) { 908 checkBox.setSelected(true); 909 } 910 if (x > numberOfCheckboxes) { 911 y++; 912 x = 0; 913 } 914 } 915 } 916 917 private void updateRoadComboBoxes() { 918 updateCabooseRoadComboBox(); 919 updateEngineRoadComboBox(); 920 } 921 922 // update caboose road box based on radio selection 923 private void updateCabooseRoadComboBox() { 924 roadCabooseBox.removeAllItems(); 925 roadCabooseBox.addItem(NONE); 926 if (noneRadioButton.isSelected()) { 927 roadCabooseBox.setEnabled(false); 928 return; 929 } 930 roadCabooseBox.setEnabled(true); 931 List<String> roads; 932 if (cabooseRadioButton.isSelected()) { 933 roads = InstanceManager.getDefault(CarManager.class).getCabooseRoadNames(); 934 } else { 935 roads = InstanceManager.getDefault(CarManager.class).getFredRoadNames(); 936 } 937 for (String road : roads) { 938 roadCabooseBox.addItem(road); 939 } 940 if (_train != null) { 941 roadCabooseBox.setSelectedItem(_train.getCabooseRoad()); 942 } 943 OperationsPanel.padComboBox(roadCabooseBox); 944 } 945 946 private void updateEngineRoadComboBox() { 947 String engineModel = (String) modelEngineBox.getSelectedItem(); 948 if (engineModel == null) { 949 return; 950 } 951 InstanceManager.getDefault(EngineManager.class).updateEngineRoadComboBox(engineModel, roadEngineBox); 952 if (_train != null) { 953 roadEngineBox.setSelectedItem(_train.getEngineRoad()); 954 } 955 } 956 957 private void addTypeCheckBoxAction(JCheckBox b) { 958 b.addActionListener(new java.awt.event.ActionListener() { 959 @Override 960 public void actionPerformed(java.awt.event.ActionEvent e) { 961 typeCheckBoxActionPerformed(e); 962 } 963 }); 964 } 965 966 public void typeCheckBoxActionPerformed(java.awt.event.ActionEvent ae) { 967 JCheckBox b = (JCheckBox) ae.getSource(); 968 log.debug("checkbox change {}", b.getText()); 969 if (_train == null) { 970 return; 971 } 972 if (b.isSelected()) { 973 _train.addTypeName(b.getText()); 974 } else { 975 _train.deleteTypeName(b.getText()); 976 } 977 } 978 979 // the train's route shown as locations with checkboxes 980 private void updateLocationCheckboxes() { 981 updateRouteStatus(); 982 locationCheckBoxes.clear(); 983 locationPanelCheckBoxes.removeAll(); 984 int y = 0; // vertical position in panel 985 Route route = null; 986 if (_train != null) { 987 route = _train.getRoute(); 988 } 989 if (route != null) { 990 List<RouteLocation> routeList = route.getLocationsBySequenceList(); 991 for (RouteLocation rl : routeList) { 992 JCheckBox checkBox = new javax.swing.JCheckBox(); 993 locationCheckBoxes.add(checkBox); 994 checkBox.setText(rl.toString()); 995 checkBox.setName(rl.getId()); 996 addItemLeft(locationPanelCheckBoxes, checkBox, 0, y++); 997 Location loc = InstanceManager.getDefault(LocationManager.class).getLocationByName(rl.getName()); 998 // does the location exist? 999 if (loc != null) { 1000 // need to listen for name and direction changes 1001 loc.removePropertyChangeListener(this); 1002 loc.addPropertyChangeListener(this); 1003 boolean services = false; 1004 // does train direction service location? 1005 if ((rl.getTrainDirection() & loc.getTrainDirections()) != 0) { 1006 services = true; 1007 } // train must service last location or single location 1008 else if (_train.isLocalSwitcher() || rl == _train.getTrainTerminatesRouteLocation()) { 1009 services = true; 1010 } 1011 // check can drop and pick up, and moves > 0 1012 if (services && 1013 (rl.isDropAllowed() || rl.isPickUpAllowed() || rl.isLocalMovesAllowed()) && 1014 rl.getMaxCarMoves() > 0) { 1015 checkBox.setSelected(!_train.isLocationSkipped(rl)); 1016 } else { 1017 checkBox.setEnabled(false); 1018 } 1019 addLocationCheckBoxAction(checkBox); 1020 } else { 1021 checkBox.setEnabled(false); 1022 } 1023 } 1024 } 1025 locationPanelCheckBoxes.revalidate(); 1026 } 1027 1028 private void updateRouteStatus() { 1029 Route route = null; 1030 textRouteStatus.setText(NONE); // clear out previous status 1031 if (_train != null) { 1032 route = _train.getRoute(); 1033 } 1034 if (route != null) { 1035 if (!route.getStatus().equals(Route.OKAY)) { 1036 textRouteStatus.setText(route.getStatus()); 1037 textRouteStatus.setForeground(Color.RED); 1038 } 1039 } 1040 } 1041 1042 RouteEditFrame ref; 1043 1044 private void editAddRoute() { 1045 log.debug("Edit/add route"); 1046 if (ref != null) { 1047 ref.dispose(); 1048 } 1049 ref = new RouteEditFrame(); 1050 setChildFrame(ref); 1051 Route route = null; 1052 Object selected = routeBox.getSelectedItem(); 1053 if (selected != null) { 1054 route = (Route) selected; 1055 } 1056 // warn user if train is built that they shouldn't edit the train's route 1057 if (route != null && route.getStatus().equals(Route.TRAIN_BUILT)) { 1058 // list the built trains for this route 1059 StringBuffer buf = new StringBuffer(Bundle.getMessage("DoNotModifyRoute")); 1060 for (Train train : InstanceManager.getDefault(TrainManager.class).getTrainsByIdList()) { 1061 if (train.getRoute() == route && train.isBuilt()) { 1062 buf.append(NEW_LINE + 1063 Bundle.getMessage("TrainIsBuilt", 1064 train.getName(), route.getName())); 1065 } 1066 } 1067 JmriJOptionPane.showMessageDialog(this, buf.toString(), Bundle.getMessage("BuiltTrain"), 1068 JmriJOptionPane.WARNING_MESSAGE); 1069 } 1070 ref.initComponents(route, _train); 1071 } 1072 1073 private void updateDepartureTime() { 1074 dayBox.setSelectedItem(_train.getDepartureTimeDay()); 1075 hourBox.setSelectedItem(_train.getDepartureTimeHour()); 1076 minuteBox.setSelectedItem(_train.getDepartureTimeMinute()); 1077 // check to see if route has a departure time from the 1st location 1078 RouteLocation rl = _train.getTrainDepartsRouteLocation(); 1079 if (rl != null && !rl.getDepartureTimeHourMinutes().equals(NONE)) { 1080 dayBox.setEnabled(false); 1081 hourBox.setEnabled(false); 1082 minuteBox.setEnabled(false); 1083 } else { 1084 dayBox.setEnabled(!_train.isBuilt()); 1085 hourBox.setEnabled(!_train.isBuilt()); 1086 minuteBox.setEnabled(!_train.isBuilt()); 1087 } 1088 } 1089 1090 private void updateRoadAndLoadStatus() { 1091 if (_train != null) { 1092 // road options 1093 if (_train.getCarRoadOption().equals(Train.INCLUDE_ROADS)) { 1094 roadOptionButton.setText(Bundle.getMessage( 1095 "AcceptOnly") + " " + _train.getCarRoadNames().length + " " + Bundle.getMessage("RoadsCar")); 1096 } else if (_train.getCarRoadOption().equals(Train.EXCLUDE_ROADS)) { 1097 roadOptionButton.setText(Bundle.getMessage( 1098 "Exclude") + " " + _train.getCarRoadNames().length + " " + Bundle.getMessage("RoadsCar")); 1099 } else if (_train.getCabooseRoadOption().equals(Train.INCLUDE_ROADS)) { 1100 roadOptionButton.setText(Bundle.getMessage( 1101 "AcceptOnly") + 1102 " " + 1103 _train.getCabooseRoadNames().length + 1104 " " + 1105 Bundle.getMessage("RoadsCaboose")); 1106 } else if (_train.getCabooseRoadOption().equals(Train.EXCLUDE_ROADS)) { 1107 roadOptionButton.setText(Bundle.getMessage( 1108 "Exclude") + 1109 " " + 1110 _train.getCabooseRoadNames().length + 1111 " " + 1112 Bundle.getMessage("RoadsCaboose")); 1113 } else if (_train.getLocoRoadOption().equals(Train.INCLUDE_ROADS)) { 1114 roadOptionButton.setText(Bundle.getMessage( 1115 "AcceptOnly") + " " + _train.getLocoRoadNames().length + " " + Bundle.getMessage("RoadsLoco")); 1116 } else if (_train.getLocoRoadOption().equals(Train.EXCLUDE_ROADS)) { 1117 roadOptionButton.setText(Bundle.getMessage( 1118 "Exclude") + " " + _train.getLocoRoadNames().length + " " + Bundle.getMessage("RoadsLoco")); 1119 } else { 1120 roadOptionButton.setText(Bundle.getMessage("AcceptAll")); 1121 } 1122 // load options 1123 if (_train.getLoadOption().equals(Train.ALL_LOADS)) { 1124 loadOptionButton.setText(Bundle.getMessage("AcceptAll")); 1125 } else if (_train.getLoadOption().equals(Train.INCLUDE_LOADS)) { 1126 loadOptionButton.setText(Bundle.getMessage( 1127 "AcceptOnly") + " " + _train.getLoadNames().length + " " + Bundle.getMessage("Loads")); 1128 } else { 1129 loadOptionButton.setText(Bundle.getMessage( 1130 "Exclude") + " " + _train.getLoadNames().length + " " + Bundle.getMessage("Loads")); 1131 } 1132 if (!_train.getCarRoadOption().equals(Train.ALL_ROADS) || 1133 !_train.getCabooseRoadOption().equals(Train.ALL_ROADS) || 1134 !_train.getLocoRoadOption().equals(Train.ALL_ROADS) || 1135 !_train.getLoadOption().equals(Train.ALL_LOADS)) { 1136 roadAndLoadStatusPanel.setVisible(true); 1137 } 1138 } 1139 } 1140 1141 List<Frame> children = new ArrayList<>(); 1142 1143 public void setChildFrame(Frame frame) { 1144 if (children.contains(frame)) { 1145 return; 1146 } 1147 children.add(frame); 1148 } 1149 1150 @Override 1151 public void dispose() { 1152 InstanceManager.getDefault(LocationManager.class).removePropertyChangeListener(this); 1153 InstanceManager.getDefault(EngineTypes.class).removePropertyChangeListener(this); 1154 InstanceManager.getDefault(EngineModels.class).removePropertyChangeListener(this); 1155 InstanceManager.getDefault(CarTypes.class).removePropertyChangeListener(this); 1156 InstanceManager.getDefault(CarRoads.class).removePropertyChangeListener(this); 1157 routeManager.removePropertyChangeListener(this); 1158 for (Frame frame : children) { 1159 frame.dispose(); 1160 } 1161 if (_train != null) { 1162 _train.removePropertyChangeListener(this); 1163 Route route = _train.getRoute(); 1164 if (route != null) { 1165 for (RouteLocation rl : route.getLocationsBySequenceList()) { 1166 Location loc = rl.getLocation(); 1167 if (loc != null) { 1168 loc.removePropertyChangeListener(this); 1169 } 1170 } 1171 } 1172 } 1173 super.dispose(); 1174 } 1175 1176 @Override 1177 public void propertyChange(java.beans.PropertyChangeEvent e) { 1178 if (Control.SHOW_PROPERTY) { 1179 log.debug("Property change ({}) old: ({}) new: ({})", e.getPropertyName(), e.getOldValue(), 1180 e.getNewValue()); // NOI18N 1181 } 1182 if (e.getPropertyName().equals(CarTypes.CARTYPES_CHANGED_PROPERTY) || 1183 e.getPropertyName().equals(Train.TYPES_CHANGED_PROPERTY)) { 1184 updateCarTypeCheckboxes(); 1185 } 1186 if (e.getPropertyName().equals(EngineTypes.ENGINETYPES_CHANGED_PROPERTY)) { 1187 updateEngineTypeCheckboxes(); 1188 } 1189 if (e.getPropertyName().equals(RouteManager.LISTLENGTH_CHANGED_PROPERTY)) { 1190 updateRouteComboBox(); 1191 } 1192 if (e.getPropertyName().equals(Route.LISTCHANGE_CHANGED_PROPERTY) || 1193 e.getPropertyName().equals(LocationManager.LISTLENGTH_CHANGED_PROPERTY) || 1194 e.getPropertyName().equals(Location.NAME_CHANGED_PROPERTY) || 1195 e.getPropertyName().equals(Location.TRAIN_DIRECTION_CHANGED_PROPERTY)) { 1196 updateLocationCheckboxes(); 1197 pack(); 1198 repaint(); 1199 } 1200 if (e.getPropertyName().equals(CarRoads.CARROADS_CHANGED_PROPERTY)) { 1201 updateRoadComboBoxes(); 1202 } 1203 if (e.getPropertyName().equals(EngineModels.ENGINEMODELS_CHANGED_PROPERTY)) { 1204 InstanceManager.getDefault(EngineModels.class).updateComboBox(modelEngineBox); 1205 modelEngineBox.insertItemAt(NONE, 0); 1206 modelEngineBox.setSelectedIndex(0); 1207 if (_train != null) { 1208 modelEngineBox.setSelectedItem(_train.getEngineModel()); 1209 } 1210 } 1211 if (e.getPropertyName().equals(Train.DEPARTURETIME_CHANGED_PROPERTY)) { 1212 updateDepartureTime(); 1213 } 1214 if (e.getPropertyName().equals(Train.TRAIN_ROUTE_CHANGED_PROPERTY) && _train != null) { 1215 routeBox.setSelectedItem(_train.getRoute()); 1216 } 1217 if (e.getPropertyName().equals(Route.ROUTE_STATUS_CHANGED_PROPERTY)) { 1218 updateDepartureTime(); 1219 enableButtons(_train != null); 1220 updateRouteStatus(); 1221 } 1222 if (e.getPropertyName().equals(Train.ROADS_CHANGED_PROPERTY) || 1223 e.getPropertyName().equals(Train.LOADS_CHANGED_PROPERTY)) { 1224 updateRoadAndLoadStatus(); 1225 } 1226 } 1227 1228 private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(TrainEditFrame.class); 1229}