001package jmri.jmrit.operations.locations.gui; 002 003import java.awt.*; 004import java.util.ArrayList; 005import java.util.List; 006 007import javax.swing.*; 008 009import jmri.*; 010import jmri.jmrit.operations.OperationsFrame; 011import jmri.jmrit.operations.OperationsXml; 012import jmri.jmrit.operations.locations.*; 013import jmri.jmrit.operations.locations.tools.*; 014import jmri.jmrit.operations.rollingstock.cars.*; 015import jmri.jmrit.operations.rollingstock.engines.EngineTypes; 016import jmri.jmrit.operations.routes.Route; 017import jmri.jmrit.operations.routes.RouteManager; 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.trainbuilder.TrainCommon; 023import jmri.swing.NamedBeanComboBox; 024import jmri.util.swing.JmriJOptionPane; 025 026/** 027 * Frame for user edit of tracks. Base for edit of all track types. 028 * 029 * @author Dan Boudreau Copyright (C) 2008, 2010, 2011, 2012, 2013, 2023 030 */ 031public abstract class TrackEditFrame extends OperationsFrame implements java.beans.PropertyChangeListener { 032 033 // where in the tool menu new items are inserted 034 protected static final int TOOL_MENU_OFFSET = 7; 035 036 // Managers 037 TrainManager trainManager = InstanceManager.getDefault(TrainManager.class); 038 RouteManager routeManager = InstanceManager.getDefault(RouteManager.class); 039 040 public Location _location = null; 041 public Track _track = null; 042 String _type = ""; 043 JMenu _toolMenu = new JMenu(Bundle.getMessage("MenuTools")); 044 045 List<JCheckBox> checkBoxes = new ArrayList<>(); 046 047 // panels 048 JPanel panelCheckBoxes = new JPanel(); 049 JScrollPane paneCheckBoxes = new JScrollPane(panelCheckBoxes); 050 JPanel panelTrainDir = new JPanel(); 051 JPanel pShipLoadOption = new JPanel(); 052 JPanel pDestinationOption = new JPanel(); 053 JPanel panelOrder = new JPanel(); 054 JPanel panelQuickService = new JPanel(); 055 056 // Alternate tool buttons 057 JButton loadOptionButton = new JButton(Bundle.getMessage("AcceptsAllLoads")); 058 JButton shipLoadOptionButton = new JButton(Bundle.getMessage("ShipsAllLoads")); 059 JButton roadOptionButton = new JButton(Bundle.getMessage("AcceptsAllRoads")); 060 JButton destinationOptionButton = new JButton(); 061 062 // major buttons 063 JButton clearButton = new JButton(Bundle.getMessage("ClearAll")); 064 JButton setButton = new JButton(Bundle.getMessage("SelectAll")); 065 JButton autoSelectButton = new JButton(Bundle.getMessage("AutoSelect")); 066 067 JButton saveTrackButton = new JButton(Bundle.getMessage("SaveTrack")); 068 JButton deleteTrackButton = new JButton(Bundle.getMessage("DeleteTrack")); 069 JButton addTrackButton = new JButton(Bundle.getMessage("AddTrack")); 070 071 JButton deleteDropButton = new JButton(Bundle.getMessage("ButtonDelete")); 072 JButton addDropButton = new JButton(Bundle.getMessage("Add")); 073 JButton deletePickupButton = new JButton(Bundle.getMessage("ButtonDelete")); 074 JButton addPickupButton = new JButton(Bundle.getMessage("Add")); 075 076 // check boxes 077 JCheckBox northCheckBox = new JCheckBox(Bundle.getMessage("North")); 078 JCheckBox southCheckBox = new JCheckBox(Bundle.getMessage("South")); 079 JCheckBox eastCheckBox = new JCheckBox(Bundle.getMessage("East")); 080 JCheckBox westCheckBox = new JCheckBox(Bundle.getMessage("West")); 081 JCheckBox autoDropCheckBox = new JCheckBox(Bundle.getMessage("Auto")); 082 JCheckBox autoPickupCheckBox = new JCheckBox(Bundle.getMessage("Auto")); 083 JCheckBox quickServiceCheckBox = new JCheckBox(Bundle.getMessage("QuickService")); 084 085 // car pick up order controls 086 JRadioButton orderNormal = new JRadioButton(Bundle.getMessage("Normal")); 087 JRadioButton orderFIFO = new JRadioButton(Bundle.getMessage("DescriptiveFIFO")); 088 JRadioButton orderLIFO = new JRadioButton(Bundle.getMessage("DescriptiveLIFO")); 089 090 JRadioButton anyDrops = new JRadioButton(Bundle.getMessage("Any")); 091 JRadioButton trainDrop = new JRadioButton(Bundle.getMessage("Trains")); 092 JRadioButton routeDrop = new JRadioButton(Bundle.getMessage("Routes")); 093 JRadioButton excludeTrainDrop = new JRadioButton(Bundle.getMessage("ExcludeTrains")); 094 JRadioButton excludeRouteDrop = new JRadioButton(Bundle.getMessage("ExcludeRoutes")); 095 096 JRadioButton anyPickups = new JRadioButton(Bundle.getMessage("Any")); 097 JRadioButton trainPickup = new JRadioButton(Bundle.getMessage("Trains")); 098 JRadioButton routePickup = new JRadioButton(Bundle.getMessage("Routes")); 099 JRadioButton excludeTrainPickup = new JRadioButton(Bundle.getMessage("ExcludeTrains")); 100 JRadioButton excludeRoutePickup = new JRadioButton(Bundle.getMessage("ExcludeRoutes")); 101 102 JComboBox<Train> comboBoxDropTrains = trainManager.getTrainComboBox(); 103 JComboBox<Route> comboBoxDropRoutes = routeManager.getComboBox(); 104 JComboBox<Train> comboBoxPickupTrains = trainManager.getTrainComboBox(); 105 JComboBox<Route> comboBoxPickupRoutes = routeManager.getComboBox(); 106 107 // text field 108 JTextField trackNameTextField = new JTextField(Control.max_len_string_track_name); 109 JTextField trackLengthTextField = new JTextField(Control.max_len_string_track_length_name); 110 111 // text area 112 JTextArea commentTextArea = new JTextArea(2, 60); 113 JScrollPane commentScroller = new JScrollPane(commentTextArea, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, 114 JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); 115 116 // optional panel for spurs, staging, and interchanges 117 JPanel dropPanel = new JPanel(); 118 JPanel pickupPanel = new JPanel(); 119 JPanel panelOpt3 = new JPanel(); // not currently used 120 JPanel panelOpt4 = new JPanel(); 121 122 // Reader selection dropdown. 123 NamedBeanComboBox<Reporter> readerSelector; 124 125 public static final String DISPOSE = "dispose"; // NOI18N 126 public static final int MAX_NAME_LENGTH = Control.max_len_string_track_name; 127 128 public TrackEditFrame(String title) { 129 super(title); 130 } 131 132 protected abstract void initComponents(Track track); 133 134 public void initComponents(Location location, Track track) { 135 _location = location; 136 _track = track; 137 138 // tool tips 139 autoDropCheckBox.setToolTipText(Bundle.getMessage("TipAutoTrack")); 140 autoPickupCheckBox.setToolTipText(Bundle.getMessage("TipAutoTrack")); 141 trackLengthTextField.setToolTipText(Bundle.getMessage("TipTrackLength", 142 Setup.getLengthUnit().toLowerCase())); 143 144 // property changes 145 _location.addPropertyChangeListener(this); 146 // listen for car road name and type changes 147 InstanceManager.getDefault(CarRoads.class).addPropertyChangeListener(this); 148 InstanceManager.getDefault(CarLoads.class).addPropertyChangeListener(this); 149 InstanceManager.getDefault(CarTypes.class).addPropertyChangeListener(this); 150 InstanceManager.getDefault(Setup.class).addPropertyChangeListener(this); 151 trainManager.addPropertyChangeListener(this); 152 routeManager.addPropertyChangeListener(this); 153 154 // the following code sets the frame's initial state 155 getContentPane().setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS)); 156 157 // place all panels in a scroll pane. 158 JPanel panels = new JPanel(); 159 panels.setLayout(new BoxLayout(panels, BoxLayout.Y_AXIS)); 160 JScrollPane pane = new JScrollPane(panels); 161 162 // row 1 163 JPanel p1 = new JPanel(); 164 p1.setLayout(new BoxLayout(p1, BoxLayout.X_AXIS)); 165 JScrollPane p1Pane = new JScrollPane(p1); 166 p1Pane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER); 167 p1Pane.setMinimumSize(new Dimension(300, 3 * trackNameTextField.getPreferredSize().height)); 168 p1Pane.setBorder(BorderFactory.createTitledBorder("")); 169 170 // row 1a 171 JPanel pName = new JPanel(); 172 pName.setLayout(new GridBagLayout()); 173 pName.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("Name"))); 174 addItem(pName, trackNameTextField, 0, 0); 175 176 // row 1b 177 JPanel pLength = new JPanel(); 178 pLength.setLayout(new GridBagLayout()); 179 pLength.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("Length"))); 180 pLength.setMinimumSize(new Dimension(60, 1)); 181 addItem(pLength, trackLengthTextField, 0, 0); 182 183 // row 1c 184 panelTrainDir.setLayout(new GridBagLayout()); 185 panelTrainDir.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("TrainTrack"))); 186 panelTrainDir.setPreferredSize(new Dimension(200, 10)); 187 addItem(panelTrainDir, northCheckBox, 1, 1); 188 addItem(panelTrainDir, southCheckBox, 2, 1); 189 addItem(panelTrainDir, eastCheckBox, 3, 1); 190 addItem(panelTrainDir, westCheckBox, 4, 1); 191 192 p1.add(pName); 193 p1.add(pLength); 194 p1.add(panelTrainDir); 195 196 // row 2 197 paneCheckBoxes.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("TypesTrack"))); 198 panelCheckBoxes.setLayout(new GridBagLayout()); 199 200 // status panel for roads and loads 201 JPanel panelRoadAndLoadStatus = new JPanel(); 202 panelRoadAndLoadStatus.setLayout(new BoxLayout(panelRoadAndLoadStatus, BoxLayout.X_AXIS)); 203 204 // row 3 205 JPanel pRoadOption = new JPanel(); 206 pRoadOption.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("RoadOption"))); 207 pRoadOption.add(roadOptionButton); 208 roadOptionButton.addActionListener(new TrackRoadEditAction(this)); 209 210 JPanel pLoadOption = new JPanel(); 211 pLoadOption.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("LoadOption"))); 212 pLoadOption.add(loadOptionButton); 213 loadOptionButton.addActionListener(new TrackLoadEditAction(this)); 214 215 pShipLoadOption.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("ShipLoadOption"))); 216 pShipLoadOption.add(shipLoadOptionButton); 217 shipLoadOptionButton.addActionListener(new TrackLoadEditAction(this)); 218 219 pDestinationOption.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("Destinations"))); 220 pDestinationOption.add(destinationOptionButton); 221 destinationOptionButton.addActionListener(new TrackDestinationEditAction(this)); 222 223 panelRoadAndLoadStatus.add(pRoadOption); 224 panelRoadAndLoadStatus.add(pLoadOption); 225 panelRoadAndLoadStatus.add(pShipLoadOption); 226 panelRoadAndLoadStatus.add(pDestinationOption); 227 228 // only staging uses the ship load option 229 pShipLoadOption.setVisible(false); 230 // only classification/interchange tracks use the destination option 231 pDestinationOption.setVisible(false); 232 233 // row 4, order panel 234 panelOrder.setLayout(new GridBagLayout()); 235 panelOrder.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("PickupOrder"))); 236 panelOrder.add(orderNormal); 237 panelOrder.add(orderFIFO); 238 panelOrder.add(orderLIFO); 239 240 ButtonGroup orderGroup = new ButtonGroup(); 241 orderGroup.add(orderNormal); 242 orderGroup.add(orderFIFO); 243 orderGroup.add(orderLIFO); 244 245 // row 5, drop panel 246 dropPanel.setLayout(new GridBagLayout()); 247 dropPanel.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("TrainsOrRoutesDrops"))); 248 249 // row 6, pickup panel 250 pickupPanel.setLayout(new GridBagLayout()); 251 pickupPanel.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("TrainsOrRoutesPickups"))); 252 253 // setup the optional panel with quick service checkbox 254 panelQuickService.setLayout(new GridBagLayout()); 255 panelQuickService.setBorder(BorderFactory.createTitledBorder(Bundle 256 .getMessage("QuickService"))); 257 addItem(panelQuickService, quickServiceCheckBox, 0, 0); 258 quickServiceCheckBox.setToolTipText(Bundle.getMessage("QuickServiceTip")); 259 260 // row 9 261 JPanel panelComment = new JPanel(); 262 panelComment.setLayout(new GridBagLayout()); 263 panelComment.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("Comment"))); 264 addItem(panelComment, commentScroller, 0, 0); 265 266 // adjust text area width based on window size 267 adjustTextAreaColumnWidth(commentScroller, commentTextArea); 268 269 // row 10, reader row 270 JPanel readerPanel = new JPanel(); 271 if (Setup.isRfidEnabled()) { 272 readerPanel.setLayout(new GridBagLayout()); 273 readerPanel.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("idReporter"))); 274 ReporterManager reporterManager = InstanceManager.getDefault(ReporterManager.class); 275 readerSelector = new NamedBeanComboBox<>(reporterManager); 276 readerSelector.setAllowNull(true); 277 addItem(readerPanel, readerSelector, 0, 0); 278 } else { 279 readerPanel.setVisible(false); 280 } 281 282 // row 11 283 JPanel panelButtons = new JPanel(); 284 panelButtons.setLayout(new GridBagLayout()); 285 286 addItem(panelButtons, deleteTrackButton, 0, 0); 287 addItem(panelButtons, addTrackButton, 1, 0); 288 addItem(panelButtons, saveTrackButton, 2, 0); 289 290 panels.add(p1Pane); 291 panels.add(paneCheckBoxes); 292 panels.add(panelRoadAndLoadStatus); 293 panels.add(panelOrder); 294 panels.add(dropPanel); 295 panels.add(pickupPanel); 296 panels.add(panelQuickService); 297 298 // add optional panels 299 panels.add(panelOpt3); 300 panels.add(panelOpt4); 301 302 panels.add(panelComment); 303 panels.add(readerPanel); 304 panels.add(panelButtons); 305 306 getContentPane().add(pane); 307 308 // setup buttons 309 addButtonAction(setButton); 310 addButtonAction(clearButton); 311 312 addButtonAction(deleteTrackButton); 313 addButtonAction(addTrackButton); 314 addButtonAction(saveTrackButton); 315 316 addButtonAction(deleteDropButton); 317 addButtonAction(addDropButton); 318 addButtonAction(deletePickupButton); 319 addButtonAction(addPickupButton); 320 321 addRadioButtonAction(orderNormal); 322 addRadioButtonAction(orderFIFO); 323 addRadioButtonAction(orderLIFO); 324 325 addRadioButtonAction(anyDrops); 326 addRadioButtonAction(trainDrop); 327 addRadioButtonAction(routeDrop); 328 addRadioButtonAction(excludeTrainDrop); 329 addRadioButtonAction(excludeRouteDrop); 330 331 addRadioButtonAction(anyPickups); 332 addRadioButtonAction(trainPickup); 333 addRadioButtonAction(routePickup); 334 addRadioButtonAction(excludeTrainPickup); 335 addRadioButtonAction(excludeRoutePickup); 336 337 // addComboBoxAction(comboBoxTypes); 338 addCheckBoxAction(autoDropCheckBox); 339 addCheckBoxAction(autoPickupCheckBox); 340 341 autoDropCheckBox.setSelected(true); 342 autoPickupCheckBox.setSelected(true); 343 344 // load fields and enable buttons 345 if (_track != null) { 346 _track.addPropertyChangeListener(this); 347 trackNameTextField.setText(_track.getName()); 348 commentTextArea.setText(_track.getComment()); 349 trackLengthTextField.setText(Integer.toString(_track.getLength())); 350 quickServiceCheckBox.setSelected(track.isQuickServiceEnabled()); 351 enableButtons(true); 352 if (Setup.isRfidEnabled()) { 353 readerSelector.setSelectedItem(_track.getReporter()); 354 } 355 } else { 356 enableButtons(false); 357 } 358 359 // build menu 360 JMenuBar menuBar = new JMenuBar(); 361 // spurs, interchanges, and staging insert menu items here 362 _toolMenu.add(new TrackLoadEditAction(this)); 363 _toolMenu.add(new TrackRoadEditAction(this)); 364 _toolMenu.add(new PoolTrackAction(this)); 365 _toolMenu.add(new IgnoreUsedTrackAction(this)); 366 _toolMenu.addSeparator(); 367 _toolMenu.add(new TrackEditCommentsAction(this)); 368 _toolMenu.addSeparator(); 369 // spurs, interchanges, and yards insert menu items here 370 _toolMenu.add(new TrackCopyAction(_track, _location)); 371 _toolMenu.addSeparator(); 372 _toolMenu.add(new ShowCarsByLocationAction(false, _location, _track)); 373 _toolMenu.add(new ShowLocosByLocationAction(false, _location, _track)); 374 _toolMenu.addSeparator(); 375 _toolMenu.add(new ShowTrainsServingLocationAction(_location, _track)); 376 377 menuBar.add(_toolMenu); 378 setJMenuBar(menuBar); 379 380 // load 381 updateCheckboxes(); 382 updateTrainDir(); 383 updateCarOrder(); 384 updateDropOptions(); 385 updatePickupOptions(); 386 updateRoadOption(); 387 updateLoadOption(); 388 updateDestinationOption(); 389 updateTrainComboBox(); 390 updateRouteComboBox(); 391 392 setMinimumSize(new Dimension(Control.panelWidth500, Control.panelHeight600)); 393 } 394 395 // Save, Delete, Add 396 @Override 397 public void buttonActionPerformed(java.awt.event.ActionEvent ae) { 398 if (ae.getSource() == addTrackButton) { 399 addNewTrack(); 400 } 401 if (_track == null) { 402 return; // not possible 403 } 404 if (ae.getSource() == saveTrackButton) { 405 if (!checkUserInputs(_track)) { 406 return; 407 } 408 saveTrack(_track); 409 checkTrackPickups(_track); // warn user if there are car types that 410 // will be stranded 411 if (Setup.isCloseWindowOnSaveEnabled()) { 412 dispose(); 413 } 414 } 415 if (ae.getSource() == deleteTrackButton) { 416 deleteTrack(); 417 } 418 if (ae.getSource() == setButton) { 419 selectCheckboxes(true); 420 } 421 if (ae.getSource() == clearButton) { 422 selectCheckboxes(false); 423 } 424 if (ae.getSource() == addDropButton) { 425 addDropId(); 426 } 427 if (ae.getSource() == deleteDropButton) { 428 deleteDropId(); 429 } 430 if (ae.getSource() == addPickupButton) { 431 addPickupId(); 432 } 433 if (ae.getSource() == deletePickupButton) { 434 deletePickupId(); 435 } 436 } 437 438 private void addDropId() { 439 String id = ""; 440 if (trainDrop.isSelected() || excludeTrainDrop.isSelected()) { 441 if (comboBoxDropTrains.getSelectedItem() == null) { 442 return; 443 } 444 Train train = ((Train) comboBoxDropTrains.getSelectedItem()); 445 Route route = train.getRoute(); 446 id = train.getId(); 447 if (!checkRoute(route)) { 448 JmriJOptionPane.showMessageDialog(this, 449 Bundle.getMessage("TrackNotByTrain", train.getName()), 450 Bundle.getMessage("ErrorTitle"), JmriJOptionPane.ERROR_MESSAGE); 451 return; 452 } 453 selectNextItemComboBox(comboBoxDropTrains); 454 } else { 455 if (comboBoxDropRoutes.getSelectedItem() == null) { 456 return; 457 } 458 Route route = ((Route) comboBoxDropRoutes.getSelectedItem()); 459 id = route.getId(); 460 if (!checkRoute(route)) { 461 JmriJOptionPane.showMessageDialog(this, 462 Bundle.getMessage("TrackNotByRoute", route.getName()), 463 Bundle.getMessage("ErrorTitle"), JmriJOptionPane.ERROR_MESSAGE); 464 return; 465 } 466 selectNextItemComboBox(comboBoxDropRoutes); 467 } 468 _track.addDropId(id); 469 } 470 471 private void deleteDropId() { 472 String id = ""; 473 if (trainDrop.isSelected() || excludeTrainDrop.isSelected()) { 474 if (comboBoxDropTrains.getSelectedItem() == null) { 475 return; 476 } 477 id = ((Train) comboBoxDropTrains.getSelectedItem()).getId(); 478 selectNextItemComboBox(comboBoxDropTrains); 479 } else { 480 if (comboBoxDropRoutes.getSelectedItem() == null) { 481 return; 482 } 483 id = ((Route) comboBoxDropRoutes.getSelectedItem()).getId(); 484 selectNextItemComboBox(comboBoxDropRoutes); 485 } 486 _track.deleteDropId(id); 487 } 488 489 private void addPickupId() { 490 String id = ""; 491 if (trainPickup.isSelected() || excludeTrainPickup.isSelected()) { 492 if (comboBoxPickupTrains.getSelectedItem() == null) { 493 return; 494 } 495 Train train = ((Train) comboBoxPickupTrains.getSelectedItem()); 496 Route route = train.getRoute(); 497 id = train.getId(); 498 if (!checkRoute(route)) { 499 JmriJOptionPane.showMessageDialog(this, 500 Bundle.getMessage("TrackNotByTrain", train.getName()), 501 Bundle.getMessage("ErrorTitle"), JmriJOptionPane.ERROR_MESSAGE); 502 return; 503 } 504 selectNextItemComboBox(comboBoxPickupTrains); 505 } else { 506 if (comboBoxPickupRoutes.getSelectedItem() == null) { 507 return; 508 } 509 Route route = ((Route) comboBoxPickupRoutes.getSelectedItem()); 510 id = route.getId(); 511 if (!checkRoute(route)) { 512 JmriJOptionPane.showMessageDialog(this, 513 Bundle.getMessage("TrackNotByRoute", route.getName()), 514 Bundle.getMessage("ErrorTitle"), JmriJOptionPane.ERROR_MESSAGE); 515 return; 516 } 517 selectNextItemComboBox(comboBoxPickupRoutes); 518 } 519 _track.addPickupId(id); 520 } 521 522 private void deletePickupId() { 523 String id = ""; 524 if (trainPickup.isSelected() || excludeTrainPickup.isSelected()) { 525 if (comboBoxPickupTrains.getSelectedItem() == null) { 526 return; 527 } 528 id = ((Train) comboBoxPickupTrains.getSelectedItem()).getId(); 529 selectNextItemComboBox(comboBoxPickupTrains); 530 } else { 531 if (comboBoxPickupRoutes.getSelectedItem() == null) { 532 return; 533 } 534 id = ((Route) comboBoxPickupRoutes.getSelectedItem()).getId(); 535 selectNextItemComboBox(comboBoxPickupRoutes); 536 } 537 _track.deletePickupId(id); 538 } 539 540 protected void addNewTrack() { 541 // check that track name is valid 542 if (!checkName(Bundle.getMessage("add"))) { 543 return; 544 } 545 // check to see if track already exists 546 Track check = _location.getTrackByName(trackNameTextField.getText(), null); 547 if (check != null) { 548 reportTrackExists(Bundle.getMessage("add")); 549 return; 550 } 551 // add track to this location 552 _track = _location.addTrack(trackNameTextField.getText(), _type); 553 // check track length 554 checkLength(_track); 555 556 // save window size so it doesn't change during the following updates 557 setPreferredSize(getSize()); 558 559 // reset all of the track's attributes 560 updateTrainDir(); 561 updateCheckboxes(); 562 updateDropOptions(); 563 updatePickupOptions(); 564 updateRoadOption(); 565 updateLoadOption(); 566 updateDestinationOption(); 567 568 _track.addPropertyChangeListener(this); 569 570 // setup check boxes 571 selectCheckboxes(true); 572 573 // default for on time mode is quick service track 574 _track.setQuickServiceEnabled(Setup.isBuildOnTime()); 575 576 // store comment 577 _track.setComment(commentTextArea.getText()); 578 // enable 579 enableButtons(true); 580 // save location file 581 OperationsXml.save(); 582 } 583 584 protected void deleteTrack() { 585 if (_track != null) { 586 int rs = _track.getNumberRS(); 587 if (rs > 0) { 588 if (JmriJOptionPane.showConfirmDialog(this, 589 Bundle.getMessage("ThereAreCars", Integer.toString(rs)), 590 Bundle.getMessage("deleteTrack?"), 591 JmriJOptionPane.YES_NO_OPTION) != JmriJOptionPane.YES_OPTION) { 592 return; 593 } 594 } 595 if (_track.getDropRS() > 0 || _track.getPickupRS() > 0) { 596 if (JmriJOptionPane.showConfirmDialog(this, 597 Bundle.getMessage("TrackInUse", _track.getPickupRS(), _track.getDropRS()), 598 Bundle.getMessage("deleteTrack?"), 599 JmriJOptionPane.YES_NO_OPTION) != JmriJOptionPane.YES_OPTION) { 600 return; 601 } 602 } 603 selectCheckboxes(false); 604 _location.deleteTrack(_track); 605 _track = null; 606 enableButtons(false); 607 // save location file 608 OperationsXml.save(); 609 } 610 } 611 612 // check to see if the route services this location 613 private boolean checkRoute(Route route) { 614 if (route == null) { 615 return false; 616 } 617 return route.getLastLocationByName(_location.getName()) != null; 618 } 619 620 protected void saveTrack(Track track) { 621 saveTrackDirections(track); 622 track.setName(trackNameTextField.getText()); 623 track.setComment(commentTextArea.getText()); 624 track.setQuickServiceEnabled(quickServiceCheckBox.isSelected()); 625 626 if (Setup.isRfidEnabled()) { 627 _track.setReporter(readerSelector.getSelectedItem()); 628 } 629 630 // save current window size so it doesn't change during updates 631 setPreferredSize(getSize()); 632 633 // enable 634 enableButtons(true); 635 // save location file 636 OperationsXml.save(); 637 } 638 639 private void saveTrackDirections(Track track) { 640 // save train directions serviced by this location 641 int direction = 0; 642 if (northCheckBox.isSelected()) { 643 direction += Track.NORTH; 644 } 645 if (southCheckBox.isSelected()) { 646 direction += Track.SOUTH; 647 } 648 if (eastCheckBox.isSelected()) { 649 direction += Track.EAST; 650 } 651 if (westCheckBox.isSelected()) { 652 direction += Track.WEST; 653 } 654 track.setTrainDirections(direction); 655 } 656 657 private boolean checkUserInputs(Track track) { 658 // check that track name is valid 659 if (!checkName(Bundle.getMessage("save"))) { 660 return false; 661 } 662 // check to see if track already exists 663 Track check = _location.getTrackByName(trackNameTextField.getText(), null); 664 if (check != null && check != track) { 665 reportTrackExists(Bundle.getMessage("save")); 666 return false; 667 } 668 // check track length 669 if (!checkLength(track)) { 670 return false; 671 } 672 // check trains and route option 673 if (!checkService(track)) { 674 return false; 675 } 676 677 return true; 678 } 679 680 /** 681 * @return true if name is less than 26 characters 682 */ 683 private boolean checkName(String s) { 684 String trackName = trackNameTextField.getText().trim(); 685 if (trackName.isEmpty()) { 686 log.debug("Must enter a track name"); 687 JmriJOptionPane.showMessageDialog(this, Bundle.getMessage("MustEnterName"), 688 Bundle.getMessage("CanNotTrack", s), 689 JmriJOptionPane.ERROR_MESSAGE); 690 return false; 691 } 692 String[] check = trackName.split(TrainCommon.HYPHEN); 693 if (check.length == 0) { 694 JmriJOptionPane.showMessageDialog(this, Bundle.getMessage("HyphenFeature"), 695 Bundle.getMessage("CanNotTrack", s), 696 JmriJOptionPane.ERROR_MESSAGE); 697 698 return false; 699 } 700 if (TrainCommon.splitString(trackName).length() > MAX_NAME_LENGTH) { 701 JmriJOptionPane.showMessageDialog(this, 702 Bundle.getMessage("TrackNameLengthMax", Integer.toString(MAX_NAME_LENGTH + 1)), 703 Bundle.getMessage("CanNotTrack", s), 704 JmriJOptionPane.ERROR_MESSAGE); 705 return false; 706 } 707 return true; 708 } 709 710 private boolean checkLength(Track track) { 711 // convert track length if in inches 712 String length = trackLengthTextField.getText(); 713 if (length.endsWith("\"")) { // NOI18N 714 length = length.substring(0, length.length() - 1); 715 try { 716 double inches = Double.parseDouble(length); 717 int feet = (int) (inches * Setup.getScaleRatio() / 12); 718 length = Integer.toString(feet); 719 } catch (NumberFormatException e) { 720 JmriJOptionPane.showMessageDialog(this, Bundle.getMessage("CanNotConvertFeet"), 721 Bundle.getMessage("ErrorTrackLength"), JmriJOptionPane.ERROR_MESSAGE); 722 return false; 723 } 724 } 725 if (length.endsWith("cm")) { // NOI18N 726 length = length.substring(0, length.length() - 2); 727 try { 728 double cm = Double.parseDouble(length); 729 int meter = (int) (cm * Setup.getScaleRatio() / 100); 730 length = Integer.toString(meter); 731 } catch (NumberFormatException e) { 732 // log.error("Can not convert from cm to meters"); 733 JmriJOptionPane.showMessageDialog(this, Bundle.getMessage("CanNotConvertMeter"), 734 Bundle.getMessage("ErrorTrackLength"), JmriJOptionPane.ERROR_MESSAGE); 735 return false; 736 } 737 } 738 // confirm that length is a number and less than 10000 feet 739 int trackLength = 0; 740 try { 741 trackLength = Integer.parseInt(length); 742 if (length.length() > Control.max_len_string_track_length_name) { 743 JmriJOptionPane.showMessageDialog(this, 744 Bundle.getMessage("TrackMustBeLessThan", 745 Math.pow(10, Control.max_len_string_track_length_name), 746 Setup.getLengthUnit().toLowerCase()), 747 Bundle.getMessage("ErrorTrackLength"), JmriJOptionPane.ERROR_MESSAGE); 748 return false; 749 } 750 } catch (NumberFormatException e) { 751 // log.error("Track length not an integer"); 752 JmriJOptionPane.showMessageDialog(this, Bundle.getMessage("TrackMustBeNumber"), 753 Bundle.getMessage("ErrorTrackLength"), JmriJOptionPane.ERROR_MESSAGE); 754 return false; 755 } 756 // track length can not be less than than the sum of used and reserved 757 // length 758 if (trackLength != track.getLength() && trackLength < track.getUsedLength() + track.getReserved()) { 759 // log.warn("Track length should not be less than used and 760 // reserved"); 761 JmriJOptionPane.showMessageDialog(this, Bundle.getMessage("TrackMustBeGreater"), 762 Bundle.getMessage("ErrorTrackLength"), JmriJOptionPane.ERROR_MESSAGE); 763 // does the user want to force the track length? 764 if (JmriJOptionPane.showConfirmDialog(this, 765 Bundle.getMessage("TrackForceLength", track.getLength(), trackLength, 766 Setup.getLengthUnit().toLowerCase()), 767 Bundle.getMessage("ErrorTrackLength"), 768 JmriJOptionPane.YES_NO_OPTION) != JmriJOptionPane.YES_OPTION) { 769 return false; 770 } 771 } 772 // if everything is okay, save length 773 track.setLength(trackLength); 774 return true; 775 } 776 777 private boolean checkService(Track track) { 778 // check train and route restrictions 779 if ((trainDrop.isSelected() || routeDrop.isSelected()) && track.getDropIds().length == 0) { 780 log.debug("Must enter trains or routes for this track"); 781 JmriJOptionPane.showMessageDialog(this, Bundle.getMessage("UseAddTrainsOrRoutes"), 782 Bundle.getMessage("SetOutDisabled"), JmriJOptionPane.ERROR_MESSAGE); 783 return false; 784 } 785 if ((trainPickup.isSelected() || routePickup.isSelected()) && track.getPickupIds().length == 0) { 786 log.debug("Must enter trains or routes for this track"); 787 JmriJOptionPane.showMessageDialog(this, Bundle.getMessage("UseAddTrainsOrRoutes"), 788 Bundle.getMessage("PickUpsDisabled"), JmriJOptionPane.ERROR_MESSAGE); 789 return false; 790 } 791 return true; 792 } 793 794 private boolean checkTrackPickups(Track track) { 795 // check to see if all car types can be pulled from this track 796 String status = track.checkPickups(); 797 if (!status.equals(Track.PICKUP_OKAY) && !track.getPickupOption().equals(Track.ANY)) { 798 JmriJOptionPane.showMessageDialog(this, status, Bundle.getMessage("ErrorStrandedCar"), 799 JmriJOptionPane.ERROR_MESSAGE); 800 return false; 801 } 802 return true; 803 } 804 805 private void reportTrackExists(String s) { 806 JmriJOptionPane.showMessageDialog(this, Bundle.getMessage("TrackAlreadyExists"), 807 Bundle.getMessage("CanNotTrack", s), JmriJOptionPane.ERROR_MESSAGE); 808 } 809 810 protected void enableButtons(boolean enabled) { 811 _toolMenu.setEnabled(enabled); 812 northCheckBox.setEnabled(enabled); 813 southCheckBox.setEnabled(enabled); 814 eastCheckBox.setEnabled(enabled); 815 westCheckBox.setEnabled(enabled); 816 clearButton.setEnabled(enabled); 817 setButton.setEnabled(enabled); 818 deleteTrackButton.setEnabled(enabled); 819 saveTrackButton.setEnabled(enabled); 820 roadOptionButton.setEnabled(enabled); 821 loadOptionButton.setEnabled(enabled); 822 shipLoadOptionButton.setEnabled(enabled); 823 destinationOptionButton.setEnabled(enabled); 824 anyDrops.setEnabled(enabled); 825 trainDrop.setEnabled(enabled); 826 routeDrop.setEnabled(enabled); 827 excludeTrainDrop.setEnabled(enabled); 828 excludeRouteDrop.setEnabled(enabled); 829 anyPickups.setEnabled(enabled); 830 trainPickup.setEnabled(enabled); 831 routePickup.setEnabled(enabled); 832 excludeTrainPickup.setEnabled(enabled); 833 excludeRoutePickup.setEnabled(enabled); 834 orderNormal.setEnabled(enabled); 835 orderFIFO.setEnabled(enabled); 836 orderLIFO.setEnabled(enabled); 837 quickServiceCheckBox.setEnabled(enabled); 838 enableCheckboxes(enabled); 839 if (readerSelector != null) { 840 // enable readerSelect. 841 readerSelector.setEnabled(enabled && Setup.isRfidEnabled()); 842 } 843 } 844 845 @Override 846 public void radioButtonActionPerformed(java.awt.event.ActionEvent ae) { 847 log.debug("radio button activated"); 848 if (ae.getSource() == orderNormal) { 849 _track.setServiceOrder(Track.NORMAL); 850 } 851 if (ae.getSource() == orderFIFO) { 852 _track.setServiceOrder(Track.FIFO); 853 } 854 if (ae.getSource() == orderLIFO) { 855 _track.setServiceOrder(Track.LIFO); 856 } 857 if (ae.getSource() == anyDrops) { 858 _track.setDropOption(Track.ANY); 859 updateDropOptions(); 860 } 861 if (ae.getSource() == trainDrop) { 862 _track.setDropOption(Track.TRAINS); 863 updateDropOptions(); 864 } 865 if (ae.getSource() == routeDrop) { 866 _track.setDropOption(Track.ROUTES); 867 updateDropOptions(); 868 } 869 if (ae.getSource() == excludeTrainDrop) { 870 _track.setDropOption(Track.EXCLUDE_TRAINS); 871 updateDropOptions(); 872 } 873 if (ae.getSource() == excludeRouteDrop) { 874 _track.setDropOption(Track.EXCLUDE_ROUTES); 875 updateDropOptions(); 876 } 877 if (ae.getSource() == anyPickups) { 878 _track.setPickupOption(Track.ANY); 879 updatePickupOptions(); 880 } 881 if (ae.getSource() == trainPickup) { 882 _track.setPickupOption(Track.TRAINS); 883 updatePickupOptions(); 884 } 885 if (ae.getSource() == routePickup) { 886 _track.setPickupOption(Track.ROUTES); 887 updatePickupOptions(); 888 } 889 if (ae.getSource() == excludeTrainPickup) { 890 _track.setPickupOption(Track.EXCLUDE_TRAINS); 891 updatePickupOptions(); 892 } 893 if (ae.getSource() == excludeRoutePickup) { 894 _track.setPickupOption(Track.EXCLUDE_ROUTES); 895 updatePickupOptions(); 896 } 897 } 898 899 // TODO only update comboBox when train or route list changes. 900 private void updateDropOptions() { 901 dropPanel.removeAll(); 902 int numberOfItems = getNumberOfCheckboxesPerLine(); 903 904 JPanel p = new JPanel(); 905 p.setLayout(new GridBagLayout()); 906 p.add(anyDrops); 907 p.add(trainDrop); 908 p.add(routeDrop); 909 p.add(excludeTrainDrop); 910 p.add(excludeRouteDrop); 911 GridBagConstraints gc = new GridBagConstraints(); 912 gc.gridwidth = numberOfItems + 1; 913 dropPanel.add(p, gc); 914 915 int y = 1; // vertical position in panel 916 917 if (_track != null) { 918 // set radio button 919 anyDrops.setSelected(_track.getDropOption().equals(Track.ANY)); 920 trainDrop.setSelected(_track.getDropOption().equals(Track.TRAINS)); 921 routeDrop.setSelected(_track.getDropOption().equals(Track.ROUTES)); 922 excludeTrainDrop.setSelected(_track.getDropOption().equals(Track.EXCLUDE_TRAINS)); 923 excludeRouteDrop.setSelected(_track.getDropOption().equals(Track.EXCLUDE_ROUTES)); 924 925 if (!anyDrops.isSelected()) { 926 p = new JPanel(); 927 p.setLayout(new FlowLayout()); 928 if (trainDrop.isSelected() || excludeTrainDrop.isSelected()) { 929 p.add(comboBoxDropTrains); 930 } else { 931 p.add(comboBoxDropRoutes); 932 } 933 p.add(addDropButton); 934 p.add(deleteDropButton); 935 p.add(autoDropCheckBox); 936 gc.gridy = y++; 937 dropPanel.add(p, gc); 938 y++; 939 940 String[] dropIds = _track.getDropIds(); 941 int x = 0; 942 for (String id : dropIds) { 943 JLabel names = new JLabel(); 944 String name = "<deleted>"; // NOI18N 945 if (trainDrop.isSelected() || excludeTrainDrop.isSelected()) { 946 Train train = trainManager.getTrainById(id); 947 if (train != null) { 948 name = train.getName(); 949 } 950 } else { 951 Route route = routeManager.getRouteById(id); 952 if (route != null) { 953 name = route.getName(); 954 } 955 } 956 if (name.equals("<deleted>")) // NOI18N 957 { 958 _track.deleteDropId(id); 959 } 960 names.setText(name); 961 addItem(dropPanel, names, x++, y); 962 if (x > numberOfItems) { 963 y++; 964 x = 0; 965 } 966 } 967 } 968 } else { 969 anyDrops.setSelected(true); 970 } 971 dropPanel.revalidate(); 972 dropPanel.repaint(); 973 revalidate(); 974 } 975 976 private void updatePickupOptions() { 977 log.debug("update pick up options"); 978 pickupPanel.removeAll(); 979 int numberOfCheckboxes = getNumberOfCheckboxesPerLine(); 980 981 JPanel p = new JPanel(); 982 p.setLayout(new GridBagLayout()); 983 p.add(anyPickups); 984 p.add(trainPickup); 985 p.add(routePickup); 986 p.add(excludeTrainPickup); 987 p.add(excludeRoutePickup); 988 GridBagConstraints gc = new GridBagConstraints(); 989 gc.gridwidth = numberOfCheckboxes + 1; 990 pickupPanel.add(p, gc); 991 992 int y = 1; // vertical position in panel 993 994 if (_track != null) { 995 // set radio button 996 anyPickups.setSelected(_track.getPickupOption().equals(Track.ANY)); 997 trainPickup.setSelected(_track.getPickupOption().equals(Track.TRAINS)); 998 routePickup.setSelected(_track.getPickupOption().equals(Track.ROUTES)); 999 excludeTrainPickup.setSelected(_track.getPickupOption().equals(Track.EXCLUDE_TRAINS)); 1000 excludeRoutePickup.setSelected(_track.getPickupOption().equals(Track.EXCLUDE_ROUTES)); 1001 1002 if (!anyPickups.isSelected()) { 1003 p = new JPanel(); 1004 p.setLayout(new FlowLayout()); 1005 if (trainPickup.isSelected() || excludeTrainPickup.isSelected()) { 1006 p.add(comboBoxPickupTrains); 1007 } else { 1008 p.add(comboBoxPickupRoutes); 1009 } 1010 p.add(addPickupButton); 1011 p.add(deletePickupButton); 1012 p.add(autoPickupCheckBox); 1013 gc.gridy = y++; 1014 pickupPanel.add(p, gc); 1015 y++; 1016 1017 int x = 0; 1018 for (String id : _track.getPickupIds()) { 1019 JLabel names = new JLabel(); 1020 String name = "<deleted>"; // NOI18N 1021 if (trainPickup.isSelected() || excludeTrainPickup.isSelected()) { 1022 Train train = trainManager.getTrainById(id); 1023 if (train != null) { 1024 name = train.getName(); 1025 } 1026 } else { 1027 Route route = routeManager.getRouteById(id); 1028 if (route != null) { 1029 name = route.getName(); 1030 } 1031 } 1032 if (name.equals("<deleted>")) // NOI18N 1033 { 1034 _track.deletePickupId(id); 1035 } 1036 names.setText(name); 1037 addItem(pickupPanel, names, x++, y); 1038 if (x > numberOfCheckboxes) { 1039 y++; 1040 x = 0; 1041 } 1042 } 1043 } 1044 } else { 1045 anyPickups.setSelected(true); 1046 } 1047 pickupPanel.revalidate(); 1048 pickupPanel.repaint(); 1049 revalidate(); 1050 } 1051 1052 protected void updateTrainComboBox() { 1053 trainManager.updateTrainComboBox(comboBoxPickupTrains); 1054 if (autoPickupCheckBox.isSelected()) { 1055 autoTrainComboBox(comboBoxPickupTrains); 1056 } 1057 trainManager.updateTrainComboBox(comboBoxDropTrains); 1058 if (autoDropCheckBox.isSelected()) { 1059 autoTrainComboBox(comboBoxDropTrains); 1060 } 1061 } 1062 1063 // filter all trains not serviced by this track 1064 private void autoTrainComboBox(JComboBox<Train> box) { 1065 for (int i = 0; i < box.getItemCount(); i++) { 1066 Train train = box.getItemAt(i); 1067 if (train == null || 1068 !checkRoute(train.getRoute()) || 1069 !train.isLocalSwitcher() && 1070 _track != null && 1071 (Setup.getTrainDirection() & 1072 _location.getTrainDirections() & 1073 _track.getTrainDirections()) == 0) { 1074 box.removeItemAt(i--); 1075 } 1076 } 1077 } 1078 1079 protected void updateRouteComboBox() { 1080 routeManager.updateComboBox(comboBoxPickupRoutes); 1081 if (autoPickupCheckBox.isSelected()) { 1082 autoRouteComboBox(comboBoxPickupRoutes); 1083 } 1084 routeManager.updateComboBox(comboBoxDropRoutes); 1085 if (autoDropCheckBox.isSelected()) { 1086 autoRouteComboBox(comboBoxDropRoutes); 1087 } 1088 } 1089 1090 // filter out all routes not serviced by this track 1091 private void autoRouteComboBox(JComboBox<Route> box) { 1092 for (int i = 0; i < box.getItemCount(); i++) { 1093 Route route = box.getItemAt(i); 1094 if (!checkRoute(route)) { 1095 box.removeItemAt(i--); 1096 } 1097 } 1098 } 1099 1100 private void enableCheckboxes(boolean enable) { 1101 for (int i = 0; i < checkBoxes.size(); i++) { 1102 checkBoxes.get(i).setEnabled(enable); 1103 } 1104 } 1105 1106 private void selectCheckboxes(boolean enable) { 1107 for (int i = 0; i < checkBoxes.size(); i++) { 1108 JCheckBox checkBox = checkBoxes.get(i); 1109 checkBox.setSelected(enable); 1110 if (_track != null) { 1111 if (enable) { 1112 _track.addTypeName(checkBox.getText()); 1113 } else { 1114 _track.deleteTypeName(checkBox.getText()); 1115 } 1116 } 1117 } 1118 } 1119 1120 // car and loco types 1121 private void updateCheckboxes() { 1122 // log.debug("Update all checkboxes"); 1123 checkBoxes.clear(); 1124 panelCheckBoxes.removeAll(); 1125 numberOfCheckBoxes = getNumberOfCheckboxesPerLine(); 1126 x = 0; 1127 y = 0; // vertical position in panel 1128 loadTypes(InstanceManager.getDefault(CarTypes.class).getNames()); 1129 1130 // add space between car and loco types 1131 checkNewLine(); 1132 1133 loadTypes(InstanceManager.getDefault(EngineTypes.class).getNames()); 1134 enableCheckboxes(_track != null); 1135 1136 JPanel p = new JPanel(); 1137 p.add(clearButton); 1138 p.add(setButton); 1139 if (_track != null && _track.isSpur()) { 1140 p.add(autoSelectButton); 1141 } 1142 GridBagConstraints gc = new GridBagConstraints(); 1143 gc.gridwidth = getNumberOfCheckboxesPerLine() + 1; 1144 gc.gridy = ++y; 1145 panelCheckBoxes.add(p, gc); 1146 1147 panelCheckBoxes.revalidate(); 1148 panelCheckBoxes.repaint(); 1149 } 1150 1151 int x = 0; 1152 int y = 0; // vertical position in panel 1153 1154 private void loadTypes(String[] types) { 1155 for (String type : types) { 1156 if (_location.acceptsTypeName(type)) { 1157 JCheckBox checkBox = new JCheckBox(); 1158 checkBoxes.add(checkBox); 1159 checkBox.setText(type); 1160 addCheckBoxAction(checkBox); 1161 addItemLeft(panelCheckBoxes, checkBox, x, y); 1162 if (_track != null && _track.isTypeNameAccepted(type)) { 1163 checkBox.setSelected(true); 1164 } 1165 checkNewLine(); 1166 } 1167 } 1168 } 1169 1170 int numberOfCheckBoxes; 1171 1172 private void checkNewLine() { 1173 if (++x > numberOfCheckBoxes) { 1174 y++; 1175 x = 0; 1176 } 1177 } 1178 1179 private void updateRoadOption() { 1180 if (_track != null) { 1181 roadOptionButton.setText(_track.getRoadOptionString()); 1182 } 1183 } 1184 1185 private void updateLoadOption() { 1186 if (_track != null) { 1187 loadOptionButton.setText(_track.getLoadOptionString()); 1188 shipLoadOptionButton.setText(_track.getShipLoadOptionString()); 1189 } 1190 } 1191 1192 private void updateTrainDir() { 1193 northCheckBox.setVisible(((Setup.getTrainDirection() & Setup.NORTH) & 1194 (_location.getTrainDirections() & Location.NORTH)) == Location.NORTH); 1195 southCheckBox.setVisible(((Setup.getTrainDirection() & Setup.SOUTH) & 1196 (_location.getTrainDirections() & Location.SOUTH)) == Location.SOUTH); 1197 eastCheckBox.setVisible(((Setup.getTrainDirection() & Setup.EAST) & 1198 (_location.getTrainDirections() & Location.EAST)) == Location.EAST); 1199 westCheckBox.setVisible(((Setup.getTrainDirection() & Setup.WEST) & 1200 (_location.getTrainDirections() & Location.WEST)) == Location.WEST); 1201 1202 if (_track != null) { 1203 northCheckBox.setSelected((_track.getTrainDirections() & Track.NORTH) == Track.NORTH); 1204 southCheckBox.setSelected((_track.getTrainDirections() & Track.SOUTH) == Track.SOUTH); 1205 eastCheckBox.setSelected((_track.getTrainDirections() & Track.EAST) == Track.EAST); 1206 westCheckBox.setSelected((_track.getTrainDirections() & Track.WEST) == Track.WEST); 1207 } 1208 panelTrainDir.revalidate(); 1209 revalidate(); 1210 } 1211 1212 @Override 1213 public void checkBoxActionPerformed(java.awt.event.ActionEvent ae) { 1214 if (ae.getSource() == autoDropCheckBox || ae.getSource() == autoPickupCheckBox) { 1215 updateTrainComboBox(); 1216 updateRouteComboBox(); 1217 return; 1218 } 1219 JCheckBox b = (JCheckBox) ae.getSource(); 1220 log.debug("checkbox change {}", b.getText()); 1221 if (b.isSelected()) { 1222 _track.addTypeName(b.getText()); 1223 } else { 1224 _track.deleteTypeName(b.getText()); 1225 } 1226 } 1227 1228 // set the service order 1229 private void updateCarOrder() { 1230 if (_track != null) { 1231 orderNormal.setSelected(_track.getServiceOrder().equals(Track.NORMAL)); 1232 orderFIFO.setSelected(_track.getServiceOrder().equals(Track.FIFO)); 1233 orderLIFO.setSelected(_track.getServiceOrder().equals(Track.LIFO)); 1234 } 1235 } 1236 1237 protected void updateDestinationOption() { 1238 if (_track != null) { 1239 if (_track.getDestinationOption().equals(Track.INCLUDE_DESTINATIONS)) { 1240 pDestinationOption.setVisible(true); 1241 destinationOptionButton.setText(Bundle.getMessage("AcceptOnly") + 1242 " " + 1243 _track.getDestinationListSize() + 1244 " " + 1245 Bundle.getMessage("Destinations")); 1246 } else if (_track.getDestinationOption().equals(Track.EXCLUDE_DESTINATIONS)) { 1247 pDestinationOption.setVisible(true); 1248 destinationOptionButton.setText(Bundle.getMessage("Exclude") + 1249 " " + 1250 (InstanceManager.getDefault(LocationManager.class).getNumberOfLocations() - 1251 _track.getDestinationListSize()) + 1252 " " + 1253 Bundle.getMessage("Destinations")); 1254 } else { 1255 destinationOptionButton.setText(Bundle.getMessage("AcceptAll")); 1256 } 1257 } 1258 } 1259 1260 @Override 1261 public void dispose() { 1262 if (_track != null) { 1263 _track.removePropertyChangeListener(this); 1264 } 1265 if (_location != null) { 1266 _location.removePropertyChangeListener(this); 1267 } 1268 InstanceManager.getDefault(CarRoads.class).removePropertyChangeListener(this); 1269 InstanceManager.getDefault(CarLoads.class).removePropertyChangeListener(this); 1270 InstanceManager.getDefault(CarTypes.class).removePropertyChangeListener(this); 1271 trainManager.removePropertyChangeListener(this); 1272 routeManager.removePropertyChangeListener(this); 1273 super.dispose(); 1274 } 1275 1276 @Override 1277 public void propertyChange(java.beans.PropertyChangeEvent e) { 1278 if (Control.SHOW_PROPERTY) { 1279 log.debug("Property change: ({}) old: ({}) new: ({})", e.getPropertyName(), e.getOldValue(), 1280 e.getNewValue()); 1281 } 1282 if (e.getPropertyName().equals(Location.TYPES_CHANGED_PROPERTY) || 1283 e.getPropertyName().equals(CarTypes.CARTYPES_CHANGED_PROPERTY) || 1284 e.getPropertyName().equals(Track.TYPES_CHANGED_PROPERTY)) { 1285 updateCheckboxes(); 1286 } 1287 if (e.getPropertyName().equals(Location.TRAIN_DIRECTION_CHANGED_PROPERTY) || 1288 e.getPropertyName().equals(Track.TRAIN_DIRECTION_CHANGED_PROPERTY) || 1289 e.getPropertyName().equals(Setup.TRAIN_DIRECTION_PROPERTY_CHANGE)) { 1290 updateTrainDir(); 1291 } 1292 if (e.getPropertyName().equals(TrainManager.LISTLENGTH_CHANGED_PROPERTY)) { 1293 updateTrainComboBox(); 1294 updateDropOptions(); 1295 updatePickupOptions(); 1296 } 1297 if (e.getPropertyName().equals(RouteManager.LISTLENGTH_CHANGED_PROPERTY)) { 1298 updateRouteComboBox(); 1299 updateDropOptions(); 1300 updatePickupOptions(); 1301 } 1302 if (e.getPropertyName().equals(Track.ROADS_CHANGED_PROPERTY)) { 1303 updateRoadOption(); 1304 } 1305 if (e.getPropertyName().equals(Track.LOADS_CHANGED_PROPERTY)) { 1306 updateLoadOption(); 1307 } 1308 if (e.getPropertyName().equals(Track.DROP_CHANGED_PROPERTY)) { 1309 updateDropOptions(); 1310 } 1311 if (e.getPropertyName().equals(Track.PICKUP_CHANGED_PROPERTY)) { 1312 updatePickupOptions(); 1313 } 1314 if (e.getPropertyName().equals(Track.SERVICE_ORDER_CHANGED_PROPERTY)) { 1315 updateCarOrder(); 1316 } 1317 if (e.getPropertyName().equals(Track.DESTINATIONS_CHANGED_PROPERTY) || 1318 e.getPropertyName().equals(Track.DESTINATION_OPTIONS_CHANGED_PROPERTY)) { 1319 updateDestinationOption(); 1320 } 1321 if (e.getPropertyName().equals(Track.LENGTH_CHANGED_PROPERTY)) { 1322 trackLengthTextField.setText(Integer.toString(_track.getLength())); 1323 } 1324 if (e.getPropertyName().equals(Track.LOAD_OPTIONS_CHANGED_PROPERTY)) { 1325 quickServiceCheckBox.setSelected(_track.isQuickServiceEnabled()); 1326 } 1327 } 1328 1329 private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(TrackEditFrame.class); 1330}