001package jmri.jmrit.consisttool; 002 003import java.awt.FlowLayout; 004import java.awt.event.ActionEvent; 005import java.awt.event.KeyEvent; 006import java.awt.event.KeyListener; 007import java.beans.PropertyChangeEvent; 008import java.io.IOException; 009import java.util.List; 010import java.util.ArrayList; 011import javax.swing.*; 012 013import jmri.Consist; 014import jmri.ConsistListListener; 015import jmri.ConsistListener; 016import jmri.ConsistManager; 017import jmri.LocoAddress; 018import jmri.DccLocoAddress; 019import jmri.InstanceManager; 020import jmri.jmrit.DccLocoAddressSelector; 021import jmri.jmrit.roster.swing.GlobalRosterEntryComboBox; 022import jmri.jmrit.roster.swing.RosterEntryComboBox; 023import jmri.jmrit.roster.Roster; 024import jmri.jmrit.roster.RosterEntry; 025import jmri.jmrit.symbolicprog.CvTableModel; 026import jmri.jmrit.symbolicprog.CvValue; 027import jmri.jmrit.throttle.ThrottleFrame; 028import jmri.jmrit.throttle.ThrottleFrameManager; 029import jmri.util.JmriJFrame; 030import jmri.util.gui.GuiLafPreferencesManager; 031import jmri.util.swing.JmriJOptionPane; 032 033import org.jdom2.JDOMException; 034 035/** 036 * Frame object for manipulating consists. 037 * 038 * @author Paul Bender Copyright (C) 2003-2008 039 */ 040public class ConsistToolFrame extends JmriJFrame implements ConsistListener, ConsistListListener { 041 042 // GUI member declarations 043 JLabel textAdrLabel = new JLabel(); 044 DccLocoAddressSelector adrSelector = new DccLocoAddressSelector(); 045 ConsistComboBox consistComboBox = new ConsistComboBox(); 046 JRadioButton isAdvancedConsist = new JRadioButton(Bundle.getMessage("AdvancedConsistButtonText")); 047 JRadioButton isCSConsist = new JRadioButton(Bundle.getMessage("CommandStationConsistButtonText")); 048 JButton deleteButton = new JButton(); 049 JButton throttleButton = new JButton(); 050 JButton reverseButton = new JButton(); 051 JButton restoreButton = new JButton(); 052 JLabel textLocoLabel = new JLabel(); 053 DccLocoAddressSelector locoSelector = new DccLocoAddressSelector(); 054 RosterEntryComboBox locoRosterBox; 055 JButton addLocoButton = new JButton(); 056 JButton resetLocoButton = new JButton(); 057 JCheckBox locoDirectionNormal = new JCheckBox(Bundle.getMessage("DirectionNormalText")); 058 ConsistDataModel consistModel = new ConsistDataModel(); 059 JTable consistTable = new JTable(consistModel); 060 ConsistManager consistManager = null; 061 JLabel _status = new JLabel(Bundle.getMessage("DefaultStatusText")); 062 private int _Consist_Type = Consist.ADVANCED_CONSIST; 063 private ConsistFile consistFile = null; 064 065 public ConsistToolFrame() { 066 super(); 067 init(); 068 } 069 070 private void init() { 071 consistManager = InstanceManager.getDefault(jmri.ConsistManager.class); 072 073 consistFile = new ConsistFile(); 074 try { 075 consistFile.readFile(); 076 } catch (IOException | JDOMException e) { 077 log.warn("error reading consist file: {}", e.getMessage()); 078 } 079 080 // register to be notified if the consist list changes. 081 consistManager.addConsistListListener(this); 082 083 // request an update from the layout. 084 consistManager.requestUpdateFromLayout(); 085 086 // configure items for GUI 087 textAdrLabel.setText(Bundle.getMessage("AddressLabelText")); 088 textAdrLabel.setVisible(true); 089 090 adrSelector.setVisible(true); 091 adrSelector.setToolTipText(Bundle.getMessage("AddressSelectorToolTip")); 092 textAdrLabel.setLabelFor(adrSelector); 093 094 initializeConsistBox(); 095 096 consistComboBox.addActionListener((ActionEvent e) -> consistSelected()); 097 098 isAdvancedConsist.setSelected(true); 099 isAdvancedConsist.setVisible(true); 100 isAdvancedConsist.setEnabled(false); 101 isAdvancedConsist.addActionListener((ActionEvent e) -> { 102 isAdvancedConsist.setSelected(true); 103 isCSConsist.setSelected(false); 104 _Consist_Type = Consist.ADVANCED_CONSIST; 105 adrSelector.setEnabled(true); 106 }); 107 isCSConsist.setSelected(false); 108 isCSConsist.setVisible(true); 109 isCSConsist.setEnabled(false); 110 isCSConsist.addActionListener((ActionEvent e) -> { 111 isAdvancedConsist.setSelected(false); 112 isCSConsist.setSelected(true); 113 _Consist_Type = Consist.CS_CONSIST; 114 adrSelector.setEnabled((consistManager.csConsistNeedsSeperateAddress())); 115 }); 116 117 if (consistManager.isCommandStationConsistPossible()) { 118 isAdvancedConsist.setEnabled(true); 119 isCSConsist.setEnabled(true); 120 } 121 122 deleteButton.setText(Bundle.getMessage("ButtonDelete")); 123 deleteButton.setVisible(true); 124 deleteButton.setToolTipText(Bundle.getMessage("DeleteButtonToolTip")); 125 deleteButton.addActionListener(this::deleteButtonActionPerformed); 126 127 throttleButton.setText(Bundle.getMessage("ThrottleButtonText")); 128 throttleButton.setVisible(true); 129 throttleButton.setToolTipText(Bundle.getMessage("ThrottleButtonToolTip")); 130 throttleButton.addActionListener(this::throttleButtonActionPerformed); 131 132 reverseButton.setText(Bundle.getMessage("ReverseButtonText")); 133 reverseButton.setVisible(true); 134 reverseButton.setToolTipText(Bundle.getMessage("ReverseButtonToolTip")); 135 reverseButton.addActionListener(this::reverseButtonActionPerformed); 136 137 restoreButton.setText(Bundle.getMessage("RestoreButtonText")); 138 restoreButton.setVisible(true); 139 restoreButton.setToolTipText(Bundle.getMessage("RestoreButtonToolTip")); 140 restoreButton.addActionListener(this::restoreButtonActionPerformed); 141 142 // Set up the controls for the First Locomotive in the consist. 143 textLocoLabel.setText(Bundle.getMessage("LocoLabelText")); 144 textLocoLabel.setVisible(true); 145 146 locoSelector.setToolTipText(Bundle.getMessage("LocoSelectorToolTip")); 147 locoSelector.setVisible(true); 148 textLocoLabel.setLabelFor(locoSelector); 149 150 locoSelector.addKeyListener(new KeyListener() { 151 @Override 152 public void keyPressed(KeyEvent e) { 153 // if we start typing, set the selected index of the locoRosterbox to nothing. 154 locoRosterBox.setSelectedIndex(0); 155 } 156 157 @Override 158 public void keyTyped(KeyEvent e) { 159 // only handling key presses 160 } 161 162 @Override 163 public void keyReleased(KeyEvent e) { 164 // only handling key presses 165 } 166 }); 167 168 locoRosterBox = new GlobalRosterEntryComboBox(); 169 locoRosterBox.setNonSelectedItem(""); 170 locoRosterBox.setSelectedIndex(0); 171 172 locoRosterBox.addPropertyChangeListener("selectedRosterEntries", (PropertyChangeEvent pce) -> locoSelected()); 173 174 locoRosterBox.setVisible(true); 175 176 locoDirectionNormal.setToolTipText(Bundle.getMessage("DirectionNormalToolTip")); 177 178 locoDirectionNormal.setSelected(true); 179 locoDirectionNormal.setVisible(true); 180 locoDirectionNormal.setEnabled(false); 181 182 addLocoButton.setText(Bundle.getMessage("ButtonAddText")); 183 addLocoButton.setVisible(true); 184 addLocoButton.setToolTipText(Bundle.getMessage("AddButtonToolTip")); 185 addLocoButton.addActionListener(this::addLocoButtonActionPerformed); 186 187 resetLocoButton.setText(Bundle.getMessage("ButtonReset")); 188 resetLocoButton.setVisible(true); 189 resetLocoButton.setToolTipText(Bundle.getMessage("ResetButtonToolTip")); 190 resetLocoButton.addActionListener(this::resetLocoButtonActionPerformed); 191 192 // general GUI config 193 setTitle(Bundle.getMessage("ConsistToolTitle")); 194 getContentPane().setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS)); 195 196 JMenuBar menuBar = new JMenuBar(); 197 setJMenuBar(menuBar); 198 199 // add a "File" menu 200 JMenu fileMenu = new JMenu(Bundle.getMessage("MenuFile")); 201 menuBar.add(fileMenu); 202 203 // Add a save item 204 fileMenu.add(new AbstractAction(Bundle.getMessage("ScanConsists")) { 205 @Override 206 public void actionPerformed(ActionEvent e) { 207 scanRoster(); 208 initializeConsistBox(); 209 consistModel.fireTableDataChanged(); 210 resetLocoButtonActionPerformed(e); 211 } 212 }); 213 214 // install items in GUI 215 // The address and related buttons are installed in a single pane 216 JPanel addressPanel = new JPanel(); 217 addressPanel.setLayout(new FlowLayout()); 218 219 addressPanel.add(textAdrLabel); 220 addressPanel.add(adrSelector.getCombinedJPanel()); 221 addressPanel.add(consistComboBox); 222 addressPanel.add(isAdvancedConsist); 223 addressPanel.add(isCSConsist); 224 225 getContentPane().add(addressPanel); 226 227 // The address and related buttons for each Locomotive 228 // are installed in a single pane 229 // New Locomotive 230 JPanel locoPanel = new JPanel(); 231 locoPanel.setLayout(new FlowLayout()); 232 233 locoPanel.add(textLocoLabel); 234 235 locoPanel.add(locoSelector.getCombinedJPanel()); 236 237 locoPanel.add(locoRosterBox); 238 locoPanel.add(locoDirectionNormal); 239 240 locoPanel.add(addLocoButton); 241 locoPanel.add(resetLocoButton); 242 243 getContentPane().add(locoPanel); 244 245 // setup the consist table 246 consistTable.setRowHeight(InstanceManager.getDefault(GuiLafPreferencesManager.class).getFontSize()*2 + 4); 247 // Set up the jtable in a Scroll Pane.. 248 JScrollPane consistPane = new JScrollPane(consistTable); 249 consistPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED); 250 consistModel.initTable(consistTable); 251 getContentPane().add(consistPane); 252 253 // Set up the Control Button panel 254 JPanel controlPanel = new JPanel(); 255 controlPanel.setLayout(new FlowLayout()); 256 257 controlPanel.add(deleteButton); 258 controlPanel.add(throttleButton); 259 controlPanel.add(reverseButton); 260 controlPanel.add(restoreButton); 261 262 getContentPane().add(controlPanel); 263 264 // add the status line directly to the bottom of the ContentPane. 265 JPanel statusPanel = new JPanel(); 266 statusPanel.setLayout(new FlowLayout()); 267 statusPanel.add(_status); 268 getContentPane().add(statusPanel); 269 270 addHelpMenu("package.jmri.jmrit.consisttool.ConsistToolFrame", true); 271 pack(); 272 273 } 274 275 private void initializeConsistBox() { 276 ArrayList<LocoAddress> existingConsists = consistManager.getConsistList(); 277 if (!existingConsists.isEmpty()) { 278 java.util.Collections.sort(existingConsists, new jmri.util.LocoAddressComparator()); // sort the consist list. 279 if (adrSelector.getAddress() != null) { 280 if (consistModel.getConsist() != null) { 281 consistModel.getConsist().removeConsistListener(this); 282 setDefaultStatus(); 283 } 284 consistModel.setConsist(adrSelector.getAddress()); 285 consistModel.getConsist().addConsistListener(this); 286 adrSelector.setEnabled(false); 287 } else { 288 if (consistModel.getConsist() != null) { 289 consistModel.getConsist().removeConsistListener(this); 290 setDefaultStatus(); 291 } 292 consistModel.setConsist((Consist) null); 293 adrSelector.setEnabled(true); 294 } 295 } else { 296 if (consistModel.getConsist() != null) { 297 consistModel.getConsist().removeConsistListener(this); 298 setDefaultStatus(); 299 } 300 consistModel.setConsist((Consist) null); 301 adrSelector.setEnabled(true); 302 } 303 } 304 305 public void deleteButtonActionPerformed(ActionEvent e) { 306 if (adrSelector.getAddress() == null) { 307 reportNoConsistSeletected(); 308 return; 309 } 310 DccLocoAddress address = adrSelector.getAddress(); 311 consistManager.getConsist(address); 312 // confirm delete 313 if (JmriJOptionPane.showConfirmDialog(this, Bundle.getMessage("DeleteWarningDialog", address), 314 Bundle.getMessage("QuestionTitle"), JmriJOptionPane.YES_NO_OPTION, 315 JmriJOptionPane.QUESTION_MESSAGE) != JmriJOptionPane.YES_OPTION ) { 316 return; // do not delete 317 } 318 try { 319 adrSelector.reset(); 320 consistManager.delConsist(address); 321 } catch (Exception ex) { 322 log.error("Error delting consist {}", address, ex); 323 } 324 adrSelector.setEnabled(true); 325 initializeConsistBox(); 326 resetLocoButtonActionPerformed(e); 327 canAdd(); 328 } 329 330 public void throttleButtonActionPerformed(ActionEvent e) { 331 if (adrSelector.getAddress() == null) { 332 reportNoConsistSeletected(); 333 return; 334 } 335 // make sure any new locomotives are added to the consist. 336 addLocoButtonActionPerformed(e); 337 // Create a throttle object with the 338 ThrottleFrame tf 339 = InstanceManager.getDefault(ThrottleFrameManager.class).createThrottleFrame(); 340 341 // Notify the throttle of the selected consist address 342 tf.getAddressPanel().setConsistAddress(adrSelector.getAddress()); 343 tf.toFront(); 344 } 345 346 public void reverseButtonActionPerformed(ActionEvent e) { 347 if (adrSelector.getAddress() == null) { 348 reportNoConsistSeletected(); 349 return; 350 } 351 // make sure any new locomotives are added to the consist. 352 addLocoButtonActionPerformed(e); 353 354 /* 355 * get the array list of the locomotives in the consist 356 */ 357 DccLocoAddress address = adrSelector.getAddress(); 358 Consist tempConsist = consistManager.getConsist(address); 359 tempConsist.reverse(); 360 consistManager.notifyConsistListChanged(); 361 } 362 363 public void restoreButtonActionPerformed(ActionEvent e) { 364 if (adrSelector.getAddress() == null) { 365 reportNoConsistSeletected(); 366 return; 367 } 368 // make sure any new locomotives are added to the consist. 369 addLocoButtonActionPerformed(e); 370 371 /* 372 * get the array list of the locomotives in the consist 373 */ 374 DccLocoAddress address = adrSelector.getAddress(); 375 Consist tempConsist = consistManager.getConsist(address); 376 tempConsist.restore(); 377 consistManager.notifyConsistListChanged(); 378 } 379 380 public void consistSelected() { 381 log.debug("Consist Selected"); 382 if (consistComboBox.getSelectedIndex() == -1 && adrSelector.getAddress() != null) { 383 log.debug("No Consist Selected"); 384 adrSelector.setEnabled(false); 385 recallConsist(); 386 } else if (consistComboBox.getSelectedIndex() == -1 387 || consistComboBox.getSelectedItem().equals("") 388 || consistComboBox.getSelectedItem().equals(Bundle.getMessage("NoConsistSelected"))) { 389 log.debug("Null Consist Selected"); 390 adrSelector.reset(); 391 adrSelector.setEnabled(true); 392 recallConsist(); 393 } else if (((DccLocoAddress) consistComboBox.getSelectedItem()) != adrSelector.getAddress()) { 394 log.debug("Consist {} consistComboBox", consistComboBox.getSelectedItem()); 395 adrSelector.setEnabled(false); 396 adrSelector.setAddress((DccLocoAddress) consistComboBox.getSelectedItem()); 397 recallConsist(); 398 } 399 } 400 401 // Recall the consist 402 private void recallConsist() { 403 if (adrSelector.getAddress() == null) { 404 // Clear any consist information that was present 405 locoSelector.reset(); 406 locoRosterBox.setSelectedIndex(0); 407 if (consistModel.getConsist() != null) { 408 consistModel.getConsist().removeConsistListener(this); 409 setDefaultStatus(); 410 } 411 consistModel.setConsist((Consist) null); 412 413 canAdd(); 414 415 return; 416 } 417 DccLocoAddress address = adrSelector.getAddress(); 418 if (consistModel.getConsist() != null) { 419 consistModel.getConsist().removeConsistListener(this); 420 _status.setText(Bundle.getMessage("DefaultStatusText")); 421 setDefaultStatus(); 422 } 423 Consist selectedConsist = consistManager.getConsist(address); 424 consistModel.setConsist(selectedConsist); 425 selectedConsist.addConsistListener(this); 426 427 // reset the editable locomotive information. 428 locoSelector.reset(); 429 locoRosterBox.setSelectedIndex(0); 430 locoDirectionNormal.setSelected(true); 431 432 // if there aren't any locomotives in the consist, don't let 433 // the user change the direction 434 locoDirectionNormal.setEnabled(consistModel.getRowCount()!=0); 435 436 log.debug("Recall Consist {}", address); 437 438 // What type of consist is this? 439 if (selectedConsist.getConsistType() == Consist.ADVANCED_CONSIST) { 440 log.debug("Consist type is Advanced Consist "); 441 isAdvancedConsist.setSelected(true); 442 isCSConsist.setSelected(false); 443 _Consist_Type = Consist.ADVANCED_CONSIST; 444 } else { 445 // This must be a CS Consist. 446 log.debug("Consist type is Command Station Consist "); 447 isAdvancedConsist.setSelected(false); 448 isCSConsist.setSelected(true); 449 _Consist_Type = Consist.CS_CONSIST; 450 } 451 452 canAdd(); 453 } 454 455 public void resetLocoButtonActionPerformed(ActionEvent e) { 456 locoSelector.reset(); 457 locoRosterBox.setSelectedIndex(0); 458 locoDirectionNormal.setSelected(true); 459 // if there aren't any locomotives in the consist, don't let 460 // the user change the direction 461 locoDirectionNormal.setEnabled(consistModel.getRowCount() != 0); 462 } 463 464 // Check to see if a consist address is selected, and if it 465 // is, dissable the "add button" if the maximum consist size is reached 466 public void canAdd() { 467 // If a consist address is selected, dissable the "add button" 468 // if the maximum size is reached 469 if (adrSelector.getAddress() != null) { 470 DccLocoAddress address = adrSelector.getAddress(); 471 if (consistModel.getRowCount() == consistManager.getConsist(address).sizeLimit()) { 472 locoSelector.setEnabled(false); 473 locoRosterBox.setEnabled(false); 474 addLocoButton.setEnabled(false); 475 resetLocoButton.setEnabled(false); 476 locoDirectionNormal.setEnabled(false); 477 } else { 478 enableGuiControls(); 479 } 480 } else { 481 enableGuiControls(); 482 } 483 } 484 485 private void enableGuiControls(){ 486 locoSelector.setEnabled(true); 487 locoRosterBox.setEnabled(true); 488 addLocoButton.setEnabled(true); 489 resetLocoButton.setEnabled(true); 490 locoDirectionNormal.setEnabled(false); 491 // if there aren't any locomotives in the consist, don't let 492 // the user change the direction 493 locoDirectionNormal.setEnabled(consistModel.getRowCount() != 0); 494 } 495 496 public void addLocoButtonActionPerformed(ActionEvent e) { 497 if (locoSelector.getAddress() == null) { 498 return; 499 } 500 if (_Consist_Type == Consist.ADVANCED_CONSIST && adrSelector.getAddress() == null) { 501 reportNoConsistSeletected(); 502 return; 503 } else if (_Consist_Type == Consist.ADVANCED_CONSIST 504 && adrSelector.getAddress().isLongAddress()) { 505 JmriJOptionPane.showMessageDialog(this, 506 Bundle.getMessage("RequiresShortConsistError")); 507 return; 508 } else if (_Consist_Type == Consist.CS_CONSIST && adrSelector.getAddress() == null) { 509 if (consistManager.csConsistNeedsSeperateAddress()) { 510 reportNoConsistSeletected(); 511 return; 512 } else { 513 // We need to set an identifier so we can recall the 514 // consist. We're going to use the lead locomotive number 515 // for this. 516 adrSelector.setAddress(locoSelector.getAddress()); 517 } 518 } 519 DccLocoAddress address = adrSelector.getAddress(); 520 /* 521 * Make sure the marked consist type matches the consist type stored for 522 * this consist 523 */ 524 if (_Consist_Type != consistManager.getConsist(address).getConsistType()) { 525 if (log.isDebugEnabled()) { 526 if (_Consist_Type == Consist.ADVANCED_CONSIST) { 527 log.debug("Setting Consist Type to Advanced Consist"); 528 } else if (_Consist_Type == Consist.CS_CONSIST) { 529 log.debug("Setting Consist Type to Command Station Assisted Consist"); 530 } 531 } 532 consistManager.getConsist(address).setConsistType(_Consist_Type); 533 } 534 535 DccLocoAddress locoaddress = locoSelector.getAddress(); 536 537 // Make sure the Address in question is allowed for this type of 538 // consist, and add it to the consist if it is 539 if (!consistManager.getConsist(address).isAddressAllowed(locoaddress)) { 540 JmriJOptionPane.showMessageDialog(this, 541 Bundle.getMessage("AddressNotAllowedError")); 542 return; 543 } 544 if (consistManager.getConsist(address).contains(locoaddress)) { 545 JmriJOptionPane.showMessageDialog(this, 546 Bundle.getMessage("AddressAlreadyInConsistError")); 547 return; 548 } 549 550 Consist tempConsist = consistManager.getConsist(address); 551 tempConsist.add(locoaddress, locoDirectionNormal.isSelected()); 552 553 // Try to get a roster entry 554 RosterEntry re = null; 555 if (locoRosterBox.getSelectedRosterEntries().length == 1) { 556 re = locoRosterBox.getSelectedRosterEntries()[0]; 557 } else { 558 List<RosterEntry> res = Roster.getDefault().matchingList(null, null, "" + locoaddress.getNumber(), null, null, null, null); 559 if (!res.isEmpty()) { 560 re = res.get(0); 561 } 562 } 563 564 if (re != null) { 565 tempConsist.setRosterId(locoaddress, re.titleString()); 566 } 567 568 if (consistComboBox.getSelectedItem() != adrSelector.getAddress()) { 569 initializeConsistBox(); 570 consistComboBox.setSelectedItem(adrSelector.getAddress()); 571 } 572 consistManager.notifyConsistListChanged(); 573 consistModel.fireTableDataChanged(); 574 resetLocoButtonActionPerformed(e); 575 } 576 577 public void locoSelected() { 578 if (locoRosterBox.getSelectedRosterEntries().length == 1) { 579 locoSelector.setAddress(locoRosterBox.getSelectedRosterEntries()[0].getDccLocoAddress()); 580 } 581 } 582 583 /** 584 * we're registering as a listener for Consist events, so we need to 585 * implement the interface. 586 * {@inheritDoc} 587 */ 588 @Override 589 public void consistReply(LocoAddress locoaddress, int status) { 590 log.debug("Consist Reply received for Locomotive {} with status {}", locoaddress, status); 591 _status.setText(consistManager.decodeErrorCode(status)); 592 // For some status codes, we want to trigger specific actions 593 //if((status & jmri.ConsistListener.CONSIST_FULL)!=0) { 594 // canAdd(); 595 //} else { 596 canAdd(); 597 //} 598 consistModel.fireTableDataChanged(); 599 try { 600 consistFile.writeFile(consistManager.getConsistList()); 601 } catch (IOException e) { 602 log.warn("error writing consist file: {}", e.getMessage()); 603 } 604 } 605 606 @Override 607 public void dispose() { 608 super.dispose(); 609 // de-register to be notified if the consist list changes. 610 consistManager.removeConsistListListener(this); 611 } 612 613 // ConsistListListener interface 614 /** 615 * {@inheritDoc} 616 */ 617 @Override 618 public void notifyConsistListChanged() { 619 // Save consist file 620 try { 621 consistFile.writeFile(consistManager.getConsistList()); 622 } catch (IOException e) { 623 log.warn("error writing consist file: {}", e.getMessage()); 624 } 625 // update the consist list. 626 initializeConsistBox(); 627 } 628 629 /** 630 * private method to scan the roster for consists 631 */ 632 private void scanRoster(){ 633 List<RosterEntry> roster = Roster.getDefault().getAllEntries(); 634 for(RosterEntry entry:roster){ 635 DccLocoAddress address = entry.getDccLocoAddress(); 636 CvTableModel cvTable = new CvTableModel(_status, null); // will hold CV objects 637 entry.readFile(); // read, but don't yet process 638 639 entry.loadCvModel(null, cvTable); 640 CvValue cv19Value = cvTable.getCvByNumber("19"); 641 if(cv19Value!=null && (cv19Value.getValue() & 0x7F)!=0){ 642 boolean direction = ((cv19Value.getValue()&0x80)==0); 643 DccLocoAddress consistAddress = new DccLocoAddress((cv19Value.getValue()&0x7f),false); 644 /* 645 * Make sure the marked consist type is an advanced consist. 646 * this consist 647 */ 648 Consist consist = consistManager.getConsist(consistAddress); 649 if (Consist.ADVANCED_CONSIST != consist.getConsistType()) { 650 consist.setConsistType(Consist.ADVANCED_CONSIST); 651 } 652 653 if (!consist.contains(address)) { 654 consist.add(address, direction ); 655 consist.setRosterId(address, entry.titleString()); 656 } 657 } 658 } 659 } 660 661 private void reportNoConsistSeletected(){ 662 JmriJOptionPane.showMessageDialog(this, 663 Bundle.getMessage("NoConsistSelectedError")); 664 665 } 666 667 public void setDefaultStatus() { 668 _status.setText(Bundle.getMessage("DefaultStatusText")); 669 } 670 671 private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(ConsistToolFrame.class); 672 673}