001package jmri.jmrix.acela.nodeconfig;
002
003import java.awt.BorderLayout;
004import java.awt.Container;
005import java.awt.FlowLayout;
006import java.awt.event.ActionEvent;
007import java.awt.event.ActionListener;
008
009import javax.swing.BorderFactory;
010import javax.swing.BoxLayout;
011import javax.swing.DefaultCellEditor;
012import javax.swing.JComboBox;
013import javax.swing.JLabel;
014import javax.swing.JPanel;
015import javax.swing.JScrollPane;
016import javax.swing.JTable;
017import javax.swing.border.Border;
018import javax.swing.table.TableColumn;
019import javax.swing.table.TableColumnModel;
020
021import jmri.jmrix.acela.AcelaNode;
022import jmri.jmrix.acela.AcelaSystemConnectionMemo;
023import jmri.util.swing.JmriJOptionPane;
024
025/**
026 * Frame for user configuration of Acela nodes
027 *
028 * @author Bob Jacobsen Copyright (C) 2004, 2007, 2008
029 * @author Dave Duchamp Copyright (C) 2004, 2006
030 */
031public class NodeConfigFrame extends jmri.util.JmriJFrame {
032
033    private AcelaSystemConnectionMemo _memo = null;
034
035    protected Container contentPane;
036    protected NodeConfigModel d8outputConfigModel;
037    protected NodeConfigModel swoutputConfigModel;
038    protected NodeConfigModel ymoutputConfigModel;
039    protected NodeConfigModel TBoutputConfigModel;
040    protected NodeConfigModel TBsensorConfigModel;
041    protected NodeConfigModel smoutputConfigModel;
042    protected NodeConfigModel wmsensorConfigModel;
043    protected NodeConfigModel sysensorConfigModel;
044
045    protected JLabel thenodesStaticH = new JLabel("  00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19");
046    protected JLabel thenodesStaticC = new JLabel("");
047    protected JLabel thenodesStaticP = new JLabel("              " + Bundle.getMessage("HwNotYet"));
048
049    protected javax.swing.JTextField nodeAddrField = new javax.swing.JTextField(3);
050    protected JLabel nodeAddrStatic = new JLabel("000");
051    protected JLabel nodeTypeStatic = new JLabel("Acela"); // NOI18N
052    protected javax.swing.JComboBox<String> nodeAddrBox;
053    protected javax.swing.JComboBox<String> nodeTypeBox;
054
055    protected javax.swing.JButton addButton = new javax.swing.JButton(Bundle.getMessage("ButtonAdd"));
056    protected javax.swing.JButton editButton = new javax.swing.JButton(Bundle.getMessage("ButtonEdit"));
057    protected javax.swing.JButton deleteButton = new javax.swing.JButton(Bundle.getMessage("ButtonDelete"));
058    protected javax.swing.JButton doneButton = new javax.swing.JButton(Bundle.getMessage("ButtonDone"));
059    protected javax.swing.JButton updateButton = new javax.swing.JButton(Bundle.getMessage("ButtonUpdate"));
060    protected javax.swing.JButton cancelButton = new javax.swing.JButton(Bundle.getMessage("ButtonCancel"));
061
062    protected JLabel statusText1 = new JLabel();
063    protected JLabel statusText2 = new JLabel();
064    protected JLabel statusText3 = new JLabel();
065
066    protected JLabel statusTextAcela1 = new JLabel();
067    protected JLabel statusTextAcela2 = new JLabel();
068    protected JLabel statusTextAcela3 = new JLabel();
069    protected JLabel statusTextAcela4 = new JLabel();
070    protected JLabel statusTextAcela5 = new JLabel();
071    protected JLabel statusTextAcela6 = new JLabel();
072    protected JLabel statusTextAcela7 = new JLabel();
073    protected JLabel statusTextAcela8 = new JLabel();
074    protected JLabel statusTextAcela9 = new JLabel();
075    protected JLabel statusTextAcela10 = new JLabel();
076    protected JLabel statusTextAcela11 = new JLabel();
077    protected JLabel statusTextTBrain1 = new JLabel();
078    protected JLabel statusTextTBrain2 = new JLabel();
079    protected JLabel statusTextTBrain3 = new JLabel();
080    protected JLabel statusTextDash81 = new JLabel();
081    protected JLabel statusTextDash82 = new JLabel();
082    protected JLabel statusTextDash83 = new JLabel();
083    protected JLabel statusTextWatchman1 = new JLabel();
084    protected JLabel statusTextWatchman2 = new JLabel();
085    protected JLabel statusTextWatchman3 = new JLabel();
086    protected JLabel statusTextSignalman1 = new JLabel();
087    protected JLabel statusTextSignalman2 = new JLabel();
088    protected JLabel statusTextSignalman3 = new JLabel();
089    protected JLabel statusTextSwitchman1 = new JLabel();
090    protected JLabel statusTextSwitchman2 = new JLabel();
091    protected JLabel statusTextSwitchman3 = new JLabel();
092    protected JLabel statusTextYardMaster1 = new JLabel();
093    protected JLabel statusTextYardMaster2 = new JLabel();
094    protected JLabel statusTextYardMaster3 = new JLabel();
095    protected JLabel statusTextSentry1 = new JLabel();
096    protected JLabel statusTextSentry2 = new JLabel();
097    protected JLabel statusTextSentry3 = new JLabel();
098
099    protected JPanel panelAcela = new JPanel();
100    protected JPanel panelTBrain = new JPanel();
101    protected JPanel panelDash8 = new JPanel();
102    protected JPanel panelWatchman = new JPanel();
103    protected JPanel panelSignalman = new JPanel();
104    protected JPanel panelSwitchman = new JPanel();
105    protected JPanel panelYardMaster = new JPanel();
106    protected JPanel panelSentry = new JPanel();
107
108    protected boolean changedNode = false;  // true if a node was changed, deleted, or added
109    protected boolean editMode = false;     // true if in edit mode
110    private boolean checkEnabled = jmri.InstanceManager.getDefault(jmri.configurexml.ShutdownPreferences.class).isStoreCheckEnabled();
111
112    protected AcelaNode curNode = null;    // Acela Node being editted
113    protected int nodeAddress = 0;          // Node address
114    protected int nodeType = AcelaNode.UN; // Node type
115
116    protected boolean errorInStatus1 = false;
117    protected boolean errorInStatus2 = false;
118    protected String stdStatus1 = Bundle.getMessage("NotesStd1");
119    protected String stdStatus2 = Bundle.getMessage("NotesStd2");
120    protected String stdStatus3 = Bundle.getMessage("NotesStd3");
121    protected String stdStatusAcela1 = Bundle.getMessage("NotesStdAcela1");
122    protected String stdStatusAcela2 = Bundle.getMessage("NotesStdAcela2");
123    protected String stdStatusAcela3 = Bundle.getMessage("NotesStdAcela3");
124    protected String stdStatusAcela4 = Bundle.getMessage("NotesStdAcela4");
125    protected String stdStatusAcela5 = Bundle.getMessage("NotesStdAcela5");
126    protected String stdStatusAcela6 = Bundle.getMessage("NotesStdAcela6");
127    protected String stdStatusAcela7 = Bundle.getMessage("NotesStdAcela7");
128    protected String stdStatusAcela8 = Bundle.getMessage("NotesStdAcela8");
129    protected String stdStatusAcela9 = Bundle.getMessage("NotesStdAcela9");
130    protected String stdStatusAcela10 = Bundle.getMessage("NotesStdAcela10");
131    protected String stdStatusAcela11 = Bundle.getMessage("NotesStdAcela11");
132    protected String stdStatusTBrain1 = Bundle.getMessage("NotesStdTBrain1");
133    protected String stdStatusTBrain2 = Bundle.getMessage("NotesStdTBrain2");
134    protected String stdStatusTBrain3 = Bundle.getMessage("NotesStdTBrain3");
135    protected String stdStatusDash81 = Bundle.getMessage("NotesStdDash81");
136    protected String stdStatusDash82 = Bundle.getMessage("NotesStdDash82");
137    protected String stdStatusDash83 = Bundle.getMessage("NotesStdDash83");
138    protected String stdStatusWatchman1 = Bundle.getMessage("NotesStdWatchman1");
139    protected String stdStatusWatchman2 = Bundle.getMessage("NotesStdWatchman2");
140    protected String stdStatusWatchman3 = Bundle.getMessage("NotesStdWatchman3");
141    protected String stdStatusSignalman1 = Bundle.getMessage("NotesStdSignalman1");
142    protected String stdStatusSignalman2 = Bundle.getMessage("NotesStdSignalman2");
143    protected String stdStatusSignalman3 = Bundle.getMessage("NotesStdSignalman3");
144    protected String stdStatusSwitchman1 = Bundle.getMessage("NotesStdSwitchman1");
145    protected String stdStatusSwitchman2 = Bundle.getMessage("NotesStdSwitchman2");
146    protected String stdStatusSwitchman3 = Bundle.getMessage("NotesStdSwitchman3");
147    protected String stdStatusYardMaster1 = Bundle.getMessage("NotesStdYardMaster1");
148    protected String stdStatusYardMaster2 = Bundle.getMessage("NotesStdYardMaster2");
149    protected String stdStatusYardMaster3 = Bundle.getMessage("NotesStdYardMaster3");
150    protected String stdStatusSentry1 = Bundle.getMessage("NotesStdSentry1");
151    protected String stdStatusSentry2 = Bundle.getMessage("NotesStdSentry2");
152    protected String stdStatusSentry3 = Bundle.getMessage("NotesStdSentry3");
153    protected String editStatus1 = Bundle.getMessage("NotesEdit1");
154    protected String editStatus2 = Bundle.getMessage("NotesEdit2");
155    protected String editStatus3 = Bundle.getMessage("NotesEdit3");
156    protected String infoStatus1 = Bundle.getMessage("NotesStd1");
157    protected String infoStatus2 = Bundle.getMessage("NotesStd2");
158    protected String infoStatus3 = Bundle.getMessage("NotesStd3");
159
160    protected javax.swing.JTextField receiveDelayField = new javax.swing.JTextField(3);
161
162    /**
163     * Constructor method.
164     * @param memo system connection.
165     */
166    public NodeConfigFrame(AcelaSystemConnectionMemo memo) {
167        super();
168        _memo = memo;
169    }
170
171    /**
172     * Initialize the config window
173     */
174    @Override
175    public void initComponents() {
176        setTitle(Bundle.getMessage("ConfigNodesTitle"));
177
178        contentPane = getContentPane();
179        contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.Y_AXIS));
180
181        // Set up node address and node type
182        JPanel panel1 = new JPanel();
183        panel1.setLayout(new BoxLayout(panel1, BoxLayout.Y_AXIS));
184
185        // Copy and pasted from the info button
186        StringBuilder nodesstring = new StringBuilder("");
187        int tempnumnodes = _memo.getTrafficController().getNumNodes();
188        for (int i = 0; i < tempnumnodes; i++) {
189            AcelaNode tempnode;
190            tempnode = (AcelaNode) _memo.getTrafficController().getNodeFromAddress(i);
191            nodesstring.append(" ").append(tempnode.getNodeTypeString());
192        }
193        thenodesStaticC.setText(nodesstring.toString());
194
195        // panelthenodes displays the current node configuration and polling result
196        JPanel panelthenodes = new JPanel();
197        panelthenodes.setLayout(new BoxLayout(panelthenodes, BoxLayout.Y_AXIS));
198
199        JPanel panelthenodes1 = new JPanel();
200        panelthenodes1.setLayout(new FlowLayout());
201        panelthenodes1.add(new JLabel(Bundle.getMessage("NodesLabel") + " "));
202        panelthenodes1.add(thenodesStaticH);
203        panelthenodes.add(panelthenodes1);
204
205        JPanel panelthenodes2 = new JPanel();
206        panelthenodes2.setLayout(new FlowLayout());
207        panelthenodes2.add(new JLabel(Bundle.getMessage("AsConfiguredLabel") + " "));
208        panelthenodes2.add(thenodesStaticC);
209        panelthenodes.add(panelthenodes2);
210
211        JPanel panelthenodes3 = new JPanel();
212        panelthenodes3.setLayout(new FlowLayout());
213        panelthenodes3.add(new JLabel(Bundle.getMessage("AsPolledLabel") + " "));
214        panelthenodes3.add(thenodesStaticP);
215        panelthenodes.add(panelthenodes3);
216
217        Border panelthenodesBorder = BorderFactory.createEtchedBorder();
218        Border panelthenodesTitled = BorderFactory.createTitledBorder(panelthenodesBorder,
219                Bundle.getMessage("BoxLabelNodes"));
220        panelthenodes.setBorder(panelthenodesTitled);
221
222        contentPane.add(panelthenodes);
223
224        // panel11 is the node address
225        JPanel panel11 = new JPanel();
226        panel11.setLayout(new FlowLayout());
227
228        panel11.add(new JLabel(Bundle.getMessage("LabelNodeAddress") + " "));
229        nodeAddrBox = new JComboBox<String>(AcelaNode.getNodeNames());
230        nodeAddrBox.addActionListener(new ActionListener() {
231            @Override
232            public void actionPerformed(ActionEvent event) {
233                infoButtonActionPerformed();
234            }
235        });
236        panel11.add(nodeAddrBox);
237        panel11.add(nodeAddrField);
238//        nodeAddrField.setToolTipText(Bundle.getMessage("TipNodeAddress"));
239        nodeAddrField.setText("0");
240        panel11.add(nodeAddrStatic);
241        nodeAddrField.setVisible(false);
242        nodeAddrStatic.setVisible(false);
243        contentPane.add(panel11);
244
245        // panelNodeInfo is the node type
246        JPanel panelNodeInfo = new JPanel();
247
248        panelNodeInfo.add(new JLabel("   " + Bundle.getMessage("LabelNodeType") + " "));
249        nodeTypeBox = new JComboBox<String>(AcelaNode.getModuleNames());
250        nodeTypeBox.addActionListener(new ActionListener() {
251            @Override
252            public void actionPerformed(ActionEvent event) {
253                String s = (String) nodeTypeBox.getSelectedItem();
254                if (s.equals("Acela")) {
255                    panelAcela.setVisible(true);
256                    panelTBrain.setVisible(false);
257                    panelDash8.setVisible(false);
258                    panelWatchman.setVisible(false);
259                    panelSignalman.setVisible(false);
260                    panelSwitchman.setVisible(false);
261                    panelYardMaster.setVisible(false);
262                    panelSentry.setVisible(false);
263                } else if (s.equals("TrainBrain")) {
264                    panelAcela.setVisible(false);
265                    panelTBrain.setVisible(true);
266                    panelDash8.setVisible(false);
267                    panelWatchman.setVisible(false);
268                    panelSignalman.setVisible(false);
269                    panelSwitchman.setVisible(false);
270                    panelYardMaster.setVisible(false);
271                    panelSentry.setVisible(false);
272                } else if (s.equals("Dash-8")) {
273                    panelAcela.setVisible(false);
274                    panelTBrain.setVisible(false);
275                    panelDash8.setVisible(true);
276                    panelWatchman.setVisible(false);
277                    panelSignalman.setVisible(false);
278                    panelSwitchman.setVisible(false);
279                    panelYardMaster.setVisible(false);
280                    panelSentry.setVisible(false);
281                } else if (s.equals("Watchman")) {
282                    panelAcela.setVisible(false);
283                    panelTBrain.setVisible(false);
284                    panelDash8.setVisible(false);
285                    panelWatchman.setVisible(true);
286                    panelSignalman.setVisible(false);
287                    panelSwitchman.setVisible(false);
288                    panelYardMaster.setVisible(false);
289                    panelSentry.setVisible(false);
290                } else if (s.equals("SignalMan")) {
291                    panelAcela.setVisible(false);
292                    panelTBrain.setVisible(false);
293                    panelDash8.setVisible(false);
294                    panelWatchman.setVisible(false);
295                    panelSignalman.setVisible(true);
296                    panelSwitchman.setVisible(false);
297                    panelYardMaster.setVisible(false);
298                    panelSentry.setVisible(false);
299                } else if (s.equals("SwitchMan")) {
300                    panelAcela.setVisible(false);
301                    panelTBrain.setVisible(false);
302                    panelDash8.setVisible(false);
303                    panelWatchman.setVisible(false);
304                    panelSignalman.setVisible(false);
305                    panelSwitchman.setVisible(true);
306                    panelYardMaster.setVisible(false);
307                    panelSentry.setVisible(false);
308                } else if (s.equals("YardMaster")) {
309                    panelAcela.setVisible(false);
310                    panelTBrain.setVisible(false);
311                    panelDash8.setVisible(false);
312                    panelWatchman.setVisible(false);
313                    panelSignalman.setVisible(false);
314                    panelSwitchman.setVisible(false);
315                    panelYardMaster.setVisible(true);
316                    panelSentry.setVisible(false);
317                } else if (s.equals("Sentry")) {
318                    panelAcela.setVisible(false);
319                    panelTBrain.setVisible(false);
320                    panelDash8.setVisible(false);
321                    panelWatchman.setVisible(false);
322                    panelSignalman.setVisible(false);
323                    panelSwitchman.setVisible(false);
324                    panelYardMaster.setVisible(false);
325                    panelSentry.setVisible(true);
326                } // Add code here for other types of nodes
327                else {
328                    panelAcela.setVisible(false);
329                    panelTBrain.setVisible(false);
330                    panelDash8.setVisible(false);
331                    panelWatchman.setVisible(false);
332                    panelSignalman.setVisible(false);
333                    panelSwitchman.setVisible(false);
334                    panelYardMaster.setVisible(false);
335                    panelSentry.setVisible(false);
336                }
337            }
338        });
339        panelNodeInfo.add(nodeTypeBox);
340        nodeTypeBox.setToolTipText(Bundle.getMessage("TipNodeType"));
341        panelNodeInfo.add(nodeTypeStatic);
342        nodeTypeBox.setVisible(false);
343        nodeTypeStatic.setVisible(true);
344        contentPane.add(panelNodeInfo);
345
346        // Set up the Acela nodes
347        panelAcela.setLayout(new BoxLayout(panelAcela, BoxLayout.Y_AXIS));
348        JPanel panelAcela1 = new JPanel();
349        panelAcela1.setLayout(new FlowLayout());
350        statusTextAcela1.setText(stdStatusAcela1);
351        statusTextAcela1.setVisible(true);
352        panelAcela1.add(statusTextAcela1);
353        panelAcela.add(panelAcela1);
354        JPanel panelAcela2 = new JPanel();
355        panelAcela2.setLayout(new FlowLayout());
356        statusTextAcela2.setText(stdStatusAcela2);
357        statusTextAcela2.setVisible(true);
358        panelAcela2.add(statusTextAcela2);
359        panelAcela.add(panelAcela2);
360        JPanel panelAcela3 = new JPanel();
361        panelAcela3.setLayout(new FlowLayout());
362        statusTextAcela3.setText(stdStatusAcela3);
363        statusTextAcela3.setVisible(true);
364        panelAcela3.add(statusTextAcela3);
365        panelAcela.add(panelAcela3);
366        JPanel panelAcela4 = new JPanel();
367        panelAcela4.setLayout(new FlowLayout());
368        statusTextAcela4.setText(stdStatusAcela4);
369        statusTextAcela4.setVisible(true);
370        panelAcela4.add(statusTextAcela4);
371        panelAcela.add(panelAcela4);
372        JPanel panelAcela5 = new JPanel();
373        panelAcela5.setLayout(new FlowLayout());
374        statusTextAcela5.setText(stdStatusAcela5);
375        statusTextAcela5.setVisible(true);
376        panelAcela5.add(statusTextAcela5);
377        panelAcela.add(panelAcela5);
378        JPanel panelAcela6 = new JPanel();
379        panelAcela6.setLayout(new FlowLayout());
380        statusTextAcela6.setText(stdStatusAcela6);
381        statusTextAcela6.setVisible(true);
382        panelAcela6.add(statusTextAcela6);
383        panelAcela.add(panelAcela6);
384        JPanel panelAcela7 = new JPanel();
385        panelAcela7.setLayout(new FlowLayout());
386        statusTextAcela7.setText(stdStatusAcela7);
387        statusTextAcela7.setVisible(true);
388        panelAcela7.add(statusTextAcela7);
389        panelAcela.add(panelAcela7);
390        JPanel panelAcela8 = new JPanel();
391        panelAcela8.setLayout(new FlowLayout());
392        statusTextAcela8.setText(stdStatusAcela8);
393        statusTextAcela8.setVisible(true);
394        panelAcela8.add(statusTextAcela8);
395        panelAcela.add(panelAcela8);
396        JPanel panelAcela9 = new JPanel();
397        panelAcela9.setLayout(new FlowLayout());
398        statusTextAcela9.setText(stdStatusAcela9);
399        statusTextAcela9.setVisible(true);
400        panelAcela9.add(statusTextAcela9);
401        panelAcela.add(panelAcela9);
402        JPanel panelAcela10 = new JPanel();
403        panelAcela10.setLayout(new FlowLayout());
404        statusTextAcela10.setText(stdStatusAcela10);
405        statusTextAcela10.setVisible(true);
406        panelAcela10.add(statusTextAcela10);
407        panelAcela.add(panelAcela10);
408        JPanel panelAcela11 = new JPanel();
409        panelAcela11.setLayout(new FlowLayout());
410        statusTextAcela11.setText(stdStatusAcela11);
411        statusTextAcela11.setVisible(true);
412        panelAcela11.add(statusTextAcela11);
413        panelAcela.add(panelAcela11);
414
415        Border panelAcelaBorder = BorderFactory.createEtchedBorder();
416        Border panelAcelaTitled = BorderFactory.createTitledBorder(panelAcelaBorder,
417                Bundle.getMessage("BoxLabelNodeSpecific"));
418        panelAcela.setBorder(panelAcelaTitled);
419
420        contentPane.add(panelAcela);
421
422        // Set up the Dash8 nodes
423        panelDash8.setLayout(new BoxLayout(panelDash8, BoxLayout.Y_AXIS));
424        JPanel panelDash81 = new JPanel();
425        panelDash81.setLayout(new FlowLayout());
426        statusTextDash81.setText(stdStatusDash81);
427        statusTextDash81.setVisible(true);
428        panelDash81.add(statusTextDash81);
429        panelDash8.add(panelDash81);
430
431        JPanel panelDash82 = new JPanel();
432        panelDash82.setLayout(new FlowLayout());
433        statusTextDash82.setText(stdStatusDash82);
434        statusTextDash82.setVisible(true);
435        panelDash82.add(statusTextDash82);
436        panelDash8.add(panelDash82);
437
438        JPanel panelDash83 = new JPanel();
439        panelDash83.setLayout(new FlowLayout());
440        statusTextDash83.setText(stdStatusDash83);
441        statusTextDash83.setVisible(true);
442        panelDash83.add(statusTextDash83);
443        panelDash8.add(panelDash83);
444
445        // Output circuit configuration
446        d8outputConfigModel = new OutputConfigModel();
447        d8outputConfigModel.setNumRows(8);
448        d8outputConfigModel.setEditMode(false);
449        JTable d8outputConfigTable = new JTable(d8outputConfigModel);
450        d8outputConfigTable.setRowSelectionAllowed(false);
451        d8outputConfigTable.setPreferredScrollableViewportSize(new java.awt.Dimension(180, 125));
452
453        JComboBox<String> d8outputWiredCombo = new JComboBox<String>();
454        d8outputWiredCombo.addItem(Bundle.getMessage("OutputWiredNC"));
455        d8outputWiredCombo.addItem(Bundle.getMessage("OutputWiredNO"));
456
457        JComboBox<String> d8initialStateCombo = new JComboBox<String>();
458        d8initialStateCombo.addItem(Bundle.getMessage("InitialStateOn"));
459        d8initialStateCombo.addItem(Bundle.getMessage("InitialStateOff"));
460
461        JComboBox<String> d8outputTypeCombo = new JComboBox<String>();
462        d8outputTypeCombo.addItem(Bundle.getMessage("OutputTypeONOFF"));
463        d8outputTypeCombo.addItem(Bundle.getMessage("OutputTypePULSE"));
464        d8outputTypeCombo.addItem(Bundle.getMessage("OutputTypeBLINK"));
465
466        JComboBox<String> d8outputLengthCombo = new JComboBox<String>();
467        for (int t = 0; t < 255; t++) {
468            d8outputLengthCombo.addItem(String.valueOf(t));
469        }
470
471        TableColumnModel d8outputColumnModel = d8outputConfigTable.getColumnModel();
472        TableColumn d8outputCircuitAddressColumn = d8outputColumnModel.getColumn(OutputConfigModel.OUTPUTCIRCUITADDRESS_COLUMN);
473        d8outputCircuitAddressColumn.setMinWidth(70);
474        d8outputCircuitAddressColumn.setMaxWidth(80);
475        TableColumn d8outputWiredColumn = d8outputColumnModel.getColumn(OutputConfigModel.OUTPUTWIRED_COLUMN);
476        d8outputWiredColumn.setCellEditor(new DefaultCellEditor(d8outputWiredCombo));
477        d8outputWiredColumn.setResizable(false);
478        d8outputWiredColumn.setMinWidth(90);
479        d8outputWiredColumn.setMaxWidth(100);
480        TableColumn d8initialStateColumn = d8outputColumnModel.getColumn(OutputConfigModel.INITIALSTATE_COLUMN);
481        d8initialStateColumn.setCellEditor(new DefaultCellEditor(d8initialStateCombo));
482        d8initialStateColumn.setResizable(false);
483        d8initialStateColumn.setMinWidth(90);
484        d8initialStateColumn.setMaxWidth(100);
485        TableColumn d8outputTypeColumn = d8outputColumnModel.getColumn(OutputConfigModel.OUTPUTTYPE_COLUMN);
486        d8outputTypeColumn.setCellEditor(new DefaultCellEditor(d8outputTypeCombo));
487        d8outputTypeColumn.setResizable(false);
488        d8outputTypeColumn.setMinWidth(90);
489        d8outputTypeColumn.setMaxWidth(100);
490        TableColumn d8outputLengthColumn = d8outputColumnModel.getColumn(OutputConfigModel.OUTPUTLENGTH_COLUMN);
491        d8outputLengthColumn.setCellEditor(new DefaultCellEditor(d8outputLengthCombo));
492        d8outputLengthColumn.setResizable(false);
493        d8outputLengthColumn.setMinWidth(90);
494        d8outputLengthColumn.setMaxWidth(100);
495        TableColumn d8outputaddressColumn = d8outputColumnModel.getColumn(OutputConfigModel.OUTPUTADDRESS_COLUMN);
496        d8outputaddressColumn.setMinWidth(110);
497        d8outputaddressColumn.setMaxWidth(120);
498
499        // Finish Set up the Dash8 nodes
500        JScrollPane d8outputScrollPane = new JScrollPane(d8outputConfigTable);
501
502        JPanel panelDash8Table = new JPanel();
503        panelDash8Table.setLayout(new BoxLayout(panelDash8Table, BoxLayout.Y_AXIS));
504
505        panelDash8Table.add(d8outputScrollPane, BorderLayout.CENTER);
506        panelDash8.add(panelDash8Table, BoxLayout.Y_AXIS);
507
508        Border panelDash8Border = BorderFactory.createEtchedBorder();
509        Border panelDash8Titled = BorderFactory.createTitledBorder(panelDash8Border,
510                Bundle.getMessage("BoxLabelNodeSpecific"));
511        panelDash8.setBorder(panelDash8Titled);
512
513        panelDash8.setVisible(false);
514        contentPane.add(panelDash8);
515
516        // Set up the TBrain nodes
517        panelTBrain.setLayout(new BoxLayout(panelTBrain, BoxLayout.Y_AXIS));
518        JPanel panelTBrain1 = new JPanel();
519        statusTextTBrain1.setText(stdStatusTBrain1);
520        statusTextTBrain1.setVisible(true);
521        panelTBrain1.add(statusTextTBrain1);
522        panelTBrain.add(panelTBrain1);
523
524        JPanel panelTBrain2 = new JPanel();
525        statusTextTBrain2.setText(stdStatusTBrain2);
526        statusTextTBrain2.setVisible(true);
527        panelTBrain2.add(statusTextTBrain2);
528        panelTBrain.add(panelTBrain2);
529
530        JPanel panelTBrain3 = new JPanel();
531        statusTextTBrain3.setText(stdStatusTBrain3);
532        statusTextTBrain3.setVisible(true);
533        panelTBrain3.add(statusTextTBrain3);
534        panelTBrain.add(panelTBrain3);
535
536        TBoutputConfigModel = new OutputConfigModel();
537        TBoutputConfigModel.setNumRows(4);
538        TBoutputConfigModel.setEditMode(false);
539        JTable TBoutputConfigTable = new JTable(TBoutputConfigModel);
540        TBoutputConfigTable.setRowSelectionAllowed(false);
541        TBoutputConfigTable.setPreferredScrollableViewportSize(new java.awt.Dimension(180, 62));
542
543        JComboBox<String> TBoutputWiredCombo = new JComboBox<String>();
544        TBoutputWiredCombo.addItem(Bundle.getMessage("OutputWiredNC"));
545        TBoutputWiredCombo.addItem(Bundle.getMessage("OutputWiredNO"));
546
547        JComboBox<String> TBoutputTypeCombo = new JComboBox<String>();
548        TBoutputTypeCombo.addItem(Bundle.getMessage("OutputTypeONOFF"));
549        TBoutputTypeCombo.addItem(Bundle.getMessage("OutputTypePULSE"));
550        TBoutputTypeCombo.addItem(Bundle.getMessage("OutputTypeBLINK"));
551
552        JComboBox<String> TBinitialStateCombo = new JComboBox<String>();
553        TBinitialStateCombo.addItem(Bundle.getMessage("InitialStateOn"));
554        TBinitialStateCombo.addItem(Bundle.getMessage("InitialStateOff"));
555
556        JComboBox<String> TBoutputLengthCombo = new JComboBox<String>();
557        for (int t = 0; t < 255; t++) {
558            TBoutputLengthCombo.addItem(String.valueOf(t));
559        }
560
561        TableColumnModel TBoutputColumnModel = TBoutputConfigTable.getColumnModel();
562        TableColumn TBoutputCircuitAddressColumn = TBoutputColumnModel.getColumn(OutputConfigModel.OUTPUTCIRCUITADDRESS_COLUMN);
563        TBoutputCircuitAddressColumn.setMinWidth(70);
564        TBoutputCircuitAddressColumn.setMaxWidth(80);
565        TableColumn TBoutputWiredColumn = TBoutputColumnModel.getColumn(OutputConfigModel.OUTPUTWIRED_COLUMN);
566        TBoutputWiredColumn.setCellEditor(new DefaultCellEditor(TBoutputWiredCombo));
567        TBoutputWiredColumn.setResizable(false);
568        TBoutputWiredColumn.setMinWidth(90);
569        TBoutputWiredColumn.setMaxWidth(100);
570        TableColumn TBinitialStateColumn = TBoutputColumnModel.getColumn(OutputConfigModel.INITIALSTATE_COLUMN);
571        TBinitialStateColumn.setCellEditor(new DefaultCellEditor(TBinitialStateCombo));
572        TBinitialStateColumn.setResizable(false);
573        TBinitialStateColumn.setMinWidth(90);
574        TBinitialStateColumn.setMaxWidth(100);
575        TableColumn TBoutputTypeColumn = TBoutputColumnModel.getColumn(OutputConfigModel.OUTPUTTYPE_COLUMN);
576        TBoutputTypeColumn.setCellEditor(new DefaultCellEditor(TBoutputTypeCombo));
577        TBoutputTypeColumn.setResizable(false);
578        TBoutputTypeColumn.setMinWidth(90);
579        TBoutputTypeColumn.setMaxWidth(100);
580        TableColumn TBoutputLengthColumn = TBoutputColumnModel.getColumn(OutputConfigModel.OUTPUTLENGTH_COLUMN);
581        TBoutputLengthColumn.setCellEditor(new DefaultCellEditor(TBoutputLengthCombo));
582        TBoutputLengthColumn.setResizable(false);
583        TBoutputLengthColumn.setMinWidth(90);
584        TBoutputLengthColumn.setMaxWidth(100);
585        TableColumn TBoutputaddressColumn = TBoutputColumnModel.getColumn(OutputConfigModel.OUTPUTADDRESS_COLUMN);
586        TBoutputaddressColumn.setMinWidth(110);
587        TBoutputaddressColumn.setMaxWidth(120);
588
589        JScrollPane TBoutputScrollPane = new JScrollPane(TBoutputConfigTable);
590
591        JPanel panelTrainBrainTable = new JPanel();
592        panelTrainBrainTable.setLayout(new BoxLayout(panelTrainBrainTable, BoxLayout.Y_AXIS));
593
594        panelTrainBrainTable.add(TBoutputScrollPane, BorderLayout.CENTER);
595        panelTBrain.add(panelTrainBrainTable, BoxLayout.Y_AXIS);
596
597        TBsensorConfigModel = new SensorConfigModel();
598        TBsensorConfigModel.setNumRows(4);
599        TBsensorConfigModel.setEditMode(false);
600
601        JTable TBsensorConfigTable = new JTable(TBsensorConfigModel);
602        TBsensorConfigTable.setRowSelectionAllowed(false);
603        TBsensorConfigTable.setPreferredScrollableViewportSize(new java.awt.Dimension(180, 62));
604
605        JComboBox<String> TBfilterTypeCombo = new JComboBox<String>();
606        TBfilterTypeCombo.addItem(Bundle.getMessage("FilterTypeNoise"));
607        TBfilterTypeCombo.addItem(Bundle.getMessage("FilterTypeDebounce"));
608        TBfilterTypeCombo.addItem(Bundle.getMessage("FilterTypeCarGap"));
609        TBfilterTypeCombo.addItem(Bundle.getMessage("FilterTypeDirtyTrack"));
610
611        JComboBox<String> TBfilterPolarityCombo = new JComboBox<String>();
612        TBfilterPolarityCombo.addItem(Bundle.getMessage("FilterNormalPolarity"));
613        TBfilterPolarityCombo.addItem(Bundle.getMessage("FilterInversePolarity"));
614
615        JComboBox<String> TBfilterThresholdCombo = new JComboBox<String>();
616        for (int t = 0; t < 32; t++) {
617            TBfilterThresholdCombo.addItem(String.valueOf(t));
618        }
619
620        TableColumnModel TBtypeColumnModel = TBsensorConfigTable.getColumnModel();
621        TableColumn TBcircuitAddressColumn = TBtypeColumnModel.getColumn(SensorConfigModel.SENSORCIRCUITADDRESS_COLUMN);
622        TBcircuitAddressColumn.setMinWidth(70);
623        TBcircuitAddressColumn.setMaxWidth(80);
624        TableColumn TBcardTypeColumn = TBtypeColumnModel.getColumn(SensorConfigModel.TYPE_COLUMN);
625        TBcardTypeColumn.setCellEditor(new DefaultCellEditor(TBfilterTypeCombo));
626        TBcardTypeColumn.setResizable(false);
627        TBcardTypeColumn.setMinWidth(90);
628        TBcardTypeColumn.setMaxWidth(100);
629        TableColumn TBcardPolarityColumn = TBtypeColumnModel.getColumn(SensorConfigModel.POLARITY_COLUMN);
630        TBcardPolarityColumn.setCellEditor(new DefaultCellEditor(TBfilterPolarityCombo));
631        TBcardPolarityColumn.setResizable(false);
632        TBcardPolarityColumn.setMinWidth(90);
633        TBcardPolarityColumn.setMaxWidth(100);
634        TableColumn TBcardThresholdColumn = TBtypeColumnModel.getColumn(SensorConfigModel.THRESHOLD_COLUMN);
635        TBcardThresholdColumn.setCellEditor(new DefaultCellEditor(TBfilterThresholdCombo));
636        TBcardThresholdColumn.setResizable(false);
637        TBcardThresholdColumn.setMinWidth(90);
638        TBcardThresholdColumn.setMaxWidth(100);
639        TableColumn TBsensorAddressColumn = TBtypeColumnModel.getColumn(SensorConfigModel.SENSORADDRESS_COLUMN);
640        TBsensorAddressColumn.setMinWidth(110);
641        TBsensorAddressColumn.setMaxWidth(1200);
642
643        JScrollPane TBsensorScrollPane = new JScrollPane(TBsensorConfigTable);
644
645        JPanel panelTBsensortable = new JPanel();
646        panelTBsensortable.setLayout(new BoxLayout(panelTBsensortable, BoxLayout.Y_AXIS));
647
648        panelTBsensortable.add(TBsensorScrollPane, BorderLayout.CENTER);
649        panelTBrain.add(panelTBsensortable, BoxLayout.Y_AXIS);
650
651        // Finish Set up the TrainBrain nodes
652        Border panelTBrainBorder = BorderFactory.createEtchedBorder();
653        Border panelTBrainTitled = BorderFactory.createTitledBorder(panelTBrainBorder,
654                Bundle.getMessage("BoxLabelNodeSpecific"));
655        panelTBrain.setBorder(panelTBrainTitled);
656
657        contentPane.add(panelTBrain);
658        panelTBrain.setVisible(false);
659
660        // Set up the Watchman nodes
661        panelWatchman.setLayout(new BoxLayout(panelWatchman, BoxLayout.Y_AXIS));
662        JPanel panelWatchman1 = new JPanel();
663        panelWatchman1.setLayout(new FlowLayout());
664        statusTextWatchman1.setText(stdStatusWatchman1);
665        statusTextWatchman1.setVisible(true);
666        panelWatchman1.add(statusTextWatchman1);
667        panelWatchman.add(panelWatchman1);
668
669        JPanel panelWatchman2 = new JPanel();
670        panelWatchman2.setLayout(new FlowLayout());
671        statusTextWatchman2.setText(stdStatusWatchman2);
672        statusTextWatchman2.setVisible(true);
673        panelWatchman2.add(statusTextWatchman2);
674        panelWatchman.add(panelWatchman2);
675
676        JPanel panelWatchman3 = new JPanel();
677        panelWatchman3.setLayout(new FlowLayout());
678        statusTextWatchman3.setText(stdStatusWatchman3);
679        statusTextWatchman3.setVisible(true);
680        panelWatchman3.add(statusTextWatchman3);
681        panelWatchman.add(panelWatchman3);
682
683        wmsensorConfigModel = new SensorConfigModel();
684        wmsensorConfigModel.setNumRows(8);
685        wmsensorConfigModel.setEditMode(false);
686
687        JTable wmsensorConfigTable = new JTable(wmsensorConfigModel);
688        wmsensorConfigTable.setRowSelectionAllowed(false);
689        wmsensorConfigTable.setPreferredScrollableViewportSize(new java.awt.Dimension(180, 125));
690
691        JComboBox<String> wmfilterTypeCombo = new JComboBox<String>();
692        wmfilterTypeCombo.addItem(Bundle.getMessage("FilterTypeNoise"));
693        wmfilterTypeCombo.addItem(Bundle.getMessage("FilterTypeDebounce"));
694        wmfilterTypeCombo.addItem(Bundle.getMessage("FilterTypeCarGap"));
695        wmfilterTypeCombo.addItem(Bundle.getMessage("FilterTypeDirtyTrack"));
696
697        JComboBox<String> wmfilterPolarityCombo = new JComboBox<String>();
698        wmfilterPolarityCombo.addItem(Bundle.getMessage("FilterNormalPolarity"));
699        wmfilterPolarityCombo.addItem(Bundle.getMessage("FilterInversePolarity"));
700
701        JComboBox<String> wmfilterThresholdCombo = new JComboBox<String>();
702        for (int t = 0; t < 32; t++) {
703            wmfilterThresholdCombo.addItem(String.valueOf(t));
704        }
705        TableColumnModel wmtypeColumnModel = wmsensorConfigTable.getColumnModel();
706        TableColumn wmcircuitAddressColumn = wmtypeColumnModel.getColumn(SensorConfigModel.SENSORCIRCUITADDRESS_COLUMN);
707        wmcircuitAddressColumn.setMinWidth(70);
708        wmcircuitAddressColumn.setMaxWidth(80);
709        TableColumn wmcardTypeColumn = wmtypeColumnModel.getColumn(SensorConfigModel.TYPE_COLUMN);
710        wmcardTypeColumn.setCellEditor(new DefaultCellEditor(wmfilterTypeCombo));
711        wmcardTypeColumn.setResizable(false);
712        wmcardTypeColumn.setMinWidth(90);
713        wmcardTypeColumn.setMaxWidth(100);
714        TableColumn wmcardPolarityColumn = wmtypeColumnModel.getColumn(SensorConfigModel.POLARITY_COLUMN);
715        wmcardPolarityColumn.setCellEditor(new DefaultCellEditor(wmfilterPolarityCombo));
716        wmcardPolarityColumn.setResizable(false);
717        wmcardPolarityColumn.setMinWidth(90);
718        wmcardPolarityColumn.setMaxWidth(100);
719        TableColumn wmcardThresholdColumn = wmtypeColumnModel.getColumn(SensorConfigModel.THRESHOLD_COLUMN);
720        wmcardThresholdColumn.setCellEditor(new DefaultCellEditor(wmfilterThresholdCombo));
721        wmcardThresholdColumn.setResizable(false);
722        wmcardThresholdColumn.setMinWidth(90);
723        wmcardThresholdColumn.setMaxWidth(100);
724        TableColumn wmsensorAddressColumn = wmtypeColumnModel.getColumn(SensorConfigModel.SENSORADDRESS_COLUMN);
725        wmsensorAddressColumn.setMinWidth(110);
726        wmsensorAddressColumn.setMaxWidth(1200);
727
728        // Finish Set up the Watchman nodes
729        JScrollPane wmsensorScrollPane = new JScrollPane(wmsensorConfigTable);
730
731        JPanel panelWatchmantable = new JPanel();
732        panelWatchmantable.setLayout(new BoxLayout(panelWatchmantable, BoxLayout.Y_AXIS));
733
734        panelWatchmantable.add(wmsensorScrollPane, BorderLayout.CENTER);
735        panelWatchman.add(panelWatchmantable, BoxLayout.Y_AXIS);
736
737        Border panelWatchmanBorder = BorderFactory.createEtchedBorder();
738        Border panelWatchmanTitled = BorderFactory.createTitledBorder(panelWatchmanBorder,
739                Bundle.getMessage("BoxLabelNodeSpecific"));
740        panelWatchman.setBorder(panelWatchmanTitled);
741
742        contentPane.add(panelWatchman);
743        panelWatchman.setVisible(false);
744
745        // Set up the Signalman nodes
746        panelSignalman.setLayout(new BoxLayout(panelSignalman, BoxLayout.Y_AXIS));
747        JPanel panelSignalman1 = new JPanel();
748        panelSignalman1.setLayout(new FlowLayout());
749        statusTextSignalman1.setText(stdStatusSignalman1);
750        statusTextSignalman1.setVisible(true);
751        panelSignalman1.add(statusTextSignalman1);
752        panelSignalman.add(panelSignalman1);
753
754        JPanel panelSignalman2 = new JPanel();
755        panelSignalman2.setLayout(new FlowLayout());
756        statusTextSignalman2.setText(stdStatusSignalman2);
757        statusTextSignalman2.setVisible(true);
758        panelSignalman2.add(statusTextSignalman2);
759        panelSignalman.add(panelSignalman2);
760
761        JPanel panelSignalman3 = new JPanel();
762        panelSignalman3.setLayout(new FlowLayout());
763        statusTextSignalman3.setText(stdStatusSignalman3);
764        statusTextSignalman3.setVisible(true);
765        panelSignalman3.add(statusTextSignalman3);
766        panelSignalman.add(panelSignalman3);
767
768        // Output circuit configuration
769        smoutputConfigModel = new OutputConfigModel();
770        smoutputConfigModel.setNumRows(16);
771        smoutputConfigModel.setEditMode(false);
772        JTable smoutputConfigTable = new JTable(smoutputConfigModel);
773        smoutputConfigTable.setRowSelectionAllowed(false);
774        smoutputConfigTable.setPreferredScrollableViewportSize(new java.awt.Dimension(180, 125));
775
776        JComboBox<String> smoutputWiredCombo = new JComboBox<String>();
777        smoutputWiredCombo.addItem(Bundle.getMessage("OutputWiredNC"));
778        smoutputWiredCombo.addItem(Bundle.getMessage("OutputWiredNO"));
779
780        JComboBox<String> sminitialStateCombo = new JComboBox<String>();
781        sminitialStateCombo.addItem(Bundle.getMessage("InitialStateOn"));
782        sminitialStateCombo.addItem(Bundle.getMessage("InitialStateOff"));
783
784        JComboBox<String> smoutputTypeCombo = new JComboBox<String>();
785        smoutputTypeCombo.addItem(Bundle.getMessage("OutputTypeONOFF"));
786        smoutputTypeCombo.addItem(Bundle.getMessage("OutputTypePULSE"));
787        smoutputTypeCombo.addItem(Bundle.getMessage("OutputTypeBLINK"));
788
789        JComboBox<String> smoutputLengthCombo = new JComboBox<String>();
790        for (int t = 0; t < 255; t++) {
791            smoutputLengthCombo.addItem(String.valueOf(t));
792        }
793
794        TableColumnModel smoutputColumnModel = smoutputConfigTable.getColumnModel();
795        TableColumn smoutputCircuitAddressColumn = smoutputColumnModel.getColumn(OutputConfigModel.OUTPUTCIRCUITADDRESS_COLUMN);
796        smoutputCircuitAddressColumn.setMinWidth(70);
797        smoutputCircuitAddressColumn.setMaxWidth(80);
798        TableColumn smoutputWiredColumn = smoutputColumnModel.getColumn(OutputConfigModel.OUTPUTWIRED_COLUMN);
799        smoutputWiredColumn.setCellEditor(new DefaultCellEditor(smoutputWiredCombo));
800        smoutputWiredColumn.setResizable(false);
801        smoutputWiredColumn.setMinWidth(90);
802        smoutputWiredColumn.setMaxWidth(100);
803        TableColumn sminitialStateColumn = smoutputColumnModel.getColumn(OutputConfigModel.INITIALSTATE_COLUMN);
804        sminitialStateColumn.setCellEditor(new DefaultCellEditor(sminitialStateCombo));
805        sminitialStateColumn.setResizable(false);
806        sminitialStateColumn.setMinWidth(90);
807        sminitialStateColumn.setMaxWidth(100);
808        TableColumn smoutputTypeColumn = smoutputColumnModel.getColumn(OutputConfigModel.OUTPUTTYPE_COLUMN);
809        smoutputTypeColumn.setCellEditor(new DefaultCellEditor(smoutputTypeCombo));
810        smoutputTypeColumn.setResizable(false);
811        smoutputTypeColumn.setMinWidth(90);
812        smoutputTypeColumn.setMaxWidth(100);
813        TableColumn smoutputLengthColumn = smoutputColumnModel.getColumn(OutputConfigModel.OUTPUTLENGTH_COLUMN);
814        smoutputLengthColumn.setCellEditor(new DefaultCellEditor(smoutputLengthCombo));
815        smoutputLengthColumn.setResizable(false);
816        smoutputLengthColumn.setMinWidth(90);
817        smoutputLengthColumn.setMaxWidth(100);
818        TableColumn smoutputaddressColumn = smoutputColumnModel.getColumn(OutputConfigModel.OUTPUTADDRESS_COLUMN);
819        smoutputaddressColumn.setMinWidth(110);
820        smoutputaddressColumn.setMaxWidth(120);
821
822        // Finish Set up the Signalman nodes
823        JScrollPane smoutputScrollPane = new JScrollPane(smoutputConfigTable);
824
825        JPanel panelSignalmanTable = new JPanel();
826        panelSignalmanTable.setLayout(new BoxLayout(panelSignalmanTable, BoxLayout.Y_AXIS));
827
828        panelSignalmanTable.add(smoutputScrollPane, BorderLayout.CENTER);
829        panelSignalman.add(panelSignalmanTable, BoxLayout.Y_AXIS);
830
831        Border panelSignalmanBorder = BorderFactory.createEtchedBorder();
832        Border panelSignalmanTitled = BorderFactory.createTitledBorder(panelSignalmanBorder,
833                Bundle.getMessage("BoxLabelNodeSpecific"));
834        panelSignalman.setBorder(panelSignalmanTitled);
835
836        panelSignalman.setVisible(false);
837        contentPane.add(panelSignalman);
838
839        // Set up the YardMaster nodes
840        panelYardMaster.setLayout(new BoxLayout(panelYardMaster, BoxLayout.Y_AXIS));
841        JPanel panelYardMaster1 = new JPanel();
842        panelYardMaster1.setLayout(new FlowLayout());
843        statusTextYardMaster1.setText(stdStatusYardMaster1);
844        statusTextYardMaster1.setVisible(true);
845        panelYardMaster1.add(statusTextYardMaster1);
846        panelYardMaster.add(panelYardMaster1);
847
848        JPanel panelYardMaster2 = new JPanel();
849        panelYardMaster2.setLayout(new FlowLayout());
850        statusTextYardMaster2.setText(stdStatusYardMaster2);
851        statusTextYardMaster2.setVisible(true);
852        panelYardMaster2.add(statusTextYardMaster2);
853        panelYardMaster.add(panelYardMaster2);
854
855        JPanel panelYardMaster3 = new JPanel();
856        panelYardMaster3.setLayout(new FlowLayout());
857        statusTextYardMaster3.setText(stdStatusYardMaster3);
858        statusTextYardMaster3.setVisible(true);
859        panelYardMaster3.add(statusTextYardMaster3);
860        panelYardMaster.add(panelYardMaster3);
861
862        // Output circuit configuration
863        ymoutputConfigModel = new OutputConfigModel();
864        ymoutputConfigModel.setNumRows(16);
865        ymoutputConfigModel.setEditMode(false);
866        JTable ymoutputConfigTable = new JTable(ymoutputConfigModel);
867        ymoutputConfigTable.setRowSelectionAllowed(false);
868        ymoutputConfigTable.setPreferredScrollableViewportSize(new java.awt.Dimension(180, 125));
869
870        JComboBox<String> ymoutputWiredCombo = new JComboBox<String>();
871        ymoutputWiredCombo.addItem(Bundle.getMessage("OutputWiredNC"));
872        ymoutputWiredCombo.addItem(Bundle.getMessage("OutputWiredNO"));
873
874        JComboBox<String> yminitialStateCombo = new JComboBox<String>();
875        yminitialStateCombo.addItem(Bundle.getMessage("InitialStateOn"));
876        yminitialStateCombo.addItem(Bundle.getMessage("InitialStateOff"));
877
878        JComboBox<String> ymoutputTypeCombo = new JComboBox<String>();
879        ymoutputTypeCombo.addItem(Bundle.getMessage("OutputTypeONOFF"));
880        ymoutputTypeCombo.addItem(Bundle.getMessage("OutputTypePULSE"));
881        ymoutputTypeCombo.addItem(Bundle.getMessage("OutputTypeBLINK"));
882
883        JComboBox<String> ymoutputLengthCombo = new JComboBox<String>();
884        for (int t = 0; t < 255; t++) {
885            ymoutputLengthCombo.addItem(String.valueOf(t));
886        }
887
888        TableColumnModel ymoutputColumnModel = ymoutputConfigTable.getColumnModel();
889        TableColumn ymoutputCircuitAddressColumn = ymoutputColumnModel.getColumn(OutputConfigModel.OUTPUTCIRCUITADDRESS_COLUMN);
890        ymoutputCircuitAddressColumn.setMinWidth(70);
891        ymoutputCircuitAddressColumn.setMaxWidth(80);
892        TableColumn ymoutputWiredColumn = ymoutputColumnModel.getColumn(OutputConfigModel.OUTPUTWIRED_COLUMN);
893        ymoutputWiredColumn.setCellEditor(new DefaultCellEditor(ymoutputWiredCombo));
894        ymoutputWiredColumn.setResizable(false);
895        ymoutputWiredColumn.setMinWidth(90);
896        ymoutputWiredColumn.setMaxWidth(100);
897        TableColumn yminitialStateColumn = ymoutputColumnModel.getColumn(OutputConfigModel.INITIALSTATE_COLUMN);
898        yminitialStateColumn.setCellEditor(new DefaultCellEditor(yminitialStateCombo));
899        yminitialStateColumn.setResizable(false);
900        yminitialStateColumn.setMinWidth(90);
901        yminitialStateColumn.setMaxWidth(100);
902        TableColumn ymoutputTypeColumn = ymoutputColumnModel.getColumn(OutputConfigModel.OUTPUTTYPE_COLUMN);
903        ymoutputTypeColumn.setCellEditor(new DefaultCellEditor(ymoutputTypeCombo));
904        ymoutputTypeColumn.setResizable(false);
905        ymoutputTypeColumn.setMinWidth(90);
906        ymoutputTypeColumn.setMaxWidth(100);
907        TableColumn ymoutputLengthColumn = ymoutputColumnModel.getColumn(OutputConfigModel.OUTPUTLENGTH_COLUMN);
908        ymoutputLengthColumn.setCellEditor(new DefaultCellEditor(ymoutputLengthCombo));
909        ymoutputLengthColumn.setResizable(false);
910        ymoutputLengthColumn.setMinWidth(90);
911        ymoutputLengthColumn.setMaxWidth(100);
912        TableColumn ymoutputaddressColumn = ymoutputColumnModel.getColumn(OutputConfigModel.OUTPUTADDRESS_COLUMN);
913        ymoutputaddressColumn.setMinWidth(110);
914        ymoutputaddressColumn.setMaxWidth(120);
915
916        // Finish Set up the YardMaster nodes
917        JScrollPane ymoutputScrollPane = new JScrollPane(ymoutputConfigTable);
918
919        JPanel panelYardMasterTable = new JPanel();
920        panelYardMasterTable.setLayout(new BoxLayout(panelYardMasterTable, BoxLayout.Y_AXIS));
921
922        panelYardMasterTable.add(ymoutputScrollPane, BorderLayout.CENTER);
923        panelYardMaster.add(panelYardMasterTable, BoxLayout.Y_AXIS);
924
925        Border panelYardMasterBorder = BorderFactory.createEtchedBorder();
926        Border panelYardMasterTitled = BorderFactory.createTitledBorder(panelYardMasterBorder,
927                Bundle.getMessage("BoxLabelNodeSpecific"));
928        panelYardMaster.setBorder(panelYardMasterTitled);
929
930        panelYardMaster.setVisible(false);
931        contentPane.add(panelYardMaster);
932
933        // Set up the SwitchMan nodes
934        panelSwitchman.setLayout(new BoxLayout(panelSwitchman, BoxLayout.Y_AXIS));
935        JPanel panelSwitchman1 = new JPanel();
936        panelSwitchman1.setLayout(new FlowLayout());
937        statusTextSwitchman1.setText(stdStatusSwitchman1);
938        statusTextSwitchman1.setVisible(true);
939        panelSwitchman1.add(statusTextSwitchman1);
940        panelSwitchman.add(panelSwitchman1);
941
942        JPanel panelSwitchman2 = new JPanel();
943        panelSwitchman2.setLayout(new FlowLayout());
944        statusTextSwitchman2.setText(stdStatusSwitchman2);
945        statusTextSwitchman2.setVisible(true);
946        panelSwitchman2.add(statusTextSwitchman2);
947        panelSwitchman.add(panelSwitchman2);
948
949        JPanel panelSwitchman3 = new JPanel();
950        panelSwitchman3.setLayout(new FlowLayout());
951        statusTextSwitchman3.setText(stdStatusSwitchman3);
952        statusTextSwitchman3.setVisible(true);
953        panelSwitchman3.add(statusTextSwitchman3);
954        panelSwitchman.add(panelSwitchman3);
955
956        // Output circuit configuration
957        swoutputConfigModel = new OutputConfigModel();
958        swoutputConfigModel.setNumRows(16);
959        swoutputConfigModel.setEditMode(false);
960        JTable swoutputConfigTable = new JTable(swoutputConfigModel);
961        swoutputConfigTable.setRowSelectionAllowed(false);
962        swoutputConfigTable.setPreferredScrollableViewportSize(new java.awt.Dimension(180, 125));
963
964        JComboBox<String> swoutputWiredCombo = new JComboBox<String>();
965        swoutputWiredCombo.addItem(Bundle.getMessage("OutputWiredNC"));
966        swoutputWiredCombo.addItem(Bundle.getMessage("OutputWiredNO"));
967
968        JComboBox<String> swinitialStateCombo = new JComboBox<String>();
969        swinitialStateCombo.addItem(Bundle.getMessage("InitialStateOn"));
970        swinitialStateCombo.addItem(Bundle.getMessage("InitialStateOff"));
971
972        JComboBox<String> swoutputTypeCombo = new JComboBox<String>();
973        swoutputTypeCombo.addItem(Bundle.getMessage("OutputTypeONOFF"));
974        swoutputTypeCombo.addItem(Bundle.getMessage("OutputTypePULSE"));
975        swoutputTypeCombo.addItem(Bundle.getMessage("OutputTypeBLINK"));
976
977        JComboBox<String> swoutputLengthCombo = new JComboBox<String>();
978        for (int t = 0; t < 255; t++) {
979            swoutputLengthCombo.addItem(String.valueOf(t));
980        }
981
982        TableColumnModel swoutputColumnModel = swoutputConfigTable.getColumnModel();
983        TableColumn swoutputCircuitAddressColumn = swoutputColumnModel.getColumn(OutputConfigModel.OUTPUTCIRCUITADDRESS_COLUMN);
984        swoutputCircuitAddressColumn.setMinWidth(70);
985        swoutputCircuitAddressColumn.setMaxWidth(80);
986        TableColumn swoutputWiredColumn = swoutputColumnModel.getColumn(OutputConfigModel.OUTPUTWIRED_COLUMN);
987        swoutputWiredColumn.setCellEditor(new DefaultCellEditor(swoutputWiredCombo));
988        swoutputWiredColumn.setResizable(false);
989        swoutputWiredColumn.setMinWidth(90);
990        swoutputWiredColumn.setMaxWidth(100);
991        TableColumn swinitialStateColumn = swoutputColumnModel.getColumn(OutputConfigModel.INITIALSTATE_COLUMN);
992        swinitialStateColumn.setCellEditor(new DefaultCellEditor(swinitialStateCombo));
993        swinitialStateColumn.setResizable(false);
994        swinitialStateColumn.setMinWidth(90);
995        swinitialStateColumn.setMaxWidth(100);
996        TableColumn swoutputTypeColumn = swoutputColumnModel.getColumn(OutputConfigModel.OUTPUTTYPE_COLUMN);
997        swoutputTypeColumn.setCellEditor(new DefaultCellEditor(swoutputTypeCombo));
998        swoutputTypeColumn.setResizable(false);
999        swoutputTypeColumn.setMinWidth(90);
1000        swoutputTypeColumn.setMaxWidth(100);
1001        TableColumn swoutputLengthColumn = swoutputColumnModel.getColumn(OutputConfigModel.OUTPUTLENGTH_COLUMN);
1002        swoutputLengthColumn.setCellEditor(new DefaultCellEditor(swoutputLengthCombo));
1003        swoutputLengthColumn.setResizable(false);
1004        swoutputLengthColumn.setMinWidth(90);
1005        swoutputLengthColumn.setMaxWidth(100);
1006        TableColumn swoutputaddressColumn = swoutputColumnModel.getColumn(OutputConfigModel.OUTPUTADDRESS_COLUMN);
1007        swoutputaddressColumn.setMinWidth(110);
1008        swoutputaddressColumn.setMaxWidth(120);
1009
1010        // Finish Set up the Switchman nodes
1011        JScrollPane swoutputScrollPane = new JScrollPane(swoutputConfigTable);
1012
1013        JPanel panelSwitchmanTable = new JPanel();
1014        panelSwitchmanTable.setLayout(new BoxLayout(panelSwitchmanTable, BoxLayout.Y_AXIS));
1015
1016        panelSwitchmanTable.add(swoutputScrollPane, BorderLayout.CENTER);
1017        panelSwitchman.add(panelSwitchmanTable, BoxLayout.Y_AXIS);
1018
1019        Border panelSwitchmanBorder = BorderFactory.createEtchedBorder();
1020        Border panelSwitchmanTitled = BorderFactory.createTitledBorder(panelSwitchmanBorder,
1021                Bundle.getMessage("BoxLabelNodeSpecific"));
1022        panelSwitchman.setBorder(panelSwitchmanTitled);
1023
1024        panelSwitchman.setVisible(false);
1025        contentPane.add(panelSwitchman);
1026
1027        // Set up the Sentry nodes
1028        panelSentry.setLayout(new BoxLayout(panelSentry, BoxLayout.Y_AXIS));
1029        JPanel panelSentry1 = new JPanel();
1030        panelSentry1.setLayout(new FlowLayout());
1031        statusTextSentry1.setText(stdStatusSentry1);
1032        statusTextSentry1.setVisible(true);
1033        panelSentry1.add(statusTextSentry1);
1034        panelSentry.add(panelSentry1);
1035
1036        JPanel panelSentry2 = new JPanel();
1037        panelSentry2.setLayout(new FlowLayout());
1038        statusTextSentry2.setText(stdStatusSentry2);
1039        statusTextSentry2.setVisible(true);
1040        panelSentry2.add(statusTextSentry2);
1041        panelSentry.add(panelSentry2);
1042
1043        JPanel panelSentry3 = new JPanel();
1044        panelSentry3.setLayout(new FlowLayout());
1045        statusTextSentry3.setText(stdStatusSentry3);
1046        statusTextSentry3.setVisible(true);
1047        panelSentry3.add(statusTextSentry3);
1048        panelSentry.add(panelSentry3);
1049
1050        sysensorConfigModel = new SensorConfigModel();
1051        sysensorConfigModel.setNumRows(16);
1052        sysensorConfigModel.setEditMode(false);
1053
1054        JTable sysensorConfigTable = new JTable(sysensorConfigModel);
1055        sysensorConfigTable.setRowSelectionAllowed(false);
1056        sysensorConfigTable.setPreferredScrollableViewportSize(new java.awt.Dimension(180, 125));
1057
1058        JComboBox<String> syfilterTypeCombo = new JComboBox<String>();
1059        syfilterTypeCombo.addItem(Bundle.getMessage("FilterTypeNoise"));
1060        syfilterTypeCombo.addItem(Bundle.getMessage("FilterTypeDebounce"));
1061        syfilterTypeCombo.addItem(Bundle.getMessage("FilterTypeCarGap"));
1062        syfilterTypeCombo.addItem(Bundle.getMessage("FilterTypeDirtyTrack"));
1063
1064        JComboBox<String> syfilterPolarityCombo = new JComboBox<String>();
1065        syfilterPolarityCombo.addItem(Bundle.getMessage("FilterNormalPolarity"));
1066        syfilterPolarityCombo.addItem(Bundle.getMessage("FilterInversePolarity"));
1067
1068        JComboBox<String> syfilterThresholdCombo = new JComboBox<String>();
1069        for (int t = 0; t < 32; t++) {
1070            syfilterThresholdCombo.addItem(String.valueOf(t));
1071        }
1072        TableColumnModel sytypeColumnModel = sysensorConfigTable.getColumnModel();
1073        TableColumn sycircuitAddressColumn = sytypeColumnModel.getColumn(SensorConfigModel.SENSORCIRCUITADDRESS_COLUMN);
1074        sycircuitAddressColumn.setMinWidth(70);
1075        sycircuitAddressColumn.setMaxWidth(80);
1076        TableColumn sycardTypeColumn = sytypeColumnModel.getColumn(SensorConfigModel.TYPE_COLUMN);
1077        sycardTypeColumn.setCellEditor(new DefaultCellEditor(syfilterTypeCombo));
1078        sycardTypeColumn.setResizable(false);
1079        sycardTypeColumn.setMinWidth(90);
1080        sycardTypeColumn.setMaxWidth(100);
1081        TableColumn sycardPolarityColumn = sytypeColumnModel.getColumn(SensorConfigModel.POLARITY_COLUMN);
1082        sycardPolarityColumn.setCellEditor(new DefaultCellEditor(syfilterPolarityCombo));
1083        sycardPolarityColumn.setResizable(false);
1084        sycardPolarityColumn.setMinWidth(90);
1085        sycardPolarityColumn.setMaxWidth(100);
1086        TableColumn sycardThresholdColumn = sytypeColumnModel.getColumn(SensorConfigModel.THRESHOLD_COLUMN);
1087        sycardThresholdColumn.setCellEditor(new DefaultCellEditor(syfilterThresholdCombo));
1088        sycardThresholdColumn.setResizable(false);
1089        sycardThresholdColumn.setMinWidth(90);
1090        sycardThresholdColumn.setMaxWidth(100);
1091        TableColumn sysensorAddressColumn = sytypeColumnModel.getColumn(SensorConfigModel.SENSORADDRESS_COLUMN);
1092        sysensorAddressColumn.setMinWidth(110);
1093        sysensorAddressColumn.setMaxWidth(1200);
1094
1095        // Finish Set up the Sentry nodes
1096        JScrollPane sysensorScrollPane = new JScrollPane(sysensorConfigTable);
1097
1098        JPanel panelSentrytable = new JPanel();
1099        panelSentrytable.setLayout(new BoxLayout(panelSentrytable, BoxLayout.Y_AXIS));
1100
1101        panelSentrytable.add(sysensorScrollPane, BorderLayout.CENTER);
1102        panelSentry.add(panelSentrytable, BoxLayout.Y_AXIS);
1103
1104        Border panelSentryBorder = BorderFactory.createEtchedBorder();
1105        Border panelSentryTitled = BorderFactory.createTitledBorder(panelSentryBorder,
1106                Bundle.getMessage("BoxLabelNodeSpecific"));
1107        panelSentry.setBorder(panelSentryTitled);
1108
1109        contentPane.add(panelSentry);
1110        panelSentry.setVisible(false);
1111
1112        // Set up the notes panel
1113        JPanel panel3 = new JPanel();
1114        panel3.setLayout(new BoxLayout(panel3, BoxLayout.Y_AXIS));
1115        JPanel panel31 = new JPanel();
1116        panel31.setLayout(new FlowLayout());
1117        statusText1.setText(stdStatus1);
1118        statusText1.setVisible(true);
1119        panel31.add(statusText1);
1120        JPanel panel32 = new JPanel();
1121        panel32.setLayout(new FlowLayout());
1122        statusText2.setText(stdStatus2);
1123        statusText2.setVisible(true);
1124        panel32.add(statusText2);
1125        JPanel panel33 = new JPanel();
1126        panel33.setLayout(new FlowLayout());
1127        statusText3.setText(stdStatus3);
1128        statusText3.setVisible(true);
1129        panel33.add(statusText3);
1130        panel3.add(panel31);
1131        panel3.add(panel32);
1132        panel3.add(panel33);
1133        Border panel3Border = BorderFactory.createEtchedBorder();
1134        Border panel3Titled = BorderFactory.createTitledBorder(panel3Border,
1135                Bundle.getMessage("BoxLabelNotes"));
1136        panel3.setBorder(panel3Titled);
1137        contentPane.add(panel3);
1138
1139        // Set up buttons
1140        JPanel panel4 = new JPanel();
1141        panel4.setLayout(new FlowLayout());
1142        addButton.setText(Bundle.getMessage("ButtonAdd"));
1143        addButton.setVisible(true);
1144        addButton.setToolTipText(Bundle.getMessage("TipAddButton"));
1145        addButton.addActionListener(new ActionListener() {
1146            @Override
1147            public void actionPerformed(ActionEvent e) {
1148                addButtonActionPerformed();
1149            }
1150        });
1151        panel4.add(addButton);
1152        editButton.setText(Bundle.getMessage("ButtonEdit"));
1153        editButton.setVisible(true);
1154        editButton.setToolTipText(Bundle.getMessage("TipEditButton"));
1155        panel4.add(editButton);
1156        editButton.addActionListener(new ActionListener() {
1157            @Override
1158            public void actionPerformed(ActionEvent e) {
1159                editButtonActionPerformed();
1160            }
1161        });
1162        panel4.add(deleteButton);
1163        deleteButton.setText(Bundle.getMessage("ButtonDelete"));
1164        deleteButton.setVisible(true);
1165        deleteButton.setToolTipText(Bundle.getMessage("TipDeleteButton"));
1166        panel4.add(deleteButton);
1167        deleteButton.addActionListener(new ActionListener() {
1168            @Override
1169            public void actionPerformed(ActionEvent e) {
1170                deleteButtonActionPerformed();
1171            }
1172        });
1173        panel4.add(doneButton);
1174        doneButton.setText(Bundle.getMessage("ButtonDone"));
1175        doneButton.setVisible(true);
1176        doneButton.setToolTipText(Bundle.getMessage("TipDoneButton"));
1177        panel4.add(doneButton);
1178        doneButton.addActionListener(new ActionListener() {
1179            @Override
1180            public void actionPerformed(ActionEvent e) {
1181                doneButtonActionPerformed();
1182            }
1183        });
1184        panel4.add(updateButton);
1185        updateButton.setText(Bundle.getMessage("ButtonUpdate"));
1186        updateButton.setVisible(true);
1187        updateButton.setToolTipText(Bundle.getMessage("TipUpdateButton"));
1188        panel4.add(updateButton);
1189        updateButton.addActionListener(new ActionListener() {
1190            @Override
1191            public void actionPerformed(ActionEvent e) {
1192                updateButtonActionPerformed();
1193            }
1194        });
1195        updateButton.setVisible(false);
1196        panel4.add(cancelButton);
1197        cancelButton.setText(Bundle.getMessage("ButtonCancel"));
1198        cancelButton.setVisible(true);
1199        cancelButton.setToolTipText(Bundle.getMessage("TipCancelButton"));
1200        panel4.add(cancelButton);
1201        cancelButton.addActionListener(new ActionListener() {
1202            @Override
1203            public void actionPerformed(ActionEvent e) {
1204                cancelButtonActionPerformed();
1205            }
1206        });
1207        cancelButton.setVisible(false);
1208
1209        contentPane.add(panel4);
1210
1211        // add help menu to window
1212        addHelpMenu("package.jmri.jmrix.acela.nodeconfig.NodeConfigFrame", true);
1213
1214        // pack for display
1215        pack();
1216    }
1217
1218    /**
1219     * Method to handle add button
1220     */
1221    public void addButtonActionPerformed() {
1222        JmriJOptionPane.showMessageDialog(this,
1223                Bundle.getMessage("NotSupported1") + "\n" + Bundle.getMessage("NotSupported2"),
1224                Bundle.getMessage("NotSupportedTitle"),
1225                JmriJOptionPane.INFORMATION_MESSAGE);
1226        resetNotes();
1227    }
1228
1229    /**
1230     * Method to handle info state
1231     */
1232    public void infoButtonActionPerformed() {
1233
1234        // lookup the nodes
1235        StringBuilder nodesstring = new StringBuilder("");
1236        int tempnumnodes = _memo.getTrafficController().getNumNodes();
1237        for (int i = 0; i < tempnumnodes; i++) {
1238            AcelaNode tempnode;
1239            tempnode = (AcelaNode) _memo.getTrafficController().getNodeFromAddress(i);
1240            nodesstring.append(" ").append(tempnode.getNodeTypeString());
1241        }
1242        thenodesStaticC.setText(nodesstring.toString());
1243
1244        // Find Acela Node address
1245        nodeAddress = readNodeAddress();
1246        if (nodeAddress < 0) {
1247            return;
1248        }
1249        // get the AcelaNode corresponding to this node address
1250        curNode = (AcelaNode) _memo.getTrafficController().getNodeFromAddress(nodeAddress);
1251        if (curNode == null) {
1252            statusText1.setText(Bundle.getMessage("Error4"));
1253            statusText1.setVisible(true);
1254            errorInStatus1 = true;
1255            resetNotes2();
1256            return;
1257        }
1258        // Set up static node address
1259        nodeAddrStatic.setText(Integer.toString(nodeAddress));
1260        nodeAddrBox.setVisible(true);
1261        nodeAddrField.setVisible(false);
1262        nodeAddrStatic.setVisible(false);
1263        // get information for this node and set up combo box
1264        nodeType = curNode.getNodeType();
1265        nodeTypeBox.setSelectedIndex(nodeType);
1266        nodeTypeBox.setVisible(false);
1267        nodeTypeStatic.setText(AcelaNode.getModuleNames()[nodeType]);
1268        nodeTypeStatic.setVisible(true);
1269
1270        // get information for this node if it is an output node
1271        int numoutputbits = curNode.getNumOutputBitsPerCard();
1272        if (numoutputbits > 0) {
1273            // set up output types
1274            for (int o = 0; o < numoutputbits; o++) {
1275                if (curNode.getOutputInit(o) == 0) {
1276                    initialState[o] = Bundle.getMessage("InitialStateOff");
1277                } else { // if (curNode.getOutputInit(o) == 1) {
1278                    initialState[o] = Bundle.getMessage("InitialStateOn");
1279                }
1280                if (curNode.getOutputWired(o) == 0) {
1281                    outputWired[o] = Bundle.getMessage("OutputWiredNO");
1282                } else { // if (curNode.getOutputWired(o) == 1) {
1283                    outputWired[o] = Bundle.getMessage("OutputWiredNC");
1284                }
1285
1286                if (curNode.getOutputType(o) == 0) {
1287                    outputType[o] = Bundle.getMessage("OutputTypeONOFF");
1288                } else {
1289                    if (curNode.getOutputType(o) == 1) {
1290                        outputType[o] = Bundle.getMessage("OutputTypePULSE");
1291                    } else { // if (curNode.getOutputType(o) == 2) {
1292                        outputType[o] = Bundle.getMessage("OutputTypeBLINK");
1293                    }
1294                }
1295
1296                outputLength[o] = String.valueOf(curNode.getOutputLength(o));
1297            }
1298        }
1299
1300        // get information for this node if it is a sensor node
1301        int numsensorbits = curNode.getNumSensorBitsPerCard();
1302        if (numsensorbits > 0) {
1303            // set up sensor types
1304            for (int i = 0; i < numsensorbits; i++) {
1305                if (curNode.getSensorType(i) == 0) {
1306                    filterType[i] = Bundle.getMessage("FilterTypeNoise");
1307                } else if (curNode.getSensorType(i) == 1) {
1308                    filterType[i] = Bundle.getMessage("FilterTypeDebounce");
1309                } else if (curNode.getSensorType(i) == 2) {
1310                    filterType[i] = Bundle.getMessage("FilterTypeCarGap");
1311                } else {
1312                    filterType[i] = Bundle.getMessage("FilterTypeDirtyTrack");
1313                }
1314
1315                if (curNode.getSensorPolarity(i) == 0) {
1316                    filterPolarity[i] = Bundle.getMessage("FilterNormalPolarity");
1317                } else {
1318                    filterPolarity[i] = Bundle.getMessage("FilterInversePolarity");
1319                }
1320
1321                filterThreshold[i] = String.valueOf(curNode.getSensorThreshold(i));
1322            }
1323        }
1324
1325        // Switch buttons
1326        editMode = false;
1327        addButton.setVisible(true);
1328        editButton.setVisible(true);
1329        deleteButton.setVisible(true);
1330        doneButton.setVisible(true);
1331        updateButton.setVisible(false);
1332        cancelButton.setVisible(false);
1333        // Switch to edit notes
1334        statusText1.setText(infoStatus1);
1335        statusText2.setText(infoStatus2);
1336        statusText3.setText(infoStatus3);
1337
1338        d8outputConfigModel.setEditMode(false);
1339        swoutputConfigModel.setEditMode(false);
1340        ymoutputConfigModel.setEditMode(false);
1341        TBoutputConfigModel.setEditMode(false);
1342        TBsensorConfigModel.setEditMode(false);
1343        smoutputConfigModel.setEditMode(false);
1344        wmsensorConfigModel.setEditMode(false);
1345        sysensorConfigModel.setEditMode(false);
1346        contentPane.repaint();
1347    }
1348
1349    /**
1350     * Method to handle edit button
1351     */
1352    public void editButtonActionPerformed() {
1353        // Find Acela Node address
1354        nodeAddress = readNodeAddress();
1355        if (nodeAddress < 0) {
1356            return;
1357        }
1358        // get the AcelaNode corresponding to this node address
1359        curNode = (AcelaNode) _memo.getTrafficController().getNodeFromAddress(nodeAddress);
1360        if (curNode == null) {
1361            statusText1.setText(Bundle.getMessage("Error4"));
1362            statusText1.setVisible(true);
1363            errorInStatus1 = true;
1364            resetNotes2();
1365            return;
1366        }
1367        // Set up static node address
1368        nodeAddrStatic.setText(Integer.toString(nodeAddress));
1369        nodeAddrBox.setVisible(false);
1370        nodeAddrField.setVisible(false);
1371        nodeAddrStatic.setVisible(true);
1372        // get information for this node and set up combo box
1373        nodeType = curNode.getNodeType();
1374        nodeTypeBox.setSelectedIndex(nodeType);
1375        nodeTypeBox.setVisible(true);
1376        nodeTypeStatic.setText(AcelaNode.getModuleNames()[nodeType]);
1377        nodeTypeStatic.setVisible(false);
1378
1379        // get information for this node if it is an output node
1380        int numoutputbits = curNode.getNumOutputBitsPerCard();
1381        if (numoutputbits > 0) {
1382            // set up output types
1383            for (int o = 0; o < numoutputbits; o++) {
1384                if (curNode.getOutputInit(o) == 0) {
1385                    initialState[o] = Bundle.getMessage("InitialStateOff");
1386                } else { // if (curNode.getOutputInit(o) == 1) {
1387                    initialState[o] = Bundle.getMessage("InitialStateOn");
1388                }
1389                if (curNode.getOutputWired(o) == 0) {
1390                    outputWired[o] = Bundle.getMessage("OutputWiredNO");
1391                } else { // if (curNode.getOutputWired(o) == 1) {
1392                    outputWired[o] = Bundle.getMessage("OutputWiredNC");
1393                }
1394
1395                if (curNode.getOutputType(o) == 0) {
1396                    outputType[o] = Bundle.getMessage("OutputTypeONOFF");
1397                } else {
1398                    if (curNode.getOutputType(o) == 1) {
1399                        outputType[o] = Bundle.getMessage("OutputTypePULSE");
1400                    } else { // if (curNode.getOutputType(o) == 2) {
1401                        outputType[o] = Bundle.getMessage("OutputTypeBLINK");
1402                    }
1403                }
1404
1405                outputLength[o] = String.valueOf(curNode.getOutputLength(o));
1406            }
1407        }
1408
1409        // get information for this node if it is a sensor node
1410        int numsensorbits = curNode.getNumSensorBitsPerCard();
1411        if (numsensorbits > 0) {
1412            // set up sensor types
1413            for (int i = 0; i < numsensorbits; i++) {
1414                if (curNode.getSensorType(i) == 0) {
1415                    filterType[i] = Bundle.getMessage("FilterTypeNoise");
1416                } else if (curNode.getSensorType(i) == 1) {
1417                    filterType[i] = Bundle.getMessage("FilterTypeDebounce");
1418                } else if (curNode.getSensorType(i) == 2) {
1419                    filterType[i] = Bundle.getMessage("FilterTypeCarGap");
1420                } else {
1421                    filterType[i] = Bundle.getMessage("FilterTypeDirtyTrack");
1422                }
1423
1424                if (curNode.getSensorPolarity(i) == 0) {
1425                    filterPolarity[i] = Bundle.getMessage("FilterNormalPolarity");
1426                } else {
1427                    filterPolarity[i] = Bundle.getMessage("FilterInversePolarity");
1428                }
1429
1430                filterThreshold[i] = String.valueOf(curNode.getSensorThreshold(i));
1431            }
1432        }
1433
1434        // Switch buttons
1435        editMode = true;
1436        addButton.setVisible(false);
1437        editButton.setVisible(false);
1438        deleteButton.setVisible(false);
1439        doneButton.setVisible(false);
1440        updateButton.setVisible(true);
1441        cancelButton.setVisible(true);
1442        // Switch to edit notes
1443        statusText1.setText(editStatus1);
1444        statusText2.setText(editStatus2);
1445        statusText3.setText(editStatus3);
1446
1447        d8outputConfigModel.setEditMode(true);
1448        swoutputConfigModel.setEditMode(true);
1449        ymoutputConfigModel.setEditMode(true);
1450        TBoutputConfigModel.setEditMode(true);
1451        TBsensorConfigModel.setEditMode(true);
1452        smoutputConfigModel.setEditMode(true);
1453        wmsensorConfigModel.setEditMode(true);
1454        sysensorConfigModel.setEditMode(true);
1455        contentPane.repaint();
1456
1457    }
1458
1459    /**
1460     * Method to handle delete button
1461     */
1462    public void deleteButtonActionPerformed() {
1463
1464        JmriJOptionPane.showMessageDialog(this,
1465                Bundle.getMessage("NotSupported1") + "\n" + Bundle.getMessage("NotSupported2"),
1466                Bundle.getMessage("NotSupportedTitle"),
1467                JmriJOptionPane.INFORMATION_MESSAGE);
1468        resetNotes();
1469    }
1470
1471    /**
1472     * Method to handle done button
1473     */
1474    public void doneButtonActionPerformed() {
1475        if (editMode) {
1476            // Reset
1477            editMode = false;
1478            curNode = null;
1479            // Switch buttons
1480            addButton.setVisible(true);
1481            editButton.setVisible(true);
1482            deleteButton.setVisible(true);
1483            doneButton.setVisible(true);
1484            updateButton.setVisible(false);
1485            cancelButton.setVisible(false);
1486            nodeAddrBox.setVisible(true);
1487//            nodeAddrField.setVisible(true);
1488            nodeAddrStatic.setVisible(false);
1489            nodeTypeStatic.setVisible(true);
1490            nodeTypeBox.setVisible(false);
1491        }
1492        if (changedNode && !checkEnabled) {
1493            // Remind user to Save new configuration
1494            JmriJOptionPane.showMessageDialog(this,
1495                    Bundle.getMessage("ReminderNode1") + "\n" + Bundle.getMessage("Reminder2"),
1496                    Bundle.getMessage("ReminderTitle"),
1497                    JmriJOptionPane.INFORMATION_MESSAGE);
1498        }
1499        setVisible(false);
1500        dispose();
1501    }
1502
1503    /**
1504     * Method to handle update button
1505     */
1506    public void updateButtonActionPerformed() {
1507        // update node information
1508        nodeType = nodeTypeBox.getSelectedIndex();
1509        log.debug("update performed: was {} request {}", curNode.getNodeType(), nodeType);
1510        if (curNode.getNodeType() != nodeType) {
1511            // node type has changed
1512            curNode.setNodeType(nodeType);
1513        }
1514        setNodeParameters();
1515        changedNode = true;
1516        // Reset Edit Mode
1517        editMode = false;
1518        curNode = null;
1519        // Switch buttons
1520        addButton.setVisible(true);
1521        editButton.setVisible(true);
1522        deleteButton.setVisible(true);
1523        doneButton.setVisible(true);
1524        updateButton.setVisible(false);
1525        cancelButton.setVisible(false);
1526        // make node address editable again
1527        nodeAddrBox.setVisible(true);
1528//        nodeAddrField.setVisible(true);
1529        nodeAddrStatic.setVisible(false);
1530        nodeTypeBox.setVisible(false);
1531        nodeTypeStatic.setVisible(true);
1532        // refresh notes panel
1533        statusText2.setText(stdStatus2);
1534        statusText3.setText(stdStatus3);
1535        // provide user feedback
1536        statusText1.setText(Bundle.getMessage("FeedBackUpdate") + " "
1537                + Integer.toString(nodeAddress));
1538        errorInStatus1 = true;
1539
1540        d8outputConfigModel.setEditMode(false);
1541        swoutputConfigModel.setEditMode(false);
1542        ymoutputConfigModel.setEditMode(false);
1543        TBoutputConfigModel.setEditMode(false);
1544        TBsensorConfigModel.setEditMode(false);
1545        smoutputConfigModel.setEditMode(false);
1546        wmsensorConfigModel.setEditMode(false);
1547        sysensorConfigModel.setEditMode(false);
1548
1549        contentPane.repaint();
1550
1551    }
1552
1553    /**
1554     * Method to handle cancel button
1555     */
1556    public void cancelButtonActionPerformed() {
1557        // Reset
1558        editMode = false;
1559        curNode = null;
1560
1561        // lookup the nodes
1562        StringBuilder nodesstring = new StringBuilder("");
1563        int tempnumnodes = _memo.getTrafficController().getNumNodes();
1564        for (int i = 0; i < tempnumnodes; i++) {
1565            AcelaNode tempnode;
1566            tempnode = (AcelaNode) _memo.getTrafficController().getNodeFromAddress(i);
1567            nodesstring.append(" ").append(tempnode.getNodeTypeString());
1568        }
1569        thenodesStaticC.setText(nodesstring.toString());
1570
1571        // Find Acela Node address
1572        nodeAddress = readNodeAddress();
1573        if (nodeAddress < 0) {
1574            return;
1575        }
1576        // get the AcelaNode corresponding to this node address
1577        curNode = (AcelaNode) _memo.getTrafficController().getNodeFromAddress(nodeAddress);
1578        if (curNode == null) {
1579            statusText1.setText(Bundle.getMessage("Error4"));
1580            statusText1.setVisible(true);
1581            errorInStatus1 = true;
1582            resetNotes2();
1583            return;
1584        }
1585        // Set up static node address
1586        nodeAddrStatic.setText(Integer.toString(nodeAddress));
1587        nodeAddrBox.setVisible(true);
1588        nodeAddrField.setVisible(false);
1589        nodeAddrStatic.setVisible(false);
1590        // get information for this node and set up combo box
1591        nodeType = curNode.getNodeType();
1592        nodeTypeBox.setSelectedIndex(nodeType);
1593        nodeTypeBox.setVisible(false);
1594        nodeTypeStatic.setText(AcelaNode.getModuleNames()[nodeType]);
1595        nodeTypeStatic.setVisible(true);
1596
1597        // get information for this node if it is an output node
1598        int numoutputbits = curNode.getNumOutputBitsPerCard();
1599        if (numoutputbits > 0) {
1600            // set up output types
1601            for (int o = 0; o < numoutputbits; o++) {
1602                if (curNode.getOutputInit(o) == 0) {
1603                    initialState[o] = Bundle.getMessage("InitialStateOff");
1604                } else { // if (curNode.getOutputInit(o) == 1) {
1605                    initialState[o] = Bundle.getMessage("InitialStateOn");
1606                }
1607                if (curNode.getOutputWired(o) == 0) {
1608                    outputWired[o] = Bundle.getMessage("OutputWiredNO");
1609                } else { // if (curNode.getOutputWired(o) == 1) {
1610                    outputWired[o] = Bundle.getMessage("OutputWiredNC");
1611                }
1612
1613                if (curNode.getOutputType(o) == 0) {
1614                    outputType[o] = Bundle.getMessage("OutputTypeONOFF");
1615                } else {
1616                    if (curNode.getOutputType(o) == 1) {
1617                        outputType[o] = Bundle.getMessage("OutputTypePULSE");
1618                    } else { // if (curNode.getOutputType(o) == 2) {
1619                        outputType[o] = Bundle.getMessage("OutputTypeBLINK");
1620                    }
1621                }
1622
1623                outputLength[o] = String.valueOf(curNode.getOutputLength(o));
1624            }
1625        }
1626
1627        // get information for this node if it is a sensor node
1628        int numsensorbits = curNode.getNumSensorBitsPerCard();
1629        if (numsensorbits > 0) {
1630            // set up sensor types
1631            for (int i = 0; i < numsensorbits; i++) {
1632                if (curNode.getSensorType(i) == 0) {
1633                    filterType[i] = Bundle.getMessage("FilterTypeNoise");
1634                } else if (curNode.getSensorType(i) == 1) {
1635                    filterType[i] = Bundle.getMessage("FilterTypeDebounce");
1636                } else if (curNode.getSensorType(i) == 2) {
1637                    filterType[i] = Bundle.getMessage("FilterTypeCarGap");
1638                } else {
1639                    filterType[i] = Bundle.getMessage("FilterTypeDirtyTrack");
1640                }
1641
1642                if (curNode.getSensorPolarity(i) == 0) {
1643                    filterPolarity[i] = Bundle.getMessage("FilterNormalPolarity");
1644                } else {
1645                    filterPolarity[i] = Bundle.getMessage("FilterInversePolarity");
1646                }
1647
1648                filterThreshold[i] = String.valueOf(curNode.getSensorThreshold(i));
1649            }
1650        }
1651
1652        // Switch buttons
1653        editMode = false;
1654        addButton.setVisible(true);
1655        editButton.setVisible(true);
1656        deleteButton.setVisible(true);
1657        doneButton.setVisible(true);
1658        updateButton.setVisible(false);
1659        cancelButton.setVisible(false);
1660        // Switch to edit notes
1661        statusText1.setText(infoStatus1);
1662        statusText2.setText(infoStatus2);
1663        statusText3.setText(infoStatus3);
1664
1665        d8outputConfigModel.setEditMode(false);
1666        swoutputConfigModel.setEditMode(false);
1667        ymoutputConfigModel.setEditMode(false);
1668        TBoutputConfigModel.setEditMode(false);
1669        TBsensorConfigModel.setEditMode(false);
1670        smoutputConfigModel.setEditMode(false);
1671        wmsensorConfigModel.setEditMode(false);
1672        sysensorConfigModel.setEditMode(false);
1673
1674        contentPane.repaint();
1675    }
1676
1677    /**
1678     * Do the done action if the window is closed early.
1679     */
1680    @Override
1681    public void windowClosing(java.awt.event.WindowEvent e) {
1682        doneButtonActionPerformed();
1683    }
1684
1685    /**
1686     * Method to set node parameters The node must exist, and be in 'curNode'
1687     * Also, the node type must be set and in 'nodeType'
1688     */
1689    void setNodeParameters() {
1690        // set curNode type
1691        curNode.setNodeType(nodeType);
1692
1693        // get information for this node if it is an output node
1694        int numoutputbits = curNode.getNumOutputBitsPerCard();
1695        if (numoutputbits > 0) {
1696            // set up output types
1697            for (int o = 0; o < numoutputbits; o++) {
1698                if (initialState[o].contentEquals(Bundle.getMessage("InitialStateOff"))) {
1699                    curNode.setOutputInit(o, 0);
1700                } else { // if (initialState[o].contentEquals(Bundle.getMessage("InitialStateOn"))) {
1701                    curNode.setOutputInit(o, 1);
1702                }
1703
1704                if (outputWired[o].contentEquals(Bundle.getMessage("OutputWiredNO"))) {
1705                    curNode.setOutputWired(o, 0);
1706                } else { // if (outputWired[o].contentEquals(Bundle.getMessage("OutputWiredNC"))) {
1707                    curNode.setOutputWired(o, 1);
1708                }
1709
1710                if (outputType[o].contentEquals(Bundle.getMessage("OutputTypeONOFF"))) {
1711                    curNode.setOutputType(o, 0);
1712                } else {
1713                    if (outputType[o].contentEquals(Bundle.getMessage("OutputTypePULSE"))) {
1714                        curNode.setOutputType(o, 1);
1715                    } else { // if (outputType[o].contentEquals(Bundle.getMessage("OutputTypeBLINK"))) {
1716                        curNode.setOutputType(o, 2);
1717                    }
1718                }
1719
1720                curNode.setOutputLength(o, Integer.parseInt(outputLength[o]));
1721            }
1722        }
1723
1724        // get information for this node if it is a sensor node
1725        int numsensorbits = curNode.getNumSensorBitsPerCard();
1726        if (numsensorbits > 0) {
1727
1728            // set up sensor types
1729            for (int i = 0; i < numsensorbits; i++) {
1730                if (filterType[i].contentEquals(Bundle.getMessage("FilterTypeNoise"))) {
1731                    curNode.setSensorType(i, 0);
1732                } else if (filterType[i].contentEquals(Bundle.getMessage("FilterTypeDebounce"))) {
1733                    curNode.setSensorType(i, 1);
1734                } else if (filterType[i].contentEquals(Bundle.getMessage("FilterTypeCarGap"))) {
1735                    curNode.setSensorType(i, 2);
1736                } else { // filterType[i].contentEquals(Bundle.getMessage("FilterTypeDirtyTrack"))
1737                    curNode.setSensorType(i, 3);
1738                }
1739
1740                if (filterPolarity[i].contentEquals(Bundle.getMessage("FilterNormalPolarity"))) {
1741                    curNode.setSensorPolarity(i, 0);
1742                } else { // filterPolarity[i].contentEquals(Bundle.getMessage("FilterInversePolarity"))
1743                    curNode.setSensorPolarity(i, 1);
1744                }
1745
1746                curNode.setSensorThreshold(i, Integer.parseInt(filterThreshold[i]));
1747            }
1748        }
1749
1750        // Cause reinitialization of this Node to reflect these parameters
1751        _memo.getTrafficController().initializeAcelaNode(curNode);
1752    }
1753
1754    /**
1755     * Method to reset the notes error after error display
1756     */
1757    private void resetNotes() {
1758        if (errorInStatus1) {
1759            if (editMode) {
1760                statusText1.setText(editStatus1);
1761            } else {
1762                statusText1.setText(stdStatus1);
1763            }
1764            errorInStatus1 = false;
1765        }
1766        resetNotes2();
1767    }
1768
1769    /**
1770     * Reset the second line of Notes area
1771     */
1772    private void resetNotes2() {
1773        if (errorInStatus2) {
1774            if (editMode) {
1775                statusText1.setText(editStatus2);
1776            } else {
1777                statusText2.setText(stdStatus2);
1778            }
1779            errorInStatus2 = false;
1780        }
1781    }
1782
1783    /**
1784     * Read node address and check for legal range If successful, a node address
1785     * in the range 0-255 is returned. If not successful, -1 is returned and an
1786     * appropriate error message is placed in statusText1.
1787     */
1788    private int readNodeAddress() {
1789        int addr = -1;
1790        try {
1791            addr = nodeAddrBox.getSelectedIndex();
1792//            addr = Integer.parseInt(nodeAddrField.getText());
1793        } catch (Exception e) {
1794            statusText1.setText(Bundle.getMessage("Error5"));
1795            statusText1.setVisible(true);
1796            errorInStatus1 = true;
1797            resetNotes2();
1798            return -1;
1799        }
1800        if ((addr < 0) || (addr > 255)) {
1801            statusText1.setText(Bundle.getMessage("Error6"));
1802            statusText1.setVisible(true);
1803            errorInStatus1 = true;
1804            resetNotes2();
1805            return -1;
1806        }
1807        return (addr);
1808    }
1809
1810    /**
1811     * Set up table for selecting sensor default parameters for Sentry or TBrain
1812     * nodes
1813     */
1814//    public class SensorConfigModel extends AbstractTableModel
1815    public class SensorConfigModel extends NodeConfigModel {
1816
1817        @Override
1818        public String getColumnName(int c) {
1819            return sensorConfigColumnNames[c];
1820        }
1821
1822        @Override
1823        public Class<?> getColumnClass(int c) {
1824            return String.class;
1825        }
1826
1827        @Override
1828        public int getColumnCount() {
1829            return 5;
1830        }
1831
1832        @Override
1833        public int getRowCount() {
1834            return numrows;
1835        }
1836
1837        @Override
1838        public void setNumRows(int r) {
1839            numrows = r;
1840        }
1841
1842        @Override
1843        public void setEditMode(boolean b) {
1844            editmode = b;
1845        }
1846
1847        @Override
1848        public boolean getEditMode() {
1849            return editmode;
1850        }
1851
1852        @Override
1853        public Object getValueAt(int r, int c) {
1854            if (c == 0) {
1855                return Integer.toString(r);
1856            } else if (c == 1) {
1857                return filterType[r];
1858            } else if (c == 2) {
1859                return filterPolarity[r];
1860            } else if (c == 3) {
1861                return filterThreshold[r];
1862            } else if (c == 4) {
1863                // Find Acela Node address
1864                nodeAddress = readNodeAddress();
1865                if (nodeAddress < 0) {
1866                    return Integer.toString(0);
1867                }
1868                // get the AcelaNode corresponding to this node address
1869                curNode = (AcelaNode) _memo.getTrafficController().getNodeFromAddress(nodeAddress);
1870                if (curNode == null) {
1871                    statusText1.setText(Bundle.getMessage("Error4"));
1872                    statusText1.setVisible(true);
1873                    errorInStatus1 = true;
1874                    resetNotes2();
1875                    return Integer.toString(0);
1876                }
1877                return Integer.toString(curNode.getStartingSensorAddress() + r);
1878            }
1879            return "";
1880        }
1881
1882        @Override
1883        public void setValueAt(Object type, int r, int c) {
1884            if (c == 1) {
1885                filterType[r] = (String) type;
1886            }
1887            if (c == 2) {
1888                filterPolarity[r] = (String) type;
1889            }
1890            if (c == 3) {
1891                filterThreshold[r] = (String) type;
1892            }
1893        }
1894
1895        @Override
1896        public boolean isCellEditable(int r, int c) {
1897            if ((c == 1) && editmode) {
1898                return (true);
1899            }
1900            if ((c == 2) && editmode) {
1901                return (true);
1902            }
1903            if ((c == 3) && editmode) {
1904                return (true);
1905            }
1906            return (false);
1907        }
1908
1909        public static final int SENSORCIRCUITADDRESS_COLUMN = 0;
1910        public static final int TYPE_COLUMN = 1;
1911        public static final int POLARITY_COLUMN = 2;
1912        public static final int THRESHOLD_COLUMN = 3;
1913        public static final int SENSORADDRESS_COLUMN = 0;
1914    }
1915    private String[] sensorConfigColumnNames = {Bundle.getMessage("HeadingSensorCircuitAddress"),
1916        Bundle.getMessage("HeadingFilterType"),
1917        Bundle.getMessage("HeadingFilterPolarity"),
1918        Bundle.getMessage("HeadingFilterThreshold"),
1919        Bundle.getMessage("HeadingSensorAddress")};
1920    private String[] filterType = new String[16];
1921    private String[] filterPolarity = new String[16];
1922    private String[] filterThreshold = new String[16];
1923
1924    /**
1925     * Set up table for selecting output default parameters for Dash-8 or TBrain
1926     * nodes
1927     */
1928    public class OutputConfigModel extends NodeConfigModel {
1929
1930        @Override
1931        public String getColumnName(int c) {
1932            return outputConfigColumnNames[c];
1933        }
1934
1935        @Override
1936        public Class<?> getColumnClass(int c) {
1937            return String.class;
1938        }
1939
1940        @Override
1941        public int getColumnCount() {
1942            return 6;
1943        }
1944
1945        @Override
1946        public int getRowCount() {
1947            return numrows;
1948        }
1949
1950        @Override
1951        public void setNumRows(int r) {
1952            numrows = r;
1953        }
1954
1955        @Override
1956        public void setEditMode(boolean b) {
1957            editmode = b;
1958        }
1959
1960        @Override
1961        public boolean getEditMode() {
1962            return editmode;
1963        }
1964
1965        @Override
1966        public Object getValueAt(int r, int c) {
1967            if (c == 0) {
1968                return Integer.toString(r);
1969            } else if (c == 1) {
1970                return outputWired[r];
1971            } else if (c == 2) {
1972                return initialState[r];
1973            } else if (c == 3) {
1974                return outputType[r];
1975            } else if (c == 4) {
1976                return outputLength[r];
1977            } else if (c == 5) {
1978                // Find Acela Node address
1979                nodeAddress = readNodeAddress();
1980                if (nodeAddress < 0) {
1981                    return Integer.toString(0);
1982                }
1983                // get the AcelaNode corresponding to this node address
1984                curNode = (AcelaNode) _memo.getTrafficController().getNodeFromAddress(nodeAddress);
1985                if (curNode == null) {
1986                    statusText1.setText(Bundle.getMessage("Error4"));
1987                    statusText1.setVisible(true);
1988                    errorInStatus1 = true;
1989                    resetNotes2();
1990                    return Integer.toString(0);
1991                }
1992                return Integer.toString(curNode.getStartingOutputAddress() + r);
1993            }
1994            return "";
1995        }
1996
1997        @Override
1998        public void setValueAt(Object type, int r, int c) {
1999            if (c == 1) {
2000                outputWired[r] = (String) type;
2001            }
2002            if (c == 2) {
2003                initialState[r] = (String) type;
2004            }
2005            if (c == 3) {
2006                outputType[r] = (String) type;
2007            }
2008            if (c == 4) {
2009                outputLength[r] = (String) type;
2010            }
2011        }
2012
2013        @Override
2014        public boolean isCellEditable(int r, int c) {
2015            if ((c == 1) && editmode) {
2016                return (true);
2017            }
2018            if ((c == 2) && editmode) {
2019                return (true);
2020            }
2021            if ((c == 3) && editmode) {
2022                return (true);
2023            }
2024            if ((c == 4) && editmode) {
2025                return (true);
2026            }
2027            return (false);
2028        }
2029
2030        public static final int OUTPUTCIRCUITADDRESS_COLUMN = 0;
2031        public static final int OUTPUTWIRED_COLUMN = 1;
2032        public static final int INITIALSTATE_COLUMN = 2;
2033        public static final int OUTPUTTYPE_COLUMN = 3;
2034        public static final int OUTPUTLENGTH_COLUMN = 4;
2035        public static final int OUTPUTADDRESS_COLUMN = 5;
2036    }
2037    private String[] outputConfigColumnNames = {Bundle.getMessage("HeadingOutputCircuitAddress"),
2038        Bundle.getMessage("HeadingOutputWired"),
2039        Bundle.getMessage("HeadingInitialState"),
2040        Bundle.getMessage("HeadingOutputType"),
2041        Bundle.getMessage("HeadingOutputLength"),
2042        Bundle.getMessage("HeadingOutputAddress")};
2043    private String[] outputWired = new String[16];
2044    private String[] initialState = new String[16];
2045    private String[] outputType = new String[16];
2046    private String[] outputLength = new String[16];
2047
2048    private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(NodeConfigFrame.class);
2049
2050}