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