001package jmri.jmrit.beantable; 002 003import java.awt.BorderLayout; 004import java.awt.Container; 005import java.awt.FlowLayout; 006import java.awt.event.ActionEvent; 007import java.awt.event.ActionListener; 008import java.util.ArrayList; 009import java.util.Arrays; 010import java.util.List; 011import java.util.ResourceBundle; 012import java.util.Set; 013import javax.annotation.Nonnull; 014import javax.swing.*; 015import javax.swing.border.TitledBorder; 016import javax.swing.event.ChangeEvent; 017import javax.swing.table.TableCellEditor; 018import javax.swing.table.TableColumn; 019import javax.swing.table.TableColumnModel; 020import jmri.*; 021import jmri.NamedBean.DisplayOptions; 022import jmri.jmrit.dispatcher.TrainInfoFile; 023import jmri.jmrit.roster.RosterEntry; 024import jmri.jmrit.roster.swing.RosterEntryComboBox; 025import jmri.util.JmriJFrame; 026import jmri.swing.NamedBeanComboBox; 027import jmri.util.swing.JComboBoxUtil; 028import jmri.util.swing.JmriJOptionPane; 029import jmri.util.table.ButtonEditor; 030import jmri.util.table.ButtonRenderer; 031 032/** 033 * Swing action to create and register a TransitTable GUI. 034 * 035 * @author Dave Duchamp Copyright (C) 2008, 2010, 2011 036 */ 037public class TransitTableAction extends AbstractTableAction<Transit> { 038 039 /** 040 * Create an action with a specific title. 041 * <p> 042 * Note that the argument is the Action title, not the title of the 043 * resulting frame. Perhaps this should be changed? 044 * 045 * @param actionName action title 046 */ 047 public TransitTableAction(String actionName) { 048 super(actionName); 049 050 transitManager = InstanceManager.getNullableDefault(TransitManager.class); 051 // disable ourself if there is no Transit manager available 052 if (sectionManager == null || transitManager == null) { 053 super.setEnabled(false); 054 } 055 updateSensorList(); 056 } 057 058 public TransitTableAction() { 059 this(Bundle.getMessage("TitleTransitTable")); 060 } 061 062 static final ResourceBundle rbx = ResourceBundle.getBundle("jmri.jmrit.beantable.SectionTransitTableBundle"); 063 064 /** 065 * Create the JTable DataModel, along with the changes for the specific case 066 * of Transit objects. 067 */ 068 @Override 069 protected void createModel() { 070 m = new BeanTableDataModel<Transit>() { 071 072 static public final int EDITCOL = NUMCOLUMN; 073 static public final int DUPLICATECOL = EDITCOL + 1; 074 075 @Override 076 public String getValue(String name) { 077 if (name == null) { 078 log.warn("requested getValue(null)"); 079 return "(no name)"; 080 } 081 Transit z = InstanceManager.getDefault(TransitManager.class).getBySystemName(name); 082 if (z == null) { 083 log.debug("requested getValue(\"{}\"), Transit doesn't exist", name); 084 return "(no Transit)"; 085 } 086 return "Transit"; 087 } 088 089 @Override 090 public TransitManager getManager() { 091 return InstanceManager.getDefault(TransitManager.class); 092 } 093 094 @Override 095 public Transit getBySystemName(@Nonnull String name) { 096 return InstanceManager.getDefault(TransitManager.class).getBySystemName(name); 097 } 098 099 @Override 100 public Transit getByUserName(@Nonnull String name) { 101 return InstanceManager.getDefault(TransitManager.class).getByUserName(name); 102 } 103 104 @Override 105 protected String getMasterClassName() { 106 return getClassName(); 107 } 108 109 @Override 110 public void clickOn(Transit t) { 111 } 112 113 @Override 114 public int getColumnCount() { 115 return DUPLICATECOL + 1; 116 } 117 118 @Override 119 public Object getValueAt(int row, int col) { 120 switch (col) { 121 case VALUECOL: 122 // some error checking 123 if (row >= sysNameList.size()) { 124 log.debug("row is greater than name list"); 125 return ""; 126 } Transit z = getBySystemName(sysNameList.get(row)); 127 if (z == null) { 128 return ""; 129 } else { 130 int state = z.getState(); 131 if (state == Transit.IDLE) { 132 return (rbx.getString("TransitIdle")); 133 } else if (state == Transit.ASSIGNED) { 134 return (rbx.getString("TransitAssigned")); 135 } 136 } break; 137 case EDITCOL: 138 return Bundle.getMessage("ButtonEdit"); 139 case DUPLICATECOL: 140 return rbx.getString("ButtonDuplicate"); 141 default: 142 return super.getValueAt(row, col); 143 } 144 return null; 145 } 146 147 @Override 148 public void setValueAt(Object value, int row, int col) { 149 switch (col) { 150 case EDITCOL: 151 SwingUtilities.invokeLater(() -> { 152 editPressed(((Transit) getValueAt(row, SYSNAMECOL)).getSystemName()); 153 }); 154 break; 155 case DUPLICATECOL: 156 SwingUtilities.invokeLater(() -> { 157 duplicatePressed(((Transit) getValueAt(row, SYSNAMECOL)).getSystemName()); 158 }); 159 break; 160 default: 161 super.setValueAt(value, row, col); 162 break; 163 } 164 } 165 166 @Override 167 public String getColumnName(int col) { 168 switch (col) { 169 case EDITCOL: // no name on Edit column 170 case DUPLICATECOL: // no name on Duplicate column 171 return ""; 172 default: 173 return super.getColumnName(col); 174 } 175 } 176 177 @Override 178 public Class<?> getColumnClass(int col) { 179 switch (col) { 180 case VALUECOL: 181 return String.class; // not a button 182 case EDITCOL: 183 case DUPLICATECOL: 184 return JButton.class; 185 default: 186 return super.getColumnClass(col); 187 } 188 } 189 190 @Override 191 public boolean isCellEditable(int row, int col) { 192 switch (col) { 193 case VALUECOL: 194 return false; 195 case EDITCOL: 196 case DUPLICATECOL: 197 return true; 198 default: 199 return super.isCellEditable(row, col); 200 } 201 } 202 203 @Override 204 public int getPreferredWidth(int col) { 205 // override default value for SystemName and UserName columns 206 switch (col) { 207 case SYSNAMECOL: 208 return new JTextField(9).getPreferredSize().width; 209 case USERNAMECOL: 210 return new JTextField(17).getPreferredSize().width; 211 case VALUECOL: 212 case EDITCOL: 213 return new JTextField(6).getPreferredSize().width; 214 case DUPLICATECOL: 215 return new JTextField(10).getPreferredSize().width; 216 default: 217 return super.getPreferredWidth(col); 218 } 219 } 220 221 @Override 222 public void configValueColumn(JTable table) { 223 // value column isn't a button, so config is null 224 } 225 226 @Override 227 protected boolean matchPropertyName(java.beans.PropertyChangeEvent e) { 228 return true; 229 // return (e.getPropertyName().indexOf("alue")=0); 230 } 231 232 @Override 233 public JButton configureButton() { 234 log.error("configureButton should not have been called"); 235 return null; 236 } 237 238 @Override 239 public void configureTable(JTable table) { 240 InstanceManager.getDefault(SensorManager.class).addPropertyChangeListener(this); 241 super.configureTable(table); 242 } 243 244 @Override 245 public void propertyChange(java.beans.PropertyChangeEvent e) { 246 if (e.getSource() instanceof SensorManager) { 247 if (e.getPropertyName().equals("DisplayListName") || e.getPropertyName().equals("length")) { 248 updateSensorList(); 249 } 250 } 251 super.propertyChange(e); 252 } 253 254 @Override 255 public void dispose(){ 256 InstanceManager.getDefault(SensorManager.class).removePropertyChangeListener(this); 257 super.dispose(); 258 } 259 260 }; 261 } 262 263 @Override 264 protected void setTitle() { 265 f.setTitle(Bundle.getMessage("TitleTransitTable")); 266 } 267 268 @Override 269 protected String helpTarget() { 270 return "package.jmri.jmrit.beantable.TransitTable"; 271 } 272 273 // instance variables 274 private boolean editMode = false; 275 private boolean duplicateMode = false; 276 private TransitManager transitManager = null; 277 private final SectionManager sectionManager = InstanceManager.getNullableDefault(SectionManager.class); 278 private Transit curTransit = null; 279 private SectionTableModel sectionTableModel = null; 280 private final List<Section> sectionList = new ArrayList<>(); 281 private final List<Integer> direction = new ArrayList<>(); 282 private final List<Integer> sequence = new ArrayList<>(); 283 private final List<List<TransitSectionAction>> action = new ArrayList<>(); 284 private final List<Boolean> alternate = new ArrayList<>(); 285 private final List<Boolean> safe = new ArrayList<>(); 286 private String sensorList[]; 287 private final List<String> sensorStopAllocation = new ArrayList<>(); 288 private final List<Section> primarySectionBoxList = new ArrayList<>(); 289 private final List<Integer> priSectionDirection = new ArrayList<>(); 290 private final List<Section> alternateSectionBoxList = new ArrayList<>(); 291 private final List<Integer> altSectionDirection = new ArrayList<>(); 292 private final List<Section> insertAtBeginningBoxList = new ArrayList<>(); 293 private final List<Integer> insertAtBeginningDirection = new ArrayList<>(); 294 private Section curSection = null; 295 private int curSectionDirection = 0; 296 private Section prevSection = null; 297 private int prevSectionDirection = 0; 298 private int curSequenceNum = 0; 299 300 // add/create variables 301 JmriJFrame addFrame = null; 302 JTextField sysName = new JTextField(15); 303 JLabel sysNameFixed = new JLabel(""); 304 JTextField userName = new JTextField(17); 305 JLabel sysNameLabel = new JLabel(Bundle.getMessage("LabelSystemName")); 306 JLabel userNameLabel = new JLabel(Bundle.getMessage("LabelUserName")); 307 JButton create = null; 308 JButton update = null; 309 JButton deleteSections = null; 310 JComboBox<String> primarySectionBox = new JComboBox<>(); 311 JButton addNextSection = null; 312 JCheckBox addAsSafe = null; 313 JComboBox<String> stopAllocatingSensorBox = new JComboBox<>(); 314 JButton removeLastSection = null; 315 JButton removeFirstSection = null; 316 JButton insertAtBeginning = null; 317 JComboBox<String> insertAtBeginningBox = new JComboBox<>(); 318 JLabel seqNumLabel = new JLabel(rbx.getString("LabelSeqNum")); 319 JSpinner seqNum = new JSpinner(new SpinnerNumberModel(1, 1, 1, 1)); 320 JButton replacePrimaryForSequence = null; 321 JButton deleteAlternateForSequence = null; 322 JButton addAlternateForSequence = null; 323 JComboBox<String> alternateSectionBox = new JComboBox<>(); 324 JButton addAlternateSection = null; 325 JCheckBox _autoSystemName = new JCheckBox(Bundle.getMessage("LabelAutoSysName")); 326 UserPreferencesManager pref; 327 String systemNameAuto = this.getClass().getName() + ".AutoSystemName"; 328 329 330 /** 331 * Responds to the Add...button and the Edit buttons in Transit Table. 332 * @param e Event causing method call. 333 */ 334 @Override 335 protected void addPressed(ActionEvent e) { 336 editMode = false; 337 duplicateMode = false; 338 if ((sectionManager.getNamedBeanSet().size()) > 0) { 339 addEditPressed(); 340 } else { 341 JmriJOptionPane.showMessageDialog(null, rbx 342 .getString("Message21"), Bundle.getMessage("ErrorTitle"), 343 JmriJOptionPane.ERROR_MESSAGE); 344 } 345 } 346 347 void editPressed(String sName) { 348 curTransit = transitManager.getBySystemName(sName); 349 if (curTransit == null) { 350 // no transit - should never happen, but protects against a $%^#@ exception 351 return; 352 } 353 sysNameFixed.setText(sName); 354 editMode = true; 355 duplicateMode = false; 356 addEditPressed(); 357 } 358 359 void duplicatePressed(String sName) { 360 curTransit = transitManager.getBySystemName(sName); 361 if (curTransit == null) { 362 // no transit - should never happen, but protects against a $%^#@ exception 363 return; 364 } 365 duplicateMode = true; 366 editMode = false; 367 addEditPressed(); 368 } 369 370 void addEditPressed() { 371 pref = InstanceManager.getDefault(UserPreferencesManager.class); 372 if (addFrame == null) { 373 addFrame = new JmriJFrame(Bundle.getMessage("TitleAddTransit")); 374 addFrame.addHelpMenu("package.jmri.jmrit.beantable.TransitAddEdit", true); 375 addFrame.getContentPane().setLayout(new BoxLayout(addFrame.getContentPane(), BoxLayout.Y_AXIS)); 376 JPanel p; 377 // system name 378 p = new JPanel(); 379 p.setLayout(new FlowLayout()); 380 p.add(sysNameLabel); 381 sysNameLabel.setLabelFor(sysName); 382 p.add(sysNameFixed); 383 p.add(sysName); 384 p.add(_autoSystemName); 385 _autoSystemName.addActionListener((ActionEvent e) -> { 386 autoSystemName(); 387 }); 388 if (pref.getSimplePreferenceState(systemNameAuto)) { 389 _autoSystemName.setSelected(true); 390 } 391 sysName.setToolTipText(rbx.getString("TransitSystemNameHint")); 392 addFrame.getContentPane().add(p); 393 // user name 394 p = new JPanel(); 395 p.add(userNameLabel); 396 userNameLabel.setLabelFor(userName); 397 p.add(userName); 398 userName.setToolTipText(rbx.getString("TransitUserNameHint")); 399 addFrame.getContentPane().add(p); 400 addFrame.getContentPane().add(new JSeparator()); 401 // instruction text fields 402 JPanel p1 = new JPanel(); 403 p1.setLayout(new BoxLayout(p1, BoxLayout.Y_AXIS)); 404 JPanel p11 = new JPanel(); 405 p11.setLayout(new FlowLayout()); 406 p11.add(new JLabel(rbx.getString("SectionTableMessage"))); 407 p1.add(p11); 408 JPanel p12 = new JPanel(); 409 p12.setLayout(new BorderLayout()); 410 // initialize table of sections 411 sectionTableModel = new SectionTableModel(); 412 JTable sectionTable = new JTable(sectionTableModel); 413 sectionTable.setDefaultRenderer(JComboBox.class, new jmri.jmrit.symbolicprog.ValueRenderer()); 414 sectionTable.setDefaultEditor(JComboBox.class, new jmri.jmrit.symbolicprog.ValueEditor()); 415 sectionTable.setDefaultRenderer(Boolean.class, new EnablingCheckboxRenderer()); 416 sectionTable.setRowSelectionAllowed(false); 417 TableColumnModel sectionColumnModel = sectionTable.getColumnModel(); 418 TableColumn sequenceColumn = sectionColumnModel.getColumn(SectionTableModel.SEQUENCE_COLUMN); 419 sequenceColumn.setResizable(true); 420 sequenceColumn.setMinWidth(50); 421 sequenceColumn.setMaxWidth(70); 422 TableColumn sectionColumn = sectionColumnModel.getColumn(SectionTableModel.SECTIONNAME_COLUMN); 423 sectionColumn.setResizable(true); 424 sectionColumn.setMinWidth(150); 425 //sectionColumn.setMaxWidth(210); 426 TableColumn actionColumn = sectionColumnModel.getColumn(SectionTableModel.ACTION_COLUMN); 427 // install button renderer and editor 428 ButtonRenderer buttonRenderer = new ButtonRenderer(); 429 sectionTable.setDefaultRenderer(JButton.class, buttonRenderer); 430 TableCellEditor buttonEditor = new ButtonEditor(new JButton()); 431 sectionTable.setDefaultEditor(JButton.class, buttonEditor); 432 JButton testButton = new JButton(rbx.getString("AddEditActions")); 433 sectionTable.setRowHeight(testButton.getPreferredSize().height); 434 actionColumn.setResizable(false); 435 actionColumn.setMinWidth(testButton.getPreferredSize().width); 436 TableColumn directionColumn = sectionColumnModel.getColumn(SectionTableModel.SEC_DIRECTION_COLUMN); 437 directionColumn.setResizable(true); 438 String s = rbx.getString("DirectionColName"); 439 directionColumn.setMinWidth((int)new JLabel(s.substring(1, Math.min(s.length(), 7))).getPreferredSize().getWidth()); 440 directionColumn.setMaxWidth((int)new JLabel(rbx.getString("DirectionColName").concat("WW")).getPreferredSize().getWidth()); 441 TableColumn alternateColumn = sectionColumnModel.getColumn(SectionTableModel.ALTERNATE_COLUMN); 442 alternateColumn.setResizable(true); 443 s = rbx.getString("AlternateColName"); 444 alternateColumn.setMinWidth((int)new JLabel(s.substring(1, Math.min(s.length(), 7))).getPreferredSize().getWidth()); 445 alternateColumn.setMaxWidth((int)new JLabel(rbx.getString("AlternateColName").concat("WW")).getPreferredSize().getWidth()); 446 JScrollPane sectionTableScrollPane = new JScrollPane(sectionTable); 447 p12.add(sectionTableScrollPane, BorderLayout.CENTER); 448 p1.add(p12); 449 JPanel p13 = new JPanel(); 450 p13.add(primarySectionBox); 451 primarySectionBox.setToolTipText(rbx.getString("PrimarySectionBoxHint")); 452 p13.add(addNextSection = new JButton(rbx.getString("AddPrimaryButton"))); 453 p13.add(addAsSafe = new JCheckBox(Bundle.getMessage("TransitSectionIsSafe"))); 454 addAsSafe.setToolTipText(Bundle.getMessage("TransitSectionIsSafeHint")); 455 JPanel p13A = new JPanel(); 456 p13A.add(new JLabel(Bundle.getMessage("PauseAllocationOnSensorActive"))); 457 p13A.add(stopAllocatingSensorBox = new JComboBox<>(sensorList)); 458 JComboBoxUtil.setupComboBoxMaxRows(stopAllocatingSensorBox); 459 p13.add(p13A); 460 stopAllocatingSensorBox.setToolTipText(Bundle.getMessage("PauseAllocationOnSensorActiveHint")); 461 addNextSection.addActionListener(this::addNextSectionPressed); 462 addNextSection.setToolTipText(rbx.getString("AddPrimaryButtonHint")); 463 p13.setLayout(new FlowLayout()); 464 p1.add(p13); 465 JPanel p14 = new JPanel(); 466 p14.setLayout(new FlowLayout()); 467 p14.add(alternateSectionBox); 468 alternateSectionBox.setToolTipText(rbx.getString("AlternateSectionBoxHint")); 469 p14.add(addAlternateSection = new JButton(rbx.getString("AddAlternateButton"))); 470 addAlternateSection.addActionListener(this::addAlternateSectionPressed); 471 addAlternateSection.setToolTipText(rbx.getString("AddAlternateButtonHint")); 472 p14.add(new JLabel(" ")); // spacer between 2 groups of label + combobox 473 p14.add(insertAtBeginningBox); 474 insertAtBeginningBox.setToolTipText(rbx.getString("InsertAtBeginningBoxHint")); 475 p14.add(insertAtBeginning = new JButton(rbx.getString("InsertAtBeginningButton"))); 476 insertAtBeginning.addActionListener(this::insertAtBeginningPressed); 477 insertAtBeginning.setToolTipText(rbx.getString("InsertAtBeginningButtonHint")); 478 p1.add(p14); 479 p1.add(new JSeparator()); 480 JPanel p15 = new JPanel(); 481 p15.setLayout(new FlowLayout()); 482 p15.add(deleteSections = new JButton(rbx.getString("DeleteSectionsButton"))); 483 deleteSections.addActionListener(this::deleteAllSections); 484 deleteSections.setToolTipText(rbx.getString("DeleteSectionsButtonHint")); 485 p15.add(new JLabel(" ")); 486 p15.add(removeLastSection = new JButton(rbx.getString("RemoveLastButton"))); 487 removeLastSection.addActionListener(this::removeLastSectionPressed); 488 removeLastSection.setToolTipText(rbx.getString("RemoveLastButtonHint")); 489 p15.add(new JLabel(" ")); 490 p15.add(removeFirstSection = new JButton(rbx.getString("RemoveFirstButton"))); 491 removeFirstSection.addActionListener(this::removeFirstSectionPressed); 492 removeFirstSection.setToolTipText(rbx.getString("RemoveFirstButtonHint")); 493 p1.add(p15); 494 JPanel p16 = new JPanel(); 495 p16.setLayout(new FlowLayout()); 496 p16.add(seqNumLabel); 497 p16.add(seqNum); 498 seqNum.setToolTipText(rbx.getString("SeqNumHint")); 499 p1.add(p16); 500 JPanel p17 = new JPanel(); 501 p17.setLayout(new FlowLayout()); 502 p17.add(replacePrimaryForSequence = new JButton(rbx.getString("ReplacePrimaryForSeqButton"))); 503 replacePrimaryForSequence.addActionListener(this::replacePrimaryForSeqPressed); 504 replacePrimaryForSequence.setToolTipText(rbx.getString("ReplacePrimaryForSeqButtonHint")); 505 p17.add(new JLabel(" ")); 506 p17.add(deleteAlternateForSequence = new JButton(rbx.getString("DeleteAlternateForSeqButton"))); 507 deleteAlternateForSequence.addActionListener(this::deleteAlternateForSeqPressed); 508 deleteAlternateForSequence.setToolTipText(rbx.getString("DeleteAlternateForSeqButtonHint")); 509 p17.add(new JLabel(" ")); 510 p17.add(addAlternateForSequence = new JButton(rbx.getString("AddAlternateForSeqButton"))); 511 addAlternateForSequence.addActionListener(this::addAlternateForSeqPressed); 512 addAlternateForSequence.setToolTipText(rbx.getString("AddAlternateForSeqButtonHint")); 513 p1.add(p17); 514 addFrame.getContentPane().add(p1); 515 // set up bottom buttons 516 addFrame.getContentPane().add(new JSeparator()); 517 JButton cancel = new JButton(Bundle.getMessage("ButtonCancel")); // NOI18N 518 JPanel pb = new JPanel(); 519 pb.setLayout(new FlowLayout()); 520 pb.add(cancel ); 521 cancel.addActionListener(this::cancelPressed); 522 cancel.setToolTipText(rbx.getString("CancelButtonHint")); 523 pb.add(create = new JButton(Bundle.getMessage("ButtonCreate"))); 524 create.addActionListener(this::createPressed); 525 create.setToolTipText(rbx.getString("SectionCreateButtonHint")); 526 pb.add(update = new JButton(Bundle.getMessage("ButtonUpdate"))); 527 update.addActionListener(this::updatePressed); 528 update.setToolTipText(rbx.getString("SectionUpdateButtonHint")); 529 addFrame.getContentPane().add(pb); 530 } 531 if (editMode) { 532 // setup for edit window 533 addFrame.setTitle(Bundle.getMessage("TitleEditTransit")); 534 _autoSystemName.setVisible(false); 535 sysNameLabel.setEnabled(true); 536 create.setVisible(false); 537 update.setVisible(true); 538 sysName.setVisible(false); 539 sysNameFixed.setVisible(true); 540 addFrame.getRootPane().setDefaultButton(update); 541 initializeEditInformation(); 542 } else { 543 // setup for create window 544 addFrame.setTitle(Bundle.getMessage("TitleAddTransit")); 545 _autoSystemName.setVisible(true); 546 _autoSystemName.setEnabled(true); 547 autoSystemName(); 548 create.setVisible(true); 549 create.setEnabled(true); 550 update.setVisible(false); 551 sysName.setVisible(true); 552 sysNameFixed.setVisible(false); 553 addFrame.getRootPane().setDefaultButton(create); 554 if (duplicateMode) { 555 // setup with information from previous Transit 556 initializeEditInformation(); 557 sysName.setText(curTransit.getSystemName()); 558 curTransit = null; 559 } else { 560 deleteAllSections(null); 561 } 562 } 563 initializeSectionCombos(); 564 updateSeqNum(); 565 addFrame.setEscapeKeyClosesWindow(true); 566 addFrame.pack(); 567 addFrame.setVisible(true); 568 } 569 570 private void initializeEditInformation() { 571 sectionList.clear(); 572 sequence.clear(); 573 action.clear(); 574 direction.clear(); 575 alternate.clear(); 576 safe.clear(); 577 sensorStopAllocation.clear(); 578 579 curSection = null; 580 curSectionDirection = 0; 581 curSequenceNum = 0; 582 prevSection = null; 583 prevSectionDirection = 0; 584 if (curTransit != null) { 585 userName.setText(curTransit.getUserName()); 586 List<TransitSection> tsList = curTransit.getTransitSectionList(); 587 for (int i = 0; i < tsList.size(); i++) { 588 TransitSection ts = tsList.get(i); 589 if (ts != null) { 590 sectionList.add(ts.getSection()); 591 sequence.add(ts.getSequenceNumber()); 592 direction.add(ts.getDirection()); 593 action.add(ts.getTransitSectionActionList()); 594 alternate.add(ts.isAlternate()); 595 safe.add(ts.isSafe()); 596 sensorStopAllocation.add(ts.getStopAllocatingSensor()); 597 } 598 } 599 int index = sectionList.size() - 1; 600 if (index >= alternate.size()) index = alternate.size() - 1; 601 while (alternate.get(index) && (index > 0)) { 602 index--; 603 } 604 if (index >= 0) { 605 curSection = sectionList.get(index); 606 curSequenceNum = sequence.get(index); 607 if (index > 0) { 608 curSectionDirection = direction.get(index); 609 } 610 index--; 611 while ((index >= 0) && alternate.get(index)) { 612 index--; 613 } 614 if (index >= 0) { 615 prevSection = sectionList.get(index); 616 prevSectionDirection = direction.get(index); 617 } 618 } 619 } 620 sectionTableModel.fireTableDataChanged(); 621 } 622 623 private void deleteAllSections(ActionEvent e) { 624 sectionList.clear(); 625 direction.clear(); 626 sequence.clear(); 627 action.clear(); 628 alternate.clear(); 629 safe.clear(); 630 sensorStopAllocation.clear(); 631 curSection = null; 632 curSectionDirection = 0; 633 prevSection = null; 634 prevSectionDirection = 0; 635 curSequenceNum = 0; 636 initializeSectionCombos(); 637 updateSeqNum(); 638 sectionTableModel.fireTableDataChanged(); 639 } 640 641 void addNextSectionPressed(ActionEvent e) { 642 if (primarySectionBoxList.isEmpty()) { 643 JmriJOptionPane.showMessageDialog(addFrame, rbx 644 .getString("Message25"), Bundle.getMessage("ErrorTitle"), 645 JmriJOptionPane.ERROR_MESSAGE); 646 return; 647 } 648 int index = primarySectionBox.getSelectedIndex(); 649 Section s = primarySectionBoxList.get(index); 650 if (s != null) { 651 int j = sectionList.size(); 652 sectionList.add(s); 653 direction.add(priSectionDirection.get(index)); 654 curSequenceNum++; 655 sequence.add(curSequenceNum); 656 safe.add(addAsSafe.isSelected()); 657 if (stopAllocatingSensorBox.getSelectedIndex() >= 0) { 658 sensorStopAllocation.add((String)stopAllocatingSensorBox.getSelectedItem()); 659 } else { 660 sensorStopAllocation.add(""); 661 } 662 action.add(new ArrayList<>()); 663 alternate.add(false); 664 if ((sectionList.size() == 2) && (curSection != null)) { 665 if (forwardConnected(curSection, s, 0)) { 666 direction.set(0, Section.REVERSE); 667 } 668 curSectionDirection = direction.get(0); 669 } 670 prevSection = curSection; 671 prevSectionDirection = curSectionDirection; 672 curSection = s; 673 if (prevSection != null) { 674 curSectionDirection = direction.get(j); 675 } 676 initializeSectionCombos(); 677 } 678 updateSeqNum(); 679 sectionTableModel.fireTableDataChanged(); 680 } 681 682 void removeLastSectionPressed(ActionEvent e) { 683 if (sectionList.size() <= 1) { 684 deleteAllSections(e); 685 } else { 686 int j = sectionList.size() - 1; 687 if (!alternate.get(j)) { 688 curSequenceNum--; 689 curSection = sectionList.get(j - 1); 690 curSectionDirection = direction.get(j - 1); 691 // delete alternate if present 692 int k = j - 2; 693 while ((k >= 0) && alternate.get(k)) { 694 k--; 695 } 696 // After this delete we need the new previous section, if there is one. 697 if (k < 0) { 698 // There is no previous section 699 prevSection = null; 700 } else { 701 prevSection = sectionList.get(k); 702 prevSectionDirection = direction.get(k); 703 } 704 } 705 removeSupportingArrayEntries(j); 706 initializeSectionCombos(); 707 } 708 updateSeqNum(); 709 sectionTableModel.fireTableDataChanged(); 710 } 711 712 void insertAtBeginningPressed(ActionEvent e) { 713 if (insertAtBeginningBoxList.isEmpty()) { 714 JmriJOptionPane.showMessageDialog(addFrame, rbx 715 .getString("Message35"), Bundle.getMessage("ErrorTitle"), 716 JmriJOptionPane.ERROR_MESSAGE); 717 return; 718 } 719 int index = insertAtBeginningBox.getSelectedIndex(); 720 Section s = insertAtBeginningBoxList.get(index); 721 if (s != null) { 722 sectionList.add(0, s); 723 direction.add(0, insertAtBeginningDirection.get(index)); 724 curSequenceNum++; 725 sequence.add(0, 1); 726 alternate.add(0, false); 727 safe.add(0, addAsSafe.isSelected()); 728 sensorStopAllocation.add(0, ""); 729 action.add(0, new ArrayList<>()); 730 if (curSequenceNum == 2) { 731 prevSectionDirection = direction.get(0); 732 prevSection = s; 733 } 734 initializeSectionCombos(); 735 } 736 updateSeqNum(); 737 sectionTableModel.fireTableDataChanged(); 738 } 739 740 void removeFirstSectionPressed(ActionEvent e) { 741 if (curSequenceNum <= 1) { 742 deleteAllSections(e); 743 } else { 744 // For alternates we delete all 745 int keep = 1; 746 while (alternate.get(keep)) { 747 keep++; 748 } 749 for (int c = 0; c < keep ; c++) { 750 removeSupportingArrayEntries(0); 751 curSequenceNum--; 752 } 753 initializeSectionCombos(); 754 } 755 updateSeqNum(); 756 sectionTableModel.fireTableDataChanged(); 757 } 758 759 void replacePrimaryForSeqPressed(ActionEvent e) { 760 int seq = getSeqNum(); 761 if (seq == 0) { 762 return; 763 } 764 Section sOld = null; 765 List<Section> altOldList = new ArrayList<>(); 766 Section beforeSection = null; 767 int beforeSectionDirection = 0; 768 Section afterSection = null; 769 int afterSectionDirection = 0; 770 int index = -1; 771 for (int i = 0; i < sectionList.size(); i++) { 772 if ((sequence.get(i) == seq) && (!alternate.get(i))) { 773 sOld = sectionList.get(i); 774 index = i; 775 } 776 if ((sequence.get(i) == seq) && alternate.get(i)) { 777 altOldList.add(sectionList.get(i)); 778 } 779 if ((sequence.get(i) == (seq - 1)) && (!alternate.get(i))) { 780 beforeSection = sectionList.get(i); 781 beforeSectionDirection = direction.get(i); 782 } 783 if ((sequence.get(i) == (seq + 1)) && (!alternate.get(i))) { 784 afterSection = sectionList.get(i); 785 afterSectionDirection = Section.FORWARD; 786 if (afterSectionDirection == direction.get(i)) { 787 afterSectionDirection = Section.REVERSE; 788 } 789 } 790 } 791 if (sOld == null) { 792 log.error("Missing primary Section for seq = {}", seq); 793 return; 794 } 795 List<Section> possibles = new ArrayList<>(); 796 List<Integer> possiblesDirection = new ArrayList<>(); 797 List<String> possibleNames = new ArrayList<>(); 798 799 for (Section s : sectionManager.getNamedBeanSet()) { 800 Section mayBeSection = null; 801 String mayBeName = s.getDisplayName(); 802 int mayBeDirection = 0; 803 if ((s != sOld) && (s != beforeSection) 804 && (s != afterSection) && (!inSectionList(s, altOldList))) { 805 if (beforeSection != null) { 806 if (forwardConnected(s, beforeSection, beforeSectionDirection)) { 807 mayBeSection = s; 808 mayBeDirection = Section.FORWARD; 809 } else if (reverseConnected(s, beforeSection, beforeSectionDirection)) { 810 mayBeSection = s; 811 mayBeDirection = Section.REVERSE; 812 } 813 if ((mayBeSection != null) && (afterSection != null)) { 814 if (mayBeDirection == Section.REVERSE) { 815 if (!forwardConnected(s, afterSection, afterSectionDirection)) { 816 mayBeSection = null; 817 } 818 } else { 819 if (!reverseConnected(s, afterSection, afterSectionDirection)) { 820 mayBeSection = null; 821 } 822 } 823 } 824 } else if (afterSection != null) { 825 if (forwardConnected(s, afterSection, afterSectionDirection)) { 826 mayBeSection = s; 827 mayBeDirection = Section.REVERSE; 828 } else if (reverseConnected(s, afterSection, afterSectionDirection)) { 829 mayBeSection = s; 830 mayBeDirection = Section.FORWARD; 831 } 832 } else { 833 mayBeSection = s; 834 mayBeDirection = Section.FORWARD; 835 } 836 if (mayBeSection != null) { 837 possibles.add(mayBeSection); 838 possiblesDirection.add(mayBeDirection); 839 possibleNames.add(mayBeName); 840 } 841 } 842 } 843 if (possibles.isEmpty()) { 844 JmriJOptionPane.showMessageDialog(addFrame, 845 java.text.MessageFormat.format(rbx.getString("Message36"), 846 new Object[]{"" + seq}), Bundle.getMessage("ErrorTitle"), 847 JmriJOptionPane.ERROR_MESSAGE); 848 return; 849 } 850 int k = 0; 851 if (possibles.size() > 1) { 852 Object choices[] = new Object[possibles.size()]; 853 for (int j = 0; j < possibles.size(); j++) { 854 choices[j] = possibleNames.get(j); 855 } 856 Object selName = JmriJOptionPane.showInputDialog(addFrame, 857 rbx.getString("ReplacePrimaryChoice"), 858 rbx.getString("ReplacePrimaryTitle"), 859 JmriJOptionPane.QUESTION_MESSAGE, null, choices, choices[0]); 860 if (selName == null) { 861 return; 862 } 863 for (int j = 0; j < possibles.size(); j++) { 864 if (selName.equals(choices[j])) { 865 k = j; 866 } 867 } 868 } 869 sectionList.remove(index); 870 sectionList.add(index, possibles.get(k)); 871 direction.set(index, possiblesDirection.get(k)); 872 if (index == (sectionList.size() - 1)) { 873 curSection = sectionList.get(index); 874 curSectionDirection = direction.get(index); 875 } else if (index == (sectionList.size() - 2)) { 876 prevSection = sectionList.get(index); 877 prevSectionDirection = direction.get(index); 878 } 879 initializeSectionCombos(); 880 sectionTableModel.fireTableDataChanged(); 881 } 882 883 boolean inSectionList(Section s, List<Section> sList) { 884 for (int i = 0; i < sList.size(); i++) { 885 if (sList.get(i) == s) { 886 return true; 887 } 888 } 889 return false; 890 } 891 892 int getSeqNum() { 893 int n = (Integer) seqNum.getValue(); // JSpinner int from 1 - sectionList.size() 894 if (n > curSequenceNum) { 895 JmriJOptionPane.showMessageDialog(null, rbx 896 .getString("Message34"), Bundle.getMessage("ErrorTitle"), 897 JmriJOptionPane.ERROR_MESSAGE); 898 return 0; 899 } 900 return n; 901 } 902 903 /** 904 * After any add, delete etc the section sequence numbers need to be 905 * rebuilt. 906 * After which we update sequence Number spinner on pane. 907 * Limit spinner to highest sequence index in 908 * section table (column 0). 909 */ 910 void updateSeqNum() { 911 int seqMax = 0; 912 int seqNumber = 0; 913 for (int ix = 0; ix<alternate.size();ix++) { 914 if (!alternate.get(ix)) { 915 seqNumber++; 916 } 917 sequence.set(ix,seqNumber); 918 } 919 seqMax = seqNumber; 920 seqNum.setModel(new SpinnerNumberModel( 921 seqMax, // initial value set 922 Math.min(seqMax, 1), // minimum value, either 0 (empty list) or 1 923 seqMax, // maximum order number 924 1)); 925 seqNum.setValue(Math.min(seqMax, 1)); 926 } 927 928 void deleteAlternateForSeqPressed(ActionEvent e) { 929 if (sectionList.size() <= 1) { 930 deleteAllSections(e); 931 } else { 932 int seq = getSeqNum(); 933 if (seq == 0) { 934 return; 935 } 936 for (int i = sectionList.size() - 1; i >= seq; i--) { 937 if ((sequence.get(i) == seq) && alternate.get(i)) { 938 removeSupportingArrayEntries(i); 939 } 940 } 941 initializeSectionCombos(); 942 } 943 updateSeqNum(); 944 sectionTableModel.fireTableDataChanged(); 945 } 946 947 void addAlternateForSeqPressed(ActionEvent e) { 948 int seq = getSeqNum(); 949 if (seq == 0) { 950 return; 951 } 952 Section primarySection = null; 953 List<Section> altOldList = new ArrayList<>(); 954 Section beforeSection = null; 955 int beforeSectionDirection = 0; 956 Section afterSection = null; 957 int afterSectionDirection = 0; 958 int index = -1; 959 for (int i = 0; i < sectionList.size(); i++) { 960 if ((sequence.get(i) == seq) && (!alternate.get(i))) { 961 primarySection = sectionList.get(i); 962 index = i; 963 } 964 if ((sequence.get(i) == seq) && alternate.get(i)) { 965 altOldList.add(sectionList.get(i)); 966 } 967 if ((sequence.get(i) == (seq - 1)) && (!alternate.get(i))) { 968 beforeSection = sectionList.get(i); 969 beforeSectionDirection = direction.get(i); 970 } 971 if ((sequence.get(i) == (seq + 1)) && (!alternate.get(i))) { 972 afterSection = sectionList.get(i); 973 afterSectionDirection = Section.FORWARD; 974 if (afterSectionDirection == direction.get(i)) { 975 afterSectionDirection = Section.REVERSE; 976 } 977 } 978 } 979 if (primarySection == null) { 980 log.error("Missing primary Section for seq = {}", seq); 981 return; 982 } 983 List<Section> possibles = new ArrayList<>(); 984 List<Integer> possiblesDirection = new ArrayList<>(); 985 List<String> possibleNames = new ArrayList<>(); 986 for (Section s : sectionManager.getNamedBeanSet()) { 987 Section mayBeSection = null; 988 String mayBeName = s.getDisplayName(); 989 int mayBeDirection = 0; 990 if ((s != primarySection) && (s != beforeSection) 991 && (s != afterSection) && (!inSectionList(s, altOldList))) { 992 if (beforeSection != null) { 993 if (forwardConnected(s, beforeSection, beforeSectionDirection)) { 994 mayBeSection = s; 995 mayBeDirection = Section.FORWARD; 996 } else if (reverseConnected(s, beforeSection, beforeSectionDirection)) { 997 mayBeSection = s; 998 mayBeDirection = Section.REVERSE; 999 } 1000 if ((mayBeSection != null) && (afterSection != null)) { 1001 if (mayBeDirection == Section.REVERSE) { 1002 if (!forwardConnected(s, afterSection, afterSectionDirection)) { 1003 mayBeSection = null; 1004 } 1005 } else { 1006 if (!reverseConnected(s, afterSection, afterSectionDirection)) { 1007 mayBeSection = null; 1008 } 1009 } 1010 } 1011 } else if (afterSection != null) { 1012 if (forwardConnected(s, afterSection, afterSectionDirection)) { 1013 mayBeSection = s; 1014 mayBeDirection = Section.REVERSE; 1015 } else if (reverseConnected(s, afterSection, afterSectionDirection)) { 1016 mayBeSection = s; 1017 mayBeDirection = Section.FORWARD; 1018 } 1019 } else { 1020 mayBeSection = s; 1021 mayBeDirection = Section.FORWARD; 1022 } 1023 if (mayBeSection != null) { 1024 possibles.add(mayBeSection); 1025 possiblesDirection.add(mayBeDirection); 1026 possibleNames.add(mayBeName); 1027 } 1028 } 1029 } 1030 if (possibles.isEmpty()) { 1031 JmriJOptionPane.showMessageDialog(addFrame, 1032 java.text.MessageFormat.format(rbx.getString("Message37"), 1033 new Object[]{"" + seq}), Bundle.getMessage("ErrorTitle"), 1034 JmriJOptionPane.ERROR_MESSAGE); 1035 return; 1036 } 1037 int k = 0; 1038 if (possibles.size() > 1) { 1039 Object choices[] = new Object[possibles.size()]; 1040 for (int j = 0; j < possibles.size(); j++) { 1041 choices[j] = possibleNames.get(j); 1042 } 1043 Object selName = JmriJOptionPane.showInputDialog(addFrame, 1044 rbx.getString("AddAlternateChoice"), 1045 rbx.getString("AddAlternateTitle"), 1046 JmriJOptionPane.QUESTION_MESSAGE, null, choices, choices[0]); 1047 if (selName == null) { 1048 return; 1049 } 1050 for (int j = 0; j < possibles.size(); j++) { 1051 if (selName.equals(choices[j])) { 1052 k = j; 1053 } 1054 } 1055 } 1056 index = index + 1 + altOldList.size(); 1057 sectionList.add(index, possibles.get(k)); 1058 direction.add(index, possiblesDirection.get(k)); 1059 sequence.add(index, sequence.get(index - 1)); 1060 alternate.add(index, true); 1061 safe.add(index, addAsSafe.isSelected()); 1062 if (stopAllocatingSensorBox.getSelectedIndex() < 0) { 1063 sensorStopAllocation.add(index, ""); 1064 } else { 1065 sensorStopAllocation.add(index, (String) stopAllocatingSensorBox.getSelectedItem()); 1066 } 1067 action.add(index, new ArrayList<>()); 1068 initializeSectionCombos(); 1069 updateSeqNum(); 1070 sectionTableModel.fireTableDataChanged(); 1071 } 1072 1073 void addAlternateSectionPressed(ActionEvent e) { 1074 if (alternateSectionBoxList.isEmpty()) { 1075 JmriJOptionPane.showMessageDialog(addFrame, rbx 1076 .getString("Message24"), Bundle.getMessage("ErrorTitle"), 1077 JmriJOptionPane.ERROR_MESSAGE); 1078 return; 1079 } 1080 int index = alternateSectionBox.getSelectedIndex(); 1081 Section s = alternateSectionBoxList.get(index); 1082 if (s != null) { 1083 sectionList.add(s); 1084 direction.add(altSectionDirection.get(index)); 1085 sequence.add(curSequenceNum); 1086 action.add(new ArrayList<>()); 1087 alternate.add(true); 1088 safe.add(addAsSafe.isSelected()); 1089 sensorStopAllocation.add((String)stopAllocatingSensorBox.getSelectedItem()); 1090 initializeSectionCombos(); 1091 } 1092 updateSeqNum(); 1093 sectionTableModel.fireTableDataChanged(); 1094 } 1095 1096 void createPressed(ActionEvent e) { 1097 if (!checkTransitInformation()) { 1098 return; 1099 } 1100 String uName = userName.getText(); 1101 if (uName.isEmpty()) { 1102 uName = null; 1103 } 1104 1105 try { 1106 // attempt to create the new Transit 1107 if (_autoSystemName.isSelected()) { 1108 curTransit = transitManager.createNewTransit(uName); 1109 } else { 1110 String sName = sysName.getText(); 1111 curTransit = transitManager.createNewTransit(sName, uName); 1112 } 1113 } catch (IllegalArgumentException ex) { 1114 JmriJOptionPane.showMessageDialog(addFrame, ex.getLocalizedMessage(), Bundle.getMessage("ErrorTitle"), 1115 JmriJOptionPane.ERROR_MESSAGE); 1116 return; 1117 } 1118 sysName.setText(curTransit.getSystemName()); 1119 setTransitInformation(); 1120 addFrame.setVisible(false); 1121 pref.setSimplePreferenceState(systemNameAuto, _autoSystemName.isSelected()); 1122 } 1123 1124 void cancelPressed(ActionEvent e) { 1125 addFrame.setVisible(false); 1126 sectionTableModel.dispose(); 1127 addFrame.dispose(); // remove addFrame from Windows menu 1128 addFrame = null; 1129 } 1130 1131 void updatePressed(ActionEvent e) { 1132 if (!checkTransitInformation()) { 1133 return; 1134 } 1135 // check if user name has been changed 1136 String uName = userName.getText(); 1137 if (uName.isEmpty()) { 1138 uName = null; 1139 } 1140 if ((uName != null) && (!uName.equals(curTransit.getUserName()))) { 1141 // check that new user name is unique 1142 Transit tTransit = transitManager.getByUserName(uName); 1143 if (tTransit != null) { 1144 JmriJOptionPane.showMessageDialog(addFrame, rbx 1145 .getString("Message22"), Bundle.getMessage("ErrorTitle"), 1146 JmriJOptionPane.ERROR_MESSAGE); 1147 return; 1148 } 1149 } 1150 curTransit.setUserName(uName); 1151 if (setTransitInformation()) { 1152 // successful update 1153 addFrame.setVisible(false); 1154 sectionTableModel.dispose(); 1155 addFrame.dispose(); // remove addFrame from Windows menu 1156 addFrame = null; 1157 } 1158 } 1159 1160 private void removeSupportingArrayEntries(int index) { 1161 sectionList.remove(index); 1162 sequence.remove(index); 1163 direction.remove(index); 1164 action.remove(index); 1165 alternate.remove(index); 1166 safe.remove(index); 1167 sensorStopAllocation.remove(index); 1168 } 1169 1170 private boolean checkTransitInformation() { 1171 //transits can now be of length 1 segmant. 1172 //With these the route has to start outside the transit 1173 /* 1174 if ((sectionList.size() <= 1) || (curSequenceNum <= 1)) { 1175 JmriJOptionPane.showMessageDialog(addFrame, rbx 1176 .getString("Message26"), Bundle.getMessage("ErrorTitle"), 1177 JmriJOptionPane.ERROR_MESSAGE); 1178 return false; 1179 } */ 1180 1181 return true; 1182 } 1183 1184 private boolean setTransitInformation() { 1185 if (curTransit == null) { 1186 return false; 1187 } 1188 curTransit.removeAllSections(); 1189 for (int i = 0; i < sectionList.size(); i++) { 1190 TransitSection ts = new TransitSection(sectionList.get(i), 1191 sequence.get(i), direction.get(i), alternate.get(i), safe.get(i), sensorStopAllocation.get(i)); 1192 List<TransitSectionAction> list = action.get(i); 1193 if (list != null) { 1194 for (int j = 0; j < list.size(); j++) { 1195 ts.addAction(list.get(j)); 1196 } 1197 } 1198 curTransit.addTransitSection(ts); 1199 } 1200 return true; 1201 } 1202 1203 private void initializeSectionCombos() { 1204 primarySectionBox.removeAllItems(); 1205 alternateSectionBox.removeAllItems(); 1206 insertAtBeginningBox.removeAllItems(); 1207 primarySectionBoxList.clear(); 1208 alternateSectionBoxList.clear(); 1209 insertAtBeginningBoxList.clear(); 1210 priSectionDirection.clear(); 1211 altSectionDirection.clear(); 1212 insertAtBeginningDirection.clear(); 1213 if (sectionList.isEmpty()) { 1214 // no Sections currently in Transit - all Sections and all Directions OK 1215 for (Section s : sectionManager.getNamedBeanSet()) { 1216 String sName = s.getDisplayName(); 1217 primarySectionBox.addItem(sName); 1218 primarySectionBoxList.add(s); 1219 priSectionDirection.add(Section.FORWARD); 1220 } 1221 } else { 1222 // limit to Sections that connect to the current Section and are not the previous Section 1223 for (Section s : sectionManager.getNamedBeanSet()) { 1224 String sName = s.getDisplayName(); 1225 if ((s != prevSection) && (forwardConnected(s, curSection, curSectionDirection))) { 1226 primarySectionBox.addItem(sName); 1227 primarySectionBoxList.add(s); 1228 priSectionDirection.add(Section.FORWARD); 1229 } else if ((s != prevSection) && (reverseConnected(s, curSection, curSectionDirection))) { 1230 primarySectionBox.addItem(sName); 1231 primarySectionBoxList.add(s); 1232 priSectionDirection.add(Section.REVERSE); 1233 } 1234 } 1235 // check if there are any alternate Section choices 1236 if (prevSection != null) { 1237 for (Section s : sectionManager.getNamedBeanSet()) { 1238 String sName = s.getDisplayName(); 1239 if ((notIncludedWithSeq(s, curSequenceNum)) 1240 && forwardConnected(s, prevSection, prevSectionDirection)) { 1241 alternateSectionBox.addItem(sName); 1242 alternateSectionBoxList.add(s); 1243 altSectionDirection.add( Section.FORWARD); 1244 } else if (notIncludedWithSeq(s, curSequenceNum) 1245 && reverseConnected(s, prevSection, prevSectionDirection)) { 1246 alternateSectionBox.addItem(sName); 1247 alternateSectionBoxList.add(s); 1248 altSectionDirection.add(Section.REVERSE); 1249 } 1250 } 1251 } 1252 // check if there are any Sections available to be inserted at beginning 1253 Section firstSection = sectionList.get(0); 1254 int testDirection = Section.FORWARD; 1255 if (direction.get(0) == Section.FORWARD) { 1256 testDirection = Section.REVERSE; 1257 } 1258 for (Section s : sectionManager.getNamedBeanSet()) { 1259 String sName = s.getDisplayName(); 1260 if ((s != firstSection) && (forwardConnected(s, firstSection, testDirection))) { 1261 insertAtBeginningBox.addItem(sName); 1262 insertAtBeginningBoxList.add(s); 1263 insertAtBeginningDirection.add( Section.REVERSE); 1264 } else if ((s != firstSection) && (reverseConnected(s, firstSection, testDirection))) { 1265 insertAtBeginningBox.addItem(sName); 1266 insertAtBeginningBoxList.add(s); 1267 insertAtBeginningDirection.add( Section.FORWARD); 1268 } 1269 } 1270 } 1271 JComboBoxUtil.setupComboBoxMaxRows(primarySectionBox); 1272 JComboBoxUtil.setupComboBoxMaxRows(alternateSectionBox); 1273 JComboBoxUtil.setupComboBoxMaxRows(insertAtBeginningBox); 1274 } 1275 1276 private boolean forwardConnected(Section s1, Section s2, int restrictedDirection) { 1277 if ((s1 != null) && (s2 != null)) { 1278 List<EntryPoint> s1ForwardEntries = s1.getForwardEntryPointList(); 1279 List<EntryPoint> s2Entries; 1280 switch (restrictedDirection) { 1281 case Section.FORWARD: 1282 s2Entries = s2.getReverseEntryPointList(); 1283 break; 1284 case Section.REVERSE: 1285 s2Entries = s2.getForwardEntryPointList(); 1286 break; 1287 default: 1288 s2Entries = s2.getEntryPointList(); 1289 break; 1290 } 1291 for (int i = 0; i < s1ForwardEntries.size(); i++) { 1292 Block b1 = s1ForwardEntries.get(i).getFromBlock(); 1293 for (int j = 0; j < s2Entries.size(); j++) { 1294 Block b2 = s2Entries.get(j).getFromBlock(); 1295 if ((b1 == s2Entries.get(j).getBlock()) 1296 && (b2 == s1ForwardEntries.get(i).getBlock())) { 1297 return true; 1298 } 1299 } 1300 } 1301 } 1302 return false; 1303 } 1304 1305 private boolean reverseConnected(Section s1, Section s2, int restrictedDirection) { 1306 if ((s1 != null) && (s2 != null)) { 1307 List<EntryPoint> s1ReverseEntries = s1.getReverseEntryPointList(); 1308 List<EntryPoint> s2Entries; 1309 switch (restrictedDirection) { 1310 case Section.FORWARD: 1311 s2Entries = s2.getReverseEntryPointList(); 1312 break; 1313 case Section.REVERSE: 1314 s2Entries = s2.getForwardEntryPointList(); 1315 break; 1316 default: 1317 s2Entries = s2.getEntryPointList(); 1318 break; 1319 } 1320 for (int i = 0; i < s1ReverseEntries.size(); i++) { 1321 Block b1 = s1ReverseEntries.get(i).getFromBlock(); 1322 for (int j = 0; j < s2Entries.size(); j++) { 1323 Block b2 = s2Entries.get(j).getFromBlock(); 1324 if ((b1 == s2Entries.get(j).getBlock()) 1325 && (b2 == s1ReverseEntries.get(i).getBlock())) { 1326 return true; 1327 } 1328 } 1329 } 1330 } 1331 return false; 1332 } 1333 1334 private boolean notIncludedWithSeq(Section s, int seq) { 1335 for (int i = 0; i < sectionList.size(); i++) { 1336 if ((sectionList.get(i) == s) && (seq == sequence.get(i))) { 1337 return false; 1338 } 1339 } 1340 return true; 1341 } 1342 1343 private void autoSystemName() { 1344 if (_autoSystemName.isSelected()) { 1345// create.setEnabled(true); 1346 sysName.setEnabled(false); 1347 sysNameLabel.setEnabled(false); 1348 } else { 1349// if (sysName.getText().length() > 0) 1350// create.setEnabled(true); 1351// else 1352// create.setEnabled(false); 1353 sysName.setEnabled(true); 1354 sysNameLabel.setEnabled(true); 1355 } 1356 } 1357 1358 // variables for View Actions window 1359 private int activeRow = 0; 1360 private SpecialActionTableModel actionTableModel = null; 1361 private JmriJFrame actionTableFrame = null; 1362 private final JLabel fixedSectionLabel = new JLabel("X"); 1363 1364 private void addEditActionsPressed(int r) { 1365 activeRow = r; 1366 if (actionTableModel != null) { 1367 actionTableModel.fireTableStructureChanged(); 1368 } 1369 if (actionTableFrame == null) { 1370 actionTableFrame = new JmriJFrame(rbx.getString("TitleViewActions")); 1371 actionTableFrame.addHelpMenu( 1372 "package.jmri.jmrit.beantable.ViewSpecialActions", true); 1373 Container contentPane = actionTableFrame.getContentPane(); 1374 contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.Y_AXIS)); 1375 JPanel panel1 = new JPanel(); 1376 panel1.setLayout(new FlowLayout()); 1377 JLabel sectionNameLabel = new JLabel(Bundle.getMessage("MakeLabel", Bundle.getMessage("BeanNameSection"))); 1378 panel1.add(sectionNameLabel); 1379 panel1.add(fixedSectionLabel); 1380 contentPane.add(panel1); 1381 addFrame.getContentPane().add(new JSeparator()); 1382 JPanel pct = new JPanel(); 1383 pct.setLayout(new BorderLayout()); 1384 // initialize table of actions 1385 actionTableModel = new SpecialActionTableModel(); 1386 JTable actionTable = new JTable(actionTableModel); 1387 actionTable.setRowSelectionAllowed(false); 1388 TableColumnModel actionColumnModel = actionTable 1389 .getColumnModel(); 1390 TableColumn whenColumn = actionColumnModel 1391 .getColumn(SpecialActionTableModel.WHEN_COLUMN); 1392 whenColumn.setResizable(true); 1393 TableColumn whatColumn = actionColumnModel 1394 .getColumn(SpecialActionTableModel.WHAT_COLUMN); 1395 whatColumn.setResizable(true); 1396 TableColumn editColumn = actionColumnModel 1397 .getColumn(SpecialActionTableModel.EDIT_COLUMN); 1398 // install button renderer and editor 1399 ButtonRenderer buttonRenderer = new ButtonRenderer(); 1400 actionTable.setDefaultRenderer(JButton.class, buttonRenderer); 1401 TableCellEditor buttonEditor = new ButtonEditor(new JButton()); 1402 actionTable.setDefaultEditor(JButton.class, buttonEditor); 1403 JButton testButton = new JButton(Bundle.getMessage("ButtonDelete")); 1404 actionTable.setRowHeight(testButton.getPreferredSize().height); 1405 editColumn.setResizable(false); 1406 editColumn.setMinWidth(testButton.getPreferredSize().width); 1407 editColumn.setMaxWidth(testButton.getPreferredSize().width); 1408 TableColumn removeColumn = actionColumnModel 1409 .getColumn(SpecialActionTableModel.REMOVE_COLUMN); 1410 removeColumn.setMinWidth(testButton.getPreferredSize().width); 1411 removeColumn.setMaxWidth(testButton.getPreferredSize().width); 1412 removeColumn.setResizable(false); 1413 JScrollPane actionTableScrollPane = new JScrollPane( 1414 actionTable); 1415 pct.add(actionTableScrollPane, BorderLayout.CENTER); 1416 contentPane.add(pct); 1417 pct.setVisible(true); 1418 // add View Action panel buttons 1419 JPanel but = new JPanel(); 1420 but.setLayout(new BoxLayout(but, BoxLayout.Y_AXIS)); 1421 JPanel panel4 = new JPanel(); 1422 panel4.setLayout(new FlowLayout()); 1423 JButton newActionButton = new JButton(rbx.getString("ButtonAddNewAction")); 1424 panel4.add(newActionButton); 1425 newActionButton.addActionListener(this::newActionPressed); 1426 newActionButton.setToolTipText(rbx.getString("NewActionButtonHint")); 1427 JButton doneButton = new JButton(Bundle.getMessage("ButtonDone")); 1428 panel4.add(doneButton); 1429 doneButton.addActionListener(this::doneWithActionsPressed); 1430 doneButton.setToolTipText(rbx.getString("DoneButtonHint")); 1431 but.add(panel4); 1432 contentPane.add(but); 1433 } 1434 fixedSectionLabel.setText(getSectionNameByRow(r) + " " 1435 + rbx.getString("SequenceAbbrev") + ": " + sequence.get(r)); 1436 actionTableFrame.addWindowListener(new java.awt.event.WindowAdapter() { 1437 @Override 1438 public void windowClosing(java.awt.event.WindowEvent e) { 1439 actionTableFrame.setVisible(false); 1440 actionTableFrame.dispose(); 1441 actionTableFrame = null; 1442 if (addEditActionFrame != null) { 1443 addEditActionFrame.setVisible(false); 1444 addEditActionFrame.dispose(); 1445 addEditActionFrame = null; 1446 } 1447 } 1448 }); 1449 actionTableFrame.pack(); 1450 actionTableFrame.setVisible(true); 1451 } 1452 1453 private void doneWithActionsPressed(ActionEvent e) { 1454 actionTableFrame.setVisible(false); 1455 actionTableFrame.dispose(); 1456 actionTableFrame = null; 1457 if (addEditActionFrame != null) { 1458 addEditActionFrame.setVisible(false); 1459 addEditActionFrame.dispose(); 1460 addEditActionFrame = null; 1461 } 1462 } 1463 1464 private void newActionPressed(ActionEvent e) { 1465 editActionMode = false; 1466 curTSA = null; 1467 addEditActionWindow(); 1468 } 1469 1470 // variables for Add/Edit Action window 1471 private boolean editActionMode = false; 1472 private JmriJFrame addEditActionFrame = null; 1473 private TransitSectionAction curTSA = null; 1474 private final JComboBox<String> whenBox = new JComboBox<>(); 1475 private final NamedBeanComboBox<Sensor> whenSensorComboBox = new NamedBeanComboBox<>(InstanceManager.getDefault(SensorManager.class), null, DisplayOptions.DISPLAYNAME); 1476 private final JSpinner whenDataSpinnerFloat = new JSpinner(new SpinnerNumberModel(Float.valueOf(0.0f), Float.valueOf(0.0f), Float.valueOf(65.0f), Float.valueOf(0.5f))); // delay 1477 private final JSpinner whenDataSpinnerInt = new JSpinner(new SpinnerNumberModel(0, 0, 65000, 100)); // delay 1478 private final JRadioButton mSecButton = new JRadioButton(Bundle.getMessage("LabelMilliseconds")); 1479 private final JRadioButton secButton = new JRadioButton(Bundle.getMessage("LabelSeconds")); 1480 private final JComboBox<String> whatBox = new JComboBox<>(); 1481 private final JSpinner whatPercentSpinner = new JSpinner(); // speed 1482 private final JSpinner whatMinuteSpinner1 = new JSpinner(new SpinnerNumberModel(1, 1, 65500, 1)); // time in ms 1483 private final JSpinner whatMinuteSpinner2 = new JSpinner(new SpinnerNumberModel(100, 100, 65500, 1)); // time in ms 1484 private final JSpinner locoFunctionSpinner = new JSpinner(new SpinnerNumberModel(0, 0, 28, 1)); // function ID 1485 private final JTextField whatStringField = new JTextField(12); 1486 private final JTextField locoAddress = new JTextField(12); 1487 private RosterEntryComboBox rosterComboBox = new RosterEntryComboBox(); 1488 private JComboBox<String> trainInfoComboBox = new JComboBox<>(); 1489 private JRadioButton locoAddressDefault = new JRadioButton(rbx.getString("TrainInfoUseDefault")); 1490 private JRadioButton locoAddressRoster = new JRadioButton(rbx.getString("TrainInfoUseRoster")); 1491 private JRadioButton locoAddressNumber = new JRadioButton(rbx.getString("TrainInfoUseAddress")); 1492 private JRadioButton locoAddressCurrent = new JRadioButton(rbx.getString("TrainInfoUseCurrentAddress")); 1493 private ButtonGroup locoAddressGroup = new ButtonGroup(); 1494 private JButton updateActionButton = null; 1495 private JButton createActionButton = null; 1496 private JButton cancelAddEditActionButton = null; 1497 private final JComboBox<String> blockBox = new JComboBox<>(); 1498 private List<Block> blockList = new ArrayList<>(); 1499 private final JRadioButton onButton = new JRadioButton(Bundle.getMessage("StateOn")); 1500 private final JRadioButton offButton = new JRadioButton(Bundle.getMessage("StateOff")); 1501 private final JLabel doneSensorLabel = new JLabel(rbx.getString("DoneSensorLabel")); 1502 private JPanel signalPanel; 1503 private JPanel panelPercentageSpinner; 1504 private JPanel panelDelay; 1505 private JLabel panelDelayLabel = new JLabel(); 1506 private JPanel panelWhatBox; 1507 private JPanel panelLoadTrainInfo; 1508 private final NamedBeanComboBox<Sensor> doneSensorComboBox = new NamedBeanComboBox<>(InstanceManager.getDefault(SensorManager.class), null, DisplayOptions.DISPLAYNAME); 1509 private final NamedBeanComboBox<SignalMast> signalMastComboBox = new NamedBeanComboBox<>(InstanceManager.getDefault(SignalMastManager.class), null, DisplayOptions.DISPLAYNAME); 1510 private final NamedBeanComboBox<SignalHead> signalHeadComboBox = new NamedBeanComboBox<>(InstanceManager.getDefault(SignalHeadManager.class), null, DisplayOptions.DISPLAYNAME); 1511 1512 private void addEditActionWindow() { 1513 if (addEditActionFrame == null) { 1514 // set up add/edit action window 1515 addEditActionFrame = new JmriJFrame(rbx.getString("TitleAddAction")); 1516 addEditActionFrame.addHelpMenu( 1517 "package.jmri.jmrit.beantable.TransitSectionAddEditAction", true); 1518 Container contentPane = addEditActionFrame.getContentPane(); 1519 contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.Y_AXIS)); 1520 // to set When to start the action 1521 JPanel panelx = new JPanel(); 1522 panelx.setLayout(new BoxLayout(panelx, BoxLayout.Y_AXIS)); 1523 JPanel panel1 = new JPanel(); 1524 panel1.setLayout(new FlowLayout()); 1525 panel1.add(new JLabel(rbx.getString("WhenText"))); 1526 initializeWhenBox(); 1527 JComboBoxUtil.setupComboBoxMaxRows(whenBox); 1528 panel1.add(whenBox); 1529 whenBox.addActionListener((ActionEvent e) -> { 1530 log.debug("whenBox was set"); 1531 if (whenBox.getSelectedItem()!=null) { 1532 setWhen(getWhenMenuCode((String)whenBox.getSelectedItem())); 1533 } 1534 }); 1535 whenBox.setToolTipText(rbx.getString("WhenBoxTip")); 1536 JComboBoxUtil.setupComboBoxMaxRows(whenSensorComboBox); 1537 panel1.add(whenSensorComboBox); 1538 whenSensorComboBox.setAllowNull(true); 1539 initializeBlockBox(); 1540 JComboBoxUtil.setupComboBoxMaxRows(blockBox); 1541 panel1.add(blockBox); 1542 panelx.add(panel1); 1543 // to set optional delay setting 1544 panelDelay = new JPanel(); 1545 panelDelay.setLayout(new FlowLayout()); 1546 panelDelayLabel.setText(" " + rbx.getString("OptionalDelay") + ": "); 1547 panelDelay.add(panelDelayLabel); 1548 panelDelay.add(whenDataSpinnerInt); 1549 whenDataSpinnerInt.setToolTipText(rbx.getString("HintDelayData")); 1550 whenDataSpinnerInt.addChangeListener((ChangeEvent e) -> { 1551 if (mSecButton.isSelected()) { 1552 float f = (int)whenDataSpinnerInt.getValue(); 1553 whenDataSpinnerFloat.setValue(Float.valueOf(f/1000.0f)); 1554 } 1555 }); 1556 panelDelay.add(whenDataSpinnerFloat); 1557 whenDataSpinnerFloat.setToolTipText(rbx.getString("HintDelayData")); 1558 whenDataSpinnerFloat.setPreferredSize(whenDataSpinnerInt.getPreferredSize()); 1559 whenDataSpinnerFloat.addChangeListener((ChangeEvent e) -> { 1560 if (secButton.isSelected()) { 1561 float dVal = (float)whenDataSpinnerFloat.getValue(); 1562 dVal *= 1000.0; 1563 whenDataSpinnerInt.setValue(Integer.valueOf(Math.round(dVal))); 1564 } 1565 }); 1566 ButtonGroup secMsec = new ButtonGroup(); 1567 secMsec.add(mSecButton); 1568 secMsec.add(secButton); 1569 panelDelay.add(mSecButton); 1570 mSecButton.addChangeListener((ChangeEvent e) -> { 1571 if (mSecButton.isSelected()) { 1572 whenDataSpinnerFloat.setVisible(false); 1573 whenDataSpinnerInt.setVisible(true); 1574 } 1575 }); 1576 panelDelay.add(secButton); 1577 secButton.addChangeListener((ChangeEvent e) -> { 1578 if (secButton.isSelected()) { 1579 whenDataSpinnerFloat.setVisible(true); 1580 whenDataSpinnerInt.setVisible(false); 1581 } 1582 }); 1583 secButton.setSelected(true); 1584 panelx.add(panelDelay); 1585 JPanel spacer = new JPanel(); 1586 spacer.setLayout(new FlowLayout()); 1587 spacer.add(new JLabel(" ")); 1588 panelx.add(spacer); 1589 // to set What action to take 1590 panelWhatBox = new JPanel(); 1591 panelWhatBox.setLayout(new FlowLayout()); 1592 panelWhatBox.add(new JLabel(rbx.getString("WhatText"))); 1593 initializeWhatBox(0); 1594 JComboBoxUtil.setupComboBoxMaxRows(whatBox); 1595 panelWhatBox.add(whatBox); 1596 whatBox.setToolTipText(rbx.getString("WhatBoxTip")); 1597 whatBox.addActionListener((ActionEvent e) -> { 1598 if (whatBox.getSelectedItem()!=null) { 1599 setWhat(getWhatMenuCode((String)whatBox.getSelectedItem())); 1600 } 1601 }); 1602 panelWhatBox.add(whatStringField); 1603 whatStringField.setToolTipText(rbx.getString("HintSoundHornPatternString")); 1604 panelx.add(panelWhatBox); 1605 1606 // Train Info 1607 TitledBorder trainInfoBorder = BorderFactory.createTitledBorder(rbx.getString("SelectTrain")); 1608 panelLoadTrainInfo = new JPanel(); 1609 panelLoadTrainInfo.setLayout(new BoxLayout(panelLoadTrainInfo, BoxLayout.Y_AXIS)); 1610 panelLoadTrainInfo.setBorder(trainInfoBorder); 1611 JPanel panelUseInfo = new JPanel(); 1612 panelUseInfo.setBorder(trainInfoBorder); 1613 panelUseInfo.add(new JLabel(rbx.getString("TrainInfoFile"))); 1614 panelUseInfo.add(trainInfoComboBox); 1615 trainInfoComboBox.setToolTipText(rbx.getString("HintTrainInfoFile")); 1616 panelLoadTrainInfo.add(panelUseInfo); 1617 TitledBorder useLocoBorder = BorderFactory.createTitledBorder(rbx.getString("SelectALoco")); 1618 JPanel panelUseLoco = new JPanel(); 1619 panelUseLoco.setBorder(useLocoBorder); 1620 1621 locoAddressGroup.add(locoAddressDefault); 1622 locoAddressDefault.setToolTipText(rbx.getString("TrainInfoUseDefaultHint")); 1623 locoAddressDefault.addActionListener(new ActionListener() { 1624 @Override 1625 public void actionPerformed(ActionEvent e) { 1626 updateTrainInfoAddressFields(e); 1627 } 1628 }); 1629 panelUseLoco.add(locoAddressDefault); 1630 locoAddressGroup.add(locoAddressCurrent); 1631 locoAddressCurrent.setToolTipText(rbx.getString("TrainInfoUseCurrentAddressHint")); 1632 locoAddressCurrent.addActionListener(new ActionListener() { 1633 @Override 1634 public void actionPerformed(ActionEvent e) { 1635 updateTrainInfoAddressFields(e); 1636 } 1637 }); 1638 panelUseLoco.add(locoAddressCurrent); 1639 locoAddressGroup.add(locoAddressRoster); 1640 locoAddressRoster.addActionListener(new ActionListener() { 1641 @Override 1642 public void actionPerformed(ActionEvent e) { 1643 updateTrainInfoAddressFields(e); 1644 } 1645 }); 1646 panelUseLoco.add(locoAddressRoster); 1647 locoAddressGroup.add(locoAddressNumber); 1648 locoAddressNumber.addActionListener(new ActionListener() { 1649 @Override 1650 public void actionPerformed(ActionEvent e) { 1651 updateTrainInfoAddressFields(e); 1652 } 1653 }); 1654 panelUseLoco.add(locoAddressNumber); 1655 panelUseLoco.add(locoAddress); 1656 locoAddress.setToolTipText(rbx.getString("HintLocoMotiveAddress")); 1657 panelUseLoco.add(rosterComboBox); 1658 panelLoadTrainInfo.add(panelUseLoco); 1659 panelx.add(panelLoadTrainInfo); 1660 panelLoadTrainInfo.setVisible(false); 1661 1662 panelPercentageSpinner = new JPanel(); 1663 panelPercentageSpinner.setLayout(new FlowLayout()); 1664 whatPercentSpinner.setModel(new SpinnerNumberModel(Float.valueOf(1.0f), Float.valueOf(0.00f), Float.valueOf(1.5f), Float.valueOf(0.01f))); 1665 whatPercentSpinner.setEditor(new JSpinner.NumberEditor(whatPercentSpinner, "# %")); // show as a percentage % sign 1666 panelPercentageSpinner.add(whatPercentSpinner); 1667 panelPercentageSpinner.add(whatMinuteSpinner1); 1668 panelPercentageSpinner.add(whatMinuteSpinner2); 1669 panelPercentageSpinner.add(locoFunctionSpinner); 1670 // signal comboboxes 1671 TitledBorder border = BorderFactory.createTitledBorder(rbx.getString("SelectASignal")); 1672 signalPanel = new JPanel(); 1673 signalPanel.setBorder(border); 1674 signalPanel.add(new JLabel(rbx.getString("MastLabel"))); 1675 JComboBoxUtil.setupComboBoxMaxRows(signalMastComboBox); 1676 signalPanel.add(signalMastComboBox); 1677 signalMastComboBox.setAllowNull(true); 1678 signalMastComboBox.addActionListener((ActionEvent e) -> { 1679 if (signalMastComboBox.getSelectedIndex() > 0) { 1680 signalHeadComboBox.setSelectedIndex(-1); // choose either a head or a mast 1681 } 1682 }); 1683 signalPanel.add(new JLabel(rbx.getString("HeadLabel"))); 1684 JComboBoxUtil.setupComboBoxMaxRows(signalHeadComboBox); 1685 signalPanel.add(signalHeadComboBox); 1686 signalHeadComboBox.setAllowNull(true); 1687 signalHeadComboBox.addActionListener((ActionEvent e) -> { 1688 if (signalHeadComboBox.getSelectedIndex() > 0) { 1689 signalMastComboBox.setSelectedIndex(-1); // choose either a head or a mast 1690 } 1691 }); 1692 signalMastComboBox.setToolTipText(rbx.getString("HintSignalEntry")); 1693 signalHeadComboBox.setToolTipText(rbx.getString("HintSignalEntry")); 1694 panelPercentageSpinner.add(signalPanel); 1695 // On/Off buttons 1696 ButtonGroup onOffGroup = new ButtonGroup(); 1697 onOffGroup.add(onButton); 1698 onOffGroup.add(offButton); 1699 panelPercentageSpinner.add(onButton); 1700 panelPercentageSpinner.add(offButton); 1701 panelPercentageSpinner.add(doneSensorLabel); 1702 panelPercentageSpinner.add(doneSensorComboBox); 1703 JComboBoxUtil.setupComboBoxMaxRows(doneSensorComboBox); 1704 doneSensorComboBox.setAllowNull(true); 1705 panelx.add(panelPercentageSpinner); 1706 contentPane.add(panelx); 1707 contentPane.add(new JSeparator()); 1708 // add buttons 1709 JPanel but = new JPanel(); 1710 but.setLayout(new FlowLayout()); 1711 but.add(cancelAddEditActionButton = new JButton(Bundle.getMessage("ButtonCancel"))); 1712 cancelAddEditActionButton.addActionListener(this::cancelAddEditActionPressed); 1713 cancelAddEditActionButton.setToolTipText(rbx.getString("CancelButtonHint")); 1714 createActionButton = new JButton(rbx.getString("CreateActionButton")); 1715 but.add(createActionButton); 1716 createActionButton.addActionListener(this::createActionPressed); 1717 createActionButton.setToolTipText(rbx.getString("CreateActionButtonHint")); 1718 updateActionButton = new JButton(rbx.getString("UpdateActionButton")); 1719 but.add(updateActionButton); 1720 updateActionButton.addActionListener(this::updateActionPressed); 1721 updateActionButton.setToolTipText(rbx.getString("UpdateActionButtonHint")); 1722 contentPane.add(but); 1723 } 1724 if (editActionMode) { 1725 // initialize window for the action being edited 1726 addEditActionFrame.setTitle(rbx.getString("TitleEditAction")); 1727 updateActionButton.setVisible(true); 1728 createActionButton.setVisible(false); 1729 whenDataSpinnerInt.setValue(Integer.valueOf(curTSA.getDataWhen())); 1730 float f = (int)whenDataSpinnerInt.getValue(); 1731 whenDataSpinnerFloat.setValue(Float.valueOf(f/1000.0f)); 1732 whenSensorComboBox.setSelectedItemByName(curTSA.getStringWhen()); 1733 // spinners are set in setWhat() 1734 tWhatString2 = curTSA.getStringWhat2(); 1735 tWhatString = curTSA.getStringWhat(); 1736 whatStringField.setText(tWhatString); 1737 onButton.setSelected(true); 1738 if (curTSA.getStringWhat().equals("Off")) { 1739 offButton.setSelected(true); 1740 } 1741 locoAddress.setText(curTSA.getStringWhat2()); 1742 panelLoadTrainInfo.setVisible(false); 1743 log.debug("setWhen called for edit of action, editmode = {}", editActionMode); 1744 whenBox.setSelectedItem(getWhenMenuText(curTSA.getWhenCode())); 1745 // setWhen(curTSA.getWhenCode()) and setWhat(idem) are set via whenBox and whatBox 1746 whatBox.setSelectedItem(getWhatMenuText(curTSA.getWhatCode())); 1747 setBlockBox(); 1748 } else { 1749 // initialize for add new action 1750 addEditActionFrame.setTitle(rbx.getString("TitleAddAction")); 1751 whenBox.setSelectedIndex(0); 1752 // setWhen(1) and setWhat(1) are set from the whenBox and whatBox listeners 1753 whatBox.setSelectedIndex(0); 1754 // set initial values after setting model 1755 whenDataSpinnerInt.setValue(0); 1756 whenDataSpinnerFloat.setValue(Float.valueOf(0.0f)); 1757 whenSensorComboBox.setSelectedItem(0); 1758 whatPercentSpinner.setValue(1.0f); 1759 whatMinuteSpinner1.setValue(100); 1760 whatMinuteSpinner2.setValue(100); 1761 locoFunctionSpinner.setValue(0); 1762 signalMastComboBox.setSelectedItem(0); 1763 signalHeadComboBox.setSelectedItem(0); 1764 doneSensorComboBox.setSelectedItem(0); 1765 whatStringField.setText(""); 1766 locoAddress.setText(""); 1767 onButton.setSelected(true); 1768 updateActionButton.setVisible(false); 1769 createActionButton.setVisible(true); 1770 panelLoadTrainInfo.setVisible(false); 1771 setBlockBox(); 1772 } 1773 addEditActionFrame.addWindowListener(new java.awt.event.WindowAdapter() { 1774 @Override 1775 public void windowClosing(java.awt.event.WindowEvent e) { 1776 addEditActionFrame.setVisible(false); 1777 addEditActionFrame.dispose(); 1778 addEditActionFrame = null; 1779 } 1780 }); 1781 addEditActionFrame.pack(); 1782 addEditActionFrame.setVisible(true); 1783 } 1784 1785 /** 1786 * Set special stuff depending on When selected. 1787 * 1788 * @param code selected item in getWhenBox 1789 */ 1790 private void setWhen(int code) { 1791 // setting the whenBox here causes recursion 1792 whenSensorComboBox.setVisible(false); 1793 blockBox.setVisible(false); 1794 panelDelay.setVisible(true); 1795 panelWhatBox.setVisible(true); 1796 panelPercentageSpinner.setVisible(true); 1797 panelDelayLabel.setText(" " + rbx.getString("OptionalDelay") + ": "); 1798 log.debug("setWhen code = {}", code); 1799 initializeWhatBox(code); 1800 switch (code) { 1801 case TransitSectionAction.EXIT: 1802 panelDelay.setVisible(false); 1803 break; 1804 case TransitSectionAction.ENTRY: 1805 case TransitSectionAction.TRAINSTOP: 1806 case TransitSectionAction.TRAINSTART: 1807 case TransitSectionAction.PRESTARTACTION: 1808 break; 1809 case TransitSectionAction.PRESTARTDELAY: 1810 panelDelay.setVisible(true); 1811 panelDelayLabel.setText(" " + rbx.getString("Delay") + ": "); 1812 panelWhatBox.setVisible(false); 1813 panelPercentageSpinner.setVisible(false); 1814 break; 1815 case TransitSectionAction.BLOCKENTRY: 1816 case TransitSectionAction.BLOCKEXIT: 1817 blockBox.setVisible(true); 1818 blockBox.setToolTipText(rbx.getString("HintBlockEntry")); 1819 break; 1820 case TransitSectionAction.SENSORACTIVE: 1821 case TransitSectionAction.SENSORINACTIVE: 1822 whenSensorComboBox.setVisible(true); 1823 whenSensorComboBox.setToolTipText(rbx.getString("HintSensorEntry")); 1824 break; 1825 case TransitSectionAction.SELECTWHEN: 1826 break; 1827 default: 1828 log.debug("Unhandled transit action code: {}", code); // causes too much noise, no harm done hiding it 1829 } 1830 addEditActionFrame.pack(); 1831 addEditActionFrame.setVisible(true); 1832 } 1833 1834 /** 1835 * Set special stuff depending on What selected, including spinner value. 1836 * 1837 * @param code selected item in getWhatBox 1838 */ 1839 private void setWhat(int code) { 1840 // setting the whatBox here causes recursion 1841 // hide all input boxes, set those needed visible via a switch case 1842 whatStringField.setVisible(false); 1843 whatPercentSpinner.setVisible(false); 1844 whatMinuteSpinner1.setVisible(false); 1845 whatMinuteSpinner2.setVisible(false); 1846 locoFunctionSpinner.setVisible(false); 1847 signalPanel.setVisible(false); 1848 onButton.setVisible(false); 1849 offButton.setVisible(false); 1850 doneSensorLabel.setVisible(false); 1851 doneSensorComboBox.setVisible(false); 1852 panelDelay.setEnabled(true); 1853 panelLoadTrainInfo.setVisible(false); 1854 log.debug("setWhat code = {}", code); 1855 switch (code) { 1856 case TransitSectionAction.TERMINATETRAIN: 1857 break; 1858 case TransitSectionAction.LOADTRAININFO: 1859 rosterComboBox.update(); 1860 String[] names = new TrainInfoFile().getTrainInfoFileNames(); 1861 trainInfoComboBox.removeAllItems(); 1862 for (String fn: names) { 1863 trainInfoComboBox.addItem(fn); 1864 if (fn.equals(tWhatString)) { 1865 trainInfoComboBox.setSelectedItem(fn); 1866 } 1867 } 1868 locoAddress.setText(Integer.toString(tWhatData1)); 1869 switch (tWhatData2) { 1870 case TransitSectionAction.LOCOADDRESSTYPEROSTER: 1871 locoAddressRoster.setSelected(true); 1872 rosterComboBox.setSelectedItem(tWhatString2); 1873 rosterComboBox.setVisible(true); 1874 locoAddress.setVisible(false); 1875 break; 1876 case TransitSectionAction.LOCOADDRESSTYPENUMBER: 1877 locoAddressNumber.setSelected(true); 1878 locoAddress.setText(tWhatString2); 1879 rosterComboBox.setVisible(false); 1880 locoAddress.setVisible(true); 1881 break; 1882 case TransitSectionAction.LOCOADDRESSTYPECURRENT: 1883 locoAddressCurrent.setSelected(true); 1884 locoAddress.setText(""); 1885 rosterComboBox.setVisible(false); 1886 locoAddress.setVisible(false); 1887 break; 1888 case TransitSectionAction.LOCOADDRESSTYPEDEFAULT: 1889 default: 1890 locoAddressDefault.setSelected(true); 1891 rosterComboBox.setVisible(false); 1892 locoAddress.setVisible(false); 1893 locoAddress.setText(""); 1894 break; 1895 } 1896 panelLoadTrainInfo.setVisible(true); 1897 break; 1898 case TransitSectionAction.PAUSE: 1899 if (getWhenMenuCode((String)whenBox.getSelectedItem()) == TransitSectionAction.PRESTARTDELAY) { 1900 panelDelay.setEnabled(false); 1901 } 1902 whatMinuteSpinner1.setModel(new SpinnerNumberModel(1, 1, 65500, 1)); 1903 if (editActionMode) { 1904 whatMinuteSpinner1.setValue(Math.max(curTSA.getDataWhat1(), 1)); 1905 } 1906 whatMinuteSpinner1.setVisible(true); 1907 whatMinuteSpinner1.setToolTipText(rbx.getString("HintPauseData")); 1908 break; 1909 case TransitSectionAction.SETMAXSPEED: 1910 case TransitSectionAction.SETCURRENTSPEED: 1911 case TransitSectionAction.RAMPTRAINSPEED: 1912 if (editActionMode) { 1913 float maxPerc = Math.max(0.01f * curTSA.getDataWhat1(), 0.0f); 1914 whatPercentSpinner.setValue(maxPerc); 1915 } 1916 whatPercentSpinner.setVisible(true); 1917 whatPercentSpinner.setToolTipText(rbx.getString("HintSetSpeedData1")); 1918 break; 1919 case TransitSectionAction.TOMANUALMODE: 1920 if (editActionMode) { 1921 doneSensorComboBox.setSelectedItemByName(curTSA.getStringWhat()); 1922 } 1923 doneSensorLabel.setVisible(true); 1924 doneSensorComboBox.setVisible(true); 1925 doneSensorComboBox.setToolTipText(rbx.getString("HintDoneSensor")); 1926 break; 1927 case TransitSectionAction.SETLIGHT: 1928 onButton.setVisible(true); 1929 offButton.setVisible(true); 1930 onButton.setToolTipText(rbx.getString("HintSetLight")); 1931 offButton.setToolTipText(rbx.getString("HintSetLight")); 1932 break; 1933 case TransitSectionAction.STARTBELL: 1934 break; 1935 case TransitSectionAction.STOPBELL: 1936 break; 1937 case TransitSectionAction.SOUNDHORN: 1938 whatMinuteSpinner1.setValue(100); 1939 whatMinuteSpinner1.setModel(new SpinnerNumberModel(100, 100, 65500, 1)); 1940 if (editActionMode) { 1941 whatMinuteSpinner1.setValue(curTSA.getDataWhat1()); 1942 } 1943 if ((Integer) whatMinuteSpinner1.getValue() < 100) { 1944 whatMinuteSpinner1.setValue(100); // might result from user changing from PAUSE to SOUNDHORN 1945 } 1946 whatMinuteSpinner1.setVisible(true); 1947 whatMinuteSpinner1.setToolTipText(rbx.getString("HintSoundHornData1")); 1948 break; 1949 case TransitSectionAction.SOUNDHORNPATTERN: 1950 whatMinuteSpinner1.setValue(100); 1951 whatMinuteSpinner1.setModel(new SpinnerNumberModel(100, 100, 65500, 1)); 1952 // whatMinuteSpinner2 model never changes 1953 if (editActionMode) { 1954 whatMinuteSpinner1.setValue(curTSA.getDataWhat1()); 1955 whatMinuteSpinner2.setValue(Math.max(curTSA.getDataWhat2(), 100)); 1956 // might result from user changing from sth.else to SOUNDHORNPATTERN 1957 } 1958 if ((Integer) whatMinuteSpinner1.getValue() < 100) { 1959 whatMinuteSpinner1.setValue(100); // might result from user changing from PAUSE to SOUNDHORNPATTERN 1960 } 1961 whatMinuteSpinner1.setVisible(true); 1962 whatMinuteSpinner1.setToolTipText(rbx.getString("HintSoundHornPatternData1")); 1963 whatMinuteSpinner2.setVisible(true); 1964 whatMinuteSpinner2.setToolTipText(rbx.getString("HintSoundHornPatternData2")); 1965 whatStringField.setVisible(true); 1966 break; 1967 case TransitSectionAction.LOCOFUNCTION: 1968 if (editActionMode) { 1969 locoFunctionSpinner.setValue(curTSA.getDataWhat1()); 1970 } 1971 locoFunctionSpinner.setVisible(true); 1972 locoFunctionSpinner.setToolTipText(rbx.getString("HintLocoFunctionData1")); 1973 onButton.setVisible(true); 1974 offButton.setVisible(true); 1975 onButton.setToolTipText(rbx.getString("HintLocoFunctionOnOff")); 1976 offButton.setToolTipText(rbx.getString("HintLocoFunctionOnOff")); 1977 break; 1978 case TransitSectionAction.SETSENSORACTIVE: 1979 case TransitSectionAction.SETSENSORINACTIVE: 1980 if (editActionMode) { 1981 doneSensorComboBox.setSelectedItemByName(curTSA.getStringWhat()); 1982 } 1983 doneSensorComboBox.setVisible(true); 1984 doneSensorComboBox.setToolTipText(rbx.getString("HintSensorEntry")); 1985 break; 1986 case TransitSectionAction.HOLDSIGNAL: 1987 case TransitSectionAction.RELEASESIGNAL: 1988 if (editActionMode) { 1989 SignalMast sm = InstanceManager.getDefault(SignalMastManager.class).getSignalMast(curTSA.getStringWhat()); 1990 if (sm != null) { // name is an existing mast 1991 signalMastComboBox.setSelectedItemByName(curTSA.getStringWhat()); 1992 } else { 1993 SignalHead sh = InstanceManager.getDefault(SignalHeadManager.class).getSignalHead(curTSA.getStringWhat()); 1994 if (sh != null) { // name is an existing head 1995 signalHeadComboBox.setSelectedItemByName(curTSA.getStringWhat()); 1996 } 1997 } 1998 } 1999 signalPanel.setVisible(true); 2000 break; 2001 case TransitSectionAction.ESTOP: 2002 default: 2003 log.debug("Unhandled transit section action: {}", code); // causes too much noise, no harm done hiding it 2004 break; 2005 } 2006 addEditActionFrame.pack(); 2007 addEditActionFrame.setVisible(true); 2008 } 2009 2010 private void updateTrainInfoAddressFields(ActionEvent e) { 2011 if (!((JRadioButton)e.getSource()).isSelected() ) { 2012 return; 2013 } 2014 if (e.getSource() == locoAddressRoster) { 2015 tWhatData2 = TransitSectionAction.LOCOADDRESSTYPEROSTER; 2016 rosterComboBox.setVisible(true); 2017 locoAddress.setVisible(false); 2018 } else if (e.getSource() == locoAddressNumber) { 2019 tWhatData2 = TransitSectionAction.LOCOADDRESSTYPENUMBER; 2020 rosterComboBox.setVisible(false); 2021 locoAddress.setVisible(true); 2022 } else if (e.getSource() == locoAddressDefault) { 2023 tWhatData2 = TransitSectionAction.LOCOADDRESSTYPEDEFAULT; 2024 rosterComboBox.setVisible(false); 2025 locoAddress.setVisible(false); 2026 } else if (e.getSource() == locoAddressCurrent) { 2027 tWhatData2 = TransitSectionAction.LOCOADDRESSTYPECURRENT; 2028 rosterComboBox.setVisible(false); 2029 locoAddress.setVisible(false); 2030 } else { 2031 log.warn("Unknown button Source"); 2032 } 2033 } 2034 2035 // temporary action variables 2036 private int tWhen = 0; 2037 private int tWhenData = 0; 2038 private String tWhenString = ""; 2039 private int tWhat = 0; 2040 private int tWhatData1 = 0; 2041 private int tWhatData2 = 0; 2042 private String tWhatString = ""; 2043 private String tWhatString2 = ""; 2044 2045 /** 2046 * Handle button presses in Add/Edit Transit Action window. 2047 * 2048 * @param e the event seen 2049 */ 2050 private void createActionPressed(ActionEvent e) { 2051 if ((!validateWhenData()) || (!validateWhatData())) { 2052 return; 2053 } 2054 // entered data is OK, create a special action 2055 curTSA = new TransitSectionAction(tWhen, tWhat, tWhenData, tWhatData1, tWhatData2, tWhenString, tWhatString, tWhatString2); 2056 List<TransitSectionAction> list = action.get(activeRow); 2057 list.add(curTSA); 2058 actionTableModel.fireTableDataChanged(); 2059 addEditActionFrame.setVisible(false); 2060 addEditActionFrame.dispose(); 2061 addEditActionFrame = null; 2062 } 2063 2064 private void updateActionPressed(ActionEvent e) { 2065 if ((!validateWhenData()) || (!validateWhatData())) { 2066 return; 2067 } 2068 // entered data is OK, update the current special action 2069 curTSA.setWhenCode(tWhen); 2070 curTSA.setWhatCode(tWhat); 2071 curTSA.setDataWhen(tWhenData); 2072 curTSA.setDataWhat1(tWhatData1); 2073 curTSA.setDataWhat2(tWhatData2); 2074 curTSA.setStringWhen(tWhenString); 2075 curTSA.setStringWhat(tWhatString); 2076 curTSA.setStringWhat2(tWhatString2); 2077 actionTableModel.fireTableDataChanged(); 2078 addEditActionFrame.setVisible(false); 2079 addEditActionFrame.dispose(); 2080 addEditActionFrame = null; 2081 } 2082 2083 private void cancelAddEditActionPressed(ActionEvent e) { 2084 addEditActionFrame.setVisible(false); 2085 addEditActionFrame.dispose(); 2086 addEditActionFrame = null; 2087 } 2088 2089 private boolean validateWhenData() { 2090 tWhen = getWhenMenuCode((String)whenBox.getSelectedItem()); 2091 tWhenData = (int)whenDataSpinnerInt.getValue(); 2092 tWhenString = ""; 2093 if (tWhen == TransitSectionAction.PRESTARTDELAY ) { 2094 // must have a delay 2095 if (tWhenData <1 ) { 2096 return false; 2097 } 2098 } 2099 if ((tWhen == TransitSectionAction.SENSORACTIVE) || (tWhen == TransitSectionAction.SENSORINACTIVE)) { 2100 if (whenSensorComboBox.getSelectedIndex() != 0) { // it's optional, so might be 0 2101 tWhenString = whenSensorComboBox.getSelectedItemSystemName(); 2102 } 2103 if (!validateSensor(tWhenString, true)) { 2104 return false; 2105 } 2106 } 2107 if ((tWhen == TransitSectionAction.BLOCKENTRY) || (tWhen == TransitSectionAction.BLOCKEXIT)) { 2108 tWhenString = blockList.get(blockBox.getSelectedIndex()).getSystemName(); 2109 } 2110 return true; 2111 } 2112 2113 private boolean validateSensor(String sName, boolean when) { 2114 // check if anything entered 2115 if (sName.length() < 1) { 2116 // no sensor selected 2117 JmriJOptionPane.showMessageDialog(addEditActionFrame, (rbx.getString("NoSensorError")), 2118 Bundle.getMessage("ErrorTitle"), JmriJOptionPane.ERROR_MESSAGE); 2119 return false; 2120 } 2121 // get the sensor corresponding to this name 2122 Sensor s = InstanceManager.sensorManagerInstance().getSensor(sName); 2123 if (s == null) { 2124 // There is no sensor corresponding to this name 2125 JmriJOptionPane.showMessageDialog(addEditActionFrame, (rbx.getString("SensorEntryError")), 2126 Bundle.getMessage("ErrorTitle"), JmriJOptionPane.ERROR_MESSAGE); 2127 return false; 2128 } 2129 if (!sName.equals(s.getUserName())) { 2130 if (when) { 2131 tWhenString = sName; 2132 } else { 2133 tWhatString = sName; 2134 } 2135 } 2136 return true; 2137 } 2138 2139 private boolean validateSignal(String sName, boolean when) { 2140 // check if anything is selected 2141 if (sName.length() < 1) { 2142 // no signal selected 2143 JmriJOptionPane.showMessageDialog(addEditActionFrame, (rbx.getString("NoSignalError")), 2144 Bundle.getMessage("ErrorTitle"), JmriJOptionPane.ERROR_MESSAGE); 2145 return false; 2146 } 2147 // get the signalMast or signalHead corresponding to this name 2148 SignalMast sm = InstanceManager.getDefault(SignalMastManager.class).getSignalMast(sName); 2149 SignalHead sh = null; 2150 if (sm == null) { 2151 sh = InstanceManager.getDefault(SignalHeadManager.class).getSignalHead(sName); 2152 } 2153 if (sm == null && sh == null) { 2154 // There is no signal corresponding to this name 2155 JmriJOptionPane.showMessageDialog(addEditActionFrame, (rbx.getString("SignalEntryError")), 2156 Bundle.getMessage("ErrorTitle"), JmriJOptionPane.ERROR_MESSAGE); 2157 return false; 2158 } 2159 return true; 2160 } 2161 2162 /** 2163 * Validate entered data for selected Action. Converted to use JSpinners 2164 * where applicable, 2017. 2165 * 2166 * @return true if data entered into field whatStringField is valid for selected Action type tWhat 2167 */ 2168 private boolean validateWhatData() { 2169 tWhat = getWhatMenuCode((String)whatBox.getSelectedItem()); 2170 tWhatData1 = 0; 2171 tWhatData2 = 0; 2172 tWhatString = ""; 2173 switch (tWhat) { 2174 case TransitSectionAction.SETMAXSPEED: 2175 case TransitSectionAction.SETCURRENTSPEED: 2176 case TransitSectionAction.RAMPTRAINSPEED: 2177 tWhatData1 = Math.round(100 * (float) whatPercentSpinner.getValue()); 2178 break; 2179 case TransitSectionAction.TOMANUALMODE: 2180 tWhatString=""; 2181 if (doneSensorComboBox.getSelectedIndex() >= 0) { // it's optional, so might be -1 2182 tWhatString = doneSensorComboBox.getSelectedItemSystemName(); // sensor system name 2183 } 2184 if (tWhatString.length() >= 1) { 2185 if (!validateSensor(tWhatString, false)) { 2186 tWhatString = ""; 2187 } 2188 } 2189 break; 2190 case TransitSectionAction.SETLIGHT: 2191 tWhatString = "On"; // NOI18N 2192 if (offButton.isSelected()) { 2193 tWhatString = "Off"; // NOI18N 2194 } 2195 break; 2196 case TransitSectionAction.STARTBELL: 2197 case TransitSectionAction.STOPBELL: 2198 case TransitSectionAction.TERMINATETRAIN: 2199 break; 2200 case TransitSectionAction.LOADTRAININFO: 2201 if (trainInfoComboBox.getSelectedIndex() < 0 ) { 2202 JmriJOptionPane.showMessageDialog(addEditActionFrame, (rbx.getString("MissingTrainInfoFile")), 2203 Bundle.getMessage("ErrorTitle"), JmriJOptionPane.ERROR_MESSAGE); 2204 return false; 2205 } 2206 tWhatString = (String)trainInfoComboBox.getSelectedItem(); 2207 if (locoAddressRoster.isSelected()) { 2208 tWhatData2 = TransitSectionAction.LOCOADDRESSTYPEROSTER; 2209 // the first item is "select..." 2210 if (rosterComboBox.getSelectedIndex() < 1) { 2211 JmriJOptionPane.showMessageDialog(addEditActionFrame, (rbx.getString("MissingRosterEntryOrLocoAddress")), 2212 Bundle.getMessage("ErrorTitle"), JmriJOptionPane.ERROR_MESSAGE); 2213 return false; 2214 } 2215 tWhatString2 =((RosterEntry) rosterComboBox.getSelectedItem()).getId(); 2216 } else if (locoAddressNumber.isSelected()) { 2217 tWhatData2 = TransitSectionAction.LOCOADDRESSTYPENUMBER; 2218 tWhatString2 = locoAddress.getText(); 2219 if ((tWhatString2 == null) || tWhatString2.isEmpty() || (tWhatString2.length() < 1)) { 2220 JmriJOptionPane.showMessageDialog(addEditActionFrame, (rbx.getString("MissingRosterEntryOrLocoAddress")), 2221 Bundle.getMessage("ErrorTitle"), JmriJOptionPane.ERROR_MESSAGE); 2222 return false; 2223 } 2224 } else if (locoAddressDefault.isSelected()) { 2225 tWhatData2 = TransitSectionAction.LOCOADDRESSTYPEDEFAULT; 2226 tWhatString2 = ""; 2227 } else if (locoAddressCurrent.isSelected()) { 2228 tWhatData2 = TransitSectionAction.LOCOADDRESSTYPECURRENT; 2229 tWhatString2 = ""; 2230 } else { 2231 JmriJOptionPane.showMessageDialog(addEditActionFrame, (rbx.getString("UnKnownlocoaddresstype")), 2232 Bundle.getMessage("ErrorTitle"), JmriJOptionPane.ERROR_MESSAGE); 2233 return false; 2234 } 2235 break; 2236 case TransitSectionAction.PAUSE: 2237 case TransitSectionAction.SOUNDHORN: 2238 tWhatData1 = (Integer) whatMinuteSpinner1.getValue(); 2239 break; 2240 case TransitSectionAction.SOUNDHORNPATTERN: 2241 tWhatData1 = (Integer) whatMinuteSpinner1.getValue(); 2242 tWhatData2 = (Integer) whatMinuteSpinner2.getValue(); 2243 tWhatString = whatStringField.getText(); 2244 if ((tWhatString == null) || tWhatString.isEmpty() || (tWhatString.length() < 1)) { 2245 JmriJOptionPane.showMessageDialog(addEditActionFrame, (rbx.getString("MissingPattern")), 2246 Bundle.getMessage("ErrorTitle"), JmriJOptionPane.ERROR_MESSAGE); 2247 return false; 2248 } 2249 tWhatString = tWhatString.trim().toLowerCase(); 2250 for (int i = 0; i < tWhatString.length(); i++) { 2251 char c = tWhatString.charAt(i); 2252 if ((c != 's') && (c != 'l')) { 2253 JmriJOptionPane.showMessageDialog(addEditActionFrame, (rbx.getString("ErrorPattern")), 2254 Bundle.getMessage("ErrorTitle"), JmriJOptionPane.ERROR_MESSAGE); 2255 return false; 2256 } 2257 } 2258 whatStringField.setText(tWhatString); // re-enter normalized value in display field 2259 break; 2260 case TransitSectionAction.LOCOFUNCTION: 2261 tWhatData1 = (Integer) locoFunctionSpinner.getValue(); 2262 tWhatString = "On"; // NOI18N 2263 if (offButton.isSelected()) { 2264 tWhatString = "Off"; // NOI18N 2265 } 2266 break; 2267 case TransitSectionAction.SETSENSORACTIVE: 2268 case TransitSectionAction.SETSENSORINACTIVE: 2269 if (doneSensorComboBox.getSelectedIndex() != 0) { 2270 tWhatString = doneSensorComboBox.getSelectedItemSystemName(); 2271 } 2272 if (!validateSensor(tWhatString, false)) { 2273 return false; 2274 } 2275 break; 2276 case TransitSectionAction.HOLDSIGNAL: 2277 case TransitSectionAction.RELEASESIGNAL: 2278 if (signalMastComboBox.getSelectedIndex() != 0) { 2279 tWhatString = signalMastComboBox.getSelectedItemSystemName(); 2280 } else if (signalHeadComboBox.getSelectedIndex() != 0) { 2281 tWhatString = signalHeadComboBox.getSelectedItemSystemName(); 2282 } 2283 if (!validateSignal(tWhatString, false)) { 2284 return false; 2285 } 2286 break; 2287 case TransitSectionAction.PRESTARTRESUME: 2288 break; 2289 default: 2290 log.warn("Unhandled transit section action code: {}", tWhat); 2291 break; 2292 } 2293 return true; 2294 } 2295 2296 // initialize combos for add/edit action window 2297 private void initializeWhenBox() { 2298 whenBox.removeAllItems(); 2299 for (int i = 0; i <= TransitSectionAction.NUM_WHENS; i++) { 2300 whenBox.addItem(getWhenMenuText(i)); 2301 } 2302 } 2303 2304 private String getWhenMenuText(int i) { 2305 switch (i) { 2306 case TransitSectionAction.ENTRY: 2307 return rbx.getString("OnEntry"); 2308 case TransitSectionAction.EXIT: 2309 return rbx.getString("OnExit"); 2310 case TransitSectionAction.BLOCKENTRY: 2311 return rbx.getString("OnBlockEntry"); 2312 case TransitSectionAction.BLOCKEXIT: 2313 return rbx.getString("OnBlockExit"); 2314 case TransitSectionAction.TRAINSTOP: 2315 return rbx.getString("TrainStop"); 2316 case TransitSectionAction.TRAINSTART: 2317 return rbx.getString("TrainStart"); 2318 case TransitSectionAction.SENSORACTIVE: 2319 return rbx.getString("OnSensorActive"); 2320 case TransitSectionAction.SENSORINACTIVE: 2321 return rbx.getString("OnSensorInactive"); 2322 case TransitSectionAction.PRESTARTDELAY: 2323 return rbx.getString("PreStartDelay"); 2324 case TransitSectionAction.PRESTARTACTION: 2325 return rbx.getString("PreStartAction"); 2326 case TransitSectionAction.SELECTWHEN: 2327 return rbx.getString("SelectWhen"); 2328 default: 2329 log.warn("Unhandled transit section when code: {}", i); 2330 return rbx.getString("SelectWhen"); 2331 } 2332 } 2333 2334 private int getWhenMenuCode(String s) { 2335 if (s.equals(rbx.getString("OnEntry"))) { 2336 return TransitSectionAction.ENTRY; 2337 } 2338 if (s.equals(rbx.getString("OnExit"))) { 2339 return TransitSectionAction.EXIT; 2340 } 2341 if (s.equals(rbx.getString("OnBlockEntry"))) { 2342 return TransitSectionAction.BLOCKENTRY; 2343 } 2344 if (s.equals(rbx.getString("OnBlockExit"))) { 2345 return TransitSectionAction.BLOCKEXIT; 2346 } 2347 if (s.equals(rbx.getString("TrainStop"))) { 2348 return TransitSectionAction.TRAINSTOP; 2349 } 2350 if (s.equals(rbx.getString("TrainStart"))) { 2351 return TransitSectionAction.TRAINSTART; 2352 } 2353 if (s.equals(rbx.getString("OnSensorActive"))) { 2354 return TransitSectionAction.SENSORACTIVE; 2355 } 2356 if (s.equals(rbx.getString("OnSensorInactive"))) { 2357 return TransitSectionAction.SENSORINACTIVE; 2358 } 2359 if (s.equals(rbx.getString("PreStartDelay"))) { 2360 return TransitSectionAction.PRESTARTDELAY; 2361 } 2362 if (s.equals(rbx.getString("PreStartAction"))) { 2363 return TransitSectionAction.PRESTARTACTION; 2364 } 2365 return TransitSectionAction.SELECTWHEN; 2366 } 2367 2368 private void initializeWhatBox(int code) { 2369 whatBox.removeAllItems(); 2370 List<Integer> excludeCodes = new ArrayList<>(); 2371 List<Integer> includeCodes = new ArrayList<>(); 2372 if (code == TransitSectionAction.PRESTARTACTION) { 2373 // exclude speed changing as that messes up the prestart.List<Section> sectionList = new ArrayList<>(); 2374 excludeCodes = new ArrayList<>(Arrays.asList(TransitSectionAction.SETMAXSPEED, TransitSectionAction.SETCURRENTSPEED, 2375 TransitSectionAction.RAMPTRAINSPEED)); 2376 } else if (code == TransitSectionAction.PRESTARTDELAY) { 2377 includeCodes.add(TransitSectionAction.PRESTARTRESUME); 2378 } else { 2379 excludeCodes.add(TransitSectionAction.PRESTARTRESUME); 2380 } 2381 for (int i = 0; i <= TransitSectionAction.NUM_WHATS; i++) { 2382 if (excludeCodes.size() > 0) { 2383 if (! excludeCodes.contains(i)) { 2384 whatBox.addItem(getWhatMenuText(i)); 2385 } 2386 } else if (includeCodes.size() > 0) { 2387 if (includeCodes.contains(i)) { 2388 whatBox.addItem(getWhatMenuText(i)); 2389 } 2390 } else { 2391 whatBox.addItem(getWhatMenuText(i)); 2392 } 2393 } 2394 } 2395 2396 private String getWhatMenuText(int i) { 2397 switch (i) { 2398 case TransitSectionAction.SELECTWHAT: 2399 return rbx.getString("SelectWhat"); 2400 case TransitSectionAction.TERMINATETRAIN: 2401 return rbx.getString("TerminateTrain"); 2402 case TransitSectionAction.LOADTRAININFO: 2403 return rbx.getString("LoadTrainInfo"); 2404 case TransitSectionAction.PAUSE: 2405 return rbx.getString("Pause"); 2406 case TransitSectionAction.SETMAXSPEED: 2407 return rbx.getString("SetMaxSpeed"); 2408 case TransitSectionAction.SETCURRENTSPEED: 2409 return rbx.getString("SetTrainSpeed"); 2410 case TransitSectionAction.RAMPTRAINSPEED: 2411 return rbx.getString("RampTrainSpeed"); 2412 case TransitSectionAction.TOMANUALMODE: 2413 return rbx.getString("ToManualMode"); 2414 case TransitSectionAction.SETLIGHT: 2415 return rbx.getString("SetLight"); 2416 case TransitSectionAction.STARTBELL: 2417 return rbx.getString("StartBell"); 2418 case TransitSectionAction.STOPBELL: 2419 return rbx.getString("StopBell"); 2420 case TransitSectionAction.SOUNDHORN: 2421 return rbx.getString("SoundHorn"); 2422 case TransitSectionAction.SOUNDHORNPATTERN: 2423 return rbx.getString("SoundHornPattern"); 2424 case TransitSectionAction.LOCOFUNCTION: 2425 return rbx.getString("LocoFunction"); 2426 case TransitSectionAction.SETSENSORACTIVE: 2427 return rbx.getString("SetSensorActive"); 2428 case TransitSectionAction.SETSENSORINACTIVE: 2429 return rbx.getString("SetSensorInactive"); 2430 case TransitSectionAction.HOLDSIGNAL: 2431 return rbx.getString("HoldSignal"); 2432 case TransitSectionAction.RELEASESIGNAL: 2433 return rbx.getString("ReleaseSignal"); 2434 case TransitSectionAction.ESTOP: 2435 return rbx.getString("EStop"); 2436 case TransitSectionAction.PRESTARTRESUME: 2437 return rbx.getString("PreStartResume"); 2438 default: 2439 log.warn("Unhandled transit section action code: {}", i); 2440 return rbx.getString("SelectWhat"); 2441 } 2442 } 2443 2444 private int getWhatMenuCode(String s) { 2445 if (s.equals(rbx.getString("SelectWhat"))) { 2446 return TransitSectionAction.SELECTWHAT; 2447 } 2448 if (s.equals(rbx.getString("TerminateTrain"))) { 2449 return TransitSectionAction.TERMINATETRAIN; 2450 } 2451 if (s.equals(rbx.getString("LoadTrainInfo"))) { 2452 return TransitSectionAction.LOADTRAININFO; 2453 } 2454 if (s.equals(rbx.getString("Pause"))) { 2455 return TransitSectionAction.PAUSE; 2456 } 2457 if (s.equals(rbx.getString("SetMaxSpeed"))) { 2458 return TransitSectionAction.SETMAXSPEED; 2459 } 2460 if (s.equals(rbx.getString("SetTrainSpeed"))) { 2461 return TransitSectionAction.SETCURRENTSPEED; 2462 } 2463 if (s.equals(rbx.getString("RampTrainSpeed"))) { 2464 return TransitSectionAction.RAMPTRAINSPEED; 2465 } 2466 if (s.equals(rbx.getString("ToManualMode"))) { 2467 return TransitSectionAction.TOMANUALMODE; 2468 } 2469 if (s.equals(rbx.getString("SetLight"))) { 2470 return TransitSectionAction.SETLIGHT; 2471 } 2472 if (s.equals(rbx.getString("StartBell"))) { 2473 return TransitSectionAction.STARTBELL; 2474 } 2475 if (s.equals(rbx.getString("StopBell"))) { 2476 return TransitSectionAction.STOPBELL; 2477 } 2478 if (s.equals(rbx.getString("SoundHorn"))) { 2479 return TransitSectionAction.SOUNDHORN; 2480 } 2481 if (s.equals(rbx.getString("SoundHornPattern"))) { 2482 return TransitSectionAction.SOUNDHORNPATTERN; 2483 } 2484 if (s.equals(rbx.getString("LocoFunction"))) { 2485 return TransitSectionAction.LOCOFUNCTION; 2486 } 2487 if (s.equals(rbx.getString("SetSensorActive"))) { 2488 return TransitSectionAction.SETSENSORACTIVE; 2489 } 2490 if (s.equals(rbx.getString("SetSensorInactive"))) { 2491 return TransitSectionAction.SETSENSORINACTIVE; 2492 } 2493 if (s.equals(rbx.getString("HoldSignal"))) { 2494 return TransitSectionAction.HOLDSIGNAL; 2495 } 2496 if (s.equals(rbx.getString("ReleaseSignal"))) { 2497 return TransitSectionAction.RELEASESIGNAL; 2498 } 2499 if (s.equals(rbx.getString("EStop"))) { 2500 return TransitSectionAction.ESTOP; 2501 } 2502 if (s.equals(rbx.getString("PreStartResume"))) { 2503 return TransitSectionAction.PRESTARTRESUME; 2504 } 2505 log.warn("Unhandled transit section action text: {}", s); 2506 return 0; 2507 } 2508 2509 private void initializeBlockBox() { 2510 blockList = sectionList.get(activeRow).getBlockList(); 2511 blockBox.removeAllItems(); 2512 for (int i = 0; i < blockList.size(); i++) { 2513 String s = blockList.get(i).getDisplayName(); 2514 blockBox.addItem(s); 2515 } 2516 } 2517 2518 private void setBlockBox() { 2519 if (editActionMode) { 2520 if ((curTSA.getWhenCode() == TransitSectionAction.BLOCKENTRY) 2521 || (curTSA.getWhenCode() == TransitSectionAction.BLOCKEXIT)) { 2522 // assumes that initializeBlockBox has been called prior to this call 2523 for (int i = 0; i < blockList.size(); i++) { 2524 if (curTSA.getStringWhen().equals(blockList.get(i).getSystemName())) { 2525 blockBox.setSelectedIndex(i); 2526 return; 2527 } 2528 } 2529 } 2530 } 2531 blockBox.setSelectedIndex(0); 2532 } 2533 2534 private void editAction(int r) { 2535 curTSA = action.get(activeRow).get(r); 2536 editActionMode = true; 2537 addEditActionWindow(); 2538 } 2539 2540 private void deleteAction(int r) { 2541 TransitSectionAction tsa = action.get(activeRow).get(r); 2542 action.get(activeRow).remove(r); 2543 tsa.dispose(); 2544 actionTableModel.fireTableDataChanged(); 2545 } 2546 2547 /** 2548 * Build display When string for Actions table. 2549 * 2550 * @param r row in the Special Actions table. A TransitSectionAction must be 2551 * available for this row. 2552 * @return display string including entered values 2553 */ 2554 private String getWhenText(int r) { 2555 TransitSectionAction tsa = action.get(activeRow).get(r); 2556 switch (tsa.getWhenCode()) { 2557 case TransitSectionAction.ENTRY: 2558 if (tsa.getDataWhen() > 0) { 2559 return java.text.MessageFormat.format(rbx.getString("OnEntryDelayedFull"), 2560 new Object[]{"" + tsa.getDataWhen()}); 2561 } 2562 return rbx.getString("OnEntryFull"); 2563 case TransitSectionAction.EXIT: 2564 if (tsa.getDataWhen() > 0) { 2565 return java.text.MessageFormat.format(rbx.getString("OnExitDelayedFull"), 2566 new Object[]{"" + tsa.getDataWhen()}); 2567 } 2568 return rbx.getString("OnExitFull"); 2569 case TransitSectionAction.BLOCKENTRY: 2570 if (tsa.getDataWhen() > 0) { 2571 return java.text.MessageFormat.format(rbx.getString("OnBlockEntryDelayedFull"), 2572 new Object[]{"" + tsa.getDataWhen(), tsa.getStringWhen()}); 2573 } 2574 return java.text.MessageFormat.format(rbx.getString("OnBlockEntryFull"), 2575 new Object[]{tsa.getStringWhen()}); 2576 case TransitSectionAction.BLOCKEXIT: 2577 if (tsa.getDataWhen() > 0) { 2578 return java.text.MessageFormat.format(rbx.getString("OnBlockExitDelayedFull"), 2579 new Object[]{"" + tsa.getDataWhen(), tsa.getStringWhen()}); 2580 } 2581 return java.text.MessageFormat.format(rbx.getString("OnBlockExitFull"), 2582 new Object[]{tsa.getStringWhen()}); 2583 case TransitSectionAction.TRAINSTOP: 2584 if (tsa.getDataWhen() > 0) { 2585 return java.text.MessageFormat.format(rbx.getString("TrainStopDelayedFull"), 2586 new Object[]{"" + tsa.getDataWhen()}); 2587 } 2588 return rbx.getString("TrainStopFull"); 2589 case TransitSectionAction.TRAINSTART: 2590 if (tsa.getDataWhen() > 0) { 2591 return java.text.MessageFormat.format(rbx.getString("TrainStartDelayedFull"), 2592 new Object[]{"" + tsa.getDataWhen()}); 2593 } 2594 return rbx.getString("TrainStartFull"); 2595 case TransitSectionAction.SENSORACTIVE: 2596 if (tsa.getDataWhen() > 0) { 2597 return java.text.MessageFormat.format(rbx.getString("OnSensorActiveDelayedFull"), 2598 new Object[]{"" + tsa.getDataWhen(), tsa.getStringWhen()}); 2599 } 2600 return java.text.MessageFormat.format(rbx.getString("OnSensorActiveFull"), 2601 new Object[]{tsa.getStringWhen()}); 2602 case TransitSectionAction.SENSORINACTIVE: 2603 if (tsa.getDataWhen() > 0) { 2604 return java.text.MessageFormat.format(rbx.getString("OnSensorInactiveDelayedFull"), 2605 new Object[]{"" + tsa.getDataWhen(), tsa.getStringWhen()}); 2606 } 2607 return java.text.MessageFormat.format(rbx.getString("OnSensorInactiveFull"), 2608 new Object[]{tsa.getStringWhen()}); 2609 case TransitSectionAction.PRESTARTDELAY: 2610 return java.text.MessageFormat.format(rbx.getString("PreStartDelayFull"), 2611 new Object[]{"" + tsa.getDataWhen(), tsa.getStringWhen()}); 2612 case TransitSectionAction.PRESTARTACTION: 2613 return java.text.MessageFormat.format(rbx.getString("PreStartActionFull"), 2614 new Object[]{"" + tsa.getDataWhen(), tsa.getStringWhen()}); 2615 default: 2616 log.warn("Unhandled transit section action When code: {}",tsa.getWhenCode()); 2617 return(""); 2618 } 2619 } 2620 2621 /** 2622 * Build display What string for Actions table. 2623 * 2624 * @param r row in the Special Actions table. A TransitSectionAction must be 2625 * available for this row. 2626 * @return display string including entered values 2627 */ 2628 private String getWhatText(int r) { 2629 TransitSectionAction tsa = action.get(activeRow).get(r); 2630 switch (tsa.getWhatCode()) { 2631 case TransitSectionAction.PAUSE: 2632 return java.text.MessageFormat.format(rbx.getString("PauseFull"), 2633 new Object[]{tsa.getDataWhat1()}); 2634 case TransitSectionAction.SETMAXSPEED: 2635 return java.text.MessageFormat.format(rbx.getString("SetMaxSpeedFull"), 2636 new Object[]{tsa.getDataWhat1()}); 2637 case TransitSectionAction.SETCURRENTSPEED: 2638 return java.text.MessageFormat.format(rbx.getString("SetTrainSpeedFull"), 2639 new Object[]{tsa.getDataWhat1()}); 2640 case TransitSectionAction.RAMPTRAINSPEED: 2641 return java.text.MessageFormat.format(rbx.getString("RampTrainSpeedFull"), 2642 new Object[]{"" + tsa.getDataWhat1()}); 2643 case TransitSectionAction.TOMANUALMODE: 2644 if (tsa.getStringWhat().length() > 0) { 2645 return java.text.MessageFormat.format(rbx.getString("ToManualModeAltFull"), 2646 new Object[]{tsa.getStringWhat()}); 2647 } 2648 return rbx.getString("ToManualModeFull"); 2649 case TransitSectionAction.SETLIGHT: 2650 if (tsa.getStringWhat().equals("Off")) { 2651 return java.text.MessageFormat.format(rbx.getString("SetLightFull"), 2652 new Object[]{Bundle.getMessage("StateOff")}); 2653 } 2654 return java.text.MessageFormat.format(rbx.getString("SetLightFull"), 2655 new Object[]{Bundle.getMessage("StateOn")}); 2656 case TransitSectionAction.STARTBELL: 2657 return rbx.getString("StartBellFull"); 2658 case TransitSectionAction.STOPBELL: 2659 return rbx.getString("StopBellFull"); 2660 case TransitSectionAction.SOUNDHORN: 2661 return java.text.MessageFormat.format(rbx.getString("SoundHornFull"), 2662 new Object[]{tsa.getDataWhat1()}); 2663 case TransitSectionAction.SOUNDHORNPATTERN: 2664 return java.text.MessageFormat.format(rbx.getString("SoundHornPatternFull"), 2665 new Object[]{tsa.getStringWhat(), "" + tsa.getDataWhat1(), "" + tsa.getDataWhat2()}); 2666 case TransitSectionAction.LOCOFUNCTION: 2667 if (tsa.getStringWhat().equals("Off")) { 2668 return java.text.MessageFormat.format(rbx.getString("LocoFunctionFull"), 2669 new Object[]{"" + tsa.getDataWhat1(), Bundle.getMessage("StateOff")}); 2670 } 2671 return java.text.MessageFormat.format(rbx.getString("LocoFunctionFull"), 2672 new Object[]{"" + tsa.getDataWhat1(), Bundle.getMessage("StateOn")}); 2673 case TransitSectionAction.SETSENSORACTIVE: 2674 return java.text.MessageFormat.format(rbx.getString("SetSensorActiveFull"), 2675 new Object[]{tsa.getStringWhat()}); 2676 case TransitSectionAction.SETSENSORINACTIVE: 2677 return java.text.MessageFormat.format(rbx.getString("SetSensorInactiveFull"), 2678 new Object[]{tsa.getStringWhat()}); 2679 case TransitSectionAction.HOLDSIGNAL: 2680 return java.text.MessageFormat.format(rbx.getString("HoldSignalFull"), 2681 new Object[]{tsa.getStringWhat()}); 2682 case TransitSectionAction.RELEASESIGNAL: 2683 return java.text.MessageFormat.format(rbx.getString("ReleaseSignalFull"), 2684 new Object[]{tsa.getStringWhat()}); 2685 case TransitSectionAction.PRESTARTRESUME: 2686 return java.text.MessageFormat.format(rbx.getString("PreStartResumeFull"), 2687 new Object[]{tsa.getDataWhen()}); 2688 case TransitSectionAction.ESTOP: 2689 return rbx.getString("EStopFull"); 2690 case TransitSectionAction.TERMINATETRAIN: 2691 return rbx.getString("TerminateTrain"); 2692 case TransitSectionAction.LOADTRAININFO: 2693 switch (tWhatData2) { 2694 case TransitSectionAction.LOCOADDRESSTYPEROSTER: 2695 return java.text.MessageFormat.format(rbx.getString("LoadTrainInfoRosterFull"), 2696 new Object[]{tsa.getStringWhat(),tsa.getStringWhat2()}); 2697 case TransitSectionAction.LOCOADDRESSTYPENUMBER: 2698 return java.text.MessageFormat.format(rbx.getString("LoadTrainInfoNumberFull"), 2699 new Object[]{tsa.getStringWhat(),tsa.getStringWhat2()}); 2700 case TransitSectionAction.LOCOADDRESSTYPECURRENT: 2701 return java.text.MessageFormat.format(rbx.getString("LoadTrainInfoCurrentFull"), 2702 new Object[]{tsa.getStringWhat()}); 2703 case TransitSectionAction.LOCOADDRESSTYPEDEFAULT: 2704 default: 2705 return java.text.MessageFormat.format(rbx.getString("LoadTrainInfoDefaultFull"), 2706 new Object[]{tsa.getStringWhat()}); 2707 } 2708 case TransitSectionAction.SELECTWHAT: 2709 return rbx.getString("SelectWhat"); 2710 default: 2711 log.warn("Unhandled transit section action What code: {}", tsa.getWhatCode()); 2712 break; 2713 } 2714 return "WHAT"; 2715 } 2716 2717 private String getSectionNameByRow(int r) { 2718 return sectionList.get(r).getDisplayName(); 2719 } 2720 2721 /** 2722 * Table model for Sections in Create/Edit Transit window. 2723 */ 2724 public class SectionTableModel extends javax.swing.table.AbstractTableModel implements 2725 java.beans.PropertyChangeListener { 2726 2727 public static final int SEQUENCE_COLUMN = 0; 2728 public static final int SECTIONNAME_COLUMN = 1; 2729 public static final int ACTION_COLUMN = 2; 2730 public static final int SEC_DIRECTION_COLUMN = 3; 2731 public static final int ALTERNATE_COLUMN = 4; 2732 public static final int SAFE_COLUMN = 5; 2733 public static final int STOPALLOCATING_SENSOR = 6; 2734 public static final int NUMBER_OF_COLUMNS = 7; 2735 2736 public SectionTableModel() { 2737 super(); 2738 addPcl(); 2739 } 2740 2741 final void addPcl(){ 2742 sectionManager.addPropertyChangeListener(this); 2743 } 2744 2745 @Override 2746 public void propertyChange(java.beans.PropertyChangeEvent e) { 2747 if (e.getPropertyName().equals("length")) { // NOI18N 2748 // a new NamedBean is available in the manager 2749 fireTableDataChanged(); 2750 } 2751 if (e.getSource() instanceof SensorManager) { 2752 if (e.getPropertyName().equals("DisplayListName")) { 2753 updateSensorList(); 2754 } 2755 } 2756 } 2757 2758 @Override 2759 public Class<?> getColumnClass(int c) { 2760 switch (c) { 2761 case ACTION_COLUMN: 2762 return JButton.class; 2763 case SAFE_COLUMN: 2764 return Boolean.class; 2765 case STOPALLOCATING_SENSOR: 2766 return JComboBox.class; 2767 default: 2768 return super.getColumnClass(c); 2769 } 2770 } 2771 2772 @Override 2773 public int getColumnCount() { 2774 return NUMBER_OF_COLUMNS; 2775 } 2776 2777 @Override 2778 public int getRowCount() { 2779 return (sectionList.size()); 2780 } 2781 2782 @Override 2783 public boolean isCellEditable(int r, int c) { 2784 switch (c) { 2785 case ACTION_COLUMN: 2786 case SAFE_COLUMN: 2787 case STOPALLOCATING_SENSOR: 2788 return true; 2789 default: 2790 return false; 2791 } 2792 } 2793 2794 @Override 2795 public String getColumnName(int col) { 2796 switch (col) { 2797 case SEQUENCE_COLUMN: 2798 return rbx.getString("SequenceColName"); 2799 case SECTIONNAME_COLUMN: 2800 return Bundle.getMessage("BeanNameSection"); 2801 case ACTION_COLUMN: 2802 return rbx.getString("ActionColName"); 2803 case SEC_DIRECTION_COLUMN: 2804 return rbx.getString("DirectionColName"); 2805 case ALTERNATE_COLUMN: 2806 return rbx.getString("AlternateColName"); 2807 case SAFE_COLUMN: 2808 return rbx.getString("SafeColName"); 2809 case STOPALLOCATING_SENSOR: 2810 return rbx.getString("StopAllocationColName"); 2811 default: 2812 return ""; 2813 } 2814 } 2815 2816 @edu.umd.cs.findbugs.annotations.SuppressFBWarnings(value = "DB_DUPLICATE_SWITCH_CLAUSES", 2817 justification="better to keep cases in column order rather than to combine") 2818 public int getPreferredWidth(int col) { 2819 switch (col) { 2820 case SEQUENCE_COLUMN: 2821 return new JTextField(8).getPreferredSize().width; 2822 case SECTIONNAME_COLUMN: 2823 return new JTextField(17).getPreferredSize().width; 2824 case ACTION_COLUMN: 2825 return new JTextField(12).getPreferredSize().width; 2826 case SEC_DIRECTION_COLUMN: 2827 return new JTextField(12).getPreferredSize().width; 2828 case ALTERNATE_COLUMN: 2829 return new JTextField(12).getPreferredSize().width; 2830 case SAFE_COLUMN: 2831 return new JTextField(4).getPreferredSize().width; 2832 case STOPALLOCATING_SENSOR: 2833 return new JTextField(12).getPreferredSize().width; 2834 default: 2835 // fall through 2836 break; 2837 } 2838 return new JTextField(5).getPreferredSize().width; 2839 } 2840 2841 @Override 2842 public Object getValueAt(int r, int c) { 2843 int rx = r; 2844 if (rx > sectionList.size()) { 2845 return null; 2846 } 2847 switch (c) { 2848 case SEQUENCE_COLUMN: 2849 return ("" + sequence.get(rx)); 2850 case SECTIONNAME_COLUMN: 2851 return (getSectionNameByRow(rx)); 2852 case ACTION_COLUMN: 2853 return rbx.getString("AddEditActions"); 2854 case SEC_DIRECTION_COLUMN: 2855 if (direction.get(rx) == Section.FORWARD) { 2856 return rbx.getString("SectionForward"); 2857 } else if (direction.get(rx) == Section.REVERSE) { 2858 return rbx.getString("SectionReverse"); 2859 } 2860 return Bundle.getMessage("BeanStateUnknown"); 2861 case ALTERNATE_COLUMN: 2862 if (alternate.get(rx)) { 2863 return rbx.getString("Alternate"); 2864 } 2865 return rbx.getString("Primary"); 2866 case SAFE_COLUMN: 2867 return safe.get(rx); 2868 case STOPALLOCATING_SENSOR: 2869 String sensor = sensorStopAllocation.get(rx); 2870 JComboBox<String> cb = new JComboBox<>(sensorList); 2871 JComboBoxUtil.setupComboBoxMaxRows(cb); 2872 String name = (sensor != null) ? sensor : ""; 2873 cb.setSelectedItem(name); 2874 return cb; 2875 default: 2876 return Bundle.getMessage("BeanStateUnknown"); 2877 } 2878 } 2879 2880 @Override 2881 public void setValueAt(Object value, int row, int col) { 2882 switch (col) { 2883 case ACTION_COLUMN: 2884 addEditActionsPressed(row); 2885 break; 2886 case SAFE_COLUMN: 2887 boolean val = ((Boolean) value); 2888 safe.set(row, val); // use checkbox to show Safe 2889 break; 2890 case STOPALLOCATING_SENSOR: 2891 JComboBox<?> cb = (JComboBox<?>) value; 2892 if (cb.getSelectedIndex() < 0) { 2893 sensorStopAllocation.set(row, ""); 2894 } else { 2895 sensorStopAllocation.set(row, (String) cb.getSelectedItem()); 2896 } 2897 break; 2898 default: 2899 break; 2900 } 2901 } 2902 2903 public void dispose(){ 2904 sectionManager.removePropertyChangeListener(this); 2905 } 2906 } 2907 2908 private void updateSensorList() { 2909 Set<Sensor> nameSet = InstanceManager.getDefault(SensorManager.class).getNamedBeanSet(); 2910 String[] displayList = new String[nameSet.size()]; 2911 int i = 0; 2912 for (Sensor nBean : nameSet) { 2913 if (nBean != null) { 2914 displayList[i++] = nBean.getDisplayName(); 2915 } 2916 } 2917 java.util.Arrays.sort(displayList, new jmri.util.AlphanumComparator()); 2918 sensorList = new String[displayList.length + 1]; 2919 sensorList[0] = ""; 2920 i = 1; 2921 for (String name : displayList) { 2922 sensorList[i] = name; 2923 i++; 2924 } 2925 } 2926 2927 2928 /** 2929 * Table model for Actions in Special Actions window. Currently shows max. 5 2930 * rows. 2931 */ 2932 public class SpecialActionTableModel extends javax.swing.table.AbstractTableModel implements 2933 java.beans.PropertyChangeListener { 2934 2935 public static final int WHEN_COLUMN = 0; 2936 public static final int WHAT_COLUMN = 1; 2937 public static final int EDIT_COLUMN = 2; 2938 public static final int REMOVE_COLUMN = 3; 2939 2940 public SpecialActionTableModel() { 2941 super(); 2942 addPcl(); 2943 } 2944 2945 final void addPcl(){ 2946 sectionManager.addPropertyChangeListener(this); 2947 } 2948 2949 @Override 2950 public void propertyChange(java.beans.PropertyChangeEvent e) { 2951 if (e.getPropertyName().equals("length")) { // NOI18N 2952 // a new NamedBean is available in the manager 2953 fireTableDataChanged(); 2954 } 2955 } 2956 2957 @Override 2958 public Class<?> getColumnClass(int c) { 2959 switch (c) { 2960 case EDIT_COLUMN: 2961 case REMOVE_COLUMN: 2962 return JButton.class; 2963 case WHEN_COLUMN: 2964 case WHAT_COLUMN: 2965 default: 2966 return String.class; 2967 } 2968 } 2969 2970 @Override 2971 public int getColumnCount() { 2972 return REMOVE_COLUMN + 1; 2973 } 2974 2975 @Override 2976 public int getRowCount() { 2977 return (action.get(activeRow).size()); 2978 } 2979 2980 @Override 2981 public boolean isCellEditable(int r, int c) { 2982 switch (c) { 2983 case EDIT_COLUMN: 2984 case REMOVE_COLUMN: 2985 return true; 2986 default: 2987 return false; 2988 } 2989 } 2990 2991 @Override 2992 public String getColumnName(int col) { 2993 switch (col) { 2994 case WHEN_COLUMN: 2995 return rbx.getString("WhenColName"); 2996 case WHAT_COLUMN: 2997 return rbx.getString("WhatColName"); 2998 default: 2999 return ""; 3000 } 3001 } 3002 3003 public int getPreferredWidth(int col) { 3004 switch (col) { 3005 case WHEN_COLUMN: 3006 case WHAT_COLUMN: 3007 return new JTextField(50).getPreferredSize().width; 3008 case EDIT_COLUMN: 3009 case REMOVE_COLUMN: 3010 default: 3011 return new JTextField(8).getPreferredSize().width; 3012 } 3013 } 3014 3015 @Override 3016 public Object getValueAt(int r, int c) { 3017 int rx = r; 3018 if (rx > action.get(activeRow).size()) { 3019 return null; 3020 } 3021 switch (c) { 3022 case WHEN_COLUMN: 3023 return (getWhenText(rx)); 3024 case WHAT_COLUMN: 3025 return (getWhatText(rx)); 3026 case EDIT_COLUMN: 3027 return Bundle.getMessage("ButtonEdit"); 3028 case REMOVE_COLUMN: 3029 return Bundle.getMessage("ButtonDelete"); 3030 default: 3031 return Bundle.getMessage("BeanStateUnknown"); // normally not in use 3032 } 3033 } 3034 3035 @Override 3036 public void setValueAt(Object value, int row, int col) { 3037 if (col == EDIT_COLUMN) { 3038 // set up to edit 3039 editAction(row); 3040 } 3041 else if (col == REMOVE_COLUMN) { 3042 deleteAction(row); 3043 } 3044 } 3045 3046 public void dispose(){ 3047 sectionManager.removePropertyChangeListener(this); 3048 } 3049 } 3050 3051 @Override 3052 protected String getClassName() { 3053 return TransitTableAction.class.getName(); 3054 } 3055 3056 @Override 3057 public String getClassDescription() { 3058 return Bundle.getMessage("TitleTransitTable"); 3059 } 3060 3061 private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(TransitTableAction.class); 3062 3063}