001package jmri.jmrit.operations.rollingstock; 002 003import java.awt.Dimension; 004import java.awt.GridBagLayout; 005import java.text.*; 006import java.util.ResourceBundle; 007 008import javax.swing.*; 009 010import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; 011import jmri.*; 012import jmri.jmrit.operations.OperationsFrame; 013import jmri.jmrit.operations.OperationsXml; 014import jmri.jmrit.operations.locations.*; 015import jmri.jmrit.operations.rollingstock.cars.*; 016import jmri.jmrit.operations.rollingstock.engines.Engine; 017import jmri.jmrit.operations.rollingstock.engines.EngineTypes; 018import jmri.jmrit.operations.setup.Control; 019import jmri.jmrit.operations.setup.Setup; 020import jmri.jmrit.operations.trains.TrainCommon; 021import jmri.swing.NamedBeanComboBox; 022import jmri.util.swing.JmriJOptionPane; 023 024/** 025 * Frame for edit of rolling stock. The common elements are: road, road number, 026 * type, blocking, length, location and track, groups (Kernel or Consist) 027 * weight, color, built, owner, comment. 028 * 029 * The edit engine frame currently doesn't show blocking or color. 030 * 031 * Engines and cars have different type, length, and group managers. 032 * 033 * @author Dan Boudreau Copyright (C) 2018 034 */ 035public abstract class RollingStockEditFrame extends OperationsFrame implements java.beans.PropertyChangeListener { 036 037 protected static final boolean IS_SAVE = true; 038 039 protected RollingStock _rs; 040 041 protected LocationManager locationManager = InstanceManager.getDefault(LocationManager.class); 042 043 JLabel textWeightTons = new JLabel(Bundle.getMessage("WeightTons")); 044 JLabel textRfidSystemName = new JLabel(); 045 046 // major buttons 047 public JButton editRoadButton = new JButton(Bundle.getMessage("ButtonEdit")); 048 public JButton clearRoadNumberButton = new JButton(Bundle.getMessage("ButtonClear")); 049 public JButton editTypeButton = new JButton(Bundle.getMessage("ButtonEdit")); 050 public JButton editLengthButton = new JButton(Bundle.getMessage("ButtonEdit")); 051 public JButton editGroupButton = new JButton(Bundle.getMessage("ButtonEdit")); 052 public JButton editOwnerButton = new JButton(Bundle.getMessage("ButtonEdit")); 053 054 public JButton saveButton = new JButton(Bundle.getMessage("ButtonSave")); 055 public JButton deleteButton = new JButton(Bundle.getMessage("ButtonDelete")); 056 public JButton addButton = new JButton(); // add car or locomotive 057 058 // check boxes 059 public JCheckBox autoTrackCheckBox = new JCheckBox(Bundle.getMessage("Auto")); 060 061 // text field 062 public JTextField roadNumberTextField = new JTextField(Control.max_len_string_road_number); 063 public JTextField builtTextField = new JTextField(Control.max_len_string_built_name + 3); 064 public JTextField blockingTextField = new JTextField(4); 065 public JTextField weightTextField = new JTextField(Control.max_len_string_weight_name); 066 public JTextField weightTonsTextField = new JTextField(Control.max_len_string_weight_name); 067 public JTextField commentTextField = new JTextField(35); 068 069 // text area 070 public JTextArea valueTextArea = new JTextArea(3, 35); 071 JScrollPane valueScroller = new JScrollPane(valueTextArea, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, 072 JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); 073 074 // combo boxes 075 public JComboBox<String> roadComboBox = InstanceManager.getDefault(CarRoads.class).getComboBox(); 076 public JComboBox<String> typeComboBox = getTypeManager().getComboBox(); 077 public JComboBox<String> lengthComboBox = getLengthManager().getComboBox(); 078 public JComboBox<String> ownerComboBox = InstanceManager.getDefault(CarOwners.class).getComboBox(); 079 public JComboBox<String> groupComboBox; 080 public JComboBox<String> modelComboBox; // for engines 081 public JComboBox<Location> locationBox = locationManager.getComboBox(); 082 public JComboBox<Track> trackLocationBox = new JComboBox<>(); 083 084 public NamedBeanComboBox<IdTag> rfidComboBox; 085 086 // panels 087 public JPanel pTypeOptions = new JPanel(); // options dependent on car or engine 088 public JPanel pGroup = new JPanel(); // Kernel or Consist 089 090 // panels for car edit 091 public JPanel pBlocking = new JPanel(); 092 public JPanel pColor = new JPanel(); 093 public JPanel pLoad = new JPanel(); 094 public JPanel pWeightOz = new JPanel(); 095 096 // panels for engine edit 097 public JPanel pModel = new JPanel(); 098 public JPanel pPower = new JPanel(); 099 100 public RollingStockEditFrame(String title) { 101 super(title); 102 // InstanceManager = InstanceManger.getInstance(); 103 } 104 105 abstract protected RollingStockAttribute getTypeManager(); 106 107 abstract protected RollingStockAttribute getLengthManager(); 108 109 abstract protected void buttonEditActionPerformed(java.awt.event.ActionEvent ae); 110 111 abstract protected ResourceBundle getRb(); 112 113 abstract protected void save(boolean isSave); 114 115 abstract protected void delete(); 116 117 @SuppressFBWarnings(value = "NP_NULL_ON_SOME_PATH_FROM_RETURN_VALUE", justification = "Checks for null") 118 @Override 119 public void initComponents() { 120 121 // disable delete and save buttons 122 deleteButton.setEnabled(false); 123 saveButton.setEnabled(false); 124 125 editRoadButton.setToolTipText(Bundle.getMessage("TipAddDeleteReplace", 126 Bundle.getMessage("road"))); // initial caps for some languages i.e. German 127 editTypeButton.setToolTipText(Bundle.getMessage("TipAddDeleteReplace", 128 Bundle.getMessage("type"))); // initial caps for some languages i.e. German 129 editLengthButton.setToolTipText(Bundle.getMessage("TipAddDeleteReplace", 130 Bundle.getMessage("length"))); // initial caps for some languages i.e. German 131 editOwnerButton.setToolTipText(Bundle.getMessage("TipAddDeleteReplace", 132 Bundle.getMessage("Owner").toLowerCase())); 133 134 autoTrackCheckBox.setToolTipText(getRb().getString("rsTipAutoTrack")); 135 136 // create panel 137 JPanel pPanel = new JPanel(); 138 pPanel.setLayout(new BoxLayout(pPanel, BoxLayout.Y_AXIS)); 139 140 // Layout the panel by rows 141 // row 1 142 JPanel pRoad = new JPanel(); 143 pRoad.setLayout(new GridBagLayout()); 144 pRoad.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("Road"))); 145 addItem(pRoad, roadComboBox, 1, 0); 146 addItem(pRoad, editRoadButton, 2, 0); 147 pPanel.add(pRoad); 148 149 // row 2 150 JPanel pRoadNumber = new JPanel(); 151 pRoadNumber.setLayout(new GridBagLayout()); 152 pRoadNumber.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("RoadNumber"))); 153 addItem(pRoadNumber, roadNumberTextField, 1, 0); 154 addItem(pRoadNumber, clearRoadNumberButton, 2, 0); 155 pPanel.add(pRoadNumber); 156 157 // only engines have a model name 158 pPanel.add(pModel); 159 pModel.setVisible(false); 160 161 // row 3 162 JPanel pType = new JPanel(); 163 pType.setLayout(new GridBagLayout()); 164 pType.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("Type"))); 165 addItem(pType, typeComboBox, 0, 0); 166 addItem(pType, editTypeButton, 1, 0); 167 168 // type options dependent on car or engine rolling stock 169 addItemWidth(pType, pTypeOptions, 3, 0, 1); 170 pPanel.add(pType); 171 172 // row 4 173 pBlocking.setLayout(new GridBagLayout()); 174 pBlocking.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("BorderLayoutBlockingOrder"))); 175 addItem(pBlocking, blockingTextField, 0, 0); 176 blockingTextField.setText("0"); 177 pPanel.add(pBlocking); 178 pBlocking.setVisible(false); // default is blocking order not shown 179 180 // row 5 181 JPanel pLength = new JPanel(); 182 pLength.setLayout(new GridBagLayout()); 183 pLength.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("Length"))); 184 addItem(pLength, lengthComboBox, 1, 0); 185 addItem(pLength, editLengthButton, 2, 0); 186 pPanel.add(pLength); 187 188 // row 6 189 JPanel pLocation = new JPanel(); 190 pLocation.setLayout(new GridBagLayout()); 191 pLocation.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("LocationAndTrack"))); 192 addItem(pLocation, locationBox, 1, 0); 193 addItem(pLocation, trackLocationBox, 2, 0); 194 addItem(pLocation, autoTrackCheckBox, 3, 0); 195 pPanel.add(pLocation); 196 197 // optional panel 198 JPanel pOptional = new JPanel(); 199 pOptional.setLayout(new BoxLayout(pOptional, BoxLayout.Y_AXIS)); 200 JScrollPane optionPane = new JScrollPane(pOptional); 201 optionPane.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("BorderLayoutOptional"))); 202 203 // row 7 204 JPanel pWeight = new JPanel(); 205 pWeight.setLayout(new BoxLayout(pWeight, BoxLayout.Y_AXIS)); 206 pWeight.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("Weight"))); 207 208 // weight in oz only shown for cars 209 pWeight.add(pWeightOz); 210 211 JPanel pWeightTons = new JPanel(); 212 pWeightTons.setLayout(new GridBagLayout()); 213 addItem(pWeightTons, textWeightTons, 0, 0); 214 addItem(pWeightTons, weightTonsTextField, 1, 0); 215 addItem(pWeightTons, new JLabel(), 2, 0); 216 addItem(pWeightTons, new JLabel(), 3, 0); 217 addItem(pWeightTons, new JLabel(), 4, 0); 218 pWeight.add(pWeightTons); 219 pOptional.add(pWeight); 220 221 // row 8 for cars 222 pOptional.add(pColor); 223 pColor.setVisible(false); 224 225 // row 9 for cars 226 pOptional.add(pLoad); 227 pLoad.setVisible(false); 228 229 // for engines 230 pOptional.add(pPower); 231 pPower.setVisible(false); 232 233 // row 10 234 pGroup.setLayout(new GridBagLayout()); 235 addItem(pGroup, groupComboBox, 1, 0); 236 addItem(pGroup, editGroupButton, 2, 0); 237 pOptional.add(pGroup); 238 239 // row 11 240 JPanel pBuilt = new JPanel(); 241 pBuilt.setLayout(new GridBagLayout()); 242 pBuilt.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("Built"))); 243 addItem(pBuilt, builtTextField, 1, 0); 244 pOptional.add(pBuilt); 245 246 // row 12 247 JPanel pOwner = new JPanel(); 248 pOwner.setLayout(new GridBagLayout()); 249 pOwner.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("Owner"))); 250 addItem(pOwner, ownerComboBox, 1, 0); 251 addItem(pOwner, editOwnerButton, 2, 0); 252 pOptional.add(pOwner); 253 254 // row 13 255 if (Setup.isValueEnabled()) { 256 JPanel pValue = new JPanel(); 257 pValue.setLayout(new GridBagLayout()); 258 pValue.setBorder(BorderFactory.createTitledBorder(Setup.getValueLabel())); 259 addItem(pValue, valueScroller, 1, 0); 260 pOptional.add(pValue); 261 262 // adjust text area width based on window size 263 adjustTextAreaColumnWidth(valueScroller, valueTextArea); 264 } 265 266 // row 14 267 IdTagManager tagManager = InstanceManager.getNullableDefault(IdTagManager.class); 268 if (Setup.isRfidEnabled() && tagManager != null) { 269 JPanel pRfid = new JPanel(); 270 pRfid.setLayout(new GridBagLayout()); 271 pRfid.setBorder(BorderFactory.createTitledBorder(Setup.getRfidLabel())); 272 rfidComboBox = new NamedBeanComboBox<IdTag>(tagManager); 273 rfidComboBox.setAllowNull(true); 274 rfidComboBox.setToolTipText(Bundle.getMessage("TipIdTag")); 275 addItem(pRfid, rfidComboBox, 0, 0); 276 addItem(pRfid, textRfidSystemName, 1, 0); 277 pOptional.add(pRfid); 278 } 279 280 // row 15 281 JPanel pComment = new JPanel(); 282 pComment.setLayout(new GridBagLayout()); 283 pComment.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("Comment"))); 284 addItem(pComment, commentTextField, 1, 0); 285 pOptional.add(pComment); 286 287 // button panel 288 JPanel pButtons = new JPanel(); 289 pButtons.setLayout(new GridBagLayout()); 290 addItem(pButtons, deleteButton, 0, 25); 291 addItem(pButtons, addButton, 1, 25); 292 addItem(pButtons, saveButton, 3, 25); 293 294 // add panels 295 getContentPane().setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS)); 296 getContentPane().add(pPanel); 297 getContentPane().add(optionPane); 298 getContentPane().add(pButtons); 299 300 // setup buttons 301 addEditButtonAction(editRoadButton); 302 addEditButtonAction(editTypeButton); 303 addEditButtonAction(editLengthButton); 304 addEditButtonAction(editGroupButton); 305 addEditButtonAction(editOwnerButton); 306 307 addButtonAction(clearRoadNumberButton); 308 addButtonAction(deleteButton); 309 addButtonAction(addButton); 310 addButtonAction(saveButton); 311 312 // setup combobox 313 addComboBoxAction(typeComboBox); 314 addComboBoxAction(lengthComboBox); 315 addComboBoxAction(locationBox); 316 317 addCheckBoxAction(autoTrackCheckBox); 318 autoTrackCheckBox.setEnabled(false); 319 320 // get notified if combo box gets modified 321 addPropertyChangeListeners(); 322 323 initMinimumSize(new Dimension(Control.panelWidth500, Control.panelHeight500)); 324 } 325 326 protected void load(RollingStock rs) { 327 _rs = rs; 328 329 // engines and cars share the same road database 330 if (!InstanceManager.getDefault(CarRoads.class).containsName(rs.getRoadName())) { 331 if (JmriJOptionPane.showConfirmDialog(this, 332 Bundle.getMessage("roadNameNotExist", rs.getRoadName()), 333 Bundle.getMessage("addRoad"), JmriJOptionPane.YES_NO_OPTION) == JmriJOptionPane.YES_OPTION) { 334 InstanceManager.getDefault(CarRoads.class).addName(rs.getRoadName()); 335 } 336 } 337 roadComboBox.setSelectedItem(rs.getRoadName()); 338 339 roadNumberTextField.setText(rs.getNumber()); 340 341 if (!getTypeManager().containsName(rs.getTypeName())) { 342 if (JmriJOptionPane.showConfirmDialog(this, 343 Bundle.getMessage("typeNameNotExist", rs.getTypeName()), 344 Bundle.getMessage("addType"), JmriJOptionPane.YES_NO_OPTION) == JmriJOptionPane.YES_OPTION) { 345 getTypeManager().addName(rs.getTypeName()); 346 } 347 } 348 typeComboBox.setSelectedItem(rs.getTypeName()); 349 blockingTextField.setText(Integer.toString(rs.getBlocking())); 350 351 if (!getLengthManager().containsName(rs.getLength())) { 352 if (JmriJOptionPane.showConfirmDialog(this, 353 Bundle.getMessage("lengthNameNotExist", rs.getLength()), 354 Bundle.getMessage("addLength"), JmriJOptionPane.YES_NO_OPTION) == JmriJOptionPane.YES_OPTION) { 355 getLengthManager().addName(rs.getLength()); 356 } 357 } 358 // } 359 lengthComboBox.setSelectedItem(rs.getLength()); 360 361 weightTextField.setText(rs.getWeight()); 362 weightTonsTextField.setText(rs.getWeightTons()); 363 locationBox.setSelectedItem(rs.getLocation()); 364 updateTrackLocationBox(); 365 366 builtTextField.setText(rs.getBuilt()); 367 368 // Engines and cars share the owner database 369 if (!InstanceManager.getDefault(CarOwners.class).containsName(rs.getOwnerName())) { 370 if (JmriJOptionPane.showConfirmDialog(this, 371 Bundle.getMessage("ownerNameNotExist", rs.getOwnerName()), 372 Bundle.getMessage("addOwner"), JmriJOptionPane.YES_NO_OPTION) == JmriJOptionPane.YES_OPTION) { 373 InstanceManager.getDefault(CarOwners.class).addName(rs.getOwnerName()); 374 } 375 } 376 ownerComboBox.setSelectedItem(rs.getOwnerName()); 377 378 commentTextField.setText(rs.getComment()); 379 valueTextArea.setText(rs.getValue()); 380 if (rfidComboBox != null) { 381 rfidComboBox.setSelectedItem(rs.getIdTag()); 382 textRfidSystemName.setText(rs.getRfid()); 383 } 384 // enable delete and save buttons 385 deleteButton.setEnabled(true); 386 saveButton.setEnabled(true); 387 autoTrackCheckBox.setEnabled(true); 388 } 389 390 @Override 391 public void comboBoxActionPerformed(java.awt.event.ActionEvent ae) { 392 if (ae.getSource() == typeComboBox && typeComboBox.getSelectedItem() != null) { 393 // turn off auto for location tracks 394 autoTrackCheckBox.setSelected(false); 395 autoTrackCheckBox.setEnabled(false); 396 updateTrackLocationBox(); 397 } 398 if (ae.getSource() == locationBox) { 399 updateTrackLocationBox(); 400 } 401 } 402 403 @Override 404 public void checkBoxActionPerformed(java.awt.event.ActionEvent ae) { 405 if (ae.getSource() == autoTrackCheckBox) { 406 updateTrackLocationBox(); 407 } 408 } 409 410 // Save, Delete, Add, Clear, Calculate, Edit Load buttons 411 @Override 412 public void buttonActionPerformed(java.awt.event.ActionEvent ae) { 413 if (ae.getSource() == saveButton) { 414 // log.debug("car save button pressed"); 415 if (!check(_rs)) { 416 return; 417 } 418 save(IS_SAVE); 419 // save car file 420 OperationsXml.save(); 421 if (Setup.isCloseWindowOnSaveEnabled()) { 422 dispose(); 423 } 424 } 425 if (ae.getSource() == addButton) { 426 if (!check(null)) { 427 return; 428 } 429 430 // enable delete and save buttons 431 deleteButton.setEnabled(true); 432 saveButton.setEnabled(true); 433 434 save(!IS_SAVE); 435 // save car file 436 OperationsXml.save(); 437 } 438 if (ae.getSource() == deleteButton) { 439 log.debug("rolling stock delete button activated"); 440 // disable delete and save buttons 441 deleteButton.setEnabled(false); 442 saveButton.setEnabled(false); 443 if (_rs != null) { 444 _rs.removePropertyChangeListener(this); 445 } 446 delete(); 447 _rs = null; 448 OperationsXml.save(); 449 } 450 if (ae.getSource() == clearRoadNumberButton) { 451 roadNumberTextField.setText(""); 452 roadNumberTextField.requestFocus(); 453 } 454 } 455 456 protected void updateTrackLocationBox() { 457 if (locationBox.getSelectedItem() == null) { 458 trackLocationBox.removeAllItems(); 459 } else { 460 log.debug("Update tracks for location: {}", locationBox.getSelectedItem()); 461 Location loc = ((Location) locationBox.getSelectedItem()); 462 loc.updateComboBox(trackLocationBox, _rs, autoTrackCheckBox.isSelected(), false); 463 if (_rs != null && _rs.getLocation() == loc) { 464 trackLocationBox.setSelectedItem(_rs.getTrack()); 465 } 466 } 467 } 468 469 protected boolean check(RollingStock rs) { 470 String roadNum = roadNumberTextField.getText(); 471 // hyphen feature needs at least one character to work properly 472 if (roadNum.contains(TrainCommon.HYPHEN) && roadNum.split(TrainCommon.HYPHEN).length == 0) { 473 JmriJOptionPane.showMessageDialog(this, Bundle.getMessage("HyphenFeature"), Bundle.getMessage("roadNumNG"), 474 JmriJOptionPane.ERROR_MESSAGE); 475 return false; 476 } 477 // ignore characters after hyphen for field length 478 String rNum = TrainCommon.splitString(roadNum); 479 if (rNum.length() > Control.max_len_string_road_number) { 480 JmriJOptionPane.showMessageDialog(this, 481 MessageFormat.format(getRb().getString("RoadNumMustBeLess"), 482 new Object[] { Control.max_len_string_road_number + 1 }), 483 getRb().getString("RoadNumTooLong"), JmriJOptionPane.ERROR_MESSAGE); 484 return false; 485 } 486 if (!OperationsXml.checkFileName(roadNum)) { 487 JmriJOptionPane.showMessageDialog(this, 488 Bundle.getMessage("NameResChar") + NEW_LINE + Bundle.getMessage("ReservedChar"), 489 Bundle.getMessage("roadNumNG"), JmriJOptionPane.ERROR_MESSAGE); 490 return false; 491 } 492 // check rolling stock's weight in tons has proper format 493 if (!weightTonsTextField.getText().trim().isEmpty()) { 494 try { 495 Integer.parseInt(weightTonsTextField.getText()); 496 } catch (Exception e) { 497 JmriJOptionPane.showMessageDialog(this, getRb().getString("WeightFormatTon"), 498 getRb().getString("WeightTonError"), JmriJOptionPane.ERROR_MESSAGE); 499 return false; 500 } 501 } 502 return true; 503 } 504 505 protected <T extends RollingStock> void save(RollingStockManager<T> manager, boolean isSave) { 506 // if the rolling stock's road or number changes, it needs a new id 507 if (isSave && 508 _rs != null && 509 (!_rs.getRoadName().equals(roadComboBox.getSelectedItem()) || 510 !_rs.getNumber().equals(roadNumberTextField.getText()))) { 511 String road = (String) roadComboBox.getSelectedItem(); 512 String number = roadNumberTextField.getText(); 513 _rs.setRoadName(road); 514 _rs.setNumber(number); 515 } 516 if (_rs == null || 517 !_rs.getRoadName().equals(roadComboBox.getSelectedItem()) || 518 !_rs.getNumber().equals(roadNumberTextField.getText())) { 519 _rs = manager.newRS((String) roadComboBox.getSelectedItem(), roadNumberTextField.getText()); 520 _rs.addPropertyChangeListener(this); 521 } 522 // engine model must be set before type, length, weight and HP 523 if (Engine.class.isInstance(_rs) && modelComboBox.getSelectedItem() != null) { 524 ((Engine) _rs).setModel((String) modelComboBox.getSelectedItem()); 525 } 526 if (typeComboBox.getSelectedItem() != null) { 527 _rs.setTypeName((String) typeComboBox.getSelectedItem()); 528 } 529 530 int blocking = RollingStock.DEFAULT_BLOCKING_ORDER; 531 try { 532 blocking = Integer.parseInt(blockingTextField.getText()); 533 // only allow numbers between -100 and 100 534 if (blocking < -RollingStock.MAX_BLOCKING_ORDER || blocking > RollingStock.MAX_BLOCKING_ORDER) { 535 blocking = RollingStock.DEFAULT_BLOCKING_ORDER; 536 } 537 } catch (Exception e) { 538 log.warn("Blocking must be a number between -{} and {}", RollingStock.MAX_BLOCKING_ORDER, 539 RollingStock.MAX_BLOCKING_ORDER); 540 } 541 blockingTextField.setText(Integer.toString(blocking)); 542 543 if (lengthComboBox.getSelectedItem() != null) { 544 _rs.setLength((String) lengthComboBox.getSelectedItem()); 545 } 546 try { 547 _rs.setWeight(NumberFormat.getNumberInstance().parse(weightTextField.getText()).toString()); 548 } catch (ParseException e1) { 549 log.debug("Weight not a number"); 550 } 551 _rs.setWeightTons(weightTonsTextField.getText()); 552 _rs.setBuilt(builtTextField.getText()); 553 if (ownerComboBox.getSelectedItem() != null) { 554 _rs.setOwnerName((String) ownerComboBox.getSelectedItem()); 555 } 556 _rs.setComment(commentTextField.getText()); 557 _rs.setValue(valueTextArea.getText()); 558 if (rfidComboBox != null) { 559 // save the IdTag for this rolling stock 560 _rs.setIdTag(rfidComboBox.getSelectedItem()); 561 textRfidSystemName.setText(_rs.getRfid()); 562 } 563 autoTrackCheckBox.setEnabled(true); 564 } 565 566 protected void checkAndSetLocationAndTrack(RollingStock rs) { 567 if (locationBox.getSelectedItem() != null && trackLocationBox.getSelectedItem() == null) { 568 JmriJOptionPane.showMessageDialog(this, getRb().getString("rsFullySelect"), getRb().getString("rsCanNotLoc"), 569 JmriJOptionPane.ERROR_MESSAGE); 570 // update location only if it has changed 571 } else if (rs.getLocation() == null || 572 !rs.getLocation().equals(locationBox.getSelectedItem()) || 573 rs.getTrack() == null || 574 !rs.getTrack().equals(trackLocationBox.getSelectedItem())) { 575 setLocationAndTrack(rs); 576 } 577 } 578 579 protected void setLocationAndTrack(RollingStock rs) { 580 if (locationBox.getSelectedItem() == null) { 581 rs.setLocation(null, null); 582 } else { 583 rs.setLastRouteId(RollingStock.NONE); // clear last route id 584 String status = rs.setLocation((Location) locationBox.getSelectedItem(), 585 (Track) trackLocationBox.getSelectedItem()); 586 if (!status.equals(Track.OKAY)) { 587 log.debug("Can't set rolling stock's location because of {}", status); 588 JmriJOptionPane.showMessageDialog(this, 589 MessageFormat.format(getRb().getString("rsCanNotLocMsg"), 590 new Object[] { rs.toString(), status }), 591 getRb().getString("rsCanNotLoc"), JmriJOptionPane.ERROR_MESSAGE); 592 // does the user want to force the rolling stock to this track? 593 int results = JmriJOptionPane.showOptionDialog(this, 594 MessageFormat.format(getRb().getString("rsForce"), 595 new Object[] { rs.toString(), (Track) trackLocationBox.getSelectedItem() }), 596 MessageFormat.format(getRb().getString("rsOverride"), new Object[] { status }), 597 JmriJOptionPane.YES_NO_OPTION, JmriJOptionPane.QUESTION_MESSAGE, null, null, null); 598 if (results == JmriJOptionPane.YES_OPTION) { 599 log.debug("Force rolling stock to track"); 600 rs.setLocation((Location) locationBox.getSelectedItem(), (Track) trackLocationBox.getSelectedItem(), 601 RollingStock.FORCE); 602 } 603 } 604 } 605 } 606 607 // for the AttributeEditFrame edit buttons 608 protected void addEditButtonAction(JButton b) { 609 b.addActionListener(new java.awt.event.ActionListener() { 610 @Override 611 public void actionPerformed(java.awt.event.ActionEvent e) { 612 buttonEditActionPerformed(e); 613 } 614 }); 615 } 616 617 @Override 618 public void dispose() { 619 removePropertyChangeListeners(); 620 super.dispose(); 621 } 622 623 protected void addPropertyChangeListeners() { 624 InstanceManager.getDefault(CarRoads.class).addPropertyChangeListener(this); 625 getTypeManager().addPropertyChangeListener(this); 626 getLengthManager().addPropertyChangeListener(this); 627 InstanceManager.getDefault(CarOwners.class).addPropertyChangeListener(this); 628 locationManager.addPropertyChangeListener(this); 629 } 630 631 protected void removePropertyChangeListeners() { 632 InstanceManager.getDefault(CarRoads.class).removePropertyChangeListener(this); 633 getTypeManager().removePropertyChangeListener(this); 634 getLengthManager().removePropertyChangeListener(this); 635 InstanceManager.getDefault(CarOwners.class).removePropertyChangeListener(this); 636 locationManager.removePropertyChangeListener(this); 637 } 638 639 @Override 640 public void propertyChange(java.beans.PropertyChangeEvent e) { 641 if (e.getPropertyName().equals(CarRoads.CARROADS_CHANGED_PROPERTY)) { 642 InstanceManager.getDefault(CarRoads.class).updateComboBox(roadComboBox); 643 if (_rs != null) { 644 roadComboBox.setSelectedItem(_rs.getRoadName()); 645 } 646 } 647 if (e.getPropertyName().equals(CarTypes.CARTYPES_CHANGED_PROPERTY) || 648 e.getPropertyName().equals(EngineTypes.ENGINETYPES_CHANGED_PROPERTY)) { 649 getTypeManager().updateComboBox(typeComboBox); 650 if (_rs != null) { 651 typeComboBox.setSelectedItem(_rs.getTypeName()); 652 } 653 } 654 if (e.getPropertyName().equals(CarOwners.CAROWNERS_CHANGED_PROPERTY)) { 655 InstanceManager.getDefault(CarOwners.class).updateComboBox(ownerComboBox); 656 if (_rs != null) { 657 ownerComboBox.setSelectedItem(_rs.getOwnerName()); 658 } 659 } 660 if (e.getPropertyName().equals(LocationManager.LISTLENGTH_CHANGED_PROPERTY) || 661 e.getPropertyName().equals(RollingStock.TRACK_CHANGED_PROPERTY)) { 662 InstanceManager.getDefault(LocationManager.class).updateComboBox(locationBox); 663 updateTrackLocationBox(); 664 if (_rs != null && _rs.getLocation() != null) { 665 locationBox.setSelectedItem(_rs.getLocation()); 666 } 667 } 668 } 669 670 private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(RollingStockEditFrame.class); 671}