java/src/jmri/jmrix/loconet/ds64/Ds64TabbedPanel.java
package jmri.jmrix.loconet.ds64;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.util.ArrayList;
import java.util.Collections;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JSeparator;
import javax.swing.JTabbedPane;
import javax.swing.JToggleButton;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import jmri.jmrix.loconet.AbstractBoardProgPanel;
import jmri.jmrix.loconet.LnConstants;
import jmri.jmrix.loconet.LocoNetMessage;
import jmri.jmrix.loconet.LocoNetSystemConnectionMemo;
import jmri.util.swing.JmriJOptionPane;
import jmri.util.swing.ValidatedTextField;
/**
* A "tabbed" swing panel to display and modify Digitrax DS64 board
* configuration.
* <p>
* The read and write operations require a sequence of operations, which are
* handled with a state variable.
* <p>
* Programming of the DS64 is done via LocoNet configuration messages, so the
* DS64 should not be manually put into its programming mode via the DS64
* built-in pushbutton while this tool is in use.
* <p>
* Some of the message formats used in this class are Copyright Digitrax, Inc.
* and used with permission as part of the JMRI project. That permission does
* not extend to uses in other software products. If you wish to use this code,
* algorithm or these message formats outside of JMRI, please contact Digitrax
* Inc for separate permission.
* <p>
* Extensions to include read/write of turnout output addresses and routes are
* based on reverse-engineering of DS64 operating characteristics by B.
* Milhaupt. As such, this tool may not be compatible with all DS64 devices.
* <hr>
* This file is part of JMRI.
* <p>
* JMRI is free software; you can redistribute it and/or modify it under the
* terms of version 2 of the GNU General Public License as published by the Free
* Software Foundation. See the "COPYING" file for a copy of this license.
* <p>
* JMRI is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
* <p>
* Based on Revision 1.1 of DS64Panel.java by Bob Jacobsen
*
* @author Bob Jacobsen Copyright (C) 2002, 2004, 2005, 2007, 2010
* @author B. Milhaupt Copyright (C) 2011, 2012, 2013, 2014, 2015, 2016, 2017
*/
public class Ds64TabbedPanel extends AbstractBoardProgPanel {
/**
* Ds64TabbedPanel constructor when the boardNum is already known. Allows
* the instantiating method to specify whether the basic feature
* configuration information will be read upon instantiation.
*
* @param boardNum initial BoardID number
* @param readOnInit true to automatically read the basic configuration
* info.
*/
public Ds64TabbedPanel(int boardNum, boolean readOnInit) {
super(boardNum, readOnInit, "DS64"); // NOI18N
origAccessBoardNum = boardNum;
boardNumsEntryValue.add(boardNum);
}
/**
* Ds64TabbedPanel constructor when the boardNum is not already known.
* <p>
* At instantiation, the object will automatically assume BoardID 1 and will
* not pre-read the basic board configuration information.
*/
public Ds64TabbedPanel() {
// this is a constructor which is in-place to support legacy applications.
this(1, false);
}
/**
* Ds64TabbedPanel constructor when the boardNum is already known.
* <p>
* When instantiated, the object will not automatically read the basic
* configuration information.
*
* @param boardNum initial BoardID number
*/
public Ds64TabbedPanel(int boardNum) {
this(boardNum, false);
origAccessBoardNum = boardNum;
}
int[] boardNumbers;
int origAccessBoardNum = 0;
ArrayList<Integer> boardNumsEntryValue = new ArrayList<>();
/**
* Ds64TabbedPanel constructor which may be used when the instantiating
* method already has an array of DS64 BoardID numbers; this array is used
* to pre-populate the GUI combobox showing BoardID numbers. The first
* BoardID number in the array will automatically be selected upon
* instantiation.
* <p>
* When instantiated, the object will automatically read the basic
* configuration information if readOnInit is true.
*
* @param readOnInit true to automatically read the basic configuration info
* from the DS64 with BoardID equal to the first value in
* the boardNums array
* @param boardNums Array of known DS64 BoardID numbers
*/
public Ds64TabbedPanel(boolean readOnInit, Integer[] boardNums) {
this(boardNums[0], readOnInit);
log.debug("into DS64 tabbed panel with list of boards of length {}", boardNums.length); // NOI18N
log.debug("boardNums[0] = {}", boardNums[0]); // NOI18N
origAccessBoardNum = boardNums[0];
boardNumsEntryValue.remove(0); // remove the entry added by Ds64TabbedPanel(int boardNum, boolean readOnInit)
for (int boardNum : boardNums) {
log.debug("board {}", boardNum); // NOI18N
boardNumsEntryValue.add(boardNum);
}
Collections.sort(boardNumsEntryValue);
}
/**
* Ds64TabbedPanel constructor when the boardNum is not known; BoardID 1 is
* assumed.
* <p>
* Allows the instantiating method to specify whether the basic feature
* configuration information will be read upon instantiation.
*
* @param readBoardOnInit true to automatically read the basic configuration
* info.
*/
public Ds64TabbedPanel(boolean readBoardOnInit) {
this(1, readBoardOnInit);
}
JPanel generalPanel = null;
JPanel opswsPanel = null;
JScrollPane opswsScrollPane = null;
JTabbedPane generalTabbedPane = null;
JTabbedPane routesTabbedPane;
JPanel opswsValues = null;
JPanel outputAddrsPanel = null;
ValidatedTextField outAddr1 = null;
JLabel outState1 = null;
ValidatedTextField outAddr2 = null;
JLabel outState2 = null;
ValidatedTextField outAddr3 = null;
JLabel outState3 = null;
ValidatedTextField outAddr4 = null;
JLabel outState4 = null;
JPanel[] routePanel;
SimpleTurnoutStateEntry[] routeTop;
SimpleTurnoutStateEntry[] routeA2;
SimpleTurnoutStateEntry[] routeA3;
SimpleTurnoutStateEntry[] routeA4;
SimpleTurnoutStateEntry[] routeA5;
SimpleTurnoutStateEntry[] routeA6;
SimpleTurnoutStateEntry[] routeA7;
SimpleTurnoutStateEntry[] routeA8;
JToggleButton resetRouteButton = null;
JComboBox<Integer> addressComboBox;
// output controls
JLabel outputTypeLabel;
JComboBox<String> outputType;
JLabel delayTimeLabel;
JComboBox<String> delayTime;
JLabel outputStatesLabel;
JComboBox<String> outputStates;
JLabel startupDelayLabel;
JComboBox<String> startupDelay;
JLabel staticOutputShutoffLabel;
JComboBox<String> staticOutputShutoff;
// command sources
JLabel commandTypeLabel;
JComboBox<String> commandType;
JLabel commandSourceLabel;
JComboBox<String> commandSource;
// Crossbuck Flasher controls
JCheckBox output1CrossbuckFlasherCheckBox;
JCheckBox output2CrossbuckFlasherCheckBox;
JCheckBox output3CrossbuckFlasherCheckBox;
JCheckBox output4CrossbuckFlasherCheckBox;
// DS64 routes
JLabel routesControlLabel;
JComboBox<String> routesControl;
// local input controls
JLabel localControlOfOutputsStyleLabel;
JComboBox<String> localControlOfOutputsStyle;
JLabel sensorMessageTriggerLabel;
JComboBox<String> sensorMessageTrigger;
JComboBox<String> localSensorType;
JToggleButton factoryResetButton;
JRadioButtonWithInteger[] opswThrown = new JRadioButtonWithInteger[21];
JRadioButtonWithInteger[] opswClosed = new JRadioButtonWithInteger[21];
JPanel sensorMessageTriggerPanel;
JPanel localInputControlsPanel;
@Override
public String getHelpTarget() {
return "package.jmri.jmrix.loconet.ds64.DS64TabbedPanel"; // NOI18N
}
@Override
public String getTitle() {
return getTitle(Bundle.getMessage("MenuItemDS64Programmer"));
}
public javax.swing.Timer boardResetResponseTimer = null;
public void updateGuiBasicOpSw(int index) {
if ((index < 1) || (index == 7) || (index > 21)) {
return;
}
if (opsw[index]) {
opswThrown[index].setSelected(false);
opswClosed[index].setSelected(true);
} else {
opswThrown[index].setSelected(true);
opswClosed[index].setSelected(false);
}
opswThrown[index].updateUI();
opswClosed[index].updateUI();
}
/**
* Copy from the GUI to the opsw array.
* <p>
* Used before write operations start.
*/
@Override
protected void copyToOpsw() {
// copy over the display
opsw[1] = (outputType.getSelectedIndex() == 1);
updateGuiBasicOpSw(1);
int selection = delayTime.getSelectedIndex();
opsw[2] = ((selection & 0x1) == 1);
opsw[3] = ((selection & 0x2) == 2);
opsw[4] = ((selection & 0x4) == 4);
opsw[5] = ((selection & 0x8) == 8);
updateGuiBasicOpSw(2);
updateGuiBasicOpSw(3);
updateGuiBasicOpSw(4);
updateGuiBasicOpSw(5);
opsw[6] = (outputStates.getSelectedIndex() == 1);
updateGuiBasicOpSw(6);
opsw[7] = (isWritingResetOpSw ? resetOpSwVal : false);
updateGuiBasicOpSw(7);
opsw[8] = startupDelay.getSelectedIndex() == 1;
updateGuiBasicOpSw(8);
opsw[9] = staticOutputShutoff.getSelectedIndex() == 1;
updateGuiBasicOpSw(9);
opsw[10] = commandType.getSelectedIndex() == 1;
updateGuiBasicOpSw(10);
opsw[11] = (routesControl.getSelectedIndex() == 1) || (routesControl.getSelectedIndex() == 3);
updateGuiBasicOpSw(11);
opsw[12] = (localControlOfOutputsStyle.getSelectedIndex() & 1) == 1; //2 -> OpSw12="c"
updateGuiBasicOpSw(12);
opsw[13] = (sensorMessageTrigger.getSelectedIndex() == 1);
updateGuiBasicOpSw(13);
opsw[14] = commandSource.getSelectedIndex() == 1;
updateGuiBasicOpSw(14);
opsw[15] = (localControlOfOutputsStyle.getSelectedIndex() >= 2); //0 -> OpSw15="c"
updateGuiBasicOpSw(15);
opsw[16] = routesControl.getSelectedIndex() >= 2;
updateGuiBasicOpSw(16);
opsw[17] = output1CrossbuckFlasherCheckBox.isSelected();
updateGuiBasicOpSw(17);
opsw[18] = output2CrossbuckFlasherCheckBox.isSelected();
updateGuiBasicOpSw(18);
opsw[19] = output3CrossbuckFlasherCheckBox.isSelected();
updateGuiBasicOpSw(19);
opsw[20] = output4CrossbuckFlasherCheckBox.isSelected();
updateGuiBasicOpSw(20);
opsw[21] = localSensorType.getSelectedIndex() == 1;
updateGuiBasicOpSw(21);
}
java.awt.Component colorizedObject;
@Override
protected void updateDisplay() {
switch (state) {
case 1:
outputType.setSelectedIndex((opsw[1] == true) ? 1 : 0);
break;
case 2:
case 3:
case 4:
case 5:
delayTime.setSelectedIndex(
((opsw[2] == true) ? 1 : 0)
+ ((opsw[3] == true) ? 2 : 0)
+ ((opsw[4] == true) ? 4 : 0)
+ ((opsw[5] == true) ? 8 : 0));
break;
case 6:
outputStates.setSelectedIndex((opsw[6] == true) ? 1 : 0);
break;
case 8:
startupDelay.setSelectedIndex((opsw[8] == true) ? 1 : 0);
break;
case 9:
staticOutputShutoff.setSelectedIndex((opsw[9] == true) ? 1 : 0);
break;
case 10:
commandType.setSelectedIndex((opsw[10] == true) ? 1 : 0);
break;
case 11:
case 16:
routesControl.setSelectedIndex((((opsw[16] == true) ? 2 : 0) + (opsw[11] ? 1 : 0)));
break;
case 15:
case 12:
localControlOfOutputsStyle.setSelectedIndex(((opsw[15] == true) ? 2 : 0) + (opsw[12] ? 1 : 0));
break;
case 13:
sensorMessageTrigger.setSelectedIndex((opsw[13] == true) ? 1 : 0); // selection 0 - only for A inputs; 1 - both A and S inputs
break;
case 14:
commandSource.setSelectedIndex((opsw[14] == true) ? 1 : 0);
break;
case 17:
output1CrossbuckFlasherCheckBox.setSelected(opsw[17]);
break;
case 18:
output2CrossbuckFlasherCheckBox.setSelected(opsw[18]);
break;
case 19:
output3CrossbuckFlasherCheckBox.setSelected(opsw[19]);
break;
case 20:
output4CrossbuckFlasherCheckBox.setSelected(opsw[20]);
break;
case 21:
localSensorType.setSelectedIndex(opsw[21] ? 1 : 0);
break;
default:
// we are only interested in the states above. Ignore the rest
log.debug("Unhandled state code: {}", state);
break;
}
updateUI();
}
@Override
@edu.umd.cs.findbugs.annotations.SuppressFBWarnings(value = "DLS_DEAD_LOCAL_STORE", justification = "Cannot catch an exception without grabbing the exception, but we don't do anything with the exception details.")
protected int nextState(int state) {
if (isWritingResetOpSw) {
if ((state == 7) && (opsw[7] == true)) {
opsw[7] = false;
return 7;
} else if (state == 7) {
return 0;
}
}
if (onlyOneOperation == true) {
onlyOneOperation = false;
return 0;
}
if ((state > 1)
&& (((isRead == true) && (readAllButton.isSelected() == false))
|| ((isRead == false)
&& ((writeAllButton.isSelected() == false)
&& (resetRouteButton.isSelected() == false))))) {
// handle case where a button is de-selected by the user during the operation
Color noAccessColor = ValidatedTextField.COLOR_BG_UNEDITED;
if ((operationType == OpSwOpType.BasicsRead)
|| (operationType == OpSwOpType.BasicsWrite)) {
unhighlightAllBasicOpSws();
unhighlightAllOutputEntryFields();
unhighlightAllRouteEntryFields();
return 0;
} else if ((operationType == OpSwOpType.OutputsRead)
|| (operationType == OpSwOpType.OutputsWrite)
|| (operationType == OpSwOpType.Route1Read)
|| (operationType == OpSwOpType.Route1Write)
|| (operationType == OpSwOpType.Route2Read)
|| (operationType == OpSwOpType.Route2Write)
|| (operationType == OpSwOpType.Route3Read)
|| (operationType == OpSwOpType.Route3Write)
|| (operationType == OpSwOpType.Route4Read)
|| (operationType == OpSwOpType.Route4Write)
|| (operationType == OpSwOpType.Route5Read)
|| (operationType == OpSwOpType.Route5Write)
|| (operationType == OpSwOpType.Route6Read)
|| (operationType == OpSwOpType.Route6Write)
|| (operationType == OpSwOpType.Route7Read)
|| (operationType == OpSwOpType.Route7Write)
|| (operationType == OpSwOpType.Route8Read)
|| (operationType == OpSwOpType.Route8Write)) {
// handle stopping of indirect access operations
if (state == 48) {
// for DS64, indirect operations for output addresses or route entries can be
// aborted after the first 16 indirect bits are accessed
changeComponentBgColor(whichComponent(33, indexToRead), noAccessColor);
log.debug("Decided to stop read/write after OpSw 48 because no read/write button selected."); // NOI18N
return 0;
} else if (state == 64) {
// for DS64, indirect operations for output addresses or route entries can be
// aborted after the second 16 indirect bits are accessed
changeComponentBgColor(whichComponent(49, indexToRead), noAccessColor);
log.debug("Decided to stop read/write after OpSw 64 because no read/write button selected."); // NOI18N
return 0;
}
}
}
switch (state) {
case 1: {
if (colorizedObject == null) {
colorizedObject = outputType;
}
colorizedObject.setBackground(null);
isRead = read;
indexToRead = 0;
if ((operationType == null)
|| (operationType == OpSwOpType.BasicsRead)
|| (operationType == OpSwOpType.BasicsWrite)) {
colorizedObject = delayTime;
colorizedObject.setBackground(Color.blue.brighter());
return 2;
} else if ((operationType == OpSwOpType.OutputsRead)
|| (operationType == OpSwOpType.OutputsWrite)) {
indexToRead = 0;
read = false; // want to write opSw 25 thru 32
setOpSwIndex(indexToRead); //set values for opSw25 thru 32 to point to correct index
return 25;
} else if ((operationType == OpSwOpType.Route1Read) || (operationType == OpSwOpType.Route1Write)) {
indexToRead = 16;
read = false; // want to write opSw 25 thru 32
setOpSwIndex(indexToRead); //set values for opSw25 thru 32 to point to correct index
return 25;
} else if ((operationType == OpSwOpType.Route2Read) || (operationType == OpSwOpType.Route2Write)) {
indexToRead = 20;
read = false; // want to write opSw 25 thru 32
setOpSwIndex(indexToRead); //set values for opSw25 thru 32 to point to correct index
return 25;
} else if ((operationType == OpSwOpType.Route3Read) || (operationType == OpSwOpType.Route3Write)) {
indexToRead = 24;
read = false; // want to write opSw 25 thru 32
setOpSwIndex(indexToRead); //set values for opSw25 thru 32 to point to correct index
return 25;
} else if ((operationType == OpSwOpType.Route4Read) || (operationType == OpSwOpType.Route4Write)) {
indexToRead = 28;
read = false; // want to write opSw 25 thru 32
setOpSwIndex(indexToRead); //set values for opSw25 thru 32 to point to correct index
return 25;
} else if ((operationType == OpSwOpType.Route5Read) || (operationType == OpSwOpType.Route5Write)) {
indexToRead = 32;
read = false; // want to write opSw 25 thru 32
setOpSwIndex(indexToRead); //set values for opSw25 thru 32 to point to correct index
return 25;
} else if ((operationType == OpSwOpType.Route6Read) || (operationType == OpSwOpType.Route6Write)) {
indexToRead = 36;
read = false; // want to write opSw 25 thru 32
setOpSwIndex(indexToRead); //set values for opSw25 thru 32 to point to correct index
return 25;
} else if ((operationType == OpSwOpType.Route7Read) || (operationType == OpSwOpType.Route7Write)) {
indexToRead = 40;
read = false; // want to write opSw 25 thru 32
setOpSwIndex(indexToRead); //set values for opSw25 thru 32 to point to correct index
return 25;
} else if ((operationType == OpSwOpType.Route8Read) || (operationType == OpSwOpType.Route8Write)) {
indexToRead = 44;
read = false; // want to write opSw 25 thru 32
setOpSwIndex(indexToRead); //set values for opSw25 thru 32 to point to correct index
return 25;
}
return 0;
}
case 2: {
if (colorizedObject != null) {
colorizedObject.setBackground(null);
}
colorizedObject = delayTime;
colorizedObject.setBackground(Color.blue.brighter());
return 3;
}
case 3: {
if (colorizedObject != null) {
colorizedObject.setBackground(null);
}
colorizedObject = delayTime;
colorizedObject.setBackground(Color.blue.brighter());
return 4;
}
case 4: {
if (colorizedObject != null) {
colorizedObject.setBackground(null);
}
colorizedObject = delayTime;
colorizedObject.setBackground(Color.blue.brighter());
return 5;
}
case 5: {
if (colorizedObject != null) {
colorizedObject.setBackground(null);
}
colorizedObject = outputStates;
colorizedObject.setBackground(Color.blue.brighter());
return 6;
}
case 6: {
if (colorizedObject != null) {
colorizedObject.setBackground(null);
}
colorizedObject = startupDelay;
colorizedObject.setBackground(Color.blue.brighter());
return 8;// 7 has to be done last, as it's reset
}
case 8: {
if (colorizedObject != null) {
colorizedObject.setBackground(null);
}
colorizedObject = staticOutputShutoff;
colorizedObject.setBackground(Color.blue.brighter());
return 9;
}
case 9: {
if (colorizedObject != null) {
colorizedObject.setBackground(null);
}
colorizedObject = commandType;
colorizedObject.setBackground(Color.blue.brighter());
return 10;
}
case 10: {
if (colorizedObject != null) {
colorizedObject.setBackground(null);
}
colorizedObject = routesControl;
colorizedObject.setBackground(Color.blue.brighter());
return 11;
}
case 11: {
if (colorizedObject != null) {
colorizedObject.setBackground(null);
}
colorizedObject = localControlOfOutputsStyle;
colorizedObject.setBackground(Color.blue.brighter());
return 12;
}
case 12: {
if (colorizedObject != null) {
colorizedObject.setBackground(null);
}
colorizedObject = sensorMessageTrigger;
colorizedObject.setBackground(Color.blue.brighter());
return 13;
}
case 13: {
if (colorizedObject != null) {
colorizedObject.setBackground(null);
}
colorizedObject = commandSource;
colorizedObject.setBackground(Color.blue.brighter());
return 14;
}
case 14: {
if (colorizedObject != null) {
colorizedObject.setBackground(null);
}
colorizedObject = localControlOfOutputsStyle;
colorizedObject.setBackground(Color.blue.brighter());
return 15;
}
case 15: {
if (colorizedObject != null) {
colorizedObject.setBackground(null);
}
colorizedObject = routesControl;
colorizedObject.setBackground(Color.blue.brighter());
return 16;
}
case 16: {
if (colorizedObject != null) {
colorizedObject.setBackground(null);
}
colorizedObject = output1CrossbuckFlasherCheckBox;
colorizedObject.setBackground(Color.blue.brighter());
return 17;
}
case 17: {
if (colorizedObject != null) {
colorizedObject.setBackground(null);
}
colorizedObject = output2CrossbuckFlasherCheckBox;
colorizedObject.setBackground(Color.blue.brighter());
return 18;
}
case 18: {
if (colorizedObject != null) {
colorizedObject.setBackground(null);
}
colorizedObject = output3CrossbuckFlasherCheckBox;
colorizedObject.setBackground(Color.blue.brighter());
return 19;
}
case 19: {
if (colorizedObject != null) {
colorizedObject.setBackground(null);
}
colorizedObject = output4CrossbuckFlasherCheckBox;
colorizedObject.setBackground(Color.blue.brighter());
return 20;
}
case 20: {
if (colorizedObject != null) {
colorizedObject.setBackground(null);
}
colorizedObject = localSensorType;
colorizedObject.setBackground(Color.blue.brighter());
return 21;
}
case 21: {
if (colorizedObject != null) {
colorizedObject.setBackground(null);
}
this.readAllButton.setEnabled(true);
this.writeAllButton.setEnabled(true);
return 0;
}
case 22: {
return 0;
}
case 25:
case 26:
case 27:
case 28:
case 29:
case 30:
case 31: {
// handle indirect index bits
return state + 1;
}
case 32: {
read = isRead; // go back to original mode of operation
log.debug("Dealing with index {}", indexToRead);
changeGuiElementHighlight(33, indexToRead);
if (isRead == true) {
return 46; // want to read "out-of-turn" to speed up reads when
// a route entry is disabled
} else {
// prepare values in opsw[] from appropriate write values
updateOpswForWrite(indexToRead);
return 33;
}
}
case 33:
case 34:
case 35:
case 36:
case 37:
case 38:
case 39:
case 40:
case 41:
case 42:
case 43:
case 44:
case 46:
case 47:
return state + 1;
case 45:
if (isRead) {
// Have already read OpSws 64-48 and determined that there is
// a valid value in bits 33-45. Deal with that velue, then
// go to the validity bits for the other half.
int extractedDataValue = 0;
for (int i = 48; i >= 33; i--) {
extractedDataValue = (extractedDataValue << 1) + (opsw[i] ? 1 : 0);
}
log.debug("Read Index {} value (OpSws 33-48) = 0x{}", indexToRead + 1, Integer.toHexString(extractedDataValue));
updateGuiFromOpSws33_48();
changeGuiElementHighlight(48, indexToRead); // clear the highlighted GUI element
return 62; // because OpSws 46, 47, and 48 were read "out-
// of-turn" for speediness, and also want to read OpSws
// 62-64 "out-of-turn" for speediness
} else {
return 46;
}
case 48: {
changeGuiElementHighlight(48, indexToRead);
if (isRead == true) {
// For reads, check the upper bits of this "half" to determine
// whether or not to read the remaining bits in the "half"
if ((opsw[47] == false) && (opsw[48] == false)) {
// entry is valid, so need to read all opSw bits in [46:33]
log.debug("Read of low value in index {} is a valid entry.", indexToRead); // NOI18N
return 33;
} else {
log.debug("Read of low value in index {} is an invalid entry.", indexToRead); // NOI18N
// entry is not valid, so do not need to read opSw bits in [46:33]
// Do need to update internal opSw bits so that they imply an unused
// entry
changeGuiElementUnHighlight(48, indexToRead);
for (int i = 33; i < 46; ++i) {
opsw[i] = true;
}
opsw[40] = false;
// need to update the GUI
updateGuiFromOpSws33_48();
changeGuiElementHighlight(48, indexToRead); // clear the highlighted GUI element
return 62; // need to skip ahead to the validity bits of the
// next entry
}
} else {
// handle the case for writes
int extractedDataValue = 0;
for (int i = 48; i >= 33; i--) {
extractedDataValue = (extractedDataValue << 1) + (opsw[i] ? 1 : 0);
}
log.debug("Wrote Index {} value (OpSws 33-48) = 0x{}", indexToRead + 1, Integer.toHexString(extractedDataValue));
updateGuiFromOpSws33_48();
switch (indexToRead) {
case 0: {
// have written a value for output1 - update GUI
outAddr1.setLastQueriedValue(outAddr1.getText());
break;
}
case 1: {
// have written a value for output3 - update GUI
outAddr3.setLastQueriedValue(outAddr3.getText());
break;
}
case 16:
case 20:
case 24:
case 28:
case 32:
case 36:
case 40:
case 44: {
// have written value for Route[n] Top entry - update GUI
Integer effectiveIndex = (indexToRead - 12) / 4;
routeTop[effectiveIndex].addressField.setLastQueriedValue(routeTop[effectiveIndex].addressField.getText());
try {
routeTop[effectiveIndex].setAddress(Integer.parseInt(routeTop[effectiveIndex].addressField.getText()));
} catch (NumberFormatException e) {
routeTop[effectiveIndex].setIsUnused();
}
break;
}
case 17:
case 21:
case 25:
case 29:
case 33:
case 37:
case 41:
case 45: {
// have written a value for Route n - update GUI
Integer effectiveIndex = (indexToRead - 13) / 4;
routeA3[effectiveIndex].addressField.setLastQueriedValue(routeA3[effectiveIndex].addressField.getText());
try {
routeA3[effectiveIndex].setAddress(Integer.parseInt(routeA3[effectiveIndex].addressField.getText()));
} catch (NumberFormatException e) {
routeA3[effectiveIndex].setIsUnused();
}
break;
}
case 18:
case 22:
case 26:
case 30:
case 34:
case 38:
case 42:
case 46: {
// have written a value for Route n - update GUI
Integer effectiveIndex = (indexToRead - 14) / 4;
routeA5[effectiveIndex].addressField.setLastQueriedValue(routeA5[effectiveIndex].addressField.getText());
try {
routeA5[effectiveIndex].setAddress(Integer.parseInt(routeA5[effectiveIndex].addressField.getText()));
} catch (NumberFormatException e) {
routeA5[effectiveIndex].setIsUnused();
}
break;
}
case 19:
case 23:
case 27:
case 31:
case 35:
case 39:
case 43:
case 47: {
// have written a value for Route n - update GUI
Integer effectiveIndex = (indexToRead - 15) / 4;
routeA7[effectiveIndex].addressField.setLastQueriedValue(routeA7[effectiveIndex].addressField.getText());
try {
routeA7[effectiveIndex].setAddress(Integer.parseInt(routeA7[effectiveIndex].addressField.getText()));
} catch (NumberFormatException e) {
routeA7[effectiveIndex].setIsUnused();
}
break;
}
default:
log.error("invalid indirectIndex for write: {}", indexToRead); // NOI18N
return 0;
}
return 49;
}
}
case 49:
case 50:
case 51:
case 52:
case 53:
case 54:
case 56:
case 57:
case 58:
case 59:
case 60:
case 62:
case 63:
return (state + 1);
case 55:
return 57; // skip apparantly-unused bit to see if this reduces amount of output state disruption during read
case 61:
if (isRead) {
int extractedDataValue = 0;
for (int i = 64; i >= 49; i--) {
extractedDataValue = (extractedDataValue << 1) + (opsw[i] ? 1 : 0);
}
log.debug("Read Index {} value (OpSws 49-64) = 0x{}", indexToRead + 1, Integer.toHexString(extractedDataValue));
updateGuiFromOpSws49_64();
changeGuiElementHighlight(61, indexToRead);
return determineNextStateForRead();
} else {
return 62;
}
case 64: {
if (isRead == true) {
// For reads, check the upper bits of this "half" to determine
// whether or not to read the remaining bits in the "half"
if ((opsw[63] == false) && (opsw[64] == false)) {
// entry is valid, so need to read all opSw bits in [62:49]
log.debug("Read of high value in index {} is a valid entry.", indexToRead); // NOI18N
changeGuiElementUnHighlight(64, indexToRead);
return 49;
} else {
// entry is not valid, so do not need to read opSw bits in [46:33]
// Do need to update internal opSw bits so that they imply an unused
// entry
log.debug("Read of high value in index {} is an invalid entry.", indexToRead); // NOI18N
for (int i = 49; i < 62; ++i) {
opsw[i] = true;
}
opsw[56] = false;
// need to update GUI to show unused value
updateGuiFromOpSws49_64();
changeGuiElementHighlight(64, indexToRead); // clear the highlighted GUI element
return determineNextStateForRead();
}
} // end handling of read operation
else {
//handle write operation
// skip to next index, or, if done with indexables,
// go to end.
changeGuiElementHighlight(64, indexToRead); // clear the highlighted GUI element
switch (indexToRead) {
case 0: {
// have written a value for output2 - update GUI
outAddr2.setLastQueriedValue(outAddr2.getText());
outAddr2.repaint();
indexToRead++;
read = false;
setOpSwIndex(indexToRead);
return 25;
}
case 1: {
// have written a value for output4 - update GUI
outAddr4.setLastQueriedValue(outAddr4.getText());
outAddr4.repaint();
this.readAllButton.setEnabled(true);
this.writeAllButton.setEnabled(true);
return 0;
}
case 16:
case 20:
case 24:
case 28:
case 32:
case 36:
case 40:
case 44: {
// have written a value for Route n - update GUI
Integer effectiveIndex = (indexToRead - 12) / 4;
routeA2[effectiveIndex].addressField.setLastQueriedValue(routeA2[effectiveIndex].addressField.getText());
try {
routeA2[effectiveIndex].setAddress(Integer.parseInt(routeA2[effectiveIndex].addressField.getText()));
} catch (NumberFormatException e) {
routeA2[effectiveIndex].setIsUnused();
}
indexToRead++;
read = false;
setOpSwIndex(indexToRead);
return 25;
}
case 17:
case 21:
case 25:
case 29:
case 33:
case 37:
case 41:
case 45: {
// have written a value for Route n - update GUI
Integer effectiveIndex = (indexToRead - 13) / 4;
routeA4[effectiveIndex].addressField.setLastQueriedValue(routeA4[effectiveIndex].addressField.getText());
try {
routeA4[effectiveIndex].setAddress(Integer.parseInt(routeA4[effectiveIndex].addressField.getText()));
} catch (NumberFormatException e) {
routeA4[effectiveIndex].setIsUnused();
}
indexToRead++;
read = false;
setOpSwIndex(indexToRead);
return 25;
}
case 18:
case 22:
case 26:
case 30:
case 34:
case 38:
case 42:
case 46: {
// have written a value for Route n - update GUI
Integer effectiveIndex = (indexToRead - 14) / 4;
routeA6[effectiveIndex].addressField.setLastQueriedValue(routeA6[effectiveIndex].addressField.getText());
try {
routeA6[effectiveIndex].setAddress(Integer.parseInt(routeA6[effectiveIndex].addressField.getText()));
} catch (NumberFormatException e) {
routeA6[effectiveIndex].setIsUnused();
}
indexToRead++;
read = false;
setOpSwIndex(indexToRead);
return 25;
}
case 19:
case 23:
case 27:
case 31:
case 35:
case 39:
case 43:
case 47: {
// have written a value for Route n - update GUI
Integer effectiveIndex = (indexToRead - 15) / 4;
routeA8[effectiveIndex].addressField.setLastQueriedValue(routeA8[effectiveIndex].addressField.getText());
try {
routeA8[effectiveIndex].setAddress(Integer.parseInt(routeA8[effectiveIndex].addressField.getText()));
} catch (NumberFormatException e) {
routeA8[effectiveIndex].setIsUnused();
}
indexToRead++;
read = false;
setOpSwIndex(indexToRead);
return 0;
}
default: {
return 0;
}
}
} // end handling for write operations
}
case 7: {
this.readAllButton.setEnabled(true);
this.writeAllButton.setEnabled(true);
log.warn("Board has been reset. The board will now respond at Address 1."); // NOI18N
return 0;
} // done!
default:
log.error("unexpected state {}", state); // NOI18N
this.readAllButton.setEnabled(true);
this.writeAllButton.setEnabled(true);
return 0;
}
}
@edu.umd.cs.findbugs.annotations.SuppressFBWarnings(value = "DLS_DEAD_LOCAL_STORE",
justification = "False positive on the implied local variable in indexToRead++")
private int determineNextStateForRead() {
switch (indexToRead) {
case 1: {
// have read output addresses 1, 2, 3, and 4. No more to
// read (for this tab of the GUI).
this.readAllButton.setEnabled(true);
this.writeAllButton.setEnabled(true);
return 0;
}
case 0:
case 16:
case 20:
case 24:
case 28:
case 32:
case 36:
case 40:
case 44:
case 17:
case 21:
case 25:
case 29:
case 33:
case 37:
case 41:
case 45:
case 18:
case 22:
case 26:
case 30:
case 34:
case 38:
case 42:
case 46: {
// have read a value for Route n. go to next value if necessary
indexToRead++;
read = false;
setOpSwIndex(indexToRead);
return 25;
}
case 19:
case 23:
case 27:
case 31:
case 35:
case 39:
case 43:
case 47: {
// have read last values for Route n. No next value so stop.
indexToRead++;
read = false;
setOpSwIndex(indexToRead);
return 0;
}
default:
return 0;
}
}
private void changeComponentBgColor(JComponent comp, Color color) {
comp.setBackground(color);
}
private JComponent whichComponent(Integer reportedState, Integer reportedIndexToRead) {
if (reportedState == 33) {
switch (reportedIndexToRead) {
case 0:
return outAddr1;
case 1:
return outAddr3;
case 16:
case 20:
case 24:
case 28:
case 32:
case 36:
case 40:
case 44:
return routeTop[(reportedIndexToRead - 12) / 4].addressField;
case 17:
case 21:
case 25:
case 29:
case 33:
case 37:
case 41:
case 45:
return routeA3[(reportedIndexToRead - 13) / 4].addressField;
case 18:
case 22:
case 26:
case 30:
case 34:
case 38:
case 42:
case 46:
return routeA5[(reportedIndexToRead - 14) / 4].addressField;
case 19:
case 23:
case 27:
case 31:
case 35:
case 39:
case 43:
case 47:
return routeA7[(reportedIndexToRead - 15) / 4].addressField;
default:
return null;
}
} else if (reportedState == 49) {
switch (reportedIndexToRead) {
case 0:
return outAddr2;
case 1:
return outAddr4;
case 16:
case 20:
case 24:
case 28:
case 32:
case 36:
case 40:
case 44:
return routeA2[(reportedIndexToRead - 12) / 4].addressField;
case 17:
case 21:
case 25:
case 29:
case 33:
case 37:
case 41:
case 45:
return routeA4[(reportedIndexToRead - 13) / 4].addressField;
case 18:
case 22:
case 26:
case 30:
case 34:
case 38:
case 42:
case 46:
return routeA6[(reportedIndexToRead - 14) / 4].addressField;
case 19:
case 23:
case 27:
case 31:
case 35:
case 39:
case 43:
case 47:
return routeA8[(reportedIndexToRead - 15) / 4].addressField;
default:
return null;
}
}
return null;
}
private void changeGuiElementUnHighlight(Integer reportedState, Integer reportedIndexToRead) {
log.debug("changedGuiElementUnHiglight st={} index={}", reportedState, reportedIndexToRead);
JComponent jc;
switch (reportedState) {
case 33:
return;
case 45:
case 48:
jc = whichComponent(33, reportedIndexToRead);
if (jc != null) {
changeComponentBgColor(jc, null); // inherit from parent
}
return;
case 61:
case 64:
jc = whichComponent(49, reportedIndexToRead);
if (jc != null) {
changeComponentBgColor(jc, null); // inherit from parent
}
break;
default:
// nothing to do in this case
break;
}
}
private void changeGuiElementHighlight(Integer reportedState, Integer reportedIndexToRead) {
log.debug("changedGuiElementHiglight st={} index={}", reportedState, reportedIndexToRead);
Color accessColor = Color.blue.brighter();
JComponent jc;
if (reportedState == 33) {
jc = whichComponent(reportedState, reportedIndexToRead);
changeComponentBgColor(jc, accessColor);
}
if (reportedState == 48) {
changeGuiElementUnHighlight(33, reportedIndexToRead);
jc = whichComponent(49, reportedIndexToRead);
if (jc != null) {
changeComponentBgColor(jc, accessColor);
}
}
if (reportedState == 64) {
jc = whichComponent(49, reportedIndexToRead);
changeComponentBgColor(jc, null); // inherit from parent component
}
}
private boolean alreadyKnowThisBoardId(Integer id) {
return (boardNumsEntryValue.contains(id));
}
private Integer addBoardIdToList(Integer id) {
boardNumsEntryValue.add(boardNumsEntryValue.size(), id);
addressComboBox.removeAllItems();
Collections.sort(boardNumsEntryValue);
Integer indexOfTargetBoardAddress = 0;
for (Integer index = 0; index < boardNumsEntryValue.size(); ++index) {
if (boardNumsEntryValue.get(index).equals(id)) {
indexOfTargetBoardAddress = index;
}
addressComboBox.addItem(boardNumsEntryValue.get(index));
}
return indexOfTargetBoardAddress;
}
private void selectBoardIdByIndex(Integer index) {
addressComboBox.setSelectedIndex(index);
}
@Override
public void readAll() {
addrField.setText(addressComboBox.getSelectedItem().toString());
Integer curAddr = Integer.parseInt(addrField.getText());
// If a new board address is specified, add it (and sort it) into the current list.
if (!alreadyKnowThisBoardId(curAddr)) {
Integer index = addBoardIdToList(curAddr);
selectBoardIdByIndex(index);
}
if (generalTabbedPane.getSelectedComponent().getClass() == JPanel.class) {
if (((JPanel) generalTabbedPane.getSelectedComponent()) == generalPanel) {
operationType = OpSwOpType.BasicsRead;
} else if (((JPanel) generalTabbedPane.getSelectedComponent()) == outputAddrsPanel) {
operationType = OpSwOpType.OutputsRead;
}
} else if (generalTabbedPane.getSelectedComponent().getClass() == JScrollPane.class) {
if (((JScrollPane) generalTabbedPane.getSelectedComponent()) == opswsScrollPane) {
operationType = OpSwOpType.BasicsRead;
}
} else if (generalTabbedPane.getSelectedComponent().getClass() == JTabbedPane.class) {
if (((JTabbedPane) generalTabbedPane.getSelectedComponent() == routesTabbedPane)) {
if (((JPanel) routesTabbedPane.getSelectedComponent()) == routePanel[1]) {
operationType = OpSwOpType.Route1Read;
} else if (((JPanel) routesTabbedPane.getSelectedComponent()) == routePanel[2]) {
operationType = OpSwOpType.Route2Read;
} else if (((JPanel) routesTabbedPane.getSelectedComponent()) == routePanel[3]) {
operationType = OpSwOpType.Route3Read;
} else if (((JPanel) routesTabbedPane.getSelectedComponent()) == routePanel[4]) {
operationType = OpSwOpType.Route4Read;
} else if (((JPanel) routesTabbedPane.getSelectedComponent()) == routePanel[5]) {
operationType = OpSwOpType.Route5Read;
} else if (((JPanel) routesTabbedPane.getSelectedComponent()) == routePanel[6]) {
operationType = OpSwOpType.Route6Read;
} else if (((JPanel) routesTabbedPane.getSelectedComponent()) == routePanel[7]) {
operationType = OpSwOpType.Route7Read;
} else if (((JPanel) routesTabbedPane.getSelectedComponent()) == routePanel[8]) {
operationType = OpSwOpType.Route8Read;
} else {
log.error("DS64 TabbedPanel into readAll(): no known Route[n] tab selected.");
return;
}
} else {
log.error("DS64 TabbedPanel into ReadAll(): no selected tab group");
return;
}
} else {
return;
}
super.readAll();
}
public void updateBoardAddress() {
addrField.setText(addressComboBox.getSelectedItem().toString());
}
@Override
public void writeAll() {
addrField.setText(addressComboBox.getSelectedItem().toString());
Integer curAddr = Integer.parseInt(addrField.getText());
// If a new board address is specified, add it (and sort it) into the current list.
if (!boardNumsEntryValue.contains(curAddr)) {
boardNumsEntryValue.add(boardNumsEntryValue.size(), curAddr);
addressComboBox.removeAllItems();
Collections.sort(boardNumsEntryValue);
Integer indexOfTargetBoardAddress = 0;
for (Integer index = 0; index < boardNumsEntryValue.size(); ++index) {
if (boardNumsEntryValue.get(index).equals(curAddr)) {
indexOfTargetBoardAddress = index;
}
addressComboBox.addItem(boardNumsEntryValue.get(index));
}
addressComboBox.setSelectedIndex(indexOfTargetBoardAddress);
}
if (generalTabbedPane.getSelectedComponent().getClass() == JPanel.class) {
if (((JPanel) generalTabbedPane.getSelectedComponent()) == generalPanel) {
operationType = OpSwOpType.BasicsWrite;
} else if (((JPanel) generalTabbedPane.getSelectedComponent()) == outputAddrsPanel) {
operationType = OpSwOpType.OutputsWrite;
}
} else if (generalTabbedPane.getSelectedComponent().getClass() == JScrollPane.class) {
if (((JScrollPane) generalTabbedPane.getSelectedComponent()) == opswsScrollPane) {
operationType = OpSwOpType.BasicsWrite;
}
} else if (generalTabbedPane.getSelectedComponent().getClass() == JTabbedPane.class) {
if (((JTabbedPane) generalTabbedPane.getSelectedComponent()) == routesTabbedPane) {
if (((JPanel) routesTabbedPane.getSelectedComponent()) == routePanel[1]) {
operationType = OpSwOpType.Route1Write;
} else if (((JPanel) routesTabbedPane.getSelectedComponent()) == routePanel[2]) {
operationType = OpSwOpType.Route2Write;
} else if (((JPanel) routesTabbedPane.getSelectedComponent()) == routePanel[3]) {
operationType = OpSwOpType.Route3Write;
} else if (((JPanel) routesTabbedPane.getSelectedComponent()) == routePanel[4]) {
operationType = OpSwOpType.Route4Write;
} else if (((JPanel) routesTabbedPane.getSelectedComponent()) == routePanel[5]) {
operationType = OpSwOpType.Route5Write;
} else if (((JPanel) routesTabbedPane.getSelectedComponent()) == routePanel[6]) {
operationType = OpSwOpType.Route6Write;
} else if (((JPanel) routesTabbedPane.getSelectedComponent()) == routePanel[7]) {
operationType = OpSwOpType.Route7Write;
} else if (((JPanel) routesTabbedPane.getSelectedComponent()) == routePanel[8]) {
operationType = OpSwOpType.Route8Write;
} else {
return;
}
} else {
return;
}
} else {
return;
}
super.writeAll();
}
private enum OpSwOpType {
OutputsRead, OutputsWrite,
Route1Read, Route1Write,
Route2Read, Route2Write,
Route3Read, Route3Write,
Route4Read, Route4Write,
Route5Read, Route5Write,
Route6Read, Route6Write,
Route7Read, Route7Write,
Route8Read, Route8Write,
BasicsRead, BasicsWrite
}
private OpSwOpType operationType = null;
Boolean isRead;
Boolean isWritingResetOpSw = false;
Integer indexToRead = 0;
Boolean resetOpSwVal = false;
/**
* Set index into OpSw table
*
* @param index the indirect address
*/
protected void setOpSwIndex(int index) {
opsw[25] = (index & 1) == 1;
opsw[26] = (index & 2) == 2;
opsw[27] = (index & 4) == 4;
opsw[28] = (index & 8) == 8;
opsw[29] = (index & 16) == 16;
opsw[30] = (index & 32) == 32;
opsw[31] = (index & 64) == 64;
opsw[32] = (index & 128) == 128;
}
/**
* Updates data register to reflect address, state, and enable for two
* turnouts.
*
* @param address1 first turnout address
* @param state1 first turnout's state
* @param is1Unused true if first turnout entry is to be "unused"
* @param address2 second turnout address
* @param state2 second turnout's state
* @param is2Unused true if second turnout entry is to be "unused"
*/
protected void updateOpSwsOutAddr(int address1, boolean state1, boolean is1Unused, int address2, boolean state2, boolean is2Unused) {
int addr1 = address1 - 1;
int addr2 = address2 - 1;
if ((address1 == 0) || (is1Unused)) {
addr1 = 2047;
is1Unused = true;
}
if ((address2 == 0) || (is2Unused)) {
addr2 = 2047;
is2Unused = true;
}
opsw[33] = ((addr1 & 1) == 1);
opsw[34] = ((addr1 & 2) == 2);
opsw[35] = ((addr1 & 4) == 4);
opsw[36] = ((addr1 & 8) == 8);
opsw[37] = ((addr1 & 16) == 16);
opsw[38] = ((addr1 & 32) == 32);
opsw[39] = ((addr1 & 64) == 64);
opsw[40] = false;
opsw[41] = ((addr1 & 128) == 128);
opsw[42] = ((addr1 & 256) == 256);
opsw[43] = ((addr1 & 512) == 512);
opsw[44] = ((addr1 & 1024) == 1024);
opsw[45] = true;
opsw[46] = state1;
if (!is1Unused) {
opsw[47] = false;
opsw[48] = false;
} else {
opsw[47] = true;
opsw[48] = true;
}
opsw[49] = ((addr2 & 1) == 1);
opsw[50] = ((addr2 & 2) == 2);
opsw[51] = ((addr2 & 4) == 4);
opsw[52] = ((addr2 & 8) == 8);
opsw[53] = ((addr2 & 16) == 16);
opsw[54] = ((addr2 & 32) == 32);
opsw[55] = ((addr2 & 64) == 64);
opsw[56] = false;
opsw[57] = ((addr2 & 128) == 128);
opsw[58] = ((addr2 & 256) == 256);
opsw[59] = ((addr2 & 512) == 512);
opsw[60] = ((addr2 & 1024) == 1024);
opsw[61] = true;
opsw[62] = state2;
if (!is2Unused) {
opsw[63] = false;
opsw[64] = false;
} else {
opsw[63] = true;
opsw[64] = true;
}
}
/**
* Updates OpSw values for a given index into the data array
*
* @param index indirect address
*/
protected void updateOpswForWrite(int index) {
Integer value1Address;
Integer value2Address;
boolean value1IsUnused;
boolean value2IsUnused;
boolean value1DirectionIsClosed;
boolean value2DirectionIsClosed;
switch (index) {
case 0: {
try {
value1Address = Integer.parseInt(outAddr1.getText());
} catch (NumberFormatException e) {
value1Address = 2048;
}
try {
value2Address = Integer.parseInt(outAddr2.getText());
} catch (NumberFormatException e) {
value2Address = 2048;
}
updateOpSwsOutAddr(value1Address, false, false, value2Address, false, false);
break;
}
case 1: {
try {
value1Address = Integer.parseInt(outAddr3.getText());
} catch (NumberFormatException e) {
value1Address = 2048;
}
try {
value2Address = Integer.parseInt(outAddr4.getText());
} catch (NumberFormatException e) {
value2Address = 2048;
}
updateOpSwsOutAddr(value1Address, false, false, value2Address, false, false);
break;
}
case 16:
case 20:
case 24:
case 28:
case 32:
case 36:
case 40:
case 44: {
Integer extractedIndex = (index - 12) / 4;
opsw[47] = false;
opsw[48] = false; // assume valid turnout address entry
opsw[63] = false;
opsw[64] = false; // assume valid turnout address entry
if (routeTop[extractedIndex].getIsUnused()) {
log.warn("updateOpswForWrite - routetop[{}] is unused.", extractedIndex); // NOI18N
value1Address = 2048;
value1IsUnused = true;
value1DirectionIsClosed = true;
} else {
value1DirectionIsClosed = routeTop[extractedIndex].closedRadioButton.isSelected();
value1IsUnused = false;
try {
value1Address = Integer.parseInt(routeTop[extractedIndex].addressField.getText());
} catch (NumberFormatException e) {
value1Address = 2048;
value1IsUnused = true;
value1DirectionIsClosed = true;
}
}
if (routeA2[extractedIndex].getIsUnused()) {
log.warn("updateOpswForWrite - routeA2[{}] is unused.", extractedIndex); // NOI18N
value2Address = 2048;
value2IsUnused = true;
value2DirectionIsClosed = true;
} else {
value2DirectionIsClosed = routeA2[extractedIndex].closedRadioButton.isSelected();
value2IsUnused = false;
try {
value2Address = Integer.parseInt(routeA2[extractedIndex].addressField.getText());
} catch (NumberFormatException e) {
value2Address = 2048;
value2IsUnused = true;
value2DirectionIsClosed = true;
}
}
updateOpSwsOutAddr(value1Address, value1DirectionIsClosed, value1IsUnused,
value2Address, value2DirectionIsClosed, value2IsUnused);
if (value1IsUnused) {
opsw[46] = true;
opsw[47] = true;
opsw[48] = true; // mark entry as invalid
routeTop[extractedIndex].unusedRadioButton.setSelected(true);
routeTop[extractedIndex].unusedRadioButton.repaint();
routeTop[extractedIndex].setAddress(2048);
routeTop[extractedIndex].addressField.setText("");
}
if (value2IsUnused) {
opsw[62] = true;
opsw[63] = true;
opsw[64] = true; // mark entry as invalid
routeA2[extractedIndex].unusedRadioButton.setSelected(true);
routeA2[extractedIndex].unusedRadioButton.repaint();
routeA2[extractedIndex].setAddress(2048);
routeA2[extractedIndex].addressField.setText("");
}
break;
}
case 17:
case 21:
case 25:
case 29:
case 33:
case 37:
case 41:
case 45: {
Integer extractedIndex = (index - 13) / 4;
opsw[47] = false;
opsw[48] = false; // assume valid turnout address entry
opsw[63] = false;
opsw[64] = false; // assume valid turnout address entry
if (routeA3[extractedIndex].getIsUnused()) {
value1Address = 2048;
value1IsUnused = true;
value1DirectionIsClosed = true;
} else {
value1DirectionIsClosed = routeA3[extractedIndex].closedRadioButton.isSelected();
value1IsUnused = false;
try {
value1Address = Integer.parseInt(routeA3[extractedIndex].addressField.getText());
} catch (NumberFormatException e) {
value1Address = 2048;
value1IsUnused = true;
}
}
if (routeA4[extractedIndex].getIsUnused()) {
value2Address = 2048;
value2IsUnused = true;
value2DirectionIsClosed = true;
} else {
value2DirectionIsClosed = routeA4[extractedIndex].closedRadioButton.isSelected();
value2IsUnused = false;
try {
value2Address = Integer.parseInt(routeA4[extractedIndex].addressField.getText());
} catch (NumberFormatException e) {
value2Address = 2048;
value2IsUnused = true;
}
}
updateOpSwsOutAddr(value1Address, value1DirectionIsClosed, value1IsUnused,
value2Address, value2DirectionIsClosed, value2IsUnused);
if (value1IsUnused) {
opsw[46] = true;
opsw[47] = true;
opsw[48] = true; // mark entry as invalid
routeA3[extractedIndex].unusedRadioButton.setSelected(true);
routeA3[extractedIndex].unusedRadioButton.repaint();
routeA3[extractedIndex].setAddress(2048);
routeA3[extractedIndex].addressField.setText("");
}
if (value2IsUnused) {
opsw[62] = true;
opsw[63] = true;
opsw[64] = true; // mark entry as invalid
routeA4[extractedIndex].unusedRadioButton.setSelected(true);
routeA4[extractedIndex].unusedRadioButton.repaint();
routeA4[extractedIndex].setAddress(2048);
routeA4[extractedIndex].addressField.setText("");
}
break;
}
case 18:
case 22:
case 26:
case 30:
case 34:
case 38:
case 42:
case 46: {
Integer extractedIndex = (index - 14) / 4;
opsw[47] = false;
opsw[48] = false; // assume valid turnout address entry
opsw[63] = false;
opsw[64] = false; // assume valid turnout address entry
if (routeA5[extractedIndex].getIsUnused()) {
value1Address = 2048;
value1IsUnused = true;
value1DirectionIsClosed = true;
} else {
value1DirectionIsClosed = routeA5[extractedIndex].closedRadioButton.isSelected();
value1IsUnused = false;
try {
value1Address = Integer.parseInt(routeA5[extractedIndex].addressField.getText());
} catch (NumberFormatException e) {
value1Address = 2048;
value1IsUnused = true;
}
}
if (routeA6[extractedIndex].getIsUnused()) {
value2Address = 2048;
value2IsUnused = true;
value2DirectionIsClosed = true;
} else {
value2DirectionIsClosed = routeA6[extractedIndex].closedRadioButton.isSelected();
value2IsUnused = false;
try {
value2Address = Integer.parseInt(routeA6[extractedIndex].addressField.getText());
} catch (NumberFormatException e) {
value2Address = 2048;
value2IsUnused = true;
}
}
updateOpSwsOutAddr(value1Address, value1DirectionIsClosed, value1IsUnused,
value2Address, value2DirectionIsClosed, value2IsUnused);
if (value1IsUnused) {
opsw[46] = true;
opsw[47] = true;
opsw[48] = true; // mark entry as invalid
routeA5[extractedIndex].unusedRadioButton.setSelected(true);
routeA5[extractedIndex].unusedRadioButton.repaint();
routeA5[extractedIndex].setAddress(2048);
routeA5[extractedIndex].addressField.setText("");
}
if (value2IsUnused) {
opsw[62] = true;
opsw[63] = true;
opsw[64] = true; // mark entry as invalid
routeA6[extractedIndex].unusedRadioButton.setSelected(true);
routeA6[extractedIndex].unusedRadioButton.repaint();
routeA6[extractedIndex].setAddress(2048);
routeA6[extractedIndex].addressField.setText("");
}
break;
}
case 19:
case 23:
case 27:
case 31:
case 35:
case 39:
case 43:
case 47: {
Integer extractedIndex = (index - 15) / 4;
opsw[47] = false;
opsw[48] = false; // assume valid turnout address entry
opsw[63] = false;
opsw[64] = false; // assume valid turnout address entry
if (routeA7[extractedIndex].getIsUnused()) {
value1Address = 2048;
value1IsUnused = true;
value1DirectionIsClosed = true;
} else {
value1DirectionIsClosed = routeA7[extractedIndex].closedRadioButton.isSelected();
value1IsUnused = false;
try {
value1Address = Integer.parseInt(routeA7[extractedIndex].addressField.getText());
} catch (NumberFormatException e) {
value1Address = 2048;
value1IsUnused = true;
}
}
if (routeA8[extractedIndex].getIsUnused()) {
value2Address = 2048;
value2IsUnused = true;
value2DirectionIsClosed = true;
} else {
value2DirectionIsClosed = routeA8[extractedIndex].closedRadioButton.isSelected();
value2IsUnused = false;
try {
value2Address = Integer.parseInt(routeA8[extractedIndex].addressField.getText());
} catch (NumberFormatException e) {
value2Address = 2048;
value2IsUnused = true;
}
}
updateOpSwsOutAddr(value1Address, value1DirectionIsClosed, value1IsUnused,
value2Address, value2DirectionIsClosed, value2IsUnused);
if (value1IsUnused) {
opsw[46] = true;
opsw[47] = true;
opsw[48] = true; // mark entry as invalid
routeA7[extractedIndex].unusedRadioButton.setSelected(true);
routeA7[extractedIndex].unusedRadioButton.repaint();
routeA7[extractedIndex].setAddress(2048);
routeA7[extractedIndex].addressField.setText("");
}
if (value2IsUnused) {
opsw[62] = true;
opsw[63] = true;
opsw[64] = true; // mark entry as invalid
routeA8[extractedIndex].unusedRadioButton.setSelected(true);
routeA8[extractedIndex].unusedRadioButton.repaint();
routeA8[extractedIndex].setAddress(2048);
routeA8[extractedIndex].addressField.setText("");
}
break;
}
case 48: {
break;
}
default: {
break;
}
}
}
private void resetRouteOperation(Integer routeNumber) {
if ((routeNumber < 1) || (routeNumber > 8)) {
return;
}
routeTop[routeNumber].unusedRadioButton.setSelected(true);
routeTop[routeNumber].setIsUnused();
routeTop[routeNumber].addressField.setText("");
routeA2[routeNumber].setIsUnused();
routeA2[routeNumber].unusedRadioButton.setSelected(true);
routeA2[routeNumber].addressField.setText("");
routeA3[routeNumber].setIsUnused();
routeA3[routeNumber].unusedRadioButton.setSelected(true);
routeA3[routeNumber].addressField.setText("");
routeA4[routeNumber].setIsUnused();
routeA4[routeNumber].unusedRadioButton.setSelected(true);
routeA4[routeNumber].addressField.setText("");
routeA5[routeNumber].setIsUnused();
routeA5[routeNumber].unusedRadioButton.setSelected(true);
routeA5[routeNumber].addressField.setText("");
routeA6[routeNumber].setIsUnused();
routeA6[routeNumber].unusedRadioButton.setSelected(true);
routeA6[routeNumber].addressField.setText("");
routeA7[routeNumber].setIsUnused();
routeA7[routeNumber].unusedRadioButton.setSelected(true);
routeA7[routeNumber].addressField.setText("");
routeA8[routeNumber].setIsUnused();
routeA8[routeNumber].unusedRadioButton.setSelected(true);
routeA8[routeNumber].addressField.setText("");
writeAll();
}
private void unhighlightAllBasicOpSws() {
outputType.setBackground(null);
delayTime.setBackground(null);
outputStates.setBackground(null);
startupDelay.setBackground(null);
staticOutputShutoff.setBackground(null);
commandType.setBackground(null);
routesControl.setBackground(null);
localControlOfOutputsStyle.setBackground(null);
sensorMessageTrigger.setBackground(null);
commandSource.setBackground(null);
output1CrossbuckFlasherCheckBox.setBackground(null);
output2CrossbuckFlasherCheckBox.setBackground(null);
output3CrossbuckFlasherCheckBox.setBackground(null);
output4CrossbuckFlasherCheckBox.setBackground(null);
localSensorType.setBackground(null);
}
private void unhighlightAllRouteEntryFields() {
for (int i = 1; i < 9; ++i) {
routeTop[i].addressField.setBackground(null);
routeA2[i].addressField.setBackground(null);
routeA3[i].addressField.setBackground(null);
routeA4[i].addressField.setBackground(null);
routeA5[i].addressField.setBackground(null);
routeA6[i].addressField.setBackground(null);
routeA7[i].addressField.setBackground(null);
routeA8[i].addressField.setBackground(null);
updateUI();
}
}
private void unhighlightAllOutputEntryFields() {
outAddr1.setBackground(null);
outAddr2.setBackground(null);
outAddr3.setBackground(null);
outAddr4.setBackground(null);
}
@Override
public void message(LocoNetMessage m) {
super.message(m);
if (m.getOpCode() == LnConstants.OPC_LONG_ACK) {
if (((m.getElement(1) == LnConstants.RE_LACK_SPEC_CASE1)
|| (m.getElement(1) == LnConstants.RE_LACK_SPEC_CASE2))
&& (state == 0) && resetRouteButton.isSelected()) {
// Handle DS64 confirmation of OpSw write when action is a DS64
// Board Factory Reset
resetRouteButton.setSelected(false);
resetRouteButton.updateUI();
}
}
if (m.getOpCode() == LnConstants.OPC_SW_REQ) {
int swAddr = (((m.getElement(2) & 0x0f) * 128) + (m.getElement(1) & 0x7f)) + 1;
boolean dir = ((m.getElement(2) & 0x20) == 0x20);
if (swAddr == Integer.parseInt(outAddr1.getText())) {
outState1.setText(dir ? Bundle.getMessage("LabelTurnoutCurrentStateX", Bundle.getMessage("BeanStateClosed"))
: Bundle.getMessage("LabelTurnoutCurrentStateX", Bundle.getMessage("BeanStateThrown")));
outState1.updateUI();
}
if (swAddr == Integer.parseInt(outAddr2.getText())) {
outState2.setText(dir ? Bundle.getMessage("LabelTurnoutCurrentStateX", Bundle.getMessage("BeanStateClosed"))
: Bundle.getMessage("LabelTurnoutCurrentStateX", Bundle.getMessage("BeanStateThrown")));
outState2.updateUI();
}
if (swAddr == Integer.parseInt(outAddr3.getText())) {
outState3.setText(dir ? Bundle.getMessage("LabelTurnoutCurrentStateX", Bundle.getMessage("BeanStateClosed"))
: Bundle.getMessage("LabelTurnoutCurrentStateX", Bundle.getMessage("BeanStateThrown")));
outState3.updateUI();
}
if (swAddr == Integer.parseInt(outAddr4.getText())) {
outState4.setText(dir ? Bundle.getMessage("LabelTurnoutCurrentStateX", Bundle.getMessage("BeanStateClosed"))
: Bundle.getMessage("LabelTurnoutCurrentStateX", Bundle.getMessage("BeanStateThrown")));
outState4.updateUI();
}
} else if ((m.getOpCode() == LnConstants.OPC_MULTI_SENSE) && ((m.getElement(1) & 0x7E) == 0x62)) {
// device identity report
if (m.getElement(3) == 0x03) {
Integer extractedBoardId = 1 + ((m.getElement(1) & 0x1) << 7)
+ (m.getElement(2) & 0x7F);
if (!alreadyKnowThisBoardId(extractedBoardId)) {
addBoardIdToList(extractedBoardId);
}
}
}
}
/**
* Reset the DS64 board
*/
@SuppressFBWarnings(value = "UPM_UNCALLED_PRIVATE_METHOD", justification = "Functionality not yet confirmed with hardware; may be useful at a future date.")
private void boardFactoryReset() {
// before proceeding, make sure that the user really wants to go forward
Object[] dialogBoxButtonOptions = {
Bundle.getMessage("ButtonResetToFactoryDefault"),
Bundle.getMessage("ButtonCancel")};
int userReply = JmriJOptionPane.showOptionDialog(this,
Bundle.getMessage("DialogTextBoardResetWarning"),
Bundle.getMessage("WarningTitle"),
JmriJOptionPane.YES_NO_OPTION, JmriJOptionPane.QUESTION_MESSAGE,
null, dialogBoxButtonOptions, dialogBoxButtonOptions[1]);
if ( userReply != JmriJOptionPane.YES_OPTION ) {
factoryResetButton.setSelected(false);
return; // compare only to exactly the value for executing the reset!
}
readAllButton.setEnabled(false);
writeAllButton.setEnabled(false);
resetRouteButton.setEnabled(false);
factoryResetButton.setEnabled(false);
// send OpSw 7 = Closed to this boardId to reset the DS64
//to its factory default settings
// then want to read all OpSws to update the display.
read = false;
isWritingResetOpSw = true;
resetOpSwVal = true;
opsw[7] = true;
updateBoardAddress();
writeOne(7);
boardResetResponseTimer = new javax.swing.Timer(750,
event -> {
factoryResetButton.setSelected(false);
factoryResetButton.setEnabled(true);
readAllButton.setEnabled(true);
writeAllButton.setEnabled(true);
resetRouteButton.setEnabled(true);
updateUI();
}
);
boardResetResponseTimer.start();
}
private final ActionListener routeResetResponseTimerListener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
log.debug("routeresetresponsetimerlistener state={}, indextoread{}", state, indexToRead);
resetRouteButton.setSelected(false);
readAllButton.setEnabled(true);
writeAllButton.setEnabled(true);
factoryResetButton.setEnabled(true);
}
};
@Override
public void initComponents(LocoNetSystemConnectionMemo memo) {
super.initComponents(memo);
LocoNetMessage m = new LocoNetMessage(6);
m.setElement(0, LnConstants.OPC_MULTI_SENSE);
m.setElement(1, 0x62);
m.setElement(2, 0);
m.setElement(3, 0x70);
m.setElement(4, 0);
memo.getLnTrafficController().sendLocoNetMessage(m);
}
@Override
public void initComponents() {
super.initComponents();
// implements an AbstractBoardProgPanel with three tabs:
// Outputs tab - configure features most related to DS64 outputs
// Inputs tab - configure features most related to DS64 inputs
// Routes tab - configure features related to routes
// Routes tab has (left side, vertical) sub-tabs, one for each of the 8 routes
// JLabel addrFieldLabel = new JTextLabel(Bundle.getMessage("LabelBoardID"));
// addrField = addressComboBox(getSelectedItem);
String[] outputTypes = {Bundle.getMessage("ComboBoxOutputType0"),
Bundle.getMessage("ComboBoxOutputType1")};
outputTypeLabel = new JLabel(Bundle.getMessage("LabelOutputType"));
outputType = new JComboBox<>(outputTypes); // opSw 1
outputType.setToolTipText(Bundle.getMessage("ToolTipOutputType"));
outputType.addActionListener(basicConfigChangeActionListener);
outputType.setName("1"); // NOI18N
String[] availableDelayTimes = new String[16];
availableDelayTimes[0] = Bundle.getMessage("ComboBoxPulseTime0point1");
availableDelayTimes[1] = Bundle.getMessage("ComboBoxPulseTime0point2");
availableDelayTimes[2] = Bundle.getMessage("ComboBoxPulseTime0point4");
availableDelayTimes[3] = Bundle.getMessage("ComboBoxPulseTime0point6");
availableDelayTimes[4] = Bundle.getMessage("ComboBoxPulseTime0point8");
availableDelayTimes[5] = Bundle.getMessage("ComboBoxPulseTime1point0");
availableDelayTimes[6] = Bundle.getMessage("ComboBoxPulseTime1point2");
availableDelayTimes[7] = Bundle.getMessage("ComboBoxPulseTime1point4");
availableDelayTimes[8] = Bundle.getMessage("ComboBoxPulseTime1point6");
availableDelayTimes[9] = Bundle.getMessage("ComboBoxPulseTime1point8");
availableDelayTimes[10] = Bundle.getMessage("ComboBoxPulseTime2point0");
availableDelayTimes[11] = Bundle.getMessage("ComboBoxPulseTime2point2");
availableDelayTimes[12] = Bundle.getMessage("ComboBoxPulseTime2point4");
availableDelayTimes[13] = Bundle.getMessage("ComboBoxPulseTime2point6");
availableDelayTimes[14] = Bundle.getMessage("ComboBoxPulseTime2point8");
availableDelayTimes[15] = Bundle.getMessage("ComboBoxPulseTime3point0");
delayTimeLabel = new JLabel(Bundle.getMessage("LabelPulseTimeout")); // opSws 2-5
delayTime = new JComboBox<>(availableDelayTimes);
delayTime.setToolTipText(Bundle.getMessage("ToolTipPulseTimeout"));
delayTime.setName("2345"); // NOI18N
delayTime.addActionListener(basicConfigChangeActionListener);
String[] initialOutputStates = {Bundle.getMessage("ComboBoxOutputPowerupType0"),
Bundle.getMessage("ComboBoxOutputPowerupType1")};
outputStatesLabel = new JLabel(Bundle.getMessage("LabelPowerUpOutputActivity"));
outputStates = new JComboBox<>(initialOutputStates); // opsw 6
outputStates.setToolTipText(Bundle.getMessage("ToolTipOutputStates"));
outputStates.setName("6"); // NOI18N
outputStates.addActionListener(basicConfigChangeActionListener);
String[] startupDelays = {Bundle.getMessage("ComboBoxOutputPowerupDelayType0"),
Bundle.getMessage("ComboBoxOutputPowerupDelayType1")};
startupDelayLabel = new JLabel(Bundle.getMessage("LabelInitialPowerUpDelay"));
startupDelay = new JComboBox<>(startupDelays); // opsw 8
startupDelay.setToolTipText(Bundle.getMessage("ToolTipStartupDelay"));
startupDelay.setName("8"); // NOI18N
startupDelay.addActionListener(basicConfigChangeActionListener);
String[] staticOutputShutoffs = {Bundle.getMessage("ComboBoxOutputPowerManagementType0"),
Bundle.getMessage("ComboBoxOutputPowerManagementType1")};
staticOutputShutoffLabel = new JLabel(Bundle.getMessage("LabelOutputPowerManagementStyle"));
staticOutputShutoff = new JComboBox<>(staticOutputShutoffs); // opSw 9
staticOutputShutoff.setToolTipText(Bundle.getMessage("ToolTipLabelOutputPowerManagementStyle"));
staticOutputShutoff.setName("9"); // NOI18N
staticOutputShutoff.addActionListener(basicConfigChangeActionListener);
// command sources
String[] commandTypes = {Bundle.getMessage("ComboBoxCommandsRecognizedFromType0"),
Bundle.getMessage("ComboBoxCommandsRecognizedFromType1")};
commandTypeLabel = new JLabel(Bundle.getMessage("LabelAcceptedSwitchCommandTypes"));
commandType = new JComboBox<>(commandTypes); //opSw 10
commandType.setToolTipText(Bundle.getMessage("ToolTipLabelAcceptedSwitchCommandTypes"));
commandType.setName("10"); // NOI18N
commandType.addActionListener(basicConfigChangeActionListener);
String[] commandSources = {Bundle.getMessage("ComboBoxCommandSourceType0"),
Bundle.getMessage("ComboBoxCommandSourceType1")};
commandSourceLabel = new JLabel(Bundle.getMessage("LabelAcceptSwitchCommandsFrom"));
commandSource = new JComboBox<>(commandSources); // opSw14
commandSource.setToolTipText(Bundle.getMessage("ToolTipCommandSource"));
commandSource.setName("14"); // NOI18N
commandSource.addActionListener(basicConfigChangeActionListener);
// Crossbuck Flasher controls
output1CrossbuckFlasherCheckBox = new JCheckBox(Bundle.getMessage("CheckBoxOutputXCrossbuck", 1));
output1CrossbuckFlasherCheckBox.setToolTipText(Bundle.getMessage("ToolTipCheckBoxOutput1Crossbuck"));
output1CrossbuckFlasherCheckBox.setName("17"); // NOI18N
output1CrossbuckFlasherCheckBox.addActionListener(basicConfigChangeActionListener);
// output 2
output2CrossbuckFlasherCheckBox = new JCheckBox(Bundle.getMessage("CheckBoxOutputXCrossbuck", 2));
output2CrossbuckFlasherCheckBox.setToolTipText(Bundle.getMessage("ToolTipCheckBoxOutput2Crossbuck"));
output2CrossbuckFlasherCheckBox.setName("18"); // NOI18N
output2CrossbuckFlasherCheckBox.addActionListener(basicConfigChangeActionListener);
// output 3
output3CrossbuckFlasherCheckBox = new JCheckBox(Bundle.getMessage("CheckBoxOutputXCrossbuck", 3));
output3CrossbuckFlasherCheckBox.setToolTipText(Bundle.getMessage("ToolTipCheckBoxOutput3Crossbuck"));
output3CrossbuckFlasherCheckBox.setName("19"); // NOI18N
output3CrossbuckFlasherCheckBox.addActionListener(basicConfigChangeActionListener);
// output 4
output4CrossbuckFlasherCheckBox = new JCheckBox(Bundle.getMessage("CheckBoxOutputXCrossbuck", 4));
output4CrossbuckFlasherCheckBox.setToolTipText(Bundle.getMessage("ToolTipCheckBoxOutput4Crossbuck"));
output4CrossbuckFlasherCheckBox.setName("20"); // NOI18N
output4CrossbuckFlasherCheckBox.addActionListener(basicConfigChangeActionListener);
// DS64 routes
String[] routesControls = {Bundle.getMessage("ComboBoxEntryRoutesOption0"),
Bundle.getMessage("ComboBoxEntryRoutesOption1"),
Bundle.getMessage("ComboBoxEntryRoutesOption2"),
Bundle.getMessage("ComboBoxEntryRoutesOption3")};
routesControlLabel = new JLabel(Bundle.getMessage("LabelTriggerDs64Routes"));
routesControl = new JComboBox<>(routesControls); // opSws 11, 16
routesControl.setToolTipText(Bundle.getMessage("ToolTipLabelRouteControlOptions"));
routesControl.setName("1116"); // NOI18N
routesControl.addActionListener(basicConfigChangeActionListener);
// local input controls
String[] localControlOfOutputsStyles = {
Bundle.getMessage("ComboBoxInputsControlOutputsType0"),
Bundle.getMessage("ComboBoxInputsControlOutputsType1"),
Bundle.getMessage("ComboBoxInputsControlOutputsType2"),
Bundle.getMessage("comboboxInputsControlOutputsType3")};
localControlOfOutputsStyleLabel = new JLabel(Bundle.getMessage("LabelLocalInputsControlOutputs"));
localControlOfOutputsStyle = new JComboBox<>(localControlOfOutputsStyles); // opSw12
localControlOfOutputsStyle.setToolTipText(Bundle.getMessage("ToolTipLocalInputsControl"));
localControlOfOutputsStyle.setName("1215"); // NOI18N
localControlOfOutputsStyle.addActionListener(basicConfigChangeActionListener);
String[] sensorMessageTriggers = {Bundle.getMessage("ComboBoxInputsCauseMessagesType0"),
Bundle.getMessage("ComboBoxInputsCauseMessagesType1")};
sensorMessageTriggerLabel = new JLabel(Bundle.getMessage("LabelBetweenForMessageTypeSent"));
sensorMessageTrigger = new JComboBox<>(sensorMessageTriggers); // opSw13
sensorMessageTrigger.setToolTipText(Bundle.getMessage("ToolTipSensorMessageTrigger"));
sensorMessageTrigger.setName("13"); // NOI18N
sensorMessageTrigger.addActionListener(basicConfigChangeActionListener);
String[] localSensorTypes = {Bundle.getMessage("ComboBoxSensorMessageTypeSentType0"),
Bundle.getMessage("ComboBoxSensorMessageTypeSentType1")};
localSensorType = new JComboBox<>(localSensorTypes); // opSw21
localSensorType.setToolTipText(Bundle.getMessage("ToolTipLocalSensorsType"));
localSensorType.setName("21"); // NOI18N
localSensorType.addActionListener(basicConfigChangeActionListener);
factoryResetButton = new JToggleButton(Bundle.getMessage("ButtonResetToFactoryDefault"));
factoryResetButton.setToolTipText(Bundle.getMessage("ToolTipButtonResetToFactoryDefault"));
factoryResetButton.addActionListener(
event -> {
readAllButton.setEnabled(false);
writeAllButton.setEnabled(false);
resetRouteButton.setEnabled(false);
boardFactoryReset();
}
);
routesTabbedPane = new JTabbedPane();
routePanel = new JPanel[9];
routeTop = new SimpleTurnoutStateEntry[9];
routeA2 = new SimpleTurnoutStateEntry[9];
routeA3 = new SimpleTurnoutStateEntry[9];
routeA4 = new SimpleTurnoutStateEntry[9];
routeA5 = new SimpleTurnoutStateEntry[9];
routeA6 = new SimpleTurnoutStateEntry[9];
routeA7 = new SimpleTurnoutStateEntry[9];
routeA8 = new SimpleTurnoutStateEntry[9];
resetRouteButton = new JToggleButton(Bundle.getMessage("ButtonResetRoute"));
resetRouteButton.setToolTipText(Bundle.getMessage("ToolTipButtonResetRoute"));
resetRouteButton.setEnabled(false);
resetRouteButton.setVisible(false);
JPanel addressingPanel = provideAddressing(" "); // create read/write buttons, address
readAllButton.setPreferredSize(null);
readAllButton.setText(Bundle.getMessage("ButtonReadFullSheet"));
readAllButton.setToolTipText(Bundle.getMessage("ToolTipButtonReadFullSheet"));
writeAllButton.setPreferredSize(null);
writeAllButton.setText(Bundle.getMessage("ButtonWriteFullSheet"));
writeAllButton.setToolTipText(Bundle.getMessage("ToolTipButtonWriteFullSheet"));
// make both buttons a little bit bigger, with identical (preferred) sizes
// (width increased because some computers/displays trim the button text)
java.awt.Dimension d = writeAllButton.getPreferredSize();
int w = d.width;
d = readAllButton.getPreferredSize();
if (d.width > w) {
w = d.width;
}
writeAllButton.setPreferredSize(new java.awt.Dimension((int) (w * 1.1), d.height));
readAllButton.setPreferredSize(new java.awt.Dimension((int) (w * 1.1), d.height));
addressingPanel.add(resetRouteButton);
int indexOfTargetBoardAddress = 0;
addressComboBox = new JComboBox<>();
for (Integer index = 0; index < boardNumsEntryValue.size(); ++index) {
if (boardNumsEntryValue.get(index) == origAccessBoardNum) {
origAccessBoardNum = -1;
indexOfTargetBoardAddress = index;
}
addressComboBox.addItem(boardNumsEntryValue.get(index));
}
addressComboBox.setSelectedIndex(indexOfTargetBoardAddress);
addressingPanel.add(addressComboBox, 1);
addressingPanel.getComponent(2).setVisible(false);
addressComboBox.setEditable(true);
appendLine(addressingPanel); // add read/write buttons, address
generalTabbedPane = new JTabbedPane();
generalPanel = new JPanel();
generalPanel.setLayout(new BoxLayout(generalPanel, BoxLayout.Y_AXIS));
generalPanel.setName("Basic Settings"); // NOI18N
JPanel allOutputControls = new JPanel();
allOutputControls.setLayout(new BoxLayout(allOutputControls, BoxLayout.Y_AXIS));
javax.swing.border.TitledBorder allOutputControlsTitleBorder;
javax.swing.border.Border blackline;
blackline = javax.swing.BorderFactory.createLineBorder(java.awt.Color.black);
allOutputControlsTitleBorder = javax.swing.BorderFactory.createTitledBorder(blackline,
Bundle.getMessage("TitledBorderLabelOutputControls"));
allOutputControls.setBorder(allOutputControlsTitleBorder);
JPanel outputTypePanel = new JPanel();
outputTypePanel.setLayout(new FlowLayout());
outputTypePanel.add(outputTypeLabel);
outputTypePanel.add(outputType);
allOutputControls.add(outputTypePanel);
JPanel delayTimePanel = new JPanel();
delayTimePanel.setLayout(new FlowLayout());
delayTimePanel.add(delayTimeLabel);
delayTimePanel.add(delayTime);
allOutputControls.add(delayTimePanel);
JPanel outputStatePanel = new JPanel();
outputStatePanel.setLayout(new FlowLayout());
outputStatePanel.add(outputStatesLabel);
outputStatePanel.add(outputStates);
allOutputControls.add(outputStatePanel);
JPanel startupDelayPanel = new JPanel();
startupDelayPanel.setLayout(new FlowLayout());
startupDelayPanel.add(startupDelayLabel);
startupDelayPanel.add(startupDelay);
allOutputControls.add(startupDelayPanel);
JPanel staticOutputShutoffPanel = new JPanel();
staticOutputShutoffPanel.setLayout(new FlowLayout());
staticOutputShutoffPanel.add(staticOutputShutoffLabel);
staticOutputShutoffPanel.add(staticOutputShutoff);
allOutputControls.add(staticOutputShutoffPanel);
JPanel crossingGateControls = new JPanel(new java.awt.GridLayout(2, 2));
crossingGateControls.add(output1CrossbuckFlasherCheckBox);
crossingGateControls.add(output3CrossbuckFlasherCheckBox); // display output 3 box to the right of output 1 box
crossingGateControls.add(output2CrossbuckFlasherCheckBox); // display output 2 box below output 1 box
crossingGateControls.add(output4CrossbuckFlasherCheckBox);
allOutputControls.add(crossingGateControls);
generalPanel.add(allOutputControls);
// command sources
JPanel ds64CommandSourcesPanel = new JPanel();
ds64CommandSourcesPanel.setLayout(new BoxLayout(ds64CommandSourcesPanel, BoxLayout.Y_AXIS));
javax.swing.border.TitledBorder ds64CommandSourcesTitleBorder;
ds64CommandSourcesTitleBorder = javax.swing.BorderFactory.createTitledBorder(blackline,
Bundle.getMessage("TitledBorderLabelCommandSources"));
ds64CommandSourcesPanel.setBorder(ds64CommandSourcesTitleBorder);
JPanel commandTypePanel = new JPanel();
commandTypePanel.setLayout(new FlowLayout());
commandTypePanel.add(commandTypeLabel);
commandTypePanel.add(commandType);
ds64CommandSourcesPanel.add(commandTypePanel);
JPanel commandSourcePanel = new JPanel();
commandSourcePanel.setLayout(new FlowLayout());
commandSourcePanel.add(commandSourceLabel);
commandSourcePanel.add(commandSource);
ds64CommandSourcesPanel.add(commandSourcePanel);
generalPanel.add(ds64CommandSourcesPanel);
// DS64 routes
JPanel localRoutesPanel = new JPanel();
localRoutesPanel.setLayout(new BoxLayout(localRoutesPanel, BoxLayout.Y_AXIS));
javax.swing.border.TitledBorder localRoutesTitleBorder;
localRoutesTitleBorder = javax.swing.BorderFactory.createTitledBorder(blackline,
Bundle.getMessage("TitledBorderLabelRoutes"));
localRoutesPanel.setBorder(localRoutesTitleBorder);
JPanel routesControlPanel = new JPanel();
routesControlPanel.setLayout(new FlowLayout());
routesControlPanel.add(routesControlLabel);
routesControlPanel.add(routesControl);
localRoutesPanel.add(routesControlPanel);
generalPanel.add(localRoutesPanel);
// local input controls
localInputControlsPanel = new JPanel();
localInputControlsPanel.setLayout(new BoxLayout(localInputControlsPanel, BoxLayout.Y_AXIS));
javax.swing.border.TitledBorder localInputControlsTitleBorder;
localInputControlsTitleBorder = javax.swing.BorderFactory.createTitledBorder(blackline,
Bundle.getMessage("TitledBorderLabelLocalInputControls"));
localInputControlsPanel.setBorder(localInputControlsTitleBorder);
JPanel localControlOfOutputsStylePanel = new JPanel(new FlowLayout());
localControlOfOutputsStylePanel.add(localControlOfOutputsStyleLabel);
localControlOfOutputsStylePanel.add(localControlOfOutputsStyle);
localInputControlsPanel.add(localControlOfOutputsStylePanel);
sensorMessageTriggerPanel = new JPanel(new FlowLayout());
sensorMessageTriggerPanel.add(localSensorType);
sensorMessageTriggerPanel.add(sensorMessageTriggerLabel);
sensorMessageTriggerPanel.add(sensorMessageTrigger);
localInputControlsPanel.add(sensorMessageTriggerPanel);
generalPanel.add(localInputControlsPanel);
generalPanel.add(new JSeparator());
JPanel factoryResetButtonPanel = new JPanel();
factoryResetButtonPanel.add(factoryResetButton);
generalPanel.add(factoryResetButtonPanel);
generalTabbedPane.addTab(Bundle.getMessage("TabTextBasicSettings"), null,
generalPanel, Bundle.getMessage("TabToolTipBasicSettings"));
// opsws panel
opswsPanel = new JPanel();
opswsValues = new JPanel();
opswsValues.setLayout(new BoxLayout(opswsValues, BoxLayout.Y_AXIS));
javax.swing.border.TitledBorder opswsValuesTitleBorder;
opswsValuesTitleBorder = javax.swing.BorderFactory.createTitledBorder(blackline,
Bundle.getMessage("TitledBorderLabelOpSws"));
opswsValues.setBorder(opswsValuesTitleBorder);
opswsPanel.setLayout(new BoxLayout(opswsPanel, BoxLayout.Y_AXIS));
JPanel innerPanel;
ButtonGroup[] g = new ButtonGroup[22];
opswThrown = new JRadioButtonWithInteger[22];
opswClosed = new JRadioButtonWithInteger[22];
for (int i = 1; i <= 21; i++) {
if (i != 7) {
log.debug("Creating entry for OpSw {}", i);
innerPanel = new JPanel(new FlowLayout());
innerPanel.add(new JLabel("OpSw " + i)); // NOI18N
opswThrown[i] = new JRadioButtonWithInteger(i, Bundle.getMessage("TurnoutStateThrown"));
opswClosed[i] = new JRadioButtonWithInteger(i, Bundle.getMessage("TurnoutStateClosed"));
g[i] = new ButtonGroup();
g[i].add(opswThrown[i]);
g[i].add(opswClosed[i]);
innerPanel.add(opswThrown[i]);
innerPanel.add(opswClosed[i]);
opswsPanel.add(innerPanel);
// opswsPanel.add(new JSeparator());
opswThrown[i].addItemListener(event -> {
if (event.getSource().getClass() == JRadioButtonWithInteger.class) {
JRadioButtonWithInteger source = ((JRadioButtonWithInteger) (event.getSource()));
int ind = source.index;
boolean st = (event.getStateChange() == ItemEvent.DESELECTED);
log.debug("ItemEventListener Opsw values: {} thrown radio button event: {} {}.", ind, st, st ? "Closed" : "Thrown"); // NOI18N
opsw[ind] = st;
copyOpswToBasic();
}
});
}
}
opswsValues.add(opswsPanel);
opswsScrollPane = new JScrollPane(opswsValues);
opswsScrollPane.setPreferredSize(new java.awt.Dimension(180, 200));
opswsScrollPane.setName("Simple OpSws"); // NOI18N
generalTabbedPane.addTab(Bundle.getMessage("TabTextOpSwValues"), null,
opswsScrollPane, Bundle.getMessage("TabToolTipOpSwValues"));
outputAddrsPanel = new JPanel();
outputAddrsPanel.setLayout(new BoxLayout(outputAddrsPanel, BoxLayout.Y_AXIS));
JPanel p = new JPanel();
p.setLayout(new FlowLayout());
p.add(new JLabel(Bundle.getMessage("LabelCautionReadingWritingCanCauseOutputChanges")));
outputAddrsPanel.add(p);
p = new JPanel();
p.setLayout(new FlowLayout());
p.add(new JLabel(Bundle.getMessage("LabelTextOutputX", 1)));
outAddr1 = new ValidatedTextField(5, false, 1, 2048, Bundle.getMessage("ErrorTextNonBlankAddressInvalid"));
outState1 = new JLabel(Bundle.getMessage("LabelTurnoutCurrentStateX", Bundle.getMessage("BeanStateUnknown")));
p.add(outAddr1);
p.add(outState1);
outputAddrsPanel.add(p);
p = new JPanel();
p.setLayout(new FlowLayout());
p.add(new JLabel(Bundle.getMessage("LabelTextOutputX", 2)));
outAddr2 = new ValidatedTextField(5, false, 1, 2048, Bundle.getMessage("ErrorTextNonBlankAddressInvalid"));
outState2 = new JLabel(Bundle.getMessage("LabelTurnoutCurrentStateX", Bundle.getMessage("BeanStateUnknown")));
p.add(outAddr2);
p.add(outState2);
outputAddrsPanel.add(p);
p = new JPanel();
p.setLayout(new FlowLayout());
p.add(new JLabel(Bundle.getMessage("LabelTextOutputX", 3)));
outAddr3 = new ValidatedTextField(5, false, 1, 2048, Bundle.getMessage("ErrorTextNonBlankAddressInvalid"));
outState3 = new JLabel(Bundle.getMessage("LabelTurnoutCurrentStateX", Bundle.getMessage("BeanStateUnknown")));
p.add(outAddr3);
p.add(outState3);
outputAddrsPanel.add(p);
p = new JPanel();
p.setLayout(new FlowLayout());
p.add(new JLabel(Bundle.getMessage("LabelTextOutputX", 4)));
outAddr4 = new ValidatedTextField(5, false, 1, 2048, Bundle.getMessage("ErrorTextNonBlankAddressInvalid"));
outState4 = new JLabel(Bundle.getMessage("LabelTurnoutCurrentStateX", Bundle.getMessage("BeanStateUnknown")));
p.add(outAddr4);
p.add(outState4);
outputAddrsPanel.add(p);
outputAddrsPanel.add(new JSeparator());
p = new JPanel();
p.setLayout(new FlowLayout());
p.add(new JLabel(Bundle.getMessage("LabelOutputsTabSensorNotes")));
outputAddrsPanel.add(p);
generalTabbedPane.addTab(Bundle.getMessage("TabTextOutputAddrs"), null,
outputAddrsPanel, Bundle.getMessage("TabToolTipOutputAddrs"));
routePanel[0] = new JPanel();
routesTabbedPane.setTabPlacement(JTabbedPane.LEFT);
// create route panels (one tab each for each of 8 routes)
for (int i = 1; i <= 8; ++i) {
routePanel[i] = new JPanel();
routePanel[i].setLayout(new BoxLayout(routePanel[i], BoxLayout.Y_AXIS));
routePanel[i].add(new JLabel(Bundle.getMessage("TabTextSpecificRoute",
Integer.toString(i))));
routePanel[i].add(new JSeparator());
JPanel q = new JPanel(new FlowLayout());
q.add(new JLabel(Bundle.getMessage("LabelCautionReadingWritingCanCauseOutputChanges")));
routePanel[i].add(q);
routePanel[i].add(new JSeparator());
routeTop[i] = new SimpleTurnoutStateEntry(2048, false, true);
routeA2[i] = new SimpleTurnoutStateEntry(2048, false, true);
routeA3[i] = new SimpleTurnoutStateEntry(2048, false, true);
routeA4[i] = new SimpleTurnoutStateEntry(2048, false, true);
routeA5[i] = new SimpleTurnoutStateEntry(2048, false, true);
routeA6[i] = new SimpleTurnoutStateEntry(2048, false, true);
routeA7[i] = new SimpleTurnoutStateEntry(2048, false, true);
routeA8[i] = new SimpleTurnoutStateEntry(2048, false, true);
routePanel[i].add(routeTop[i].createEntryPanel(Bundle.getMessage("LabelTextRouteXSpecificTurnout",
Bundle.getMessage("LabelTextRouteXTopTurnout"))));
routePanel[i].add(routeA2[i].createEntryPanel(Bundle.getMessage("LabelTextRouteXSpecificTurnout", 2)));
routePanel[i].add(routeA3[i].createEntryPanel(Bundle.getMessage("LabelTextRouteXSpecificTurnout", 3)));
routePanel[i].add(routeA4[i].createEntryPanel(Bundle.getMessage("LabelTextRouteXSpecificTurnout", 4)));
routePanel[i].add(routeA5[i].createEntryPanel(Bundle.getMessage("LabelTextRouteXSpecificTurnout", 5)));
routePanel[i].add(routeA6[i].createEntryPanel(Bundle.getMessage("LabelTextRouteXSpecificTurnout", 6)));
routePanel[i].add(routeA7[i].createEntryPanel(Bundle.getMessage("LabelTextRouteXSpecificTurnout", 7)));
routePanel[i].add(routeA8[i].createEntryPanel(Bundle.getMessage("LabelTextRouteXSpecificTurnout", 8)));
routesTabbedPane.addTab(
Bundle.getMessage("TabTextSpecificRoute", Integer.toString(i)),
null,
routePanel[i],
Bundle.getMessage("TabToolTipSpecificRoute", Integer.toString(i))
);
}
generalTabbedPane.addTab(Bundle.getMessage("TabTextRoutes"),
null, routesTabbedPane,
Bundle.getMessage("ToolTipTabTextRoutes"));
resetRouteButton.addActionListener(
event -> {
readAllButton.setEnabled(false);
writeAllButton.setEnabled(false);
factoryResetButton.setEnabled(false);
Integer routeNumber = 0;
if (((JTabbedPane) generalTabbedPane.getSelectedComponent()) != routesTabbedPane) {
return;
}
if (((JPanel) routesTabbedPane.getSelectedComponent()) == routePanel[1]) {
routeNumber = 1;
} else if (((JPanel) routesTabbedPane.getSelectedComponent()) == routePanel[2]) {
routeNumber = 2;
} else if (((JPanel) routesTabbedPane.getSelectedComponent()) == routePanel[3]) {
routeNumber = 3;
} else if (((JPanel) routesTabbedPane.getSelectedComponent()) == routePanel[4]) {
routeNumber = 4;
} else if (((JPanel) routesTabbedPane.getSelectedComponent()) == routePanel[5]) {
routeNumber = 5;
} else if (((JPanel) routesTabbedPane.getSelectedComponent()) == routePanel[6]) {
routeNumber = 6;
} else if (((JPanel) routesTabbedPane.getSelectedComponent()) == routePanel[7]) {
routeNumber = 7;
} else if (((JPanel) routesTabbedPane.getSelectedComponent()) == routePanel[8]) {
routeNumber = 8;
}
if (routeNumber != 0) {
// before proceeding, make sure that the user really wants to go forward
Object[] dialogBoxButtonOptions = {
Bundle.getMessage("ButtonResetRouteN", routeNumber),
Bundle.getMessage("ButtonCancel")};
int userReply = JmriJOptionPane.showOptionDialog(this,
Bundle.getMessage("DialogTextClearRouteWarning", routeNumber),
Bundle.getMessage("WarningTitle"),
JmriJOptionPane.YES_NO_OPTION, JmriJOptionPane.QUESTION_MESSAGE,
null, dialogBoxButtonOptions, dialogBoxButtonOptions[1]);
if ( userReply != JmriJOptionPane.YES_OPTION ) {
resetRouteButton.setSelected(false);
return; // compare only to exactly the value for executing the "clear route" operation!
}
resetRouteOperation(routeNumber);
}
readAllButton.setEnabled(true);
writeAllButton.setEnabled(true);
factoryResetButton.setEnabled(true);
resetRouteButton.setSelected(false);
}
);
appendLine(generalTabbedPane);
JPanel statusPanel = new JPanel();
setStatus(" ");
statusPanel.add(new JSeparator());
statusPanel.add(provideStatusLine());
statusPanel.add(new JSeparator());
appendLine(statusPanel);
setTypeWord(0x73); // configure DS64 message type
opsw[7] = false;
operationType = OpSwOpType.BasicsRead;
routesTabbedPane.addChangeListener(new ChangeListener() {
// This method is called whenever the selected tab changes
String route1TabText = Bundle.getMessage("TabTextSpecificRoute", Integer.toString(1));
String route2TabText = Bundle.getMessage("TabTextSpecificRoute", Integer.toString(2));
String route3TabText = Bundle.getMessage("TabTextSpecificRoute", Integer.toString(3));
String route4TabText = Bundle.getMessage("TabTextSpecificRoute", Integer.toString(4));
String route5TabText = Bundle.getMessage("TabTextSpecificRoute", Integer.toString(5));
String route6TabText = Bundle.getMessage("TabTextSpecificRoute", Integer.toString(6));
String route7TabText = Bundle.getMessage("TabTextSpecificRoute", Integer.toString(7));
String route8TabText = Bundle.getMessage("TabTextSpecificRoute", Integer.toString(8));
@Override
public void stateChanged(ChangeEvent evt) {
unhighlightAllBasicOpSws();
unhighlightAllOutputEntryFields();
unhighlightAllRouteEntryFields();
String activeTabTitle = routesTabbedPane.getTitleAt(routesTabbedPane.getSelectedIndex());
if ((activeTabTitle.equals(route1TabText))
|| (activeTabTitle.equals(route2TabText))
|| (activeTabTitle.equals(route3TabText))
|| (activeTabTitle.equals(route4TabText))
|| (activeTabTitle.equals(route5TabText))
|| (activeTabTitle.equals(route6TabText))
|| (activeTabTitle.equals(route7TabText))
|| (activeTabTitle.equals(route8TabText))) {
resetRouteButton.setVisible(true);
resetRouteButton.setEnabled(true);
resetRouteButton.updateUI();
readAllButton.setSelected(false);
readAllButton.updateUI();
updateUI();
}
}
});
generalTabbedPane.addChangeListener(new ChangeListener() {
// This method is called whenever the selected tab changes
String route1TabText = Bundle.getMessage("TabTextSpecificRoute", Integer.toString(1));
String route2TabText = Bundle.getMessage("TabTextSpecificRoute", Integer.toString(2));
String route3TabText = Bundle.getMessage("TabTextSpecificRoute", Integer.toString(3));
String route4TabText = Bundle.getMessage("TabTextSpecificRoute", Integer.toString(4));
String route5TabText = Bundle.getMessage("TabTextSpecificRoute", Integer.toString(5));
String route6TabText = Bundle.getMessage("TabTextSpecificRoute", Integer.toString(6));
String route7TabText = Bundle.getMessage("TabTextSpecificRoute", Integer.toString(7));
String route8TabText = Bundle.getMessage("TabTextSpecificRoute", Integer.toString(8));
String outputsTabText = Bundle.getMessage("TabTextOutputAddrs");
@Override
public void stateChanged(ChangeEvent evt) {
String activeTabTitle;
unhighlightAllBasicOpSws();
unhighlightAllOutputEntryFields();
unhighlightAllRouteEntryFields();
activeTabTitle = generalTabbedPane.getTitleAt(generalTabbedPane.getSelectedIndex());
JTabbedPane pane = (JTabbedPane) evt.getSource();
// Get current tab
if ((activeTabTitle.equals(Bundle.getMessage("TabTextRoutes")))) {
activeTabTitle = routesTabbedPane.getTitleAt(routesTabbedPane.getSelectedIndex());
if ((activeTabTitle.equals(route1TabText))
|| (activeTabTitle.equals(route2TabText))
|| (activeTabTitle.equals(route3TabText))
|| (activeTabTitle.equals(route4TabText))
|| (activeTabTitle.equals(route5TabText))
|| (activeTabTitle.equals(route6TabText))
|| (activeTabTitle.equals(route7TabText))
|| (activeTabTitle.equals(route8TabText))) {
resetRouteButton.setEnabled(true);
resetRouteButton.setVisible(true);
readAllButton.setEnabled(true);
writeAllButton.setSelected(false);
readAllButton.setSelected(false);
writeAllButton.setEnabled(true);
factoryResetButton.setEnabled(true);
routesTabbedPane.updateUI();
updateUI();
} else {
routesTabbedPane.setSelectedIndex(0);
routesTabbedPane.updateUI();
}
} else if (activeTabTitle.equals(outputsTabText)) {
resetRouteButton.setEnabled(false);
resetRouteButton.setVisible(false);
readAllButton.setEnabled(true);
writeAllButton.setSelected(false);
readAllButton.setSelected(false);
writeAllButton.setEnabled(true);
readAllButton.updateUI();
updateUI();
} else {
readAllButton.setEnabled(true);
writeAllButton.setEnabled(true);
writeAllButton.setSelected(false);
readAllButton.setSelected(false);
resetRouteButton.setVisible(false);
resetRouteButton.setEnabled(false);
readAllButton.updateUI();
updateUI();
}
Container c = pane.getRootPane().getParent();
c.setPreferredSize(null);
if (c instanceof Window) {
((Window) c).pack();
}
}
});
responseTimer.addActionListener(routeResetResponseTimerListener);
commandType.setToolTipText(Bundle.getMessage("ToolTipLabelAcceptedSwitchCommandTypes"));
updateBasicOpSwTab();
panelToScroll();
}
@edu.umd.cs.findbugs.annotations.SuppressFBWarnings(value = "DLS_DEAD_LOCAL_STORE", justification = "Cannot catch an exception without grabbing the exception, but we don't do anything with the exception details.")
private void updateGuiFromOpSws49_64() {
Integer readValue;
boolean isUsed = true;
readValue = 0;
for (int i = 60; i >= 49; i--) {
if (i != 56) {
readValue = (readValue << 1) + (opsw[i] ? 1 : 0);
}
}
readValue++; // account for physical/user numbering difference
String readValueString = readValue.toString();
if ((opsw[63] == true) && (opsw[64] == true)) {
readValueString = "";
isUsed = false;
}
boolean direction = opsw[62];
switch (indexToRead) {
case 0: {
// have read value for output2 - update local storage
outAddr2.setText(Integer.toString(readValue));
outAddr2.setLastQueriedValue(outAddr2.getText());
outState2.setText(direction
? Bundle.getMessage("LabelTurnoutCurrentStateX", Bundle.getMessage("BeanStateClosed"))
: Bundle.getMessage("LabelTurnoutCurrentStateX", Bundle.getMessage("BeanStateThrown")));
break;
}
case 1: {
// have read value for output4 - update local storage
outAddr4.setText(Integer.toString(readValue));
outAddr4.setLastQueriedValue(outAddr4.getText());
outState4.setText(direction
? Bundle.getMessage("LabelTurnoutCurrentStateX", Bundle.getMessage("BeanStateClosed"))
: Bundle.getMessage("LabelTurnoutCurrentStateX", Bundle.getMessage("BeanStateThrown")));
break;
}
case 16:
case 20:
case 24:
case 28:
case 32:
case 36:
case 40:
case 44: {
// have a read value for Route n - update local storage
Integer effectiveIndex = (indexToRead - 12) / 4;
if (isUsed == false) {
routeA2[effectiveIndex].setIsUnused();
routeA2[effectiveIndex].addressField.setText("");
routeA2[effectiveIndex].unusedRadioButton.setSelected(true);
} else {
routeA2[effectiveIndex].setAddress(readValue);
routeA2[effectiveIndex].addressField.setText(readValueString);
routeA2[effectiveIndex].addressField.setLastQueriedValue(readValueString);
if (opsw[62] == true) {
routeA2[effectiveIndex].closedRadioButton.setSelected(true);
} else {
routeA2[effectiveIndex].thrownRadioButton.setSelected(true);
}
}
break;
}
case 17:
case 21:
case 25:
case 29:
case 33:
case 37:
case 41:
case 45: {
// have a read value for Route n - update local storage
Integer effectiveIndex = (indexToRead - 13) / 4;
if (isUsed == false) {
routeA4[effectiveIndex].setIsUnused();
routeA4[effectiveIndex].addressField.setText("");
routeA4[effectiveIndex].unusedRadioButton.setSelected(true);
} else {
routeA4[effectiveIndex].setAddress(readValue);
routeA4[effectiveIndex].addressField.setText(readValueString);
routeA4[effectiveIndex].addressField.setLastQueriedValue(readValueString);
if (opsw[62] == true) {
routeA4[effectiveIndex].closedRadioButton.setSelected(true);
} else {
routeA4[effectiveIndex].thrownRadioButton.setSelected(true);
}
}
break;
}
case 18:
case 22:
case 26:
case 30:
case 34:
case 38:
case 42:
case 46: {
// have a read value for Route n - update local storage
Integer effectiveIndex = (indexToRead - 14) / 4;
if (isUsed == false) {
routeA6[effectiveIndex].setIsUnused();
routeA6[effectiveIndex].addressField.setText("");
routeA6[effectiveIndex].unusedRadioButton.setSelected(true);
} else {
routeA6[effectiveIndex].setAddress(readValue);
routeA6[effectiveIndex].addressField.setText(readValueString);
routeA6[effectiveIndex].addressField.setLastQueriedValue(readValueString);
if (opsw[62] == true) {
routeA6[effectiveIndex].closedRadioButton.setSelected(true);
} else {
routeA6[effectiveIndex].thrownRadioButton.setSelected(true);
}
}
break;
}
case 19:
case 23:
case 27:
case 31:
case 35:
case 39:
case 43:
case 47: {
// have a read value for Route n - update local storage
Integer effectiveIndex = (indexToRead - 15) / 4;
if (isUsed == false) {
routeA8[effectiveIndex].setIsUnused();
routeA8[effectiveIndex].addressField.setText("");
routeA8[effectiveIndex].unusedRadioButton.setSelected(true);
} else {
routeA8[effectiveIndex].setAddress(readValue);
routeA8[effectiveIndex].addressField.setText(readValueString);
routeA8[effectiveIndex].addressField.setLastQueriedValue(readValueString);
if (opsw[62] == true) {
routeA8[effectiveIndex].closedRadioButton.setSelected(true);
} else {
routeA8[effectiveIndex].thrownRadioButton.setSelected(true);
}
}
break;
}
default:
break;
}
}
@edu.umd.cs.findbugs.annotations.SuppressFBWarnings(value = "DLS_DEAD_LOCAL_STORE", justification = "Cannot catch an exception without grabbing the exception, but we don't do anything with the exception details.")
void updateGuiFromOpSws33_48() {
Integer readValue;
boolean isUsed = true;
readValue = 0;
for (int i = 44; i >= 33; i--) {
if (i != 40) {
readValue = (readValue << 1) + (opsw[i] ? 1 : 0);
}
}
readValue++; // account for physical/user numbering difference
String readValueString = readValue.toString();
if ((opsw[47] == true) && (opsw[48] == true)) {
readValueString = "";
isUsed = false;
}
boolean direction = opsw[46];
switch (indexToRead) {
case 0: {
// have read value for output1 - update local storage
outAddr1.setText(readValueString);
outAddr1.setLastQueriedValue(readValueString);
outAddr1.isValid();
outState1.setText(direction
? Bundle.getMessage("LabelTurnoutCurrentStateX", Bundle.getMessage("BeanStateClosed"))
: Bundle.getMessage("LabelTurnoutCurrentStateX", Bundle.getMessage("BeanStateThrown")));
break;
}
case 1: {
// have read value for output3 - update local storage
outAddr3.setText(readValueString);
outAddr3.setLastQueriedValue(readValueString);
outState3.setText(direction
? Bundle.getMessage("LabelTurnoutCurrentStateX", Bundle.getMessage("BeanStateClosed"))
: Bundle.getMessage("LabelTurnoutCurrentStateX", Bundle.getMessage("BeanStateThrown")));
break;
}
case 16:
case 20:
case 24:
case 28:
case 32:
case 36:
case 40:
case 44: {
// have read value for Route n Top - update local storage
Integer effectiveIndex = (indexToRead - 12) / 4;
if (isUsed == false) {
routeTop[effectiveIndex].setIsUnused();
routeTop[effectiveIndex].addressField.setText("");
routeTop[effectiveIndex].unusedRadioButton.setSelected(true);
} else {
routeTop[effectiveIndex].setAddress(readValue);
routeTop[effectiveIndex].addressField.setText(readValueString);
routeTop[effectiveIndex].addressField.setLastQueriedValue(readValueString);
if (opsw[46] == true) {
routeTop[effectiveIndex].closedRadioButton.setSelected(true);
} else {
routeTop[effectiveIndex].thrownRadioButton.setSelected(true);
}
}
break;
}
case 17:
case 21:
case 25:
case 29:
case 33:
case 37:
case 41:
case 45: {
// have a read value for Route n - update local storage
Integer effectiveIndex = (indexToRead - 13) / 4;
if (isUsed == false) {
routeA3[effectiveIndex].setIsUnused();
routeA3[effectiveIndex].addressField.setText("");
routeA3[effectiveIndex].unusedRadioButton.setSelected(true);
} else {
routeA3[effectiveIndex].setAddress(readValue);
routeA3[effectiveIndex].addressField.setText(readValueString);
routeA3[effectiveIndex].addressField.setLastQueriedValue(readValueString);
if (opsw[46] == true) {
routeA3[effectiveIndex].closedRadioButton.setSelected(true);
} else {
routeA3[effectiveIndex].thrownRadioButton.setSelected(true);
}
}
break;
}
case 18:
case 22:
case 26:
case 30:
case 34:
case 38:
case 42:
case 46: {
// have a read value for Route n - update local storage
Integer effectiveIndex = (indexToRead - 14) / 4;
if (isUsed == false) {
routeA5[effectiveIndex].setIsUnused();
routeA5[effectiveIndex].addressField.setText("");
routeA5[effectiveIndex].unusedRadioButton.setSelected(true);
} else {
routeA5[effectiveIndex].setAddress(readValue);
routeA5[effectiveIndex].addressField.setText(readValueString);
routeA5[effectiveIndex].addressField.setLastQueriedValue(readValueString);
if (opsw[46] == true) {
routeA5[effectiveIndex].closedRadioButton.setSelected(true);
} else {
routeA5[effectiveIndex].thrownRadioButton.setSelected(true);
}
}
break;
}
case 19:
case 23:
case 27:
case 31:
case 35:
case 39:
case 43:
case 47: {
// have a read value for Route n - update local storage
Integer effectiveIndex = (indexToRead - 15) / 4;
if (isUsed == false) {
routeA7[effectiveIndex].setIsUnused();
routeA7[effectiveIndex].addressField.setText("");
routeA7[effectiveIndex].unusedRadioButton.setSelected(true);
} else {
routeA7[effectiveIndex].setAddress(readValue);
routeA7[effectiveIndex].addressField.setText(readValueString);
routeA7[effectiveIndex].addressField.setLastQueriedValue(readValueString);
if (opsw[46] == true) {
routeA7[effectiveIndex].closedRadioButton.setSelected(true);
} else {
routeA7[effectiveIndex].thrownRadioButton.setSelected(true);
}
}
break;
}
default: {
break;
}
}
}
private final ActionListener basicConfigChangeActionListener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource().getClass() == JComboBox.class) {
switch (((Component) e.getSource()).getName()) {
case "1": // NOI18N
opsw[1] = (outputType.getSelectedIndex() == 1);
updateGuiBasicOpSw(1);
break;
case "2345": // NOI18N
int selection = delayTime.getSelectedIndex();
opsw[2] = ((selection & 0x1) == 1);
opsw[3] = ((selection & 0x2) == 2);
opsw[4] = ((selection & 0x4) == 4);
opsw[5] = ((selection & 0x8) == 8);
updateGuiBasicOpSw(2);
updateGuiBasicOpSw(3);
updateGuiBasicOpSw(4);
updateGuiBasicOpSw(5);
break;
case "6": // NOI18N
opsw[6] = (outputStates.getSelectedIndex() == 1);
updateGuiBasicOpSw(6);
break;
case "8": // NOI18N
opsw[8] = startupDelay.getSelectedIndex() == 1;
updateGuiBasicOpSw(8);
break;
case "9": // NOI18N
opsw[9] = staticOutputShutoff.getSelectedIndex() == 1;
updateGuiBasicOpSw(9);
break;
case "10": // NOI18N
opsw[10] = commandType.getSelectedIndex() == 1;
updateGuiBasicOpSw(10);
break;
case "13": // NOI18N
opsw[13] = (sensorMessageTrigger.getSelectedIndex() == 1);
updateGuiBasicOpSw(13);
break;
case "14": // NOI18N
opsw[14] = commandSource.getSelectedIndex() == 1;
updateGuiBasicOpSw(14);
break;
case "21": // NOI18N
opsw[21] = localSensorType.getSelectedIndex() == 1;
updateGuiBasicOpSw(21);
break;
case "1116": // NOI18N
opsw[11] = (routesControl.getSelectedIndex() == 1) || (routesControl.getSelectedIndex() == 3);
opsw[16] = routesControl.getSelectedIndex() >= 2;
updateGuiBasicOpSw(11);
updateGuiBasicOpSw(16);
break;
case "1215": // NOI18N
opsw[12] = (localControlOfOutputsStyle.getSelectedIndex() & 1) == 1; //2 -> OpSw12="c"
opsw[15] = (localControlOfOutputsStyle.getSelectedIndex() >= 2); //0 -> OpSw15="c"
updateGuiBasicOpSw(12);
updateGuiBasicOpSw(15);
break;
default:
}
} else if (e.getSource().getClass() == JCheckBox.class) {
switch (((Component) e.getSource()).getName()) {
case "17": // NOI18N
opsw[17] = output1CrossbuckFlasherCheckBox.isSelected();
updateGuiBasicOpSw(17);
break;
case "18": // NOI18N
opsw[18] = output2CrossbuckFlasherCheckBox.isSelected();
updateGuiBasicOpSw(18);
break;
case "19": // NOI18N
opsw[19] = output3CrossbuckFlasherCheckBox.isSelected();
updateGuiBasicOpSw(19);
break;
case "20": // NOI18N
opsw[20] = output4CrossbuckFlasherCheckBox.isSelected();
updateGuiBasicOpSw(20);
break;
default:
break;
}
}
}
};
private void updateBasicOpSwTab() {
for (int i = 1; i <= 21; ++i) {
if (i != 7) {
opswThrown[i].setSelected(!opsw[i]);
opswClosed[i].setSelected(opsw[i]);
}
}
}
private class JRadioButtonWithInteger extends JRadioButton {
public int index;
JRadioButtonWithInteger(int i, String s) {
super(s);
index = i;
}
}
/**
* Copy from the GUI OpSw tab to the GUI Basics tab
*/
protected void copyOpswToBasic() {
// copy over values from OpSw tab to the Basics tab
outputType.setSelectedIndex(opsw[1]?1:0);
delayTime.setSelectedIndex(
(opsw[2]?1:0) + (opsw[3]?2:0) + (opsw[4]?4:0) + (opsw[5]?8:0));
outputStates.setSelectedIndex(opsw[6]?1:0);
isWritingResetOpSw = opsw[7];
startupDelay.setSelectedIndex(opsw[8]?1:0);
staticOutputShutoff.setSelectedIndex(opsw[9]?1:0);
commandType.setSelectedIndex(opsw[10]?1:0);
routesControl.setSelectedIndex((opsw[11]?1:0) + (opsw[16]?2:0));
localControlOfOutputsStyle.setSelectedIndex((opsw[12]?1:0) + (opsw[15]?2:0));
sensorMessageTrigger.setSelectedIndex(opsw[13]?1:0);
commandSource.setSelectedIndex(opsw[14]?1:0);
output1CrossbuckFlasherCheckBox.setSelected(opsw[17]);
output2CrossbuckFlasherCheckBox.setSelected(opsw[18]);
output3CrossbuckFlasherCheckBox.setSelected(opsw[19]);
output4CrossbuckFlasherCheckBox.setSelected(opsw[20]);
localSensorType.setSelectedIndex(opsw[21]?1:0);
}
private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(Ds64TabbedPanel.class);
}