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