001package jmri.jmrit.conditional; 002 003import java.awt.Container; 004import java.awt.Dimension; 005import java.awt.FlowLayout; 006import java.awt.Font; 007import java.awt.event.ActionEvent; 008import java.awt.event.ActionListener; 009import java.util.ArrayList; 010import java.util.TreeMap; 011 012import javax.swing.*; 013import javax.swing.border.Border; 014import javax.swing.filechooser.FileNameExtensionFilter; 015import javax.swing.table.*; 016 017import jmri.*; 018import jmri.Conditional.Operator; 019import jmri.Conditional.State; 020import jmri.implementation.DefaultConditionalAction; 021import jmri.jmrit.beantable.LRouteTableAction; 022import jmri.jmrit.conditional.ConditionalEditBase.NameBoxListener; 023import jmri.jmrit.conditional.ConditionalEditBase.SelectionMode; 024import jmri.jmrit.logix.OBlock; 025import jmri.jmrit.logix.Warrant; 026import jmri.script.swing.ScriptFileChooser; 027import jmri.swing.NamedBeanComboBox; 028import jmri.util.FileUtil; 029import jmri.util.JmriJFrame; 030import jmri.util.swing.JComboBoxUtil; 031import jmri.util.swing.JmriJOptionPane; 032import jmri.util.table.ButtonEditor; 033import jmri.util.table.ButtonRenderer; 034 035/** 036 * Extracted from ConditionalEditList. 037 * Allows ConditionalEditList to open alternate frame 038 * for copying Conditionals. 039 * 040 * @author Pete Cressman Copyright (C) 2020 041 */ 042public class ConditionalEditFrame extends ConditionalFrame { 043 044 // ------------ Edit Conditional Variables ------------ 045 JRadioButton _triggerOnChangeButton; 046 boolean _inActReorder = false; 047 boolean _inVarReorder = false; 048 int _nextInOrder = 0; 049 050 // ------------ Select Logix/Conditional Variables ------------ 051 JPanel _selectLogixPanel = null; 052 JPanel _selectConditionalPanel = null; 053 054 ActionTableModel _actionTableModel = null; 055 VariableTableModel _variableTableModel = null; 056 JComboBox<Conditional.AntecedentOperator> _operatorBox; 057 JComboBox<String> _andOperatorBox; 058 JComboBox<String> _notOperatorBox; 059 JTextField _antecedentField; 060 JPanel _antecedentPanel; 061 boolean _newItem = false; // marks a new Action or Variable object was added 062 063 // ------------ Components of Edit Variable panes ------------ 064 JmriJFrame _editVariableFrame = null; 065 JComboBox<Conditional.ItemType> _variableItemBox; 066 JComboBox<Conditional.Type> _variableStateBox; 067 JTextField _variableNameField; 068 JComboBox<String> _variableCompareOpBox; 069 JComboBox<String> _variableSignalBox; 070 JComboBox<Conditional.Type> _variableCompareTypeBox; 071 JTextField _variableData1Field; 072 JTextField _variableData2Field; 073 JButton _reorderVarButton; 074 JPanel _variableNamePanel; 075 JPanel _variableStatePanel; 076 JPanel _variableComparePanel; 077 JPanel _variableSignalPanel; 078 JPanel _variableData1Panel; 079 JPanel _variableData2Panel; 080 JPanel _variableComboNamePanel; 081 082 // ------------ Components of Edit Action panes ------------ 083 JmriJFrame _editActionFrame = null; 084 JComboBox<Conditional.ItemType> _actionItemBox; 085 JComboBox<Conditional.Action> _actionTypeBox; 086 JComboBox<String> _actionBox; 087 JTextField _actionNameField; 088 JTextField _longActionString; 089 JTextField _shortActionString; 090 JComboBox<String> _actionOptionBox; 091 JPanel _actionPanel; 092 JPanel _actionTypePanel; 093 JPanel _actionNamePanel; 094 JPanel _shortTextPanel; 095 JPanel _optionPanel; 096 JPanel _actionComboNamePanel; 097 098 JPanel _setPanel; 099 JPanel _textPanel; 100 NamedBeanComboBox<?> _comboNameBox = null; 101 102 // ------------ Current Variable Information ------------ 103 ConditionalVariable _curVariable; 104 int _curVariableRowNumber; 105 Conditional.ItemType _curVariableItem = Conditional.ItemType.NONE; 106 107 // ------------ Current Action Information ------------ 108 ConditionalAction _curAction; 109 int _curActionRowNumber; 110 Conditional.ItemType _curActionItem = Conditional.ItemType.NONE; 111 112 // ------------ Components of Logix and SConditional selection ------------ 113 JComboBox<String> _selectLogixBox = new JComboBox<>(); 114 JComboBox<String> _selectConditionalBox = new JComboBox<>(); 115 TreeMap<String, String> _selectLogixMap = new TreeMap<>(); 116 ArrayList<String> _selectConditionalList = new ArrayList<>(); 117 118 // ------------------------------------------------------------------ 119 120 ConditionalEditFrame(String title, Conditional conditional, ConditionalList parent) { 121 super(title, conditional, parent); 122 makeConditionalFrame(conditional); 123 } 124 125 void makeConditionalFrame(Conditional conditional) { 126 addHelpMenu( 127 "package.jmri.jmrit.conditional.ConditionalListEditor", true); // NOI18N 128 Container contentPane = getContentPane(); 129 contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.Y_AXIS)); 130 contentPane.add(makeTopPanel(conditional)); 131 132 // add Logical Expression Section 133 JPanel logicPanel = new JPanel(); 134 logicPanel.setLayout(new BoxLayout(logicPanel, BoxLayout.Y_AXIS)); 135 136 // add Antecedent Expression Panel - ONLY appears for MIXED operator statements 137 _antecedentField = new JTextField(65); 138 _antecedentField.setText(ConditionalEditBase.translateAntecedent(_antecedent, false)); 139 _antecedentField.setFont(new Font("SansSerif", Font.BOLD, 14)); // NOI18N 140 _antecedentPanel = makeEditPanel(_antecedentField, "LabelAntecedent", "LabelAntecedentHint"); // NOI18N 141 142 JButton helpButton = new JButton(Bundle.getMessage("MenuHelp")); // NOI18N 143 _antecedentPanel.add(helpButton); 144 helpButton.addActionListener(new ActionListener() { 145 @Override 146 public void actionPerformed(ActionEvent e) { 147 helpPressed(e); 148 } 149 }); 150 _antecedentPanel.add(helpButton); 151 _antecedentPanel.setVisible(_logicType == Conditional.AntecedentOperator.MIXED); 152 logicPanel.add(_antecedentPanel); 153 154 // add state variable table title 155 JPanel varTitle = new JPanel(); 156 varTitle.setLayout(new FlowLayout()); 157 varTitle.add(new JLabel(Bundle.getMessage("StateVariableTableTitle"))); // NOI18N 158 logicPanel.add(varTitle); 159 // set up state variables table 160 // initialize and populate Combo boxes for table of state variables 161 _notOperatorBox = new JComboBox<String>(); 162 _notOperatorBox.addItem(" "); 163 _notOperatorBox.addItem(Bundle.getMessage("LogicNOT")); // NOI18N 164 165 _andOperatorBox = new JComboBox<String>(); 166 _andOperatorBox.addItem(Bundle.getMessage("LogicAND")); // NOI18N 167 _andOperatorBox.addItem(Bundle.getMessage("LogicOR")); // NOI18N 168 // initialize table of state variables 169 _variableTableModel = new VariableTableModel(); 170 JTable variableTable = new JTable(_variableTableModel); 171 variableTable.setRowHeight(_notOperatorBox.getPreferredSize().height); 172 variableTable.setRowSelectionAllowed(false); 173 int rowHeight = variableTable.getRowHeight(); 174 175 TableColumnModel variableColumnModel = variableTable.getColumnModel(); 176 177 TableColumn rowColumn = variableColumnModel.getColumn(VariableTableModel.ROWNUM_COLUMN); 178 rowColumn.setResizable(false); 179 rowColumn.setMaxWidth(new JTextField(3).getPreferredSize().width); 180 181 TableColumn andColumn = variableColumnModel.getColumn(VariableTableModel.AND_COLUMN); 182 andColumn.setResizable(false); 183 andColumn.setCellEditor(new DefaultCellEditor(_andOperatorBox)); 184 andColumn.setMaxWidth(_andOperatorBox.getPreferredSize().width - 5); 185 186 TableColumn notColumn = variableColumnModel.getColumn(VariableTableModel.NOT_COLUMN); 187 notColumn.setCellEditor(new DefaultCellEditor(_notOperatorBox)); 188 notColumn.setMaxWidth(_notOperatorBox.getPreferredSize().width - 5); 189 notColumn.setResizable(false); 190 191 TableColumn descColumn = variableColumnModel.getColumn(VariableTableModel.DESCRIPTION_COLUMN); 192 descColumn.setMinWidth(200); 193 descColumn.setResizable(true); 194 195 TableColumn stateColumn = variableColumnModel.getColumn(VariableTableModel.STATE_COLUMN); 196 stateColumn.setResizable(true); 197 stateColumn.setMinWidth(50); 198 stateColumn.setMaxWidth(80); 199 200 TableColumn triggerColumn = variableColumnModel.getColumn(VariableTableModel.TRIGGERS_COLUMN); 201 triggerColumn.setResizable(true); 202 triggerColumn.setMinWidth(30); 203 triggerColumn.setMaxWidth(80); 204 205 TableColumn editColumn = variableColumnModel.getColumn(VariableTableModel.EDIT_COLUMN); 206 ButtonRenderer buttonRenderer = new ButtonRenderer(); 207 variableTable.setDefaultRenderer(JButton.class, buttonRenderer); 208 TableCellEditor buttonEditor = new ButtonEditor(new JButton()); 209 variableTable.setDefaultEditor(JButton.class, buttonEditor); 210 JButton testButton = new JButton("XXXXXX"); // NOI18N 211 variableTable.setRowHeight(testButton.getPreferredSize().height); 212 editColumn.setMinWidth(testButton.getPreferredSize().width); 213 editColumn.setMaxWidth(testButton.getPreferredSize().width); 214 editColumn.setResizable(false); 215 216 TableColumn deleteColumn = variableColumnModel.getColumn(VariableTableModel.DELETE_COLUMN); 217 // ButtonRenderer and TableCellEditor already set 218 deleteColumn.setMinWidth(testButton.getPreferredSize().width); 219 deleteColumn.setMaxWidth(testButton.getPreferredSize().width); 220 deleteColumn.setResizable(false); 221 // add a scroll pane 222 JScrollPane variableTableScrollPane = new JScrollPane(variableTable); 223 Dimension dim = variableTable.getPreferredSize(); 224 dim.height = 7 * rowHeight; 225 variableTableScrollPane.getViewport().setPreferredSize(dim); 226 227 logicPanel.add(variableTableScrollPane); 228 229 // set up state variable buttons and logic 230 JPanel panel42 = new JPanel(); 231 panel42.setLayout(new FlowLayout()); 232 233 // Add State Variable 234 JButton addVariableButton = new JButton(Bundle.getMessage("AddVariableButton")); // NOI18N 235 panel42.add(addVariableButton); 236 addVariableButton.addActionListener(new ActionListener() { 237 @Override 238 public void actionPerformed(ActionEvent e) { 239 addVariablePressed(e); 240 } 241 }); 242 addVariableButton.setToolTipText(Bundle.getMessage("AddVariableButtonHint")); // NOI18N 243 244 JButton checkVariableButton = new JButton(Bundle.getMessage("CheckVariableButton")); // NOI18N 245 panel42.add(checkVariableButton); 246 checkVariableButton.addActionListener(new ActionListener() { 247 @Override 248 public void actionPerformed(ActionEvent e) { 249 checkVariablePressed(e); 250 } 251 }); 252 checkVariableButton.setToolTipText(Bundle.getMessage("CheckVariableButtonHint")); // NOI18N 253 254 // - Reorder variable button 255 _reorderVarButton = new JButton(Bundle.getMessage("ReorderButton")); // NOI18N 256 panel42.add(_reorderVarButton); 257 _reorderVarButton.addActionListener(new ActionListener() { 258 @Override 259 public void actionPerformed(ActionEvent e) { 260 reorderVariablePressed(e); 261 } 262 }); 263 _reorderVarButton.setToolTipText(Bundle.getMessage("ReorderButtonHint")); // NOI18N 264 _reorderVarButton.setEnabled(!(_logicType == Conditional.AntecedentOperator.MIXED)); 265 logicPanel.add(panel42); 266 267 // logic type area 268 _operatorBox = new JComboBox<>(); 269 for (Conditional.AntecedentOperator operator : Conditional.AntecedentOperator.values()) { 270 _operatorBox.addItem(operator); 271 } 272 JPanel typePanel = makeEditPanel(_operatorBox, "LabelLogicType", "TypeLogicHint"); // NOI18N 273 _operatorBox.setSelectedItem(_logicType); 274 _operatorBox.addActionListener(new ActionListener() { 275 @Override 276 public void actionPerformed(ActionEvent e) { 277 logicTypeChanged(e); 278 _dataChanged = true; 279 } 280 }); 281 logicPanel.add(typePanel); 282 logicPanel.add(Box.createHorizontalStrut(STRUT)); 283 284 Border logicPanelBorder = BorderFactory.createEtchedBorder(); 285 Border logicPanelTitled = BorderFactory.createTitledBorder( 286 logicPanelBorder, Bundle.getMessage("TitleLogicalExpression") + " "); // NOI18N 287 logicPanel.setBorder(logicPanelTitled); 288 contentPane.add(logicPanel); 289 // End of Logic Expression Section 290 291 JPanel triggerPanel = new JPanel(); 292 triggerPanel.setLayout(new BoxLayout(triggerPanel, BoxLayout.Y_AXIS)); 293 ButtonGroup tGroup = new ButtonGroup(); 294 _triggerOnChangeButton = new JRadioButton(Bundle.getMessage("triggerOnChange")); // NOI18N 295 _triggerOnChangeButton.addActionListener(new ActionListener() { 296 @Override 297 public void actionPerformed(ActionEvent e) { 298 _actionTableModel.fireTableDataChanged(); 299 _dataChanged = true; 300 } 301 }); 302 tGroup.add(_triggerOnChangeButton); 303 triggerPanel.add(_triggerOnChangeButton); 304 JRadioButton triggerOnAny = new JRadioButton(Bundle.getMessage("triggerOnAny")); // NOI18N 305 triggerOnAny.addActionListener(new ActionListener() { 306 @Override 307 public void actionPerformed(ActionEvent e) { 308 _actionTableModel.fireTableDataChanged(); 309 _dataChanged = true; 310 } 311 }); 312 tGroup.add(triggerOnAny); 313 triggerPanel.add(triggerOnAny); 314 triggerOnAny.setSelected(true); 315 JPanel trigPanel = new JPanel(); 316 trigPanel.add(triggerPanel); 317 contentPane.add(trigPanel); 318 _triggerOnChangeButton.setSelected(conditional.getTriggerOnChange()); 319 320 // add Action Consequents Section 321 JPanel conseqentPanel = new JPanel(); 322 conseqentPanel.setLayout(new BoxLayout(conseqentPanel, BoxLayout.Y_AXIS)); 323 324 JPanel actTitle = new JPanel(); 325 actTitle.setLayout(new FlowLayout()); 326 actTitle.add(new JLabel(Bundle.getMessage("ActionTableTitle"))); // NOI18N 327 conseqentPanel.add(actTitle); 328 329 // set up action consequents table 330 _actionTableModel = new ActionTableModel(); 331 JTable actionTable = new JTable(_actionTableModel); 332 actionTable.setRowSelectionAllowed(false); 333 actionTable.setRowHeight(testButton.getPreferredSize().height); 334 JPanel actionPanel = new JPanel(); 335 actionPanel.setLayout(new BoxLayout(actionPanel, BoxLayout.Y_AXIS)); 336 JPanel actionTitle = new JPanel(); 337 actionTitle.setLayout(new FlowLayout()); 338 conseqentPanel.add(actionPanel); 339 340 TableColumnModel actionColumnModel = actionTable.getColumnModel(); 341 342 TableColumn descriptionColumn = actionColumnModel.getColumn( 343 ActionTableModel.DESCRIPTION_COLUMN); 344 descriptionColumn.setResizable(true); 345 descriptionColumn.setMinWidth(300); 346 347 TableColumn actionEditColumn = actionColumnModel.getColumn(ActionTableModel.EDIT_COLUMN); 348 // ButtonRenderer already exists 349 actionTable.setDefaultRenderer(JButton.class, buttonRenderer); 350 TableCellEditor editButEditor = new ButtonEditor(new JButton()); 351 actionTable.setDefaultEditor(JButton.class, editButEditor); 352 actionEditColumn.setMinWidth(testButton.getPreferredSize().width); 353 actionEditColumn.setMaxWidth(testButton.getPreferredSize().width); 354 actionEditColumn.setResizable(false); 355 356 TableColumn actionDeleteColumn = actionColumnModel.getColumn(ActionTableModel.DELETE_COLUMN); 357 // ButtonRenderer and TableCellEditor already set 358 actionDeleteColumn.setMinWidth(testButton.getPreferredSize().width); 359 actionDeleteColumn.setMaxWidth(testButton.getPreferredSize().width); 360 actionDeleteColumn.setResizable(false); 361 // add a scroll pane 362 JScrollPane actionTableScrollPane = new JScrollPane(actionTable); 363 dim = actionTableScrollPane.getPreferredSize(); 364 dim.height = 7 * rowHeight; 365 actionTableScrollPane.getViewport().setPreferredSize(dim); 366 conseqentPanel.add(actionTableScrollPane); 367 368 // add action buttons to Action Section 369 JPanel panel43 = new JPanel(); 370 panel43.setLayout(new FlowLayout()); 371 JButton addActionButton = new JButton(Bundle.getMessage("addActionButton")); // NOI18N 372 panel43.add(addActionButton); 373 addActionButton.addActionListener(new ActionListener() { 374 @Override 375 public void actionPerformed(ActionEvent e) { 376 addActionPressed(e); 377 } 378 }); 379 380 addActionButton.setToolTipText(Bundle.getMessage("addActionButtonHint")); // NOI18N 381 conseqentPanel.add(panel43); 382 383 // - Reorder action button 384 JButton reorderButton = new JButton(Bundle.getMessage("ReorderButton")); // NOI18N 385 panel43.add(reorderButton); 386 reorderButton.addActionListener(new ActionListener() { 387 @Override 388 public void actionPerformed(ActionEvent e) { 389 reorderActionPressed(e); 390 } 391 }); 392 reorderButton.setToolTipText(Bundle.getMessage("ReorderButtonHint")); // NOI18N 393 conseqentPanel.add(panel43); 394 395 Border conseqentPanelBorder = BorderFactory.createEtchedBorder(); 396 Border conseqentPanelTitled = BorderFactory.createTitledBorder( 397 conseqentPanelBorder, Bundle.getMessage("TitleAction")); // NOI18N 398 conseqentPanel.setBorder(conseqentPanelTitled); 399 contentPane.add(conseqentPanel); 400 // End of Action Consequents Section 401 402 contentPane.add(_parent.makeBottomPanel()); 403 404 // setup window closing listener 405 this.addWindowListener( 406 new java.awt.event.WindowAdapter() { 407 @Override 408 public void windowClosing(java.awt.event.WindowEvent e) { 409 cancelConditionalPressed(); 410 } 411 }); 412 // initialize state variable table 413 _variableTableModel.fireTableDataChanged(); 414 // initialize action variables 415 _actionTableModel.fireTableDataChanged(); 416 checkVariablePressed(null); // update variables to their current states 417 } // end makeConditionalFrame 418 419 420 // ============ Edit Conditional Window and Methods ============ 421 422 /** 423 * Respond to the Add State Variable Button in the Edit Conditional window. 424 * 425 * @param e The event heard 426 */ 427 void addVariablePressed(ActionEvent e) { 428 if (alreadyEditingActionOrVariable()) { 429 return; 430 } 431 _curVariableItem = Conditional.ItemType.NONE; 432 ConditionalVariable variable = new ConditionalVariable(); 433 _variableList.add(variable); 434 _newItem = true; 435 int size = _variableList.size(); 436 // default of operator for postion 0 (row 1) is Conditional.OPERATOR_NONE 437 if (size > 1) { 438 if (_logicType == Conditional.AntecedentOperator.ALL_OR) { 439 variable.setOpern(Conditional.Operator.OR); 440 } else { 441 variable.setOpern(Conditional.Operator.AND); 442 } 443 } 444 size--; 445 _variableTableModel.fireTableRowsInserted(size, size); 446 makeEditVariableWindow(size); 447 appendToAntecedent(); 448 } 449 450 /** 451 * Respond to the Check State Variable Button in the Edit Conditional 452 * window. 453 * 454 * @param e the event heard 455 */ 456 void checkVariablePressed(ActionEvent e) { 457 for (int i = 0; i < _variableList.size(); i++) { 458 _variableList.get(i).evaluate(); 459 } 460 _variableTableModel.fireTableDataChanged(); 461 } 462 463 /** 464 * Respond to the Reorder Variable Button in the Edit Conditional window. 465 * 466 * @param e The event heard 467 */ 468 void reorderVariablePressed(ActionEvent e) { 469 if (alreadyEditingActionOrVariable()) { 470 return; 471 } 472 // Check if reorder is reasonable 473 if (_variableList.size() <= 1) { 474 JmriJOptionPane.showMessageDialog(this, 475 Bundle.getMessage("Error51"), 476 Bundle.getMessage("ErrorTitle"), // NOI18N 477 JmriJOptionPane.ERROR_MESSAGE); 478 return; 479 } 480 _nextInOrder = 0; 481 _inVarReorder = true; 482 _variableTableModel.fireTableDataChanged(); 483 _dataChanged = true; 484 } 485 486 /** 487 * Respond to the First/Next (Delete) Button in the Edit Conditional window. 488 * 489 * @param row index of the row to put as next in line (instead of the one 490 * that was supposed to be next) 491 */ 492 void swapVariables(int row) { 493 ConditionalVariable temp = _variableList.get(row); 494 for (int i = row; i > _nextInOrder; i--) { 495 _variableList.set(i, _variableList.get(i - 1)); 496 } 497 498 // Adjust operator type 499 Operator oper; 500 if (_nextInOrder == 0) { 501 oper = Conditional.Operator.NONE; 502 } else { 503 oper = (_logicType == Conditional.AntecedentOperator.ALL_AND) 504 ? Conditional.Operator.AND 505 : Conditional.Operator.OR; 506 } 507 508 temp.setOpern(oper); 509 _variableList.set(_nextInOrder, temp); 510 _nextInOrder++; 511 if (_nextInOrder >= _variableList.size()) { 512 _inVarReorder = false; 513 } 514 _variableTableModel.fireTableDataChanged(); 515 } 516 517 /** 518 * Respond to the Negation column in the Edit Conditional window. 519 * 520 * @param row index of the Conditional to change the setting on 521 * @param oper NOT (i18n) as negation of condition 522 */ 523 void variableNegationChanged(int row, String oper) { 524 ConditionalVariable variable = _variableList.get(row); 525 boolean state = variable.isNegated(); 526 if (oper == null) { 527 variable.setNegation(false); 528 } else { 529 variable.setNegation(oper.equals(Bundle.getMessage("LogicNOT"))); // NOI18N 530 } 531 if (variable.isNegated() != state) { 532 makeAntecedent(); 533 } 534 } 535 536 /** 537 * Respond to the Operator column in the Edit Conditional window. 538 * 539 * @param row index of the Conditional to change the setting on 540 * @param oper AND or OR (i18n) as operand on the list of conditions 541 */ 542 void variableOperatorChanged(int row, String oper) { 543 ConditionalVariable variable = _variableList.get(row); 544 Operator oldOper = variable.getOpern(); 545 if (row > 0) { 546 if (oper.equals(Bundle.getMessage("LogicOR"))) { // NOI18N 547 variable.setOpern(Conditional.Operator.OR); 548 } else { 549 variable.setOpern(Conditional.Operator.AND); 550 } 551 } else { 552 variable.setOpern(Conditional.Operator.NONE); 553 } 554 if (variable.getOpern() != oldOper) { 555 makeAntecedent(); 556 } 557 } 558 559 /** 560 * Respond to Add action button in the EditConditional window. 561 * 562 * @param e The event heard 563 */ 564 void addActionPressed(ActionEvent e) { 565 if (alreadyEditingActionOrVariable()) { 566 return; 567 } 568 _curActionItem = Conditional.ItemType.NONE; 569 _actionList.add(new DefaultConditionalAction()); 570 _newItem = true; 571 _actionTableModel.fireTableRowsInserted(_actionList.size(), 572 _actionList.size()); 573 makeEditActionWindow(_actionList.size() - 1); 574 } 575 576 /** 577 * Respond to the Reorder Action Button in the Edit Conditional window. 578 * 579 * @param e The event heard 580 */ 581 void reorderActionPressed(ActionEvent e) { 582 if (alreadyEditingActionOrVariable()) { 583 return; 584 } 585 // Check if reorder is reasonable 586 if (_actionList.size() <= 1) { 587 JmriJOptionPane.showMessageDialog(this, 588 Bundle.getMessage("Error46"), 589 Bundle.getMessage("ErrorTitle"), // NOI18N 590 JmriJOptionPane.ERROR_MESSAGE); 591 return; 592 } 593 _nextInOrder = 0; 594 _inActReorder = true; 595 _actionTableModel.fireTableDataChanged(); 596 _dataChanged = true; 597 } 598 599 /** 600 * Respond to the First/Next (Delete) Button in the Edit Conditional window. 601 * 602 * @param row index of the row to put as next in line (instead of the one 603 * that was supposed to be next) 604 */ 605 void swapActions(int row) { 606 ConditionalAction temp = _actionList.get(row); 607 for (int i = row; i > _nextInOrder; i--) { 608 _actionList.set(i, _actionList.get(i - 1)); 609 } 610 _actionList.set(_nextInOrder, temp); 611 _nextInOrder++; 612 if (_nextInOrder >= _actionList.size()) { 613 _inActReorder = false; 614 } 615 _actionTableModel.fireTableDataChanged(); 616 } 617 618 /** 619 * Respond to the Update Conditional Button in the Edit Conditional window. 620 * 621 * @param e The event heard 622 * @return true if updated 623 */ 624 @Override 625 boolean updateConditionalPressed(ActionEvent e) { 626 if (alreadyEditingActionOrVariable()) { 627 return false; 628 } 629 log.debug("updateConditionalPressed"); 630 if (validateAntecedent()) { 631 _antecedent = ConditionalEditBase.translateAntecedent(_antecedentField.getText(), true); 632 _trigger = _triggerOnChangeButton.isSelected(); 633 } else { 634 return false; 635 } 636 return super.updateConditionalPressed(e); 637 } 638 639 /** 640 * Respond to the Cancel button in the Edit Conditional frame. 641 * <p> 642 * Does the cleanup from deleteConditionalPressed, updateConditionalPressed 643 * and _editConditionalFrame window closer. 644 */ 645 @Override 646 void cancelConditionalPressed() { 647 log.debug("cancelConditionalPressed"); 648 if (_editActionFrame != null) { 649 cleanUpAction(); 650 } 651 if (_editVariableFrame != null) { 652 cleanUpVariable(); 653 } 654 super.cancelConditionalPressed(); 655 } 656 657 /** 658 * Respond to a change of Conditional Type in the Edit Conditional pane by 659 * showing/hiding the _antecedentPanel when Mixed is selected. 660 * 661 * @param e The event heard 662 * @return false if there is no change in operator 663 */ 664 boolean logicTypeChanged(ActionEvent e) { 665 Conditional.AntecedentOperator type = 666 _operatorBox.getItemAt(_operatorBox.getSelectedIndex()); 667 if (type == _logicType) { 668 return false; 669 } 670 makeAntecedent(); 671 672 if (type == Conditional.AntecedentOperator.MIXED) { 673 _antecedentPanel.setVisible(true); 674 _reorderVarButton.setEnabled(false); 675 } else { 676 Operator oper = (type == Conditional.AntecedentOperator.ALL_AND) 677 ? Conditional.Operator.AND 678 : Conditional.Operator.OR; 679 for (int i = 1; i < _variableList.size(); i++) { 680 _variableList.get(i).setOpern(oper); 681 } 682 _antecedentPanel.setVisible(false); 683 _reorderVarButton.setEnabled(true); 684 } 685 686 _logicType = type; 687 _dataChanged = true; 688 _variableTableModel.fireTableDataChanged(); 689 repaint(); 690 return true; 691 } 692 693 /** 694 * Respond to Help button press in the Edit Conditional pane. 695 * 696 * @param e The event heard 697 */ 698 void helpPressed(ActionEvent e) { 699 JmriJOptionPane.showMessageDialog(this, 700 new String[]{ 701 Bundle.getMessage("ConditionalHelpText1"), // NOI18N 702 Bundle.getMessage("ConditionalHelpText2"), // NOI18N 703 Bundle.getMessage("ConditionalHelpText3"), // NOI18N 704 Bundle.getMessage("ConditionalHelpText4"), // NOI18N 705 Bundle.getMessage("ConditionalHelpText5"), // NOI18N 706 Bundle.getMessage("ConditionalHelpText6"), // NOI18N 707 Bundle.getMessage("ConditionalHelpText7") // NOI18N 708 }, 709 Bundle.getMessage("MenuHelp"), 710 JmriJOptionPane.INFORMATION_MESSAGE); // NOI18N 711 } 712 713 /** 714 * Build the antecedent statement. 715 */ 716 void makeAntecedent() { 717 _antecedent = _parent.makeAntecedent(_variableList); 718 _antecedentField.setText(ConditionalEditBase.translateAntecedent(_antecedent, false)); 719 } 720 721 /** 722 * Add a R# to the antecedent statement. 723 */ 724 void appendToAntecedent() { 725 _antecedent = _parent.appendToAntecedent(_logicType, _variableList.size(), _antecedent); 726 _antecedentField.setText(ConditionalEditBase.translateAntecedent(_antecedent, false)); 727 } 728 729 /** 730 * Check the antecedent and logic type. 731 * 732 * @return false if antecedent can't be validated 733 */ 734 boolean validateAntecedent() { 735 return _parent.validateAntecedent(_logicType, _antecedentField.getText(), 736 _variableList, _parent._curConditional); 737 } 738 739 // ============ Shared Variable and Action Methods ============ 740 741 /** 742 * Check if an editing session is going on. 743 * <p> 744 * If it is, display a message to user and bring current editing pane to 745 * front. 746 * 747 * @return true if an _editActionFrame or _editVariableFrame exists 748 */ 749 boolean alreadyEditingActionOrVariable() { 750 if (_editActionFrame != null) { 751 if (!_dataChanged) { 752 cleanUpAction(); 753 return false; 754 } 755 JmriJOptionPane.showMessageDialog(_editActionFrame, 756 Bundle.getMessage("Error48"), 757 Bundle.getMessage("ErrorTitle"), // NOI18N 758 JmriJOptionPane.ERROR_MESSAGE); 759 _editActionFrame.setVisible(true); 760 _editActionFrame.toFront(); 761 return true; 762 } 763 if (_editVariableFrame != null) { 764 if (!_dataChanged) { 765 cleanUpVariable(); 766 return false; 767 } 768 JmriJOptionPane.showMessageDialog(_editVariableFrame, 769 Bundle.getMessage("Error47"), 770 Bundle.getMessage("ErrorTitle"), // NOI18N 771 JmriJOptionPane.ERROR_MESSAGE); 772 _editVariableFrame.setVisible(true); 773 _editVariableFrame.toFront(); 774 return true; 775 } 776 if (_parent._selectionMode == SelectionMode.USEMULTI) { 777 _parent.openPickListTable(); 778 } 779 return false; 780 } 781 782 /** 783 * Fetch valid localized appearances for a given Signal Head. 784 * <p> 785 * Warn if head is not found. 786 * 787 * @param box the comboBox on the setup pane to fill 788 * @param signalHeadName user or system name of the Signal Head 789 */ 790 void loadJComboBoxWithHeadAppearances(JComboBox<String> box, String signalHeadName) { 791 box.removeAllItems(); 792 log.debug("loadJComboBoxWithSignalHeadAppearances called with name: {}", signalHeadName); // NOI18N 793 SignalHead h = InstanceManager.getDefault(jmri.SignalHeadManager.class).getSignalHead(signalHeadName); 794 if (h == null) { 795 box.addItem(Bundle.getMessage("PromptLoadHeadName")); // NOI18N 796 } else { 797 String[] v = h.getValidStateNames(); 798 for (int i = 0; i < v.length; i++) { 799 box.addItem(v[i]); 800 } 801 box.setSelectedItem(h.getAppearanceName()); 802 } 803 } 804 805 /** 806 * Fetch valid aspects for a given Signal Mast. 807 * <p> 808 * Warn if mast is not found. 809 * 810 * @param box the comboBox on the setup pane to fill 811 * @param mastName user or system name of the Signal Mast 812 */ 813 void loadJComboBoxWithMastAspects(JComboBox<String> box, String mastName) { 814 box.removeAllItems(); 815 log.debug("loadJComboBoxWithMastAspects called with name: {}", mastName); // NOI18N 816 SignalMast m = InstanceManager.getDefault(jmri.SignalMastManager.class).getSignalMast(mastName); 817 if (m == null) { 818 box.addItem(Bundle.getMessage("PromptLoadMastName")); // NOI18N 819 } else { 820 java.util.Vector<String> v = m.getValidAspects(); 821 for (int i = 0; i < v.size(); i++) { 822 box.addItem(v.get(i)); 823 } 824 box.setSelectedItem(m.getAspect()); 825 } 826 } 827 828 // ------------ Build sub-panels ------------ 829 830 /** 831 * Create Variable and Action editing pane top part. 832 * 833 * @param frame JFrame to add to 834 * @param title property key for border title 835 * @param width fixed dimension to use 836 * @param height fixed dimension to use 837 * @return JPanel containing interface 838 */ 839 JPanel makeTopPanel(JFrame frame, String title, int width, int height) { 840 Container contentPane = frame.getContentPane(); 841 contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.X_AXIS)); 842 contentPane.add(Box.createRigidArea(new Dimension(0, height))); 843 JPanel topPanel = new JPanel(); 844 topPanel.setLayout(new BoxLayout(topPanel, BoxLayout.Y_AXIS)); 845 Border panelBorder = BorderFactory.createEtchedBorder(); 846 Border panelTitled = BorderFactory.createTitledBorder(panelBorder, Bundle.getMessage(title)); 847 topPanel.setBorder(panelTitled); 848 topPanel.add(Box.createRigidArea(new Dimension(width, 0))); 849 topPanel.add(Box.createVerticalGlue()); 850 return topPanel; 851 } 852 853 /** 854 * Create Variable and Action editing pane bottom part. 855 * <p> 856 * Called from {@link #makeEditVariableWindow(int)} 857 * 858 * @param updateListener listener for Update pressed 859 * @param cancelListener listener for Cancel pressed 860 * @param deleteListener listener for Delete pressed 861 * @return JPanel containing Update etc. buttons 862 */ 863 JPanel makeButtonPanel(ActionListener updateListener, 864 ActionListener cancelListener, 865 ActionListener deleteListener) { 866 JPanel panel3 = new JPanel(); 867 panel3.setLayout(new BoxLayout(panel3, BoxLayout.X_AXIS)); 868 869 JButton cancelAction = new JButton(Bundle.getMessage("ButtonCancel")); // NOI18N 870 panel3.add(cancelAction); 871 panel3.add(Box.createHorizontalStrut(STRUT)); 872 cancelAction.addActionListener(cancelListener); 873 cancelAction.setToolTipText(Bundle.getMessage("CancelButtonHint")); // NOI18N 874 875 JButton updateAction = new JButton(Bundle.getMessage("ButtonUpdate")); // NOI18N 876 panel3.add(updateAction); 877 panel3.add(Box.createHorizontalStrut(STRUT)); 878 updateAction.addActionListener(updateListener); 879 updateAction.setToolTipText(Bundle.getMessage("UpdateButtonHint")); // NOI18N 880 881 JButton deleteAction = new JButton(Bundle.getMessage("ButtonDelete")); // NOI18N 882 panel3.add(deleteAction); 883 deleteAction.addActionListener(deleteListener); 884 deleteAction.setToolTipText(Bundle.getMessage("DeleteButtonHint")); // NOI18N 885 return panel3; 886 } 887 888 // ============ Edit Variable Window and Methods ============ 889 890 /** 891 * Create and/or initialize the Edit a Variable pane. 892 * <p> 893 * Note: you can get here via the New Variable button (addVariablePressed) 894 * or via an Edit button in the Variable table of the EditConditional 895 * window. 896 * 897 * @param row index of item to be edited in _variableList 898 */ 899 void makeEditVariableWindow(int row) { 900 if (alreadyEditingActionOrVariable()) { 901 return; 902 } 903 log.debug("makeEditVariableWindow: row = {}", row); 904 _curVariableRowNumber = row; 905 _curVariable = _variableList.get(row); 906 _editVariableFrame = new JmriJFrame(Bundle.getMessage("TitleEditVariable"), true, true); // NOI18N 907 _editVariableFrame.addHelpMenu( 908 "package.jmri.jmrit.conditional.StateVariableActionList", true); // NOI18N 909 JPanel topPanel = makeTopPanel(_editVariableFrame, "TitleAntecedentPhrase", 500, 160); // NOI18N 910 911 Box panel1 = Box.createHorizontalBox(); 912 panel1.add(Box.createHorizontalGlue()); 913 panel1.add(Box.createHorizontalStrut(STRUT)); 914 915 // Item Type 916 _variableItemBox = new JComboBox<>(); 917 for (Conditional.ItemType itemType : Conditional.ItemType.getStateVarList()) { 918 _variableItemBox.addItem(itemType); 919 } 920 JComboBoxUtil.setupComboBoxMaxRows(_variableItemBox); 921 panel1.add(makeEditPanel(_variableItemBox, "LabelVariableType", "VariableTypeHint")); // NOI18N 922 panel1.add(Box.createHorizontalStrut(STRUT)); 923 924 // Item Name 925 _variableNameField = new JTextField(30); 926 _variableNamePanel = makeEditPanel(_variableNameField, "LabelItemName", null); // NOI18N 927 _variableNamePanel.setMaximumSize( 928 new Dimension(50, _variableNamePanel.getPreferredSize().height)); 929 _variableNamePanel.setVisible(false); 930 panel1.add(_variableNamePanel); 931 panel1.add(Box.createHorizontalStrut(STRUT)); 932 933 // Arbitrary name combo box to facilitate the panel construction 934 if (_parent._selectionMode == SelectionMode.USECOMBO) { 935 _comboNameBox = _parent.createNameBox(Conditional.ItemType.SENSOR); 936 _variableComboNamePanel = makeEditPanel(_comboNameBox, "LabelItemName", null); // NOI18N 937 _variableComboNamePanel.setVisible(false); 938 panel1.add(_variableComboNamePanel); 939 panel1.add(Box.createHorizontalStrut(STRUT)); 940 } 941 942 // Combo box section for selecting conditional reference 943 // First box selects the Logix, the second selects the conditional within the logix 944 _selectLogixBox.addItem("XXXXXXXXXXXXXXXXXXXXX"); // NOI18N 945 _selectConditionalBox.addItem("XXXXXXXXXXXXXXXXXXXXX"); // NOI18N 946 _selectLogixPanel = makeEditPanel(_selectLogixBox, "SelectLogix", null); // NOI18N 947 _selectConditionalPanel = makeEditPanel(_selectConditionalBox, "SelectConditional", null); // NOI18N 948 _selectLogixPanel.setVisible(false); 949 _selectConditionalPanel.setVisible(false); 950 panel1.add(_selectLogixPanel); 951 panel1.add(_selectConditionalPanel); 952 panel1.add(Box.createHorizontalStrut(STRUT)); 953 954 // State Box 955 _variableStateBox = new JComboBox<>(); 956 _variableStateBox.addItem(Conditional.Type.XXXXXXX); 957 _variableStatePanel = makeEditPanel(_variableStateBox, "LabelVariableState", "VariableStateHint"); // NOI18N 958 _variableStatePanel.setVisible(false); 959 panel1.add(_variableStatePanel); 960 panel1.add(Box.createHorizontalStrut(STRUT)); 961 962 // Aspects 963 _variableSignalBox = new JComboBox<String>(); 964 _variableSignalBox.addItem("XXXXXXXXX"); // NOI18N 965 _variableSignalPanel = makeEditPanel(_variableSignalBox, "LabelVariableAspect", "VariableAspectHint"); // NOI18N 966 _variableSignalPanel.setVisible(false); 967 panel1.add(_variableSignalPanel); 968 panel1.add(Box.createHorizontalStrut(STRUT)); 969 970 // Compare operator 971 _variableComparePanel = new JPanel(); 972 _variableComparePanel.setLayout(new BoxLayout(_variableComparePanel, BoxLayout.X_AXIS)); 973 _variableCompareOpBox = new JComboBox<String>(); 974 for (int i = 1; i <= ConditionalVariable.NUM_COMPARE_OPERATIONS; i++) { 975 _variableCompareOpBox.addItem(ConditionalVariable.getCompareOperationString(i)); 976 } 977 _variableComparePanel.add(makeEditPanel(_variableCompareOpBox, "LabelCompareOp", "CompareHintMemory")); // NOI18N 978 _variableComparePanel.add(Box.createHorizontalStrut(STRUT)); 979 980 // Compare type 981 _variableCompareTypeBox = new JComboBox<>(); 982 for (Conditional.Type t : Conditional.Type.getMemoryItems()) { 983 _variableCompareTypeBox.addItem(t); 984 } 985 _variableComparePanel.add(makeEditPanel(_variableCompareTypeBox, "LabelCompareType", "CompareTypeHint")); // NOI18N 986 _variableComparePanel.setVisible(false); 987 _variableCompareTypeBox.addActionListener(new ActionListener() { 988 @Override 989 public void actionPerformed(ActionEvent e) { 990 compareTypeChanged(_variableCompareTypeBox.getSelectedIndex()); 991 _editVariableFrame.pack(); 992 _dataChanged = true; 993 } 994 }); 995 panel1.add(_variableComparePanel); 996 panel1.add(Box.createHorizontalStrut(STRUT)); 997 998 // Data 1 999 _variableData1Field = new JTextField(30); 1000 _variableData1Panel = makeEditPanel(_variableData1Field, "LabelStartTime", "DataHintTime"); // NOI18N 1001 _variableData1Panel.setMaximumSize( 1002 new Dimension(45, _variableData1Panel.getPreferredSize().height)); 1003 _variableData1Panel.setVisible(false); 1004 panel1.add(_variableData1Panel); 1005 panel1.add(Box.createHorizontalStrut(STRUT)); 1006 1007 // Data 2 1008 _variableData2Field = new JTextField(30); 1009 _variableData2Panel = makeEditPanel(_variableData2Field, "LabelEndTime", "DataHintTime"); // NOI18N 1010 _variableData2Panel.setMaximumSize( 1011 new Dimension(45, _variableData2Panel.getPreferredSize().height)); 1012 _variableData2Panel.setVisible(false); 1013 panel1.add(_variableData2Panel); 1014 panel1.add(Box.createHorizontalStrut(STRUT)); 1015 panel1.add(Box.createHorizontalGlue()); 1016 topPanel.add(panel1); 1017 1018 ActionListener updateListener = new ActionListener() { 1019 @Override 1020 public void actionPerformed(ActionEvent e) { 1021 updateVariablePressed(); 1022 } 1023 }; 1024 ActionListener cancelListener = new ActionListener() { 1025 @Override 1026 public void actionPerformed(ActionEvent e) { 1027 cancelEditVariablePressed(); 1028 } 1029 }; 1030 ActionListener deleteListener = new ActionListener() { 1031 @Override 1032 public void actionPerformed(ActionEvent e) { 1033 deleteVariablePressed(); 1034 } 1035 }; 1036 JPanel panel = makeButtonPanel(updateListener, cancelListener, deleteListener); 1037 topPanel.add(panel); 1038 topPanel.add(Box.createVerticalGlue()); 1039 1040 Container contentPane = _editVariableFrame.getContentPane(); 1041 contentPane.add(topPanel); 1042 1043 _variableItemBox.addActionListener(new ActionListener() { 1044 @Override 1045 public void actionPerformed(ActionEvent e) { 1046 Conditional.ItemType newVariableItem = _variableItemBox.getItemAt(_variableItemBox.getSelectedIndex()); 1047 if (log.isDebugEnabled()) { 1048 log.debug("_variableItemBox Listener: new = {}, curr = {}, row = {}", // NOI18N 1049 newVariableItem, _curVariableItem, _curVariableRowNumber); 1050 } 1051 if (newVariableItem != _curVariableItem) { 1052 if (_curVariableRowNumber >= 0) { 1053 _curVariable = new ConditionalVariable(); 1054 if (_curVariableRowNumber > 0) { 1055 if (_logicType == Conditional.AntecedentOperator.ALL_OR) { 1056 _curVariable.setOpern(Conditional.Operator.OR); 1057 } else { 1058 _curVariable.setOpern(Conditional.Operator.AND); 1059 } 1060 } 1061 _variableList.set(_curVariableRowNumber, _curVariable); 1062 } 1063 _curVariableItem = newVariableItem; 1064 } 1065 _dataChanged = true; 1066 variableItemChanged(newVariableItem); 1067 _editVariableFrame.pack(); 1068 } 1069 }); 1070 // setup window closing listener 1071 _editVariableFrame.addWindowListener( 1072 new java.awt.event.WindowAdapter() { 1073 @Override 1074 public void windowClosing(java.awt.event.WindowEvent e) { 1075 cancelEditVariablePressed(); 1076 } 1077 }); 1078 _curVariableItem = _curVariable.getType().getItemType(); 1079 initializeStateVariables(); 1080 _dataChanged = false; 1081 _editVariableFrame.pack(); 1082 _editVariableFrame.setVisible(true); 1083 } 1084 1085 // ------------ Main Variable methods ------------ 1086 1087 /** 1088 * Set display to show current state variable (_curVariable) parameters. 1089 */ 1090 void initializeStateVariables() { 1091 Conditional.Type testType = _curVariable.getType(); 1092 Conditional.ItemType itemType = testType.getItemType(); 1093 if (log.isDebugEnabled()) { 1094 log.debug("initializeStateVariables: itemType = {}, testType = {}", itemType, testType); // NOI18N 1095 } 1096 if (testType == Conditional.Type.NONE) { 1097 return; 1098 } 1099 // set item - _variableItemBox Listener will call variableItemChanged 1100 _variableItemBox.setSelectedItem(itemType); 1101 switch (itemType) { 1102 case SENSOR: 1103 case TURNOUT: 1104 case LIGHT: 1105 case CONDITIONAL: 1106 case WARRANT: 1107 _variableStateBox.setSelectedItem(testType); 1108 _variableNameField.setText(_curVariable.getName()); 1109 break; 1110 1111 case SIGNALHEAD: 1112 _variableStateBox.setSelectedItem(testType); 1113 _variableNameField.setText(_curVariable.getName()); 1114 if (Conditional.Type.isSignalHeadApperance(testType)) { 1115 _variableStateBox.setSelectedItem(Conditional.Type.SIGNAL_HEAD_APPEARANCE_EQUALS); 1116 loadJComboBoxWithHeadAppearances(_variableSignalBox, _curVariable.getName()); 1117 _variableSignalBox.setSelectedItem(_curVariable.getType()); 1118 _variableSignalPanel.setVisible(true); 1119 } 1120 break; 1121 1122 case SIGNALMAST: 1123 // set display to show current state variable (curVariable) parameters 1124 _variableStateBox.setSelectedItem(testType); 1125 _variableNameField.setText(_curVariable.getName()); 1126 if (testType == Conditional.Type.SIGNAL_MAST_ASPECT_EQUALS) { 1127 loadJComboBoxWithMastAspects(_variableSignalBox, _curVariable.getName()); 1128 _variableSignalBox.setSelectedItem(_curVariable.getDataString()); 1129 _variableSignalPanel.setVisible(true); 1130 } 1131 break; 1132 1133 case MEMORY: 1134 _variableCompareTypeBox.setSelectedIndex( 1135 Conditional.Type.getIndexInList(Conditional.Type.getMemoryItems(), testType)); 1136 _variableNameField.setText(_curVariable.getName()); 1137 int num1 = _curVariable.getNum1() - 1; 1138 if (num1 == -1) { // former code was only equals 1139 num1 = ConditionalVariable.EQUAL - 1; 1140 } 1141 _variableCompareOpBox.setSelectedIndex(num1); 1142 _variableData1Field.setText(_curVariable.getDataString()); 1143 break; 1144 1145 case CLOCK: 1146 int time = _curVariable.getNum1(); 1147 _variableData1Field.setText(ConditionalEditBase.formatTime(time / 60, time - ((time / 60) * 60))); 1148 time = _curVariable.getNum2(); 1149 _variableData2Field.setText(ConditionalEditBase.formatTime(time / 60, time - ((time / 60) * 60))); 1150 _variableNameField.setText(""); 1151 break; 1152 1153 case OBLOCK: 1154 _variableNameField.setText(_curVariable.getName()); 1155 //_variableStateBox.removeAllItems(); 1156 for (Conditional.Type type : Conditional.Type.getOBlockItems()) { 1157 _variableStateBox.addItem(type); 1158 if (type.toString().equals(OBlock.getLocalStatusName(_curVariable.getDataString()))) { 1159 _variableStateBox.setSelectedItem(type); 1160 } 1161 } 1162// Iterator<String> names = OBlock.getLocalStatusNames(); 1163// while (names.hasNext()) { 1164// _variableStateBox.addItem(names.next()); 1165// } 1166// _variableStateBox.setSelectedItem(OBlock.getLocalStatusName(_curVariable.getDataString())); 1167 _variableStateBox.setVisible(true); 1168 break; 1169 1170 case ENTRYEXIT: 1171 _variableNameField.setText(_curVariable.getBean().getUserName()); 1172 _variableStateBox.setSelectedItem(testType); 1173 _variableStateBox.setVisible(true); 1174 break; 1175 1176 default: 1177 break; 1178 } 1179 _editVariableFrame.pack(); 1180 _editVariableFrame.transferFocusBackward(); 1181 } 1182 1183 /** 1184 * Respond to change in variable item chosen in the State Variable Table in 1185 * the Edit Conditional pane. 1186 * <p> 1187 * Also used to set up for Edit of a Conditional with state variables. 1188 * 1189 * @param itemType value representing the newly selected Conditional type, 1190 * i.e. ITEM_TYPE_SENSOR 1191 */ 1192 private void variableItemChanged(Conditional.ItemType itemType) { 1193 Conditional.Type testType = _curVariable.getType(); 1194 if (log.isDebugEnabled()) { 1195 log.debug("variableItemChanged: itemType = {}, testType = {}", itemType, testType); // NOI18N 1196 } 1197 _variableNamePanel.setVisible(false); 1198 _variableStatePanel.setVisible(false); 1199 _variableComparePanel.setVisible(false); 1200 _variableSignalPanel.setVisible(false); 1201 _variableData1Panel.setVisible(false); 1202 _variableData2Panel.setVisible(false); 1203 _selectLogixPanel.setVisible(false); 1204 _selectConditionalPanel.setVisible(false); 1205 _variableStateBox.removeAllItems(); 1206 _variableNameField.removeActionListener(variableSignalHeadNameListener); 1207 _variableNameField.removeActionListener(variableSignalMastNameListener); 1208 _variableStateBox.removeActionListener(variableSignalTestStateListener); 1209 _selectLogixBox.removeActionListener(selectLogixBoxListener); 1210 _selectConditionalBox.removeActionListener(selectConditionalBoxListener); 1211 1212 if (_parent._selectionMode == SelectionMode.USECOMBO) { 1213 _variableComboNamePanel.setVisible(false); 1214 } else if (_parent._selectionMode == SelectionMode.USESINGLE) { 1215 _parent.createSinglePanelPickList(itemType, _parent.getPickSingleListener(_variableNameField, itemType), false); 1216 } else { 1217 // Default and USEMULTI 1218 _parent.setPickListTab(itemType, false); 1219 } 1220 1221 switch (itemType) { 1222 case NONE: 1223 return; 1224 case SENSOR: 1225 _variableNamePanel.setToolTipText(Bundle.getMessage("NameHintSensor")); // NOI18N 1226 for (Conditional.Type type : Conditional.Type.getSensorItems()) { 1227 _variableStateBox.addItem(type); 1228 } 1229 _variableStatePanel.setVisible(true); 1230 _variableNamePanel.setVisible(true); 1231 setVariableNameBox(itemType); 1232 break; 1233 1234 case TURNOUT: 1235 _variableNamePanel.setToolTipText(Bundle.getMessage("NameHintTurnout")); // NOI18N 1236 for (Conditional.Type type : Conditional.Type.getTurnoutItems()) { 1237 _variableStateBox.addItem(type); 1238 } 1239 _variableNamePanel.setVisible(true); 1240 _variableStatePanel.setVisible(true); 1241 setVariableNameBox(itemType); 1242 break; 1243 1244 case LIGHT: 1245 _variableNamePanel.setToolTipText(Bundle.getMessage("NameHintLight")); // NOI18N 1246 for (Conditional.Type type : Conditional.Type.getLightItems()) { 1247 _variableStateBox.addItem(type); 1248 } 1249 _variableStatePanel.setVisible(true); 1250 _variableNamePanel.setVisible(true); 1251 setVariableNameBox(itemType); 1252 break; 1253 1254 case SIGNALHEAD: 1255 _variableStateBox.addActionListener(variableSignalTestStateListener); 1256 loadJComboBoxWithHeadAppearances(_variableSignalBox, _variableNameField.getText().trim()); 1257 1258 for (Conditional.Type type : Conditional.Type.getSignalHeadStateMachineItems()) { 1259 _variableStateBox.addItem(type); 1260 } 1261 _variableNamePanel.setToolTipText(Bundle.getMessage("NameHintSignal")); // NOI18N 1262 _variableNamePanel.setVisible(true); 1263 _variableStatePanel.setVisible(true); 1264 if (testType == Conditional.Type.SIGNAL_HEAD_APPEARANCE_EQUALS) { 1265 _variableSignalPanel.setVisible(true); 1266 } else { 1267 _variableSignalPanel.setVisible(false); 1268 } 1269 setVariableNameBox(itemType); 1270 _variableNameField.addActionListener(variableSignalHeadNameListener); 1271 break; 1272 1273 case SIGNALMAST: 1274 _variableStateBox.addActionListener(variableSignalTestStateListener); 1275 loadJComboBoxWithMastAspects(_variableSignalBox, _variableNameField.getText().trim()); 1276 1277 for (Conditional.Type type : Conditional.Type.getSignalMastItems()) { 1278 _variableStateBox.addItem(type); 1279 } 1280 _variableNamePanel.setToolTipText(Bundle.getMessage("NameHintSignalMast")); // NOI18N 1281 _variableNamePanel.setVisible(true); 1282 _variableStatePanel.setVisible(true); 1283 if (testType == Conditional.Type.SIGNAL_MAST_ASPECT_EQUALS) { 1284 _variableSignalPanel.setVisible(true); 1285 } else { 1286 _variableSignalPanel.setVisible(false); 1287 } 1288 setVariableNameBox(itemType); 1289 _variableNameField.addActionListener(variableSignalMastNameListener); 1290 break; 1291 1292 case MEMORY: 1293 JPanel p = (JPanel) _variableData1Panel.getComponent(0); 1294 JLabel l = (JLabel) p.getComponent(0); 1295 if ((testType == Conditional.Type.MEMORY_COMPARE) 1296 || (testType == Conditional.Type.MEMORY_COMPARE_INSENSITIVE)) { 1297 l.setText(Bundle.getMessage("LabelMemoryValue")); // NOI18N 1298 _variableData1Panel.setToolTipText(Bundle.getMessage("DataHintMemory")); // NOI18N 1299 } else { 1300 l.setText(Bundle.getMessage("LabelLiteralValue")); // NOI18N 1301 _variableData1Panel.setToolTipText(Bundle.getMessage("DataHintValue")); // NOI18N 1302 } 1303 _variableNamePanel.setToolTipText(Bundle.getMessage("NameHintMemory")); // NOI18N 1304 _variableNamePanel.setVisible(true); 1305 _variableData1Panel.setToolTipText(Bundle.getMessage("DataHintMemory")); // NOI18N 1306 _variableData1Panel.setVisible(true); 1307 _variableComparePanel.setVisible(true); 1308 setVariableNameBox(itemType); 1309 break; 1310 1311 case CONDITIONAL: 1312 _variableNamePanel.setToolTipText(Bundle.getMessage("NameHintConditional")); // NOI18N 1313 for (Conditional.Type type : Conditional.Type.getConditionalItems()) { 1314 _variableStateBox.addItem(type); 1315 } 1316 // Load the Logix and Conditional combo boxes 1317 loadSelectLogixBox(_curVariable); 1318 _selectLogixPanel.setPreferredSize(_selectLogixBox.getPreferredSize()); 1319 _selectConditionalPanel.setPreferredSize(_selectConditionalBox.getPreferredSize()); 1320 _selectLogixPanel.setVisible(true); 1321 _selectConditionalPanel.setVisible(true); 1322 _variableStatePanel.setVisible(true); 1323 _selectLogixBox.addActionListener(selectLogixBoxListener); 1324 _selectConditionalBox.addActionListener(selectConditionalBoxListener); 1325 break; 1326 1327 case WARRANT: 1328 _variableNamePanel.setToolTipText(Bundle.getMessage("NameHintWarrant")); // NOI18N 1329 for (Conditional.Type type : Conditional.Type.getWarrantItems()) { 1330 _variableStateBox.addItem(type); 1331 } 1332 _variableNamePanel.setVisible(true); 1333 _variableStatePanel.setVisible(true); 1334 setVariableNameBox(itemType); 1335 break; 1336 1337 case CLOCK: 1338 p = (JPanel) _variableData1Panel.getComponent(0); 1339 l = (JLabel) p.getComponent(0); 1340 l.setText(Bundle.getMessage("LabelStartTime")); // NOI18N 1341 _variableData1Panel.setToolTipText(Bundle.getMessage("DataHintTime")); // NOI18N 1342 _variableData1Panel.setVisible(true); 1343 _variableData2Panel.setVisible(true); 1344 break; 1345 1346 case OBLOCK: 1347 _variableNamePanel.setToolTipText(Bundle.getMessage("NameHintOBlock")); // NOI18N 1348 _variableNamePanel.setVisible(true); 1349 _variableStateBox.removeAllItems(); 1350 for (Conditional.Type type : Conditional.Type.getOBlockItems()) { 1351 _variableStateBox.addItem(type); 1352 } 1353// Iterator<String> names = OBlock.getLocalStatusNames(); 1354// while (names.hasNext()) { 1355// _variableStateBox.addItem(names.next()); 1356// } 1357 _variableStatePanel.setVisible(true); 1358 setVariableNameBox(itemType); 1359 break; 1360 1361 case ENTRYEXIT: 1362 _variableNamePanel.setToolTipText(Bundle.getMessage("NameHintEntryExit")); // NOI18N 1363 _variableNameField.setText(_curVariable.getName()); 1364 for (Conditional.Type type : Conditional.Type.getEntryExitItems()) { 1365 _variableStateBox.addItem(type); 1366 } 1367 _variableStatePanel.setVisible(true); 1368 _variableNamePanel.setVisible(true); 1369 setVariableNameBox(itemType); 1370 break; 1371 1372 default: 1373 break; 1374 } 1375 _variableStateBox.setMaximumSize(_variableStateBox.getPreferredSize()); 1376 } 1377 1378 /** 1379 * Update the name combo box selection based on the current contents of the 1380 * name field. 1381 * 1382 * @since 4.7.3 1383 * @param itemType The type of name box to be created. 1384 */ 1385 void setVariableNameBox(Conditional.ItemType itemType) { 1386 if (_parent._selectionMode != SelectionMode.USECOMBO) { 1387 return; 1388 } 1389 _comboNameBox = _parent.createNameBox(itemType); 1390 if (_comboNameBox == null) { 1391 return; 1392 } 1393 _comboNameBox.setSelectedItemByName(_curVariable.getName()); 1394 _comboNameBox.addActionListener(new NameBoxListener(_variableNameField)); 1395 _variableComboNamePanel.remove(1); 1396 _variableComboNamePanel.add(_comboNameBox, null, 1); 1397 _variableNamePanel.setVisible(false); 1398 _variableComboNamePanel.setVisible(true); 1399 } 1400 1401 // ------------ Variable detail methods ------------ 1402 1403 /** 1404 * Respond to Update Variable button in the Edit Action pane. 1405 */ 1406 void updateVariablePressed() { 1407 if (!validateVariable()) { 1408 _editVariableFrame.toFront(); 1409 return; 1410 } 1411 _variableTableModel.fireTableRowsUpdated(_curVariableRowNumber, _curVariableRowNumber); 1412 cleanUpVariable(); 1413 } 1414 1415 /** 1416 * Respond to Cancel action button and window closer of the Edit Variable 1417 * pane. 1418 * <p> 1419 * Also does cleanup of Update and Delete Variable buttons. 1420 */ 1421 void cancelEditVariablePressed() { 1422 if (_newItem) { 1423 deleteVariablePressed(_curVariableRowNumber); 1424 } else { 1425 cleanUpVariable(); 1426 } 1427 } 1428 1429 /** 1430 * Clean up Update and Delete Variable buttons. 1431 */ 1432 void cleanUpVariable() { 1433 _newItem = false; 1434 if (_editVariableFrame != null) { 1435 _editVariableFrame.setVisible(false); 1436 _editVariableFrame.dispose(); 1437 _editVariableFrame = null; 1438 _parent.closeSinglePanelPickList(); 1439 } 1440 _curVariableRowNumber = -1; 1441 } 1442 1443 /** 1444 * Respond to Delete action button in the Edit Variable window. 1445 */ 1446 void deleteVariablePressed() { 1447 deleteVariablePressed(_curVariableRowNumber); 1448 } 1449 1450 /** 1451 * Respond to the Delete Button in the State Variable Table of the Edit 1452 * Conditional window. 1453 * 1454 * @param row index in table of variable to be deleted 1455 */ 1456 void deleteVariablePressed(int row) { 1457 if (row != _curVariableRowNumber && alreadyEditingActionOrVariable()) { 1458 return; 1459 } 1460 if (_variableList.size() < 1 && !_parent._suppressReminder) { 1461 // warning message - last State Variable deleted 1462 JmriJOptionPane.showMessageDialog(this, 1463 Bundle.getMessage("Warn3"), 1464 Bundle.getMessage("WarningTitle"), // NOI18N 1465 JmriJOptionPane.WARNING_MESSAGE); 1466 } 1467 // move remaining state variables if needed 1468 _variableList.remove(row); 1469 _variableTableModel.fireTableRowsDeleted(row, row); 1470 _dataChanged = true; 1471 makeAntecedent(); 1472 cleanUpVariable(); 1473 } 1474 1475 /** 1476 * Check if Memory type in a Conditional was changed by the user. 1477 * <p> 1478 * Update GUI if it has. Called from {@link #makeEditVariableWindow(int)} 1479 * 1480 * @param selection index of the currently selected type in the 1481 * _variableCompareTypeBox 1482 */ 1483 private void compareTypeChanged(int selection) { 1484 JPanel p = (JPanel) _variableData1Panel.getComponent(0); 1485 JLabel l = (JLabel) p.getComponent(0); 1486 Conditional.Type testType = Conditional.Type.getMemoryItems().get(selection); 1487 if ((testType == Conditional.Type.MEMORY_COMPARE) 1488 || (testType == Conditional.Type.MEMORY_COMPARE_INSENSITIVE)) { 1489 l.setText(Bundle.getMessage("LabelMemoryValue")); // NOI18N 1490 _variableData1Panel.setToolTipText(Bundle.getMessage("DataHintMemory")); // NOI18N 1491 } else { 1492 l.setText(Bundle.getMessage("LabelLiteralValue")); // NOI18N 1493 _variableData1Panel.setToolTipText(Bundle.getMessage("DataHintValue")); // NOI18N 1494 } 1495 } 1496 1497 1498 // ------------ Variable update processes ------------ 1499 1500 /** 1501 * Validate Variable data from Edit Variable Window, and transfer it to 1502 * current action object as appropriate. 1503 * <p> 1504 * Messages are sent to the user for any errors found. This routine returns 1505 * false immediately after finding the first error, even if there might be 1506 * more errors. 1507 * 1508 * @return true if all data checks out OK, otherwise false 1509 */ 1510 boolean validateVariable() { 1511 String name = _variableNameField.getText().trim(); 1512 _variableNameField.setText(name); 1513 _curVariable.setDataString(""); 1514 _curVariable.setNum1(0); 1515 _curVariable.setNum2(0); 1516 Conditional.ItemType itemType = _variableItemBox.getItemAt(_variableItemBox.getSelectedIndex()); 1517 Conditional.Type testType = Conditional.Type.NONE; 1518 if (!checkIsAction(name, itemType) ) { 1519 return false; 1520 } 1521 _dataChanged = true; 1522 switch (itemType) { 1523 case SENSOR: 1524 case TURNOUT: 1525 case LIGHT: 1526 case SIGNALHEAD: 1527 case SIGNALMAST: 1528 case CONDITIONAL: 1529 case WARRANT: 1530 case ENTRYEXIT: 1531 testType = _variableStateBox.getItemAt(_variableStateBox.getSelectedIndex()); 1532 break; 1533 case MEMORY: 1534 testType = _variableCompareTypeBox.getItemAt(_variableCompareTypeBox.getSelectedIndex()); 1535 break; 1536 case CLOCK: 1537 testType = Conditional.Type.FAST_CLOCK_RANGE; 1538 break; 1539 case OBLOCK: 1540 testType = Conditional.Type.BLOCK_STATUS_EQUALS; 1541 break; 1542 default: 1543 JmriJOptionPane.showMessageDialog(this, 1544 Bundle.getMessage("ErrorVariableType"), 1545 Bundle.getMessage("ErrorTitle"), // NOI18N 1546 JmriJOptionPane.ERROR_MESSAGE); 1547 return false; 1548 } 1549 _curVariable.setType(testType); 1550 log.debug("validateVariable: itemType= {}, testType= {}", itemType, testType); // NOI18N 1551 switch (itemType) { 1552 case SENSOR: 1553 name = _parent.validateSensorReference(name); 1554 if (name == null) { 1555 return false; 1556 } 1557 break; 1558 case TURNOUT: 1559 name = _parent.validateTurnoutReference(name); 1560 if (name == null) { 1561 return false; 1562 } 1563 break; 1564 case CONDITIONAL: 1565 name = _parent.validateConditionalReference(name); 1566 if (name == null) { 1567 return false; 1568 } 1569 _curVariable.setName(name); 1570 Conditional c = _parent._conditionalManager.getBySystemName(name); 1571 if (c == null) { 1572 return false; 1573 } 1574 String uName = c.getUserName(); 1575 if (uName == null || uName.isEmpty()) { 1576 _curVariable.setGuiName(c.getSystemName()); 1577 } else { 1578 _curVariable.setGuiName(uName); 1579 } 1580 break; 1581 case LIGHT: 1582 name = _parent.validateLightReference(name); 1583 if (name == null) { 1584 return false; 1585 } 1586 break; 1587 case MEMORY: 1588 name = _parent.validateMemoryReference(name); 1589 if (name == null) { 1590 return false; 1591 } 1592 String name2 = _variableData1Field.getText(); 1593 if ((testType == Conditional.Type.MEMORY_COMPARE) 1594 || (testType == Conditional.Type.MEMORY_COMPARE_INSENSITIVE)) { 1595 name2 = _parent.validateMemoryReference(name2); 1596 if (name2 == null) { 1597 return false; 1598 } 1599 } 1600 _curVariable.setDataString(name2); 1601 _curVariable.setNum1(_variableCompareOpBox.getSelectedIndex() + 1); 1602 break; 1603 case CLOCK: 1604 int beginTime = _parent.parseTime(_variableData1Field.getText()); 1605 if (beginTime < 0) { 1606 // parse error occurred - message has been sent 1607 return (false); 1608 } 1609 int endTime = _parent.parseTime(_variableData2Field.getText()); 1610 if (endTime < 0) { 1611 return (false); 1612 } 1613 // set beginning and end time (minutes since midnight) 1614 _curVariable.setNum1(beginTime); 1615 _curVariable.setNum2(endTime); 1616 name = "Clock"; // NOI18N 1617 break; 1618 case SIGNALHEAD: 1619 name = _parent.validateSignalHeadReference(name); 1620 if (name == null) { 1621 return false; 1622 } 1623 if (testType == Conditional.Type.SIGNAL_HEAD_APPEARANCE_EQUALS) { 1624 String appStr = (String) _variableSignalBox.getSelectedItem(); 1625 Conditional.Type type = ConditionalVariable.stringToVariableTest(appStr); 1626 if (type == Conditional.Type.ERROR) { 1627 JmriJOptionPane.showMessageDialog(this, 1628 Bundle.getMessage("ErrorAppearance"), 1629 Bundle.getMessage("ErrorTitle"), // NOI18N 1630 JmriJOptionPane.ERROR_MESSAGE); 1631 return false; 1632 } 1633 _curVariable.setType(type); 1634 _curVariable.setDataString(appStr); 1635 log.debug("SignalHead \"{}\" of type '{}' _variableSignalBox.getSelectedItem()= {}", 1636 name, testType, _variableSignalBox.getSelectedItem()); // NOI18N 1637 } 1638 break; 1639 case SIGNALMAST: 1640 name = _parent.validateSignalMastReference(name); 1641 if (name == null) { 1642 return false; 1643 } 1644 if (testType == Conditional.Type.SIGNAL_MAST_ASPECT_EQUALS) { 1645 if (_variableSignalBox.getSelectedIndex() < 0) { 1646 JmriJOptionPane.showMessageDialog(this, 1647 Bundle.getMessage("ErrorAspect"), 1648 Bundle.getMessage("ErrorTitle"), // NOI18N 1649 JmriJOptionPane.ERROR_MESSAGE); 1650 return false; 1651 } 1652 // save the selected aspect for comparison 1653 _curVariable.setDataString((String) _variableSignalBox.getSelectedItem()); 1654 // _curVariable.setType(ConditionalVariable.stringToVariableTest(appStr)); 1655 } 1656 break; 1657 case WARRANT: 1658 name = _parent.validateWarrantReference(name); 1659 if (name == null) { 1660 return false; 1661 } 1662 break; 1663 case OBLOCK: 1664 name = _parent.validateOBlockReference(name); 1665 if (name == null) { 1666 return false; 1667 } 1668 String str = _variableStateBox.getSelectedItem().toString(); 1669 _curVariable.setDataString(OBlock.getSystemStatusName(str)); 1670 log.debug("OBlock \"{}\" of type '{}' _variableStateBox.getSelectedItem()= {}", 1671 name, testType, _variableStateBox.getSelectedItem()); // NOI18N 1672 break; 1673 case ENTRYEXIT: 1674 name = _parent.validateEntryExitReference(name); 1675 if (name == null) { 1676 return false; 1677 } 1678 break; 1679 default: 1680 JmriJOptionPane.showMessageDialog(this, 1681 Bundle.getMessage("ErrorVariableType"), 1682 Bundle.getMessage("ErrorTitle"), // NOI18N 1683 JmriJOptionPane.ERROR_MESSAGE); 1684 return false; 1685 } 1686 _curVariable.setName(name); 1687 boolean result = _curVariable.evaluate(); 1688 log.debug("State Variable \"{}\" of type '{}' state= {} type= {}", // NOI18N 1689 name, testType.getTestTypeString(), result, _curVariable.getType()); 1690 if (_curVariable.getType() == Conditional.Type.NONE) { 1691 JmriJOptionPane.showMessageDialog(this, 1692 Bundle.getMessage("ErrorVariableState"), 1693 Bundle.getMessage("ErrorTitle"), // NOI18N 1694 JmriJOptionPane.ERROR_MESSAGE); 1695 return false; 1696 } 1697 return (true); 1698 } 1699 1700 // ------------ Variable detail listeners ------------ 1701 1702 transient ActionListener variableSignalTestStateListener = new ActionListener() { 1703 @Override 1704 public void actionPerformed(ActionEvent e) { 1705 log.debug("variableSignalTestStateListener fires; _variableItemBox.getSelectedIndex()= \"{}\" _variableStateBox.getSelectedIndex()= \"{}\"", // NOI18N 1706 _variableItemBox.getSelectedIndex(), _variableStateBox.getSelectedIndex()); 1707 1708 Conditional.ItemType itemType = _variableItemBox.getItemAt(_variableItemBox.getSelectedIndex()); 1709 1710 if (_variableStateBox.getSelectedIndex() == 1) { 1711 if (itemType == Conditional.ItemType.SIGNALHEAD) { 1712 loadJComboBoxWithHeadAppearances(_variableSignalBox, _variableNameField.getText().trim()); 1713 _variableSignalPanel.setVisible(true); 1714 } else if (itemType == Conditional.ItemType.SIGNALMAST) { 1715 loadJComboBoxWithMastAspects(_variableSignalBox, _variableNameField.getText().trim()); 1716 _variableSignalPanel.setVisible(true); 1717 } else { 1718 _variableSignalPanel.setVisible(false); 1719 } 1720 } else { 1721 _variableSignalPanel.setVisible(false); 1722 } 1723 1724 _variableSignalBox.setMaximumSize(_variableSignalBox.getPreferredSize()); 1725 if (_editVariableFrame != null) { 1726 _editVariableFrame.pack(); 1727 } 1728 _dataChanged = true; 1729 } 1730 }; 1731 1732 transient ActionListener variableSignalHeadNameListener = new ActionListener() { 1733 @Override 1734 public void actionPerformed(ActionEvent e) { 1735 // fired when signal head name changes, but only 1736 // while in signal head mode 1737 log.debug("variableSignalHeadNameListener fires; _variableNameField: {}", _variableNameField.getText().trim()); 1738 loadJComboBoxWithHeadAppearances(_variableSignalBox, _variableNameField.getText().trim()); 1739 _dataChanged = true; 1740 } 1741 }; 1742 1743 transient ActionListener variableSignalMastNameListener = new ActionListener() { 1744 @Override 1745 public void actionPerformed(ActionEvent e) { 1746 // fired when signal mast name changes, but only 1747 // while in signal mast mode 1748 log.debug("variableSignalMastNameListener fires; _variableNameField: {}", _variableNameField.getText().trim()); // NOI18N 1749 loadJComboBoxWithMastAspects(_variableSignalBox, _variableNameField.getText().trim()); 1750 _dataChanged = true; 1751 } 1752 }; 1753 1754 transient ActionListener selectLogixBoxListener = new ActionListener() { 1755 @Override 1756 public void actionPerformed(ActionEvent e) { 1757 String lgxItem = (String) _selectLogixBox.getSelectedItem(); 1758 if (lgxItem != null) { 1759 String lgxName = _selectLogixMap.get(lgxItem); 1760 if (lgxName != null) { 1761 loadSelectConditionalBox(lgxName, _curVariable); 1762 } 1763 } 1764 _dataChanged = true; 1765 } 1766 }; 1767 1768 transient ActionListener selectConditionalBoxListener = new ActionListener() { 1769 @Override 1770 public void actionPerformed(ActionEvent e) { 1771 int cdlIndex = _selectConditionalBox.getSelectedIndex(); 1772 if (cdlIndex > 0 && cdlIndex < _selectConditionalList.size()) { 1773 String cdlName = _selectConditionalList.get(cdlIndex); 1774 _variableNameField.setText(cdlName); 1775 } 1776 _dataChanged = true; 1777 } 1778 }; 1779 1780 // ============ Edit Action Window and Methods ============ 1781 1782 /** 1783 * Create and/or initialize the Edit Action window. 1784 * <p> 1785 * Note: you can get here via the New Action button (addActionPressed) or 1786 * via an Edit button in the Action table of the EditConditional window. 1787 * 1788 * @param row index in the table of the Action to be edited 1789 */ 1790 void makeEditActionWindow(int row) { 1791 if (alreadyEditingActionOrVariable()) { 1792 return; 1793 } 1794 log.debug("makeEditActionWindow: row = {}", row); 1795 _curActionRowNumber = row; 1796 _curAction = _actionList.get(row); 1797 _editActionFrame = new JmriJFrame(Bundle.getMessage("TitleEditAction"), true, true); // NOI18N 1798 _editActionFrame.addHelpMenu( 1799 "package.jmri.jmrit.conditional.StateVariableActionList", true); // NOI18N 1800 JPanel topPanel = makeTopPanel(_editActionFrame, "TitleConsequentPhrase", 600, 160); // NOI18N 1801 1802 Box panel1 = Box.createHorizontalBox(); 1803 panel1.add(Box.createHorizontalGlue()); 1804 1805 _actionItemBox = new JComboBox<>(); 1806 for (Conditional.ItemType itemType : Conditional.ItemType.values()) { 1807 _actionItemBox.addItem(itemType); 1808 } 1809 JComboBoxUtil.setupComboBoxMaxRows(_actionItemBox); 1810 panel1.add(makeEditPanel(_actionItemBox, "LabelActionItem", "ActionItemHint")); // NOI18N 1811 panel1.add(Box.createHorizontalStrut(STRUT)); 1812 1813 _actionNameField = new JTextField(30); 1814 _actionNamePanel = makeEditPanel(_actionNameField, "LabelItemName", null); // NOI18N 1815 _actionNamePanel.setMaximumSize( 1816 new Dimension(50, _actionNamePanel.getPreferredSize().height)); 1817 _actionNamePanel.setVisible(false); 1818 panel1.add(_actionNamePanel); 1819 panel1.add(Box.createHorizontalStrut(STRUT)); 1820 1821 // Arbitrary name combo box to facilitate the panel construction 1822 if (_parent._selectionMode == SelectionMode.USECOMBO) { 1823 _comboNameBox = _parent.createNameBox(Conditional.ItemType.SENSOR); 1824 _actionComboNamePanel = makeEditPanel(_comboNameBox, "LabelItemName", null); // NOI18N 1825 _actionComboNamePanel.setVisible(false); 1826 panel1.add(_actionComboNamePanel); 1827 panel1.add(Box.createHorizontalStrut(STRUT)); 1828 } 1829 1830 _actionTypeBox = new JComboBox<>(); 1831 JComboBoxUtil.setupComboBoxMaxRows(_actionTypeBox); 1832 _actionTypeBox.addItem(Conditional.Action.NONE); 1833 _actionTypePanel = makeEditPanel(_actionTypeBox, "LabelActionType", "ActionTypeHint"); // NOI18N 1834 _actionTypePanel.setVisible(false); 1835 panel1.add(_actionTypePanel); 1836 panel1.add(Box.createHorizontalStrut(STRUT)); 1837 1838 _actionBox = new JComboBox<String>(); 1839 _actionBox.addItem(""); 1840 _actionPanel = makeEditPanel(_actionBox, "LabelActionType", "ActionTypeHint"); // NOI18N 1841 _actionPanel.setVisible(false); 1842 panel1.add(_actionPanel); 1843 panel1.add(Box.createHorizontalStrut(STRUT)); 1844 1845 _shortActionString = new JTextField(15); 1846 _shortTextPanel = makeEditPanel(_shortActionString, "LabelActionText", null); // NOI18N 1847 _shortTextPanel.setMaximumSize( 1848 new Dimension(25, _shortTextPanel.getPreferredSize().height)); 1849 _shortTextPanel.add(Box.createVerticalGlue()); 1850 _shortTextPanel.setVisible(false); 1851 panel1.add(_shortTextPanel); 1852 panel1.add(Box.createHorizontalStrut(STRUT)); 1853 1854 _actionOptionBox = new JComboBox<String>(); 1855 for (int i = 1; i <= Conditional.NUM_ACTION_OPTIONS; i++) { 1856 _actionOptionBox.addItem(DefaultConditionalAction.getOptionString(i, _triggerOnChangeButton.isSelected())); 1857 } 1858 _optionPanel = makeEditPanel(_actionOptionBox, "LabelActionOption", "ActionOptionHint"); // NOI18N 1859 _optionPanel.setVisible(false); 1860 panel1.add(_optionPanel); 1861 panel1.add(Box.createHorizontalStrut(STRUT)); 1862 1863 panel1.add(Box.createHorizontalGlue()); 1864 topPanel.add(panel1); 1865 topPanel.add(Box.createVerticalStrut(5)); 1866 topPanel.add(Box.createVerticalGlue()); 1867 1868 Box panel2 = Box.createHorizontalBox(); 1869 panel2.add(Box.createHorizontalGlue()); 1870 1871 _setPanel = new JPanel(); 1872 _setPanel.setLayout(new BoxLayout(_setPanel, BoxLayout.Y_AXIS)); 1873 JPanel p = new JPanel(); 1874 p.add(new JLabel(Bundle.getMessage("LabelActionFile"))); // NOI18N 1875 _setPanel.add(p); 1876 JButton _actionSetButton = new JButton("..."); // "File" replaced by ... 1877 _actionSetButton.setMaximumSize(_actionSetButton.getPreferredSize()); 1878 _actionSetButton.setToolTipText(Bundle.getMessage("FileButtonHint")); // NOI18N 1879 _actionSetButton.addActionListener(new ActionListener() { 1880 @Override 1881 public void actionPerformed(ActionEvent e) { 1882 validateAction(); 1883 setFileLocation(e); 1884 } 1885 }); 1886 _setPanel.add(_actionSetButton); 1887 _setPanel.add(Box.createVerticalGlue()); 1888 _setPanel.setVisible(false); 1889 panel2.add(_setPanel); 1890 panel2.add(Box.createHorizontalStrut(5)); 1891 1892 _longActionString = new JTextField(50); 1893 _textPanel = makeEditPanel(_longActionString, "LabelActionText", null); // NOI18N 1894 _textPanel.setMaximumSize( 1895 new Dimension(80, _textPanel.getPreferredSize().height)); 1896 _textPanel.add(Box.createVerticalGlue()); 1897 _textPanel.setVisible(false); 1898 panel2.add(_textPanel); 1899 panel2.add(Box.createHorizontalGlue()); 1900 topPanel.add(panel2); 1901 topPanel.add(Box.createVerticalStrut(5)); 1902 topPanel.add(Box.createVerticalGlue()); 1903 1904 ActionListener updateListener = new ActionListener() { 1905 @Override 1906 public void actionPerformed(ActionEvent e) { 1907 updateActionPressed(); 1908 } 1909 }; 1910 ActionListener cancelListener = new ActionListener() { 1911 @Override 1912 public void actionPerformed(ActionEvent e) { 1913 cancelEditActionPressed(); 1914 } 1915 }; 1916 ActionListener deleteListener = new ActionListener() { 1917 @Override 1918 public void actionPerformed(ActionEvent e) { 1919 deleteActionPressed(); 1920 } 1921 }; 1922 JPanel panel = makeButtonPanel(updateListener, cancelListener, deleteListener); 1923 topPanel.add(panel); 1924 topPanel.add(Box.createVerticalGlue()); 1925 1926 Container contentPane = _editActionFrame.getContentPane(); 1927 contentPane.add(topPanel); 1928 1929 _actionItemBox.addActionListener(new ActionListener() { 1930 @Override 1931 public void actionPerformed(ActionEvent e) { 1932 Conditional.ItemType newActionItem = _actionItemBox.getItemAt(_actionItemBox.getSelectedIndex()); 1933 log.debug("_actionItemBox Listener: new = {}, curr = {}, row = {}", // NOI18N 1934 newActionItem, _curActionItem, _curActionRowNumber); 1935 if (newActionItem != _curActionItem) { 1936 if (_curActionRowNumber >= 0) { 1937 _curAction = new DefaultConditionalAction(); 1938 _actionList.set(_curActionRowNumber, _curAction); 1939 } 1940 _curActionItem = newActionItem; 1941 } 1942 _dataChanged = true; 1943 actionItemChanged(newActionItem); 1944 _editActionFrame.pack(); 1945 } 1946 }); 1947 // setup window closing listener 1948 _editActionFrame.addWindowListener( 1949 new java.awt.event.WindowAdapter() { 1950 @Override 1951 public void windowClosing(java.awt.event.WindowEvent e) { 1952 cancelEditActionPressed(); 1953 } 1954 }); 1955 _curActionItem = _curAction.getType().getItemType(); 1956 initializeActionVariables(); 1957 _dataChanged = false; 1958 _editActionFrame.setVisible(true); 1959 _editActionFrame.pack(); 1960 } 1961 1962 // ----------------- utilities for logix and Conditional variables 1963 1964 /** 1965 * Load the Logix selection box. Set the selection to the current Logix. 1966 * 1967 * @since 4.7.4 1968 * @param curVariable Current ConditionalVariable 1969 */ 1970 void loadSelectLogixBox(ConditionalVariable curVariable) { 1971 // Get the current Logix name for selecting the current combo box row 1972 String cdlName = curVariable.getName(); 1973 String lgxName; 1974 if (cdlName.length() == 0 || (curVariable.getType() != Conditional.Type.CONDITIONAL_TRUE 1975 && curVariable.getType() != Conditional.Type.CONDITIONAL_FALSE)) { 1976 // Use the current logix name for "add" state variable 1977 lgxName = _parent._curLogix.getSystemName(); 1978 } else { 1979 Logix x = _parent._conditionalManager.getParentLogix(cdlName); 1980 if (x == null) { 1981 log.error("Unable to find the Logix for {}, using the current Logix", cdlName); // NOI18N 1982 lgxName = _parent._curLogix.getSystemName(); 1983 } else { 1984 lgxName = x.getSystemName(); 1985 } 1986 } 1987 1988 _selectLogixBox.removeAllItems(); 1989 _selectLogixMap.clear(); 1990 1991 // Create Logix list sorted by a custom display name 1992 String itemKey = ""; 1993 for (Logix lgx : _parent._logixManager.getNamedBeanSet()) { 1994 String sName = lgx.getSystemName(); 1995 if (sName.equals("SYS")) { // NOI18N 1996 // Cannot refer to sensor name groups 1997 continue; 1998 } 1999 String uName = lgx.getUserName(); 2000 String itemName = ""; 2001 if (uName == null || uName.length() < 1) { 2002 itemName = sName; 2003 } else { 2004 itemName = uName + " ( " + sName + " )"; 2005 } 2006 _selectLogixMap.put(itemName, sName); 2007 if (lgxName.equals(sName)) { 2008 itemKey = itemName; 2009 } 2010 } 2011 2012 // Load the combo box 2013 for (String item : _selectLogixMap.keySet()) { 2014 _selectLogixBox.addItem(item); 2015 } 2016 2017 JComboBoxUtil.setupComboBoxMaxRows(_selectLogixBox); 2018 _selectLogixBox.setSelectedItem(itemKey); 2019 loadSelectConditionalBox(lgxName, curVariable); 2020 } 2021 2022 /** 2023 * Load the Conditional selection box. The first row is a prompt. 2024 * 2025 * @since 4.7.4 2026 * @param logixName The Logix system name for selecting the owned 2027 * Conditionals 2028 * @param curVariable Current ConditionalVariable 2029 */ 2030 void loadSelectConditionalBox(String logixName, ConditionalVariable curVariable) { 2031 // Get the current Conditional name for selecting the current combo box row 2032 String cdlName = curVariable.getName(); 2033 2034 _selectConditionalBox.removeAllItems(); 2035 _selectConditionalList.clear(); 2036 2037 // Create the first row 2038 String itemKey = Bundle.getMessage("SelectFirstRow"); // NOI18N 2039 _selectConditionalBox.addItem(itemKey); 2040 _selectConditionalList.add("-None-"); // NOI18N 2041 2042 Logix x = _parent._logixManager.getBySystemName(logixName); 2043 if (x == null) { 2044 log.error("Logix '{}' not found while building the conditional list", logixName); // NOI18N 2045 return; 2046 } 2047 if (x.getNumConditionals() == 0) { 2048 return; 2049 } 2050 for (String cName : _parent._conditionalManager.getSystemNameListForLogix(x)) { 2051 Conditional c = _parent._conditionalManager.getConditional(cName); 2052 if (_parent._curConditional.getSystemName().equals(c.getSystemName())) { 2053 // Don't add myself to the list 2054 continue; 2055 } 2056 String uName = c.getUserName(); 2057 String itemName = ""; 2058 if (uName == null || uName.length() < 1) { 2059 itemName = cName; 2060 } else { 2061 itemName = uName + " ( " + cName + " )"; 2062 } 2063 _selectConditionalBox.addItem(itemName); 2064 _selectConditionalList.add(cName); 2065 if (cdlName.equals(cName)) { 2066 itemKey = itemName; 2067 } 2068 } 2069 JComboBoxUtil.setupComboBoxMaxRows(_selectConditionalBox); 2070 _selectConditionalBox.setSelectedItem(itemKey); 2071 } 2072 2073 // ------------ Main Action methods ------------ 2074 2075 /** 2076 * Set display to show current action (curAction) parameters. 2077 */ 2078 void initializeActionVariables() { 2079 Conditional.Action actionType = _curAction.getType(); 2080 Conditional.ItemType itemType = actionType.getItemType(); 2081 if (log.isDebugEnabled()) { 2082 log.debug("initializeActionVariables: itemType = {}, actionType = {}", itemType, actionType); // NOI18N 2083 } 2084 if (actionType == Conditional.Action.NONE) { 2085 return; 2086 } 2087 _actionItemBox.setSelectedItem(itemType); 2088 _actionNameField.setText(_curAction.getDeviceName()); 2089 switch (itemType) { 2090 case SENSOR: 2091 _actionTypeBox.setSelectedItem(actionType); 2092 if ((actionType == Conditional.Action.RESET_DELAYED_SENSOR) 2093 || (actionType == Conditional.Action.DELAYED_SENSOR)) { 2094 _shortActionString.setText(_curAction.getActionString()); 2095 } 2096 if (actionType == Conditional.Action.SET_SENSOR 2097 || actionType == Conditional.Action.DELAYED_SENSOR 2098 || actionType == Conditional.Action.RESET_DELAYED_SENSOR) { 2099 if (_curAction.getActionData() == Sensor.ACTIVE) { 2100 _actionBox.setSelectedIndex(0); 2101 } else if (_curAction.getActionData() == Sensor.INACTIVE) { 2102 _actionBox.setSelectedIndex(1); 2103 } else if (_curAction.getActionData() == Route.TOGGLE) { 2104 _actionBox.setSelectedIndex(2); 2105 } 2106 } 2107 break; 2108 2109 case TURNOUT: 2110 _actionTypeBox.setSelectedItem(actionType); 2111 if ((actionType == Conditional.Action.RESET_DELAYED_TURNOUT) 2112 || (actionType == Conditional.Action.DELAYED_TURNOUT)) { 2113 _shortActionString.setText(_curAction.getActionString()); 2114 } 2115 if ((actionType == Conditional.Action.SET_TURNOUT) 2116 || (actionType == Conditional.Action.RESET_DELAYED_TURNOUT) 2117 || (actionType == Conditional.Action.DELAYED_TURNOUT)) { 2118 if (_curAction.getActionData() == Turnout.CLOSED) { 2119 _actionBox.setSelectedIndex(0); 2120 } else if (_curAction.getActionData() == Turnout.THROWN) { 2121 _actionBox.setSelectedIndex(1); 2122 } else if (_curAction.getActionData() == Route.TOGGLE) { 2123 _actionBox.setSelectedIndex(2); 2124 } 2125 } else if (actionType == Conditional.Action.LOCK_TURNOUT) { 2126 if (_curAction.getActionData() == Turnout.UNLOCKED) { 2127 _actionBox.setSelectedIndex(0); 2128 } else if (_curAction.getActionData() == Turnout.LOCKED) { 2129 _actionBox.setSelectedIndex(1); 2130 } else if (_curAction.getActionData() == Route.TOGGLE) { 2131 _actionBox.setSelectedIndex(2); 2132 } 2133 } 2134 break; 2135 2136 case LIGHT: 2137 _actionTypeBox.setSelectedItem(actionType); 2138 if (actionType == Conditional.Action.SET_LIGHT) { 2139 if (_curAction.getActionData() == Light.ON) { 2140 _actionBox.setSelectedIndex(0); 2141 } else if (_curAction.getActionData() == Light.OFF) { 2142 _actionBox.setSelectedIndex(1); 2143 } else if (_curAction.getActionData() == Route.TOGGLE) { 2144 _actionBox.setSelectedIndex(2); 2145 } 2146 } else if ((actionType == Conditional.Action.SET_LIGHT_INTENSITY) 2147 || (actionType == Conditional.Action.SET_LIGHT_TRANSITION_TIME)) { 2148 _shortActionString.setText(_curAction.getActionString()); 2149 } 2150 break; 2151 2152 case CLOCK: 2153 _actionTypeBox.setSelectedItem(actionType); 2154 if (actionType == Conditional.Action.SET_FAST_CLOCK_TIME) { 2155 int time = _curAction.getActionData(); 2156 _longActionString.setText(ConditionalEditBase.formatTime(time / 60, time - ((time / 60) * 60))); 2157 _actionNameField.setText(""); 2158 } 2159 break; 2160 2161 case MEMORY: 2162 _actionTypeBox.setSelectedItem(actionType); 2163 _shortActionString.setText(_curAction.getActionString()); 2164 break; 2165 2166 2167 case WARRANT: 2168 _actionTypeBox.setSelectedItem(actionType); 2169 if (actionType == Conditional.Action.CONTROL_TRAIN) { 2170 switch (_curAction.getActionData()) { 2171 case Warrant.HALT: 2172 _actionBox.setSelectedIndex(0); 2173 break; 2174 case Warrant.RESUME: 2175 _actionBox.setSelectedIndex(1); 2176 break; 2177 case Warrant.RETRY_FWD: 2178 _actionBox.setSelectedIndex(2); 2179 break; 2180 case Warrant.SPEED_UP: 2181 _actionBox.setSelectedIndex(3); 2182 break; 2183 case Warrant.STOP: 2184 _actionBox.setSelectedIndex(4); 2185 break; 2186 case Warrant.ESTOP: 2187 _actionBox.setSelectedIndex(5); 2188 break; 2189 case Warrant.ABORT: 2190 _actionBox.setSelectedIndex(6); 2191 break; 2192 default: 2193 log.warn("Unexpected _curAction.getActionData() of {}", _curAction.getActionData()); // NOI18N 2194 } 2195 } else if (actionType == Conditional.Action.SET_TRAIN_ID 2196 || actionType == Conditional.Action.SET_TRAIN_NAME 2197 || actionType == Conditional.Action.GET_TRAIN_LOCATION) { 2198 _shortActionString.setText(_curAction.getActionString()); 2199 } 2200 break; 2201 2202 case OBLOCK: 2203 _actionTypeBox.setSelectedItem(actionType); 2204 if (actionType == Conditional.Action.SET_BLOCK_VALUE 2205 || actionType == Conditional.Action.GET_BLOCK_TRAIN_NAME 2206 || actionType == Conditional.Action.GET_BLOCK_WARRANT) { 2207 _shortActionString.setText(_curAction.getActionString()); 2208 } 2209 break; 2210 2211 case ENTRYEXIT: 2212 _actionTypeBox.setSelectedItem(actionType); 2213 _actionNameField.setText(_curAction.getBean().getUserName()); 2214 break; 2215 2216 case AUDIO: 2217 _actionTypeBox.setSelectedItem(actionType); 2218 if (actionType == Conditional.Action.PLAY_SOUND) { 2219 _longActionString.setText(_curAction.getActionString()); 2220 } else if (actionType == Conditional.Action.CONTROL_AUDIO) { 2221 switch (_curAction.getActionData()) { 2222 case Audio.CMD_PLAY: 2223 _actionBox.setSelectedIndex(0); 2224 break; 2225 case Audio.CMD_STOP: 2226 _actionBox.setSelectedIndex(1); 2227 break; 2228 case Audio.CMD_PLAY_TOGGLE: 2229 _actionBox.setSelectedIndex(2); 2230 break; 2231 case Audio.CMD_PAUSE: 2232 _actionBox.setSelectedIndex(3); 2233 break; 2234 case Audio.CMD_RESUME: 2235 _actionBox.setSelectedIndex(4); 2236 break; 2237 case Audio.CMD_PAUSE_TOGGLE: 2238 _actionBox.setSelectedIndex(5); 2239 break; 2240 case Audio.CMD_REWIND: 2241 _actionBox.setSelectedIndex(6); 2242 break; 2243 case Audio.CMD_FADE_IN: 2244 _actionBox.setSelectedIndex(7); 2245 break; 2246 case Audio.CMD_FADE_OUT: 2247 _actionBox.setSelectedIndex(8); 2248 break; 2249 case Audio.CMD_RESET_POSITION: 2250 _actionBox.setSelectedIndex(9); 2251 break; 2252 default: 2253 log.warn("Unexpected _curAction.getActionData() of {}", _curAction.getActionData()); // NOI18N 2254 break; 2255 } 2256 } 2257 break; 2258 2259 case SCRIPT: 2260 _actionTypeBox.setSelectedItem(actionType); 2261 if (actionType == Conditional.Action.RUN_SCRIPT) { 2262 _longActionString.setText(_curAction.getActionString()); 2263 } else if (actionType == Conditional.Action.JYTHON_COMMAND) { 2264 _shortActionString.setText(_curAction.getActionString()); 2265 } 2266 break; 2267 2268 case SIGNALHEAD: 2269 case SIGNALMAST: 2270 case LOGIX: 2271 case OTHER: // ACTION_TRIGGER_ROUTE 2272 _actionTypeBox.setSelectedItem(actionType); 2273 break; 2274 2275 default: 2276 log.error("Unhandled type: {}", itemType); // NOI18N 2277 break; 2278 } 2279 _actionOptionBox.setSelectedIndex(_curAction.getOption() - 1); 2280 _editActionFrame.pack(); 2281 _editActionFrame.transferFocusBackward(); 2282 } 2283 2284 /** 2285 * Respond to a change in an Action Type comboBox on the Edit Conditional 2286 * Action pane. 2287 * <p> 2288 * Set components visible for the selected type. 2289 * 2290 * @param type index of the newly selected Action type 2291 */ 2292 void actionItemChanged(Conditional.ItemType type) { 2293 Conditional.Action actionType = _curAction.getType(); 2294 if (log.isDebugEnabled()) { 2295 log.debug("actionItemChanged: itemType = {}, actionType = {}", type, actionType); // NOI18N 2296 } 2297 _actionTypeBox.removeActionListener(_actionTypeListener); 2298 _actionTypePanel.setVisible(false); 2299 _setPanel.setVisible(false); 2300 _shortTextPanel.setVisible(false); 2301 _shortActionString.setText(""); 2302 _textPanel.setVisible(false); 2303 _longActionString.setText(""); 2304 _actionNamePanel.setVisible(false); 2305 _actionPanel.setVisible(false); 2306 _optionPanel.setVisible(false); 2307 Conditional.ItemType itemType = actionType.getItemType(); 2308 if (type == Conditional.ItemType.NONE && itemType == Conditional.ItemType.NONE) { 2309 return; 2310 } 2311 _actionTypePanel.setVisible(true); 2312 _actionTypeBox.removeAllItems(); 2313 _actionBox.removeAllItems(); 2314 if (type != Conditional.ItemType.NONE) { // actionItem listener choice overrides current item 2315 itemType = type; 2316 } 2317 if (itemType != actionType.getItemType()) { 2318 actionType = Conditional.Action.NONE; // chosen item type does not support action type 2319 } 2320 if (actionType != Conditional.Action.NONE) { 2321 _optionPanel.setVisible(true); // item type compatible with action type 2322 } 2323 _actionTypeBox.addItem(Conditional.Action.NONE); 2324 _actionNameField.removeActionListener(actionSignalHeadNameListener); 2325 _actionNameField.removeActionListener(actionSignalMastNameListener); 2326 2327 if (_parent._selectionMode == SelectionMode.USECOMBO) { 2328 _actionComboNamePanel.setVisible(false); 2329 } else if (_parent._selectionMode == SelectionMode.USESINGLE) { 2330 _parent.createSinglePanelPickList(itemType, _parent.getPickSingleListener(_actionNameField, itemType), true); 2331 } else { 2332 // Default and USEMULTI 2333 _parent.setPickListTab(itemType, true); 2334 } 2335 2336 switch (itemType) { 2337 case TURNOUT: 2338 for (Conditional.Action action : Conditional.Action.getTurnoutItems()) { 2339 _actionTypeBox.addItem(action); 2340 } 2341 if ((actionType == Conditional.Action.RESET_DELAYED_TURNOUT) 2342 || (actionType == Conditional.Action.DELAYED_TURNOUT)) { 2343 JPanel p = (JPanel) _shortTextPanel.getComponent(0); 2344 JLabel l = (JLabel) p.getComponent(0); 2345 l.setText(Bundle.getMessage("LabelDelayTime")); // NOI18N 2346 _shortTextPanel.setToolTipText(Bundle.getMessage("DataHintDelayedTurnout")); // NOI18N 2347 _shortTextPanel.setVisible(true); 2348 } 2349 JPanel panel = (JPanel) _actionPanel.getComponent(0); 2350 JLabel label = (JLabel) panel.getComponent(0); 2351 if ((actionType == Conditional.Action.SET_TURNOUT) 2352 || (actionType == Conditional.Action.RESET_DELAYED_TURNOUT) 2353 || (actionType == Conditional.Action.DELAYED_TURNOUT)) { 2354 label.setText(Bundle.getMessage("LabelActionTurnout")); // NOI18N 2355 _actionBox.addItem(Bundle.getMessage("TurnoutStateClosed")); // NOI18N 2356 _actionBox.addItem(Bundle.getMessage("TurnoutStateThrown")); // NOI18N 2357 _actionBox.addItem(Bundle.getMessage("Toggle")); // NOI18N 2358 _actionPanel.setToolTipText(Bundle.getMessage("TurnoutSetHint")); // NOI18N 2359 _actionPanel.setVisible(true); 2360 } else if (actionType == Conditional.Action.LOCK_TURNOUT) { 2361 label.setText(Bundle.getMessage("LabelActionLock")); // NOI18N 2362 _actionBox.addItem(Bundle.getMessage("TurnoutUnlock")); // NOI18N 2363 _actionBox.addItem(Bundle.getMessage("TurnoutLock")); // NOI18N 2364 _actionBox.addItem(Bundle.getMessage("Toggle")); // NOI18N 2365 _actionPanel.setToolTipText(Bundle.getMessage("LockSetHint")); // NOI18N 2366 _actionPanel.setVisible(true); 2367 } 2368 _actionNamePanel.setToolTipText(Bundle.getMessage("NameHintTurnout")); // NOI18N 2369 _actionNamePanel.setVisible(true); 2370 setActionNameBox(itemType); 2371 break; 2372 2373 case SENSOR: 2374 for (Conditional.Action action : Conditional.Action.getSensorItems()) { 2375 _actionTypeBox.addItem(action); 2376 } 2377 if ((actionType == Conditional.Action.RESET_DELAYED_SENSOR) 2378 || (actionType == Conditional.Action.DELAYED_SENSOR)) { 2379 JPanel p = (JPanel) _shortTextPanel.getComponent(0); 2380 JLabel l = (JLabel) p.getComponent(0); 2381 l.setText(Bundle.getMessage("LabelDelayTime")); // NOI18N 2382 _shortTextPanel.setToolTipText(Bundle.getMessage("DataHintDelayedTurnout")); // NOI18N 2383 _shortTextPanel.setVisible(true); 2384 } 2385 if ((actionType == Conditional.Action.SET_SENSOR) 2386 || (actionType == Conditional.Action.RESET_DELAYED_SENSOR) 2387 || (actionType == Conditional.Action.DELAYED_SENSOR)) { 2388 JPanel p = (JPanel) _actionPanel.getComponent(0); 2389 JLabel l = (JLabel) p.getComponent(0); 2390 l.setText(Bundle.getMessage("LabelActionSensor")); // NOI18N 2391 _actionBox.addItem(Bundle.getMessage("SensorStateActive")); // NOI18N 2392 _actionBox.addItem(Bundle.getMessage("SensorStateInactive")); // NOI18N 2393 _actionBox.addItem(Bundle.getMessage("Toggle")); // NOI18N 2394 _actionPanel.setToolTipText(Bundle.getMessage("SensorSetHint")); // NOI18N 2395 _actionPanel.setVisible(true); 2396 } 2397 _actionNamePanel.setToolTipText(Bundle.getMessage("NameHintSensor")); // NOI18N 2398 _actionNamePanel.setVisible(true); 2399 setActionNameBox(itemType); 2400 break; 2401 2402 case SIGNALHEAD: 2403 for (Conditional.Action action : Conditional.Action.getSignalHeadItems()) { 2404 _actionTypeBox.addItem(action); 2405 } 2406 if (actionType == Conditional.Action.SET_SIGNAL_APPEARANCE) { 2407 JPanel p = (JPanel) _actionPanel.getComponent(0); 2408 JLabel l = (JLabel) p.getComponent(0); 2409 l.setText(Bundle.getMessage("LabelActionSignal")); // NOI18N 2410 loadJComboBoxWithHeadAppearances(_actionBox, _actionNameField.getText().trim()); 2411 _actionBox.setSelectedItem(_curAction.getActionDataString()); 2412 _actionPanel.setToolTipText(Bundle.getMessage("SignalSetHint")); // NOI18N 2413 _actionPanel.setVisible(true); 2414 } 2415 _actionNamePanel.setToolTipText(Bundle.getMessage("NameHintSignal")); // NOI18N 2416 _actionNamePanel.setVisible(true); 2417 setActionNameBox(itemType); 2418 _actionNameField.addActionListener(actionSignalHeadNameListener); 2419 break; 2420 2421 case SIGNALMAST: 2422 for (Conditional.Action action : Conditional.Action.getSignalMastItems()) { 2423 _actionTypeBox.addItem(action); 2424 } 2425 if (actionType == Conditional.Action.SET_SIGNALMAST_ASPECT) { 2426 JPanel p = (JPanel) _actionPanel.getComponent(0); 2427 JLabel l = (JLabel) p.getComponent(0); 2428 l.setText(Bundle.getMessage("LabelSignalAspect")); // NOI18N 2429 loadJComboBoxWithMastAspects(_actionBox, _actionNameField.getText().trim()); 2430 _actionBox.setSelectedItem(_curAction.getActionString()); 2431 _actionPanel.setToolTipText(Bundle.getMessage("SignalMastSetHint")); // NOI18N 2432 _actionPanel.setVisible(true); 2433 } 2434 _actionNamePanel.setToolTipText(Bundle.getMessage("NameHintSignalMast")); // NOI18N 2435 _actionNamePanel.setVisible(true); 2436 setActionNameBox(itemType); 2437 _actionNameField.addActionListener(actionSignalMastNameListener); 2438 break; 2439 2440 case LIGHT: 2441 for (Conditional.Action action : Conditional.Action.getLightItems()) { 2442 _actionTypeBox.addItem(action); 2443 } 2444 if (actionType == Conditional.Action.SET_LIGHT_INTENSITY) { 2445 JPanel p = (JPanel) _shortTextPanel.getComponent(0); 2446 JLabel l = (JLabel) p.getComponent(0); 2447 l.setText(Bundle.getMessage("LabelLightIntensity")); // NOI18N 2448 _shortTextPanel.setToolTipText(Bundle.getMessage("DataHintLightIntensity")); // NOI18N 2449 _shortTextPanel.setVisible(true); 2450 } else if (actionType == Conditional.Action.SET_LIGHT_TRANSITION_TIME) { 2451 JPanel p = (JPanel) _shortTextPanel.getComponent(0); 2452 JLabel l = (JLabel) p.getComponent(0); 2453 l.setText(Bundle.getMessage("LabelTransitionTime")); // NOI18N 2454 _shortTextPanel.setToolTipText(Bundle.getMessage("DataHintLightTransitionTime")); // NOI18N 2455 _shortTextPanel.setVisible(true); 2456 } else if (actionType == Conditional.Action.SET_LIGHT) { 2457 JPanel p = (JPanel) _actionPanel.getComponent(0); 2458 JLabel l = (JLabel) p.getComponent(0); 2459 l.setText(Bundle.getMessage("LabelActionLight")); // NOI18N 2460 _actionBox.addItem(Bundle.getMessage("LightOn")); // NOI18N 2461 _actionBox.addItem(Bundle.getMessage("LightOff")); // NOI18N 2462 _actionBox.addItem(Bundle.getMessage("Toggle")); 2463 _actionPanel.setToolTipText(Bundle.getMessage("LightSetHint")); // NOI18N 2464 _actionPanel.setVisible(true); 2465 } 2466 _actionNamePanel.setToolTipText(Bundle.getMessage("NameHintLight")); // NOI18N 2467 _actionNamePanel.setVisible(true); 2468 setActionNameBox(itemType); 2469 break; 2470 2471 case MEMORY: 2472 for (Conditional.Action action : Conditional.Action.getMemoryItems()) { 2473 _actionTypeBox.addItem(action); 2474 } 2475 JPanel p = (JPanel) _shortTextPanel.getComponent(0); 2476 JLabel l = (JLabel) p.getComponent(0); 2477 if (actionType == Conditional.Action.COPY_MEMORY) { 2478 _shortTextPanel.setToolTipText(Bundle.getMessage("DataHintToMemory")); // NOI18N 2479 l.setText(Bundle.getMessage("LabelMemoryLocation")); // NOI18N 2480 } else { 2481 _shortTextPanel.setToolTipText(Bundle.getMessage("DataHintMemory")); // NOI18N 2482 l.setText(Bundle.getMessage("LabelValue")); 2483 } 2484 _shortTextPanel.setVisible(true); 2485 _actionNamePanel.setToolTipText(Bundle.getMessage("NameHintMemory")); // NOI18N 2486 _actionNamePanel.setVisible(true); 2487 setActionNameBox(itemType); 2488 break; 2489 2490 case CLOCK: 2491 for (Conditional.Action action : Conditional.Action.getClockItems()) { 2492 _actionTypeBox.addItem(action); 2493 } 2494 if (actionType == Conditional.Action.SET_FAST_CLOCK_TIME) { 2495 p = (JPanel) _textPanel.getComponent(0); 2496 l = (JLabel) p.getComponent(0); 2497 l.setText(Bundle.getMessage("LabelSetTime")); // NOI18N 2498 _textPanel.setToolTipText(Bundle.getMessage("DataHintTime")); // NOI18N 2499 _textPanel.setVisible(true); 2500 } 2501 break; 2502 2503 case LOGIX: 2504 for (Conditional.Action action : Conditional.Action.getLogixItems()) { 2505 _actionTypeBox.addItem(action); 2506 } 2507 _actionNamePanel.setToolTipText(Bundle.getMessage("NameHintLogix")); // NOI18N 2508 _actionNamePanel.setVisible(true); 2509 setActionNameBox(itemType); 2510 break; 2511 2512 case WARRANT: 2513 for (Conditional.Action action : Conditional.Action.getWarrantItems()) { 2514 _actionTypeBox.addItem(action); 2515 } 2516 _actionNamePanel.setToolTipText(Bundle.getMessage("NameHintWarrant")); // NOI18N 2517 _actionNamePanel.setVisible(true); 2518 if (actionType == Conditional.Action.CONTROL_TRAIN) { 2519 p = (JPanel) _actionPanel.getComponent(0); 2520 l = (JLabel) p.getComponent(0); 2521 _actionBox.addItem(Bundle.getMessage("WarrantHalt")); 2522 _actionBox.addItem(Bundle.getMessage("WarrantResume")); 2523 _actionBox.addItem(Bundle.getMessage("WarrantMoveToNext")); 2524 _actionBox.addItem(Bundle.getMessage("WarrantSpeedUp")); 2525 _actionBox.addItem(Bundle.getMessage("WarrantStop")); 2526 _actionBox.addItem(Bundle.getMessage("WarrantEStop")); 2527 _actionBox.addItem(Bundle.getMessage("WarrantAbort")); 2528 l.setText(Bundle.getMessage("LabelControlTrain")); // NOI18N 2529 _actionPanel.setVisible(true); 2530 } else if (actionType == Conditional.Action.SET_TRAIN_ID 2531 || actionType == Conditional.Action.SET_TRAIN_NAME 2532 || actionType == Conditional.Action.GET_TRAIN_LOCATION) { 2533 p = (JPanel) _shortTextPanel.getComponent(0); 2534 l = (JLabel) p.getComponent(0); 2535 if (actionType == Conditional.Action.SET_TRAIN_ID) { 2536 _shortTextPanel.setToolTipText(Bundle.getMessage("DataHintTrainId")); // NOI18N 2537 l.setText(Bundle.getMessage("LabelTrainId")); 2538 } else if (actionType == Conditional.Action.SET_TRAIN_NAME) { 2539 _shortTextPanel.setToolTipText(Bundle.getMessage("DataHintTrainName")); // NOI18N 2540 l.setText(Bundle.getMessage("LabelTrainName")); 2541 } else if (actionType == Conditional.Action.GET_TRAIN_LOCATION) { 2542 _shortTextPanel.setToolTipText(Bundle.getMessage("DataHintToMemory")); // NOI18N 2543 l.setText(Bundle.getMessage("LabelMemoryLocation")); // NOI18N 2544 } 2545 _shortTextPanel.setVisible(true); 2546 } 2547 setActionNameBox(itemType); 2548 break; 2549 2550 case OBLOCK: 2551 for (Conditional.Action action : Conditional.Action.getOBlockItems()) { 2552 _actionTypeBox.addItem(action); 2553 } 2554 _actionNamePanel.setToolTipText(Bundle.getMessage("NameHintOBlock")); // NOI18N 2555 _actionNamePanel.setVisible(true); 2556 if (actionType == Conditional.Action.SET_BLOCK_VALUE 2557 || actionType == Conditional.Action.GET_BLOCK_TRAIN_NAME 2558 || actionType == Conditional.Action.GET_BLOCK_WARRANT) { 2559 p = (JPanel) _shortTextPanel.getComponent(0); 2560 l = (JLabel) p.getComponent(0); 2561 if (actionType == Conditional.Action.SET_BLOCK_VALUE) { 2562 _shortTextPanel.setToolTipText(Bundle.getMessage("DataHintBlockValue")); // NOI18N 2563 l.setText(Bundle.getMessage("LabelBlockValue")); // NOI18N 2564 } else { 2565 _shortTextPanel.setToolTipText(Bundle.getMessage("DataHintToMemory")); // NOI18N 2566 l.setText(Bundle.getMessage("LabelMemoryLocation")); // NOI18 2567 } 2568 _shortTextPanel.setVisible(true); 2569 } 2570 setActionNameBox(itemType); 2571 break; 2572 2573 case ENTRYEXIT: 2574 for (Conditional.Action action : Conditional.Action.getEntryExitItems()) { 2575 _actionTypeBox.addItem(action); 2576 } 2577 _actionNamePanel.setToolTipText(Bundle.getMessage("NameHintEntryExit")); // NOI18N 2578 _actionNamePanel.setVisible(true); 2579 setActionNameBox(itemType); 2580 break; 2581 2582 case AUDIO: 2583 for (Conditional.Action action : Conditional.Action.getAudioItems()) { 2584 _actionTypeBox.addItem(action); 2585 } 2586 if (actionType == Conditional.Action.PLAY_SOUND) { 2587 p = (JPanel) _textPanel.getComponent(0); 2588 l = (JLabel) p.getComponent(0); 2589 l.setText(Bundle.getMessage("LabelSetFile")); // NOI18N 2590 _textPanel.setToolTipText(Bundle.getMessage("SetHintSound")); // NOI18N 2591 _textPanel.setVisible(true); 2592 _setPanel.setVisible(true); 2593 } else if (actionType == Conditional.Action.CONTROL_AUDIO) { 2594 p = (JPanel) _actionPanel.getComponent(0); 2595 l = (JLabel) p.getComponent(0); 2596 l.setText(Bundle.getMessage("LabelActionAudio")); // NOI18N 2597 _actionBox.addItem(Bundle.getMessage("AudioSourcePlay")); // NOI18N 2598 _actionBox.addItem(Bundle.getMessage("AudioSourceStop")); // NOI18N 2599 _actionBox.addItem(Bundle.getMessage("AudioSourcePlayToggle")); // NOI18N 2600 _actionBox.addItem(Bundle.getMessage("AudioSourcePause")); // NOI18N 2601 _actionBox.addItem(Bundle.getMessage("AudioSourceResume")); // NOI18N 2602 _actionBox.addItem(Bundle.getMessage("AudioSourcePauseToggle")); // NOI18N 2603 _actionBox.addItem(Bundle.getMessage("AudioSourceRewind")); // NOI18N 2604 _actionBox.addItem(Bundle.getMessage("AudioSourceFadeIn")); // NOI18N 2605 _actionBox.addItem(Bundle.getMessage("AudioSourceFadeOut")); // NOI18N 2606 _actionBox.addItem(Bundle.getMessage("AudioResetPosition")); // NOI18N 2607 _actionPanel.setToolTipText(Bundle.getMessage("SetHintAudio")); // NOI18N 2608 _actionPanel.setVisible(true); 2609 _actionNamePanel.setToolTipText(Bundle.getMessage("NameHintAudio")); // NOI18N 2610 _actionNamePanel.setVisible(true); 2611 } 2612 break; 2613 2614 case SCRIPT: 2615 for (Conditional.Action action : Conditional.Action.getScriptItems()) { 2616 _actionTypeBox.addItem(action); 2617 } 2618 if (actionType == Conditional.Action.RUN_SCRIPT) { 2619 p = (JPanel) _textPanel.getComponent(0); 2620 l = (JLabel) p.getComponent(0); 2621 l.setText(Bundle.getMessage("LabelSetFile")); // NOI18N 2622 _textPanel.setToolTipText(Bundle.getMessage("SetHintScript")); // NOI18N 2623 _textPanel.setVisible(true); 2624 _setPanel.setVisible(true); 2625 } else if (actionType == Conditional.Action.JYTHON_COMMAND) { 2626 p = (JPanel) _shortTextPanel.getComponent(0); 2627 l = (JLabel) p.getComponent(0); 2628 l.setText(Bundle.getMessage("LabelScriptCommand")); // NOI18N 2629 _shortTextPanel.setToolTipText(Bundle.getMessage("SetHintJythonCmd")); // NOI18N 2630 _shortTextPanel.setVisible(true); 2631 } 2632 break; 2633 2634 case OTHER: 2635 for (Conditional.Action action : Conditional.Action.getOtherItems()) { 2636 _actionTypeBox.addItem(action); 2637 } 2638 if (actionType == Conditional.Action.TRIGGER_ROUTE) { 2639 _actionNamePanel.setToolTipText(Bundle.getMessage("NameHintRoute")); // NOI18N 2640 _actionNamePanel.setVisible(true); 2641 setActionNameBox(itemType); 2642 } 2643 break; 2644 default: 2645 break; 2646 } 2647 _actionTypeBox.setMaximumSize(_actionTypeBox.getPreferredSize()); 2648 _actionBox.setMaximumSize(_actionBox.getPreferredSize()); 2649 _actionTypeListener.setItemType(itemType); 2650 _actionTypeBox.addActionListener(_actionTypeListener); 2651 _editActionFrame.pack(); // TODO fit all components 2652 } 2653 2654 /** 2655 * Update the name combo box selection based on the current contents of the 2656 * name field. Called by {@link #actionItemChanged(Conditional.ItemType)}. 2657 * 2658 * @since 4.7.3 2659 * @param itemType The type of name box to be created. 2660 */ 2661 void setActionNameBox(Conditional.ItemType itemType) { 2662 if (_parent._selectionMode != SelectionMode.USECOMBO) { 2663 return; 2664 } 2665 _comboNameBox = _parent.createNameBox(itemType); 2666 if (_comboNameBox == null) { 2667 return; 2668 } 2669 _comboNameBox.setSelectedItemByName(_curAction.getDeviceName()); 2670 _comboNameBox.addActionListener(new NameBoxListener(_actionNameField)); 2671 _actionComboNamePanel.remove(1); 2672 _actionComboNamePanel.add(_comboNameBox, null, 1); 2673 _actionNamePanel.setVisible(false); 2674 _actionComboNamePanel.setVisible(true); 2675 } 2676 2677 // ------------ Action detail methods ------------ 2678 2679 /** 2680 * Respond to Update Action button in the Edit Action pane. 2681 */ 2682 void updateActionPressed() { 2683 if (!validateAction()) { 2684 _editActionFrame.toFront(); 2685 return; 2686 } 2687 _actionTableModel.fireTableRowsUpdated(_curActionRowNumber, _curActionRowNumber); 2688 cleanUpAction(); 2689 } 2690 2691 /** 2692 * Respond to Cancel action button and window closer of the Edit Action 2693 * window. 2694 * <p> 2695 * Also does cleanup of Update and Delete buttons. 2696 */ 2697 void cancelEditActionPressed() { 2698 if (_newItem) { 2699 deleteActionPressed(_curActionRowNumber); 2700 } else { 2701 cleanUpAction(); 2702 } 2703 } 2704 2705 /** 2706 * Clean up Update and Delete Action buttons. 2707 */ 2708 void cleanUpAction() { 2709 _newItem = false; 2710 if (_editActionFrame != null) { 2711 _actionTypeBox.removeActionListener(_actionTypeListener); 2712 _editActionFrame.setVisible(false); 2713 _editActionFrame.dispose(); 2714 _editActionFrame = null; 2715 _parent.closeSinglePanelPickList(); 2716 } 2717 _curActionRowNumber = -1; 2718 } 2719 2720 /** 2721 * Respond to Delete action button in the Edit Action window. 2722 */ 2723 void deleteActionPressed() { 2724 deleteActionPressed(_curActionRowNumber); 2725 } 2726 2727 /** 2728 * Respond to Delete action button in an action row of the Edit Conditional 2729 * pane. 2730 * 2731 * @param row index in table of action to be deleted 2732 */ 2733 void deleteActionPressed(int row) { 2734 if (row != _curActionRowNumber && alreadyEditingActionOrVariable()) { 2735 return; 2736 } 2737 _actionList.remove(row); 2738 _actionTableModel.fireTableRowsDeleted(row, row); 2739 cleanUpAction(); 2740 _dataChanged = true; 2741 } 2742 2743 JFileChooser sndFileChooser = null; 2744 ScriptFileChooser scriptFileChooser = null; 2745 JFileChooser defaultFileChooser = null; 2746 2747 /** 2748 * Respond to the [...] button in the Edit Action window action section. 2749 * <p> 2750 * Ask user to select an audio or python script file on disk. 2751 * 2752 * @param e the event heard 2753 */ 2754 void setFileLocation(ActionEvent e) { 2755 ConditionalAction action = _actionList.get(_curActionRowNumber); 2756 JFileChooser currentChooser; 2757 Conditional.Action actionType = action.getType(); 2758 if (actionType == Conditional.Action.PLAY_SOUND) { 2759 if (sndFileChooser == null) { 2760 sndFileChooser = new jmri.util.swing.JmriJFileChooser(System.getProperty("user.dir") // NOI18N 2761 + java.io.File.separator + "resources" // NOI18N 2762 + java.io.File.separator + "sounds"); // NOI18N 2763 sndFileChooser.setFileFilter(new FileNameExtensionFilter("wav sound files", "wav")); // NOI18N 2764 } 2765 currentChooser = sndFileChooser; 2766 } else if (actionType == Conditional.Action.RUN_SCRIPT) { 2767 if (scriptFileChooser == null) { 2768 scriptFileChooser = new ScriptFileChooser(FileUtil.getScriptsPath()); 2769 } 2770 currentChooser = scriptFileChooser; 2771 } else { 2772 log.warn("Unexpected actionType[{}] = {}", actionType.name(), actionType.toString()); // NOI18N 2773 if (defaultFileChooser == null) { 2774 defaultFileChooser = new jmri.util.swing.JmriJFileChooser(FileUtil.getUserFilesPath()); 2775 defaultFileChooser.setFileFilter(new jmri.util.NoArchiveFileFilter()); 2776 } 2777 currentChooser = defaultFileChooser; 2778 } 2779 2780 currentChooser.rescanCurrentDirectory(); 2781 int retVal = currentChooser.showOpenDialog(null); 2782 // handle selection or cancel 2783 if (retVal == JFileChooser.APPROVE_OPTION) { 2784 // set selected file location in data string 2785 try { 2786 _longActionString.setText(FileUtil.getPortableFilename(currentChooser.getSelectedFile().getCanonicalPath())); 2787 } catch (java.io.IOException ex) { 2788 if (log.isDebugEnabled()) { 2789 log.error("exception setting file location", ex); // NOI18N 2790 } 2791 _longActionString.setText(""); 2792 } 2793 } 2794 } 2795 2796 // ------------ Action update processes ------------ 2797 2798 /** 2799 * Validate Action data from Edit Action Window, and transfer it to current 2800 * action object as appropriate. 2801 * <p> 2802 * Messages are sent to the user for any errors found. This routine returns 2803 * false immediately after finding an error, even if there might be more 2804 * errors. 2805 * 2806 * @return true if all data checks out OK, otherwise false 2807 */ 2808 boolean validateAction() { 2809 Conditional.ItemType itemType = _actionItemBox.getItemAt(_actionItemBox.getSelectedIndex()); 2810 Conditional.Action actionType = Conditional.Action.NONE; 2811 Conditional.Action selection = _actionTypeBox.getItemAt(_actionTypeBox.getSelectedIndex()); 2812 if (selection == Conditional.Action.NONE) { 2813 JmriJOptionPane.showMessageDialog(this, 2814 Bundle.getMessage("makeSelection"), // NOI18N 2815 Bundle.getMessage("WarningTitle"), 2816 JmriJOptionPane.WARNING_MESSAGE); // NOI18N 2817 return false; 2818 } 2819 String name = _actionNameField.getText().trim(); 2820 String actionString = _shortActionString.getText().trim(); 2821 _dataChanged = true; 2822 _curAction.setActionString(""); 2823 _curAction.setActionData(-1); 2824 if (!checkReferenceByMemory(name)) { 2825 return false; 2826 } 2827 if (!checkIsVariable(name, itemType) ) { 2828 return false; 2829 } 2830 switch (itemType) { 2831 case SENSOR: 2832 if (!_referenceByMemory) { 2833 name = _parent.validateSensorReference(name); 2834 if (name == null) { 2835 return false; 2836 } 2837 } 2838 actionType = selection; 2839 if ((actionType == Conditional.Action.RESET_DELAYED_SENSOR) 2840 || (actionType == Conditional.Action.DELAYED_SENSOR)) { 2841 if (!_parent.validateTimeReference(actionType, actionString)) { 2842 return (false); 2843 } 2844 _curAction.setActionString(actionString); 2845 } 2846 if ((actionType == Conditional.Action.SET_SENSOR) 2847 || (actionType == Conditional.Action.RESET_DELAYED_SENSOR) 2848 || (actionType == Conditional.Action.DELAYED_SENSOR)) { 2849 if (_actionBox.getSelectedIndex() == 0) { 2850 _curAction.setActionData(Sensor.ACTIVE); 2851 } else if (_actionBox.getSelectedIndex() == 1) { 2852 _curAction.setActionData(Sensor.INACTIVE); 2853 } else { 2854 _curAction.setActionData(Route.TOGGLE); 2855 } 2856 } 2857 _actionNameField.setText(name); 2858 _curAction.setDeviceName(name); 2859 break; 2860 case TURNOUT: 2861 if (!_referenceByMemory) { 2862 name = _parent.validateTurnoutReference(name); 2863 if (name == null) { 2864 return false; 2865 } 2866 } 2867 actionType = selection; 2868 if ((actionType == Conditional.Action.RESET_DELAYED_TURNOUT) 2869 || (actionType == Conditional.Action.DELAYED_TURNOUT)) { 2870 if (!_parent.validateTimeReference(actionType, actionString)) { 2871 return (false); 2872 } 2873 _curAction.setActionString(actionString); 2874 } 2875 if ((actionType == Conditional.Action.SET_TURNOUT) 2876 || (actionType == Conditional.Action.RESET_DELAYED_TURNOUT) 2877 || (actionType == Conditional.Action.DELAYED_TURNOUT)) { 2878 if (_actionBox.getSelectedIndex() == 0) { 2879 _curAction.setActionData(Turnout.CLOSED); 2880 } else if (_actionBox.getSelectedIndex() == 1) { 2881 _curAction.setActionData(Turnout.THROWN); 2882 } else { 2883 _curAction.setActionData(Route.TOGGLE); 2884 } 2885 } else if (actionType == Conditional.Action.LOCK_TURNOUT) { 2886 if (_actionBox.getSelectedIndex() == 0) { 2887 _curAction.setActionData(Turnout.UNLOCKED); 2888 } else if (_actionBox.getSelectedIndex() == 1) { 2889 _curAction.setActionData(Turnout.LOCKED); 2890 } else { 2891 _curAction.setActionData(Route.TOGGLE); 2892 } 2893 } 2894 _actionNameField.setText(name); 2895 _curAction.setDeviceName(name); 2896 break; 2897 case LIGHT: 2898 if (!_referenceByMemory) { 2899 name = _parent.validateLightReference(name); 2900 if (name == null) { 2901 return false; 2902 } 2903 } 2904 actionType = selection; 2905 if (actionType == Conditional.Action.SET_LIGHT_INTENSITY) { 2906 Light lgtx = _parent.getLight(name); 2907 // check if light user name was entered 2908 if (lgtx == null) { 2909 return false; 2910 } 2911 if (!(lgtx instanceof VariableLight)) { 2912 JmriJOptionPane.showMessageDialog(this, 2913 Bundle.getMessage("Error45", name), // NOI18N 2914 Bundle.getMessage("ErrorTitle"), 2915 JmriJOptionPane.ERROR_MESSAGE); // NOI18N 2916 return (false); 2917 } 2918 if (!_parent.validateIntensityReference(actionType, actionString)) { 2919 return (false); 2920 } 2921 _curAction.setActionString(actionString); 2922 } else if (actionType == Conditional.Action.SET_LIGHT_TRANSITION_TIME) { 2923 Light lgtx = _parent.getLight(name); 2924 // check if light user name was entered 2925 if (lgtx == null) { 2926 return false; 2927 } 2928 if ( !(lgtx instanceof VariableLight) || 2929 !((VariableLight)lgtx).isTransitionAvailable()) { 2930 JmriJOptionPane.showMessageDialog(this, 2931 Bundle.getMessage("Error40", name), // NOI18N 2932 Bundle.getMessage("ErrorTitle"), 2933 JmriJOptionPane.ERROR_MESSAGE); // NOI18N 2934 return (false); 2935 } 2936 if (!_parent.validateTimeReference(actionType, actionString)) { 2937 return (false); 2938 } 2939 _curAction.setActionString(actionString); 2940 } else if (actionType == Conditional.Action.SET_LIGHT) { 2941 if (_actionBox.getSelectedIndex() == 0) { 2942 _curAction.setActionData(Light.ON); 2943 } else if (_actionBox.getSelectedIndex() == 1) { 2944 _curAction.setActionData(Light.OFF); 2945 } else { 2946 _curAction.setActionData(Route.TOGGLE); 2947 } 2948 } 2949 _actionNameField.setText(name); 2950 _curAction.setDeviceName(name); 2951 break; 2952 case SIGNALHEAD: 2953 if (!_referenceByMemory) { 2954 name = _parent.validateSignalHeadReference(name); 2955 if (name == null) { 2956 return false; 2957 } 2958 } 2959 actionType = selection; 2960 if (actionType == Conditional.Action.SET_SIGNAL_APPEARANCE) { 2961 String appStr = (String) _actionBox.getSelectedItem(); 2962 _curAction.setActionData(DefaultConditionalAction.stringToActionData(appStr)); 2963 _curAction.setActionString(appStr); 2964 } 2965 _actionNameField.setText(name); 2966 _curAction.setDeviceName(name); 2967 break; 2968 case SIGNALMAST: 2969 if (!_referenceByMemory) { 2970 name = _parent.validateSignalMastReference(name); 2971 if (name == null) { 2972 return false; 2973 } 2974 } 2975 actionType = selection; 2976 if (actionType == Conditional.Action.SET_SIGNALMAST_ASPECT) { 2977 _curAction.setActionString((String) _actionBox.getSelectedItem()); 2978 } 2979 _actionNameField.setText(name); 2980 _curAction.setDeviceName(name); 2981 break; 2982 case MEMORY: 2983 if (_referenceByMemory) { 2984 JmriJOptionPane.showMessageDialog(_editActionFrame, 2985 Bundle.getMessage("Warn6"), 2986 Bundle.getMessage("WarningTitle"), // NOI18N 2987 JmriJOptionPane.WARNING_MESSAGE); 2988 return false; 2989 } 2990 name = _parent.validateMemoryReference(name); 2991 if (name == null) { 2992 return false; 2993 } 2994 actionType = selection; 2995 if (actionType == Conditional.Action.COPY_MEMORY) { 2996 actionString = _parent.validateMemoryReference(actionString); 2997 if (actionString == null) { 2998 return false; 2999 } 3000 } 3001 _actionNameField.setText(name); 3002 _curAction.setDeviceName(name); 3003 _curAction.setActionString(actionString); 3004 break; 3005 case LOGIX: 3006 if (!_referenceByMemory) { 3007 name = _parent.validateLogixReference(name); 3008 if (name == null) { 3009 return false; 3010 } 3011 } 3012 actionType = selection; 3013 _actionNameField.setText(name); 3014 _curAction.setDeviceName(name); 3015 break; 3016 case WARRANT: 3017 if (!_referenceByMemory) { 3018 name = _parent.validateWarrantReference(name); 3019 if (name == null) { 3020 return false; 3021 } 3022 } 3023 actionType = selection; 3024 _actionNameField.setText(name); 3025 _curAction.setDeviceName(name); 3026 if (actionType == Conditional.Action.CONTROL_TRAIN) { 3027 switch (_actionBox.getSelectedIndex()) { 3028 case 0: 3029 _curAction.setActionData(Warrant.HALT); 3030 break; 3031 case 1: 3032 _curAction.setActionData(Warrant.RESUME); 3033 break; 3034 case 2: 3035 _curAction.setActionData(Warrant.RETRY_FWD); 3036 break; 3037 case 3: 3038 _curAction.setActionData(Warrant.SPEED_UP); 3039 break; 3040 case 4: 3041 _curAction.setActionData(Warrant.STOP); 3042 break; 3043 case 5: 3044 _curAction.setActionData(Warrant.ESTOP); 3045 break; 3046 case 6: 3047 _curAction.setActionData(Warrant.ABORT); 3048 break; 3049 default: 3050 log.warn("Unexpected _actionBox.getSelectedIndex() of {}", _actionBox.getSelectedIndex()); // NOI18N 3051 break; 3052 } 3053 } else if (actionType == Conditional.Action.SET_TRAIN_ID 3054 || actionType == Conditional.Action.SET_TRAIN_NAME 3055 || actionType == Conditional.Action.GET_TRAIN_LOCATION) { 3056 _curAction.setActionString(actionString); 3057 } 3058 break; 3059 case OBLOCK: 3060 if (!_referenceByMemory) { 3061 name = _parent.validateOBlockReference(name); 3062 if (name == null) { 3063 return false; 3064 } 3065 } 3066 actionType = selection; 3067 _actionNameField.setText(name); 3068 _curAction.setDeviceName(name); 3069 if (actionType == Conditional.Action.SET_BLOCK_VALUE 3070 || actionType == Conditional.Action.GET_BLOCK_TRAIN_NAME 3071 || actionType == Conditional.Action.GET_BLOCK_WARRANT) { 3072 _curAction.setActionString(actionString); 3073 } 3074 break; 3075 case ENTRYEXIT: 3076 if (!_referenceByMemory) { 3077 name = _parent.validateEntryExitReference(name); 3078 if (name == null) { 3079 return false; 3080 } 3081 } 3082 actionType = selection; 3083 _actionNameField.setText(name); 3084 _curAction.setDeviceName(name); 3085 break; 3086 case CLOCK: 3087 actionType = selection; 3088 if (actionType == Conditional.Action.SET_FAST_CLOCK_TIME) { 3089 int time = _parent.parseTime(_longActionString.getText().trim()); 3090 if (time < 0) { 3091 return (false); 3092 } 3093 _curAction.setActionData(time); 3094 } 3095 break; 3096 case AUDIO: 3097 actionType = selection; 3098 if (actionType == Conditional.Action.PLAY_SOUND) { 3099 _curAction.setActionString(_longActionString.getText().trim()); 3100 } else if (actionType == Conditional.Action.CONTROL_AUDIO) { 3101 if (!_referenceByMemory) { 3102 name = _parent.validateAudioReference(name); 3103 if (name == null) { 3104 return false; 3105 } 3106 } 3107 _actionNameField.setText(name); 3108 _curAction.setDeviceName(name); 3109 switch (_actionBox.getSelectedIndex()) { 3110 case 0: 3111 _curAction.setActionData(Audio.CMD_PLAY); 3112 break; 3113 case 1: 3114 _curAction.setActionData(Audio.CMD_STOP); 3115 break; 3116 case 2: 3117 _curAction.setActionData(Audio.CMD_PLAY_TOGGLE); 3118 break; 3119 case 3: 3120 _curAction.setActionData(Audio.CMD_PAUSE); 3121 break; 3122 case 4: 3123 _curAction.setActionData(Audio.CMD_RESUME); 3124 break; 3125 case 5: 3126 _curAction.setActionData(Audio.CMD_PAUSE_TOGGLE); 3127 break; 3128 case 6: 3129 _curAction.setActionData(Audio.CMD_REWIND); 3130 break; 3131 case 7: 3132 _curAction.setActionData(Audio.CMD_FADE_IN); 3133 break; 3134 case 8: 3135 _curAction.setActionData(Audio.CMD_FADE_OUT); 3136 break; 3137 case 9: 3138 _curAction.setActionData(Audio.CMD_RESET_POSITION); 3139 break; 3140 default: 3141 log.warn("Unexpected _actionBox.getSelectedIndex() of {}", _actionBox.getSelectedIndex()); // NOI18N 3142 break; 3143 } 3144 } 3145 break; 3146 case SCRIPT: 3147 actionType = selection; 3148 if (actionType == Conditional.Action.RUN_SCRIPT) { 3149 _curAction.setActionString(_longActionString.getText().trim()); 3150 } else if (actionType == Conditional.Action.JYTHON_COMMAND) { 3151 _curAction.setActionString(_shortActionString.getText().trim()); 3152 } 3153 break; 3154 case OTHER: 3155 actionType = selection; 3156 if (actionType == Conditional.Action.TRIGGER_ROUTE) { 3157 if (!_referenceByMemory) { 3158 name = _parent.validateRouteReference(name); 3159 if (name == null) { 3160 return false; 3161 } 3162 } 3163 _actionNameField.setText(name); 3164 _curAction.setDeviceName(name); 3165 } 3166 break; 3167 default: 3168 break; 3169 } 3170 _curAction.setType(actionType); 3171 if (actionType != Conditional.Action.NONE) { 3172 _curAction.setOption(_actionOptionBox.getSelectedIndex() + 1); 3173 } else { 3174 _curAction.setOption(0); 3175 } 3176 _editActionFrame.pack(); 3177 return (true); 3178 } 3179 3180 // ------------ Action detail listeners ------------ 3181 /** 3182 * Listener for _actionTypeBox. 3183 */ 3184 class ActionTypeListener implements ActionListener { 3185 3186 Conditional.ItemType _itemType; 3187 3188 @Override 3189 public void actionPerformed(ActionEvent e) { 3190 Conditional.ItemType select1 = _actionItemBox.getItemAt(_actionItemBox.getSelectedIndex()); 3191 Conditional.Action select2 = _actionTypeBox.getItemAt(_actionTypeBox.getSelectedIndex()); 3192 log.debug("ActionTypeListener: actionItemType= {}, _itemType= {}, action= {}", 3193 select1, _itemType, select2); // NOI18N 3194 if (select1 != _itemType) { 3195 log.debug("ActionTypeListener actionItem selection ({}) != expected actionItem ({})", 3196 select1, _itemType); // NOI18N 3197 } 3198 if (_curAction != null) { 3199 if (select1 != Conditional.ItemType.NONE && _itemType == select1) { 3200 _curAction.setType(select2); 3201 if (select1 == _itemType) { 3202 String text = _actionNameField.getText(); 3203 if (text != null && text.length() > 0) { 3204 _curAction.setDeviceName(text); 3205 } 3206 } 3207 actionItemChanged(_itemType); 3208 initializeActionVariables(); 3209 _dataChanged = true; 3210 } 3211 } 3212 } 3213 3214 public void setItemType(Conditional.ItemType type) { 3215 _itemType = type; 3216 } 3217 } 3218 ActionTypeListener _actionTypeListener = new ActionTypeListener(); 3219 3220 transient ActionListener actionSignalHeadNameListener = new ActionListener() { 3221 @Override 3222 public void actionPerformed(ActionEvent e) { 3223 // fired when signal head name changes, but only 3224 // while in signal head mode 3225 log.debug("actionSignalHeadNameListener fires; _actionNameField: {}", _actionNameField.getText().trim()); // NOI18N 3226 loadJComboBoxWithHeadAppearances(_actionBox, _actionNameField.getText().trim()); 3227 _dataChanged = true; 3228 } 3229 }; 3230 3231 transient ActionListener actionSignalMastNameListener = new ActionListener() { 3232 @Override 3233 public void actionPerformed(ActionEvent e) { 3234 // fired when signal mast name changes, but only 3235 // while in signal mast mode 3236 log.debug("actionSignalMastNameListener fires; _actionNameField: {}", _actionNameField.getText().trim()); // NOI18N 3237 loadJComboBoxWithMastAspects(_actionBox, _actionNameField.getText().trim()); 3238 _dataChanged = true; 3239 } 3240 }; 3241 3242 /** 3243 * Table model for State Variables in Edit Conditional pane. 3244 */ 3245 public class VariableTableModel extends AbstractTableModel { 3246 3247 public static final int ROWNUM_COLUMN = 0; 3248 public static final int AND_COLUMN = 1; 3249 public static final int NOT_COLUMN = 2; 3250 public static final int DESCRIPTION_COLUMN = 3; 3251 public static final int STATE_COLUMN = 4; 3252 public static final int TRIGGERS_COLUMN = 5; 3253 public static final int EDIT_COLUMN = 6; 3254 public static final int DELETE_COLUMN = 7; 3255 3256 @Override 3257 public Class<?> getColumnClass(int c) { 3258 switch (c) { 3259 case ROWNUM_COLUMN: 3260 return String.class; 3261 case AND_COLUMN: 3262 return JComboBox.class; 3263 case NOT_COLUMN: 3264 return JComboBox.class; 3265 case DESCRIPTION_COLUMN: 3266 return String.class; 3267 case STATE_COLUMN: 3268 return String.class; 3269 case TRIGGERS_COLUMN: 3270 return Boolean.class; 3271 case EDIT_COLUMN: 3272 case DELETE_COLUMN: 3273 return JButton.class; 3274 default: 3275 // fall through 3276 break; 3277 } 3278 return String.class; 3279 } 3280 3281 @Override 3282 public int getColumnCount() { 3283 return 8; 3284 } 3285 3286 @Override 3287 public int getRowCount() { 3288 return _variableList.size(); 3289 } 3290 3291 @Override 3292 public boolean isCellEditable(int r, int c) { 3293 switch (c) { 3294 case ROWNUM_COLUMN: 3295 case DESCRIPTION_COLUMN: 3296 case STATE_COLUMN: 3297 return (false); 3298 case AND_COLUMN: 3299 return (_logicType == Conditional.AntecedentOperator.MIXED); 3300 case NOT_COLUMN: 3301 case TRIGGERS_COLUMN: 3302 return (true); 3303 case EDIT_COLUMN: 3304 if (_inVarReorder) { 3305 return false; 3306 } 3307 return (true); 3308 case DELETE_COLUMN: 3309 if (_inVarReorder && r < _nextInOrder) { 3310 return false; 3311 } 3312 return true; 3313 default: 3314 // fall through 3315 break; 3316 } 3317 return false; 3318 } 3319 3320 @Override 3321 public String getColumnName(int col) { 3322 switch (col) { 3323 case ROWNUM_COLUMN: 3324 return (Bundle.getMessage("ColumnLabelRow")); // NOI18N 3325 case AND_COLUMN: 3326 return (Bundle.getMessage("ColumnLabelOperator")); // NOI18N 3327 case NOT_COLUMN: 3328 return (Bundle.getMessage("ColumnLabelNot")); // NOI18N 3329 case DESCRIPTION_COLUMN: 3330 return (Bundle.getMessage("ColumnLabelDescription")); // NOI18N 3331 case STATE_COLUMN: 3332 return (Bundle.getMessage("ColumnState")); // NOI18N 3333 case TRIGGERS_COLUMN: 3334 return (Bundle.getMessage("ColumnLabelTriggersCalculation")); // NOI18N 3335 case EDIT_COLUMN: 3336 return ""; 3337 case DELETE_COLUMN: 3338 return ""; 3339 default: 3340 // fall through 3341 break; 3342 } 3343 return ""; 3344 } 3345 3346 public int getPreferredWidth(int col) { 3347 if (col == DESCRIPTION_COLUMN) { 3348 return 400; 3349 } 3350 return 10; 3351 } 3352 3353 @Override 3354 public Object getValueAt(int row, int col) { 3355 if (row >= _variableList.size()) { 3356 return null; 3357 } 3358 ConditionalVariable variable = _variableList.get(row); 3359 switch (col) { 3360 case ROWNUM_COLUMN: 3361 return ("R" + (row + 1)); // NOI18N 3362 case AND_COLUMN: 3363 if (row == 0) { //removed: || _logicType == Conditional.MIXED 3364 return ""; 3365 } 3366 return variable.getOpernString(); // also display Operand selection when set to Mixed 3367 case NOT_COLUMN: 3368 if (variable.isNegated()) { 3369 return Bundle.getMessage("LogicNOT"); // NOI18N 3370 } 3371 break; 3372 case DESCRIPTION_COLUMN: 3373 return variable.toString(); 3374 case STATE_COLUMN: 3375 switch (variable.getState()) { 3376 case Conditional.TRUE: 3377 return Bundle.getMessage("True"); // NOI18N 3378 case Conditional.FALSE: 3379 return Bundle.getMessage("False"); // NOI18N 3380 case NamedBean.UNKNOWN: 3381 return Bundle.getMessage("BeanStateUnknown"); // NOI18N 3382 default: 3383 log.warn("Unhandled state type: {}", variable.getState()); // NOI18N 3384 break; 3385 } 3386 break; 3387 case TRIGGERS_COLUMN: 3388 return variable.doTriggerActions(); 3389 case EDIT_COLUMN: 3390 return Bundle.getMessage("ButtonEdit"); // NOI18N 3391 case DELETE_COLUMN: 3392 if (!_inVarReorder) { 3393 return Bundle.getMessage("ButtonDelete"); // NOI18N 3394 } else if (_nextInOrder == 0) { 3395 return Bundle.getMessage("ButtonFirst"); // NOI18N 3396 } else if (_nextInOrder <= row) { 3397 return Bundle.getMessage("ButtonNext"); // NOI18N 3398 } 3399 return Integer.toString(row + 1); 3400 default: 3401 break; 3402 } 3403 return null; 3404 } 3405 3406 @Override 3407 public void setValueAt(Object value, int row, int col) { 3408 if (row >= _variableList.size()) { 3409 return; 3410 } 3411 ConditionalVariable variable = _variableList.get(row); 3412 switch (col) { 3413 case AND_COLUMN: 3414 variableOperatorChanged(row, (String) value); 3415 break; 3416 case NOT_COLUMN: 3417 variableNegationChanged(row, (String) value); 3418 break; 3419 case STATE_COLUMN: 3420 String state = ((String) value); 3421 if (state.equals(Bundle.getMessage("True").toUpperCase().trim())) { // NOI18N 3422 variable.setState(State.TRUE.getIntValue()); 3423 } else if (state.equals(Bundle.getMessage("False").toUpperCase().trim())) { // NOI18N 3424 variable.setState(State.FALSE.getIntValue()); 3425 } else { 3426 variable.setState(State.UNKNOWN.getIntValue()); 3427 } 3428 break; 3429 case TRIGGERS_COLUMN: 3430 variable.setTriggerActions(!variable.doTriggerActions()); 3431 break; 3432 case EDIT_COLUMN: 3433 if (LRouteTableAction.getLogixInitializer().equals(_parent._curLogix.getSystemName())) { 3434 JmriJOptionPane.showMessageDialog(_editVariableFrame, 3435 Bundle.getMessage("Error49"), 3436 Bundle.getMessage("ErrorTitle"), // NOI18N 3437 JmriJOptionPane.ERROR_MESSAGE); 3438 break; 3439 } 3440 // Use separate Runnable so window is created on top 3441 class WindowMaker implements Runnable { 3442 int row; 3443 WindowMaker(int r) { 3444 row = r; 3445 } 3446 3447 @Override 3448 public void run() { 3449 makeEditVariableWindow(row); 3450 } 3451 } 3452 WindowMaker t = new WindowMaker(row); 3453 javax.swing.SwingUtilities.invokeLater(t); 3454 break; 3455 case DELETE_COLUMN: 3456 if (_inVarReorder) { 3457 swapVariables(row); 3458 } else { 3459 deleteVariablePressed(row); 3460 } 3461 break; 3462 default: 3463 break; 3464 } 3465 } 3466 } 3467 3468 //------------------- Table Models ---------------------- 3469 /** 3470 * Table model for Actions in Edit Conditional pane. 3471 */ 3472 public class ActionTableModel extends AbstractTableModel { 3473 3474 public static final int DESCRIPTION_COLUMN = 0; 3475 public static final int EDIT_COLUMN = 1; 3476 public static final int DELETE_COLUMN = 2; 3477 3478 @Override 3479 public Class<?> getColumnClass(int c) { 3480 if (c == EDIT_COLUMN || c == DELETE_COLUMN) { 3481 return JButton.class; 3482 } 3483 return super.getColumnClass(c); 3484 } 3485 3486 @Override 3487 public int getColumnCount() { 3488 return 3; 3489 } 3490 3491 @Override 3492 public int getRowCount() { 3493 return _actionList.size(); 3494 } 3495 3496 @Override 3497 public boolean isCellEditable(int r, int c) { 3498 if (c == DESCRIPTION_COLUMN) { 3499 return false; 3500 } 3501 if (_inActReorder && (c == EDIT_COLUMN || r < _nextInOrder)) { 3502 return false; 3503 } 3504 return true; 3505 } 3506 3507 @Override 3508 public String getColumnName(int col) { 3509 if (col == DESCRIPTION_COLUMN) { 3510 return Bundle.getMessage("LabelActionDescription"); // NOI18N 3511 } 3512 return ""; 3513 } 3514 3515 public int getPreferredWidth(int col) { 3516 if (col == DESCRIPTION_COLUMN) { 3517 return 800; 3518 } 3519 return 20; 3520 } 3521 3522 @Override 3523 public Object getValueAt(int row, int col) { 3524 if (row >= _actionList.size()) { 3525 return null; 3526 } 3527 switch (col) { 3528 case DESCRIPTION_COLUMN: 3529 ConditionalAction action = _actionList.get(row); 3530 return action.description(_triggerOnChangeButton.isSelected()); 3531 case EDIT_COLUMN: 3532 return Bundle.getMessage("ButtonEdit"); // NOI18N 3533 case DELETE_COLUMN: 3534 if (!_inActReorder) { 3535 return Bundle.getMessage("ButtonDelete"); // NOI18N 3536 } else if (_nextInOrder == 0) { 3537 return Bundle.getMessage("ButtonFirst"); // NOI18N 3538 } else if (_nextInOrder <= row) { 3539 return Bundle.getMessage("ButtonNext"); // NOI18N 3540 } 3541 return Integer.toString(row + 1); 3542 default: 3543 // fall through 3544 break; 3545 } 3546 return null; 3547 } 3548 3549 @Override 3550 public void setValueAt(Object value, int row, int col) { 3551 if (col == EDIT_COLUMN) { 3552 // Use separate Runnable so window is created on top 3553 class WindowMaker implements Runnable { 3554 private int _row; 3555 WindowMaker(int r) { 3556 _row = r; 3557 } 3558 3559 @Override 3560 public void run() { 3561 makeEditActionWindow(_row); 3562 } 3563 } 3564 WindowMaker t = new WindowMaker(row); 3565 javax.swing.SwingUtilities.invokeLater(t); 3566 } else if (col == DELETE_COLUMN) { 3567 if (_inActReorder) { 3568 swapActions(row); 3569 } else { 3570 deleteActionPressed(row); 3571 } 3572 } 3573 } 3574 } 3575 3576 private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(ConditionalEditFrame.class); 3577 3578}