001package jmri.jmrix.maple.nodeconfig;
002
003import java.awt.Container;
004import java.awt.FlowLayout;
005
006import javax.swing.BorderFactory;
007import javax.swing.BoxLayout;
008import javax.swing.JButton;
009import javax.swing.JLabel;
010import javax.swing.JPanel;
011import javax.swing.JSpinner;
012import javax.swing.JTextField;
013import javax.swing.SpinnerNumberModel;
014import javax.swing.border.Border;
015
016import jmri.jmrix.maple.InputBits;
017import jmri.jmrix.maple.MapleSystemConnectionMemo;
018import jmri.jmrix.maple.OutputBits;
019import jmri.jmrix.maple.SerialNode;
020import jmri.util.swing.JmriJOptionPane;
021
022/**
023 * Frame for user configuration of Maple panel nodes.
024 * <p>
025 * Note: Currently anything to do with pulse width for pulsing a turnout is
026 * commented out. This code from the C/MRI version was not deleted in case it is
027 * needed in the future.
028 *
029 * @author Bob Jacobsen Copyright (C) 2004, 2008
030 * @author Dave Duchamp Copyright (C) 2004, 2009
031 */
032public class NodeConfigFrame extends jmri.util.JmriJFrame {
033
034    protected JSpinner nodeAddrSpinner;
035    protected JLabel nodeAddrStatic = new JLabel("000");
036    protected JTextField pollTimeoutField = new JTextField(3);
037    protected JTextField sendDelayField = new JTextField(3);
038//    protected JTextField pulseWidthField = new JTextField(4);
039    protected JTextField numInputField = new JTextField(4);
040    protected JTextField numOutputField = new JTextField(4);
041
042    protected JButton addButton = new JButton(Bundle.getMessage("ButtonAdd"));
043    protected JButton editButton = new JButton(Bundle.getMessage("ButtonEdit"));
044    protected JButton deleteButton = new JButton(Bundle.getMessage("ButtonDelete"));
045    protected JButton doneButton = new JButton(Bundle.getMessage("ButtonDone"));
046    protected JButton updateButton = new JButton(Bundle.getMessage("ButtonUpdate"));
047    protected JButton cancelButton = new JButton(Bundle.getMessage("ButtonCancel"));
048
049    protected JLabel statusText1 = new JLabel();
050    protected JLabel statusText2 = new JLabel();
051    protected JLabel statusText3 = new JLabel();
052
053    protected JPanel panel2 = new JPanel();
054    protected JPanel panel2a = new JPanel();
055
056    protected boolean changedNode = false;  // true if a node was changed, deleted, or added
057    protected boolean editMode = false;     // true if in edit mode
058    private boolean checkEnabled = jmri.InstanceManager.getDefault(jmri.configurexml.ShutdownPreferences.class).isStoreCheckEnabled();
059
060    protected SerialNode curNode = null;    // Serial Node being editted
061    protected int nodeAddress = 0;          // Node address
062    protected int pollTimeoutTime = 2000;   // reply timeout time
063    protected int sendDelay = 200;   // delay time after send commands
064    // protected int pulseWidth = 500;   // pulse width for turnout control (milliseconds)
065    protected int inputBits = 40;   // maximum number of input bits - all nodes
066    protected int outputBits = 40;   // maximum number of output bits - all nodes
067
068    protected boolean errorInStatus1 = false;
069    protected boolean errorInStatus2 = false;
070    protected String stdStatus1 = Bundle.getMessage("NotesStd1");
071    protected String stdStatus2 = Bundle.getMessage("NotesStd2");
072    protected String stdStatus3 = Bundle.getMessage("NotesStd3");
073    protected String editStatus1 = Bundle.getMessage("NotesEdit1");
074    protected String editStatus2 = Bundle.getMessage("NotesEdit2");
075    protected String editStatus3 = Bundle.getMessage("NotesEdit3");
076
077    private MapleSystemConnectionMemo _memo = null;
078
079    /**
080     * Constructor method.
081     * @param memo system connection.
082     */
083    public NodeConfigFrame(MapleSystemConnectionMemo memo) {
084        super();
085        _memo = memo;
086
087        addHelpMenu("package.jmri.jmrix.maple.nodeconfig.NodeConfigFrame", true);
088    }
089
090    /**
091     * Initialize the config window
092     */
093    @Override
094    public void initComponents() {
095        setTitle(Bundle.getMessage("WindowTitle"));
096        inputBits = InputBits.getNumInputBits();
097        pollTimeoutTime = InputBits.getTimeoutTime();
098        outputBits = OutputBits.getNumOutputBits();
099        sendDelay = OutputBits.getSendDelay();
100
101        Container contentPane = getContentPane();
102        contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.Y_AXIS));
103
104        // Set up node address
105        JPanel panel1 = new JPanel();
106        panel1.setLayout(new BoxLayout(panel1, BoxLayout.Y_AXIS));
107        JPanel panel11 = new JPanel();
108        panel11.setLayout(new FlowLayout());
109        panel11.add(new JLabel(Bundle.getMessage("LabelNodeAddress") + " "));
110        nodeAddrSpinner = new JSpinner(new SpinnerNumberModel(1, 1, 99, 1));
111        panel11.add(nodeAddrSpinner);
112        nodeAddrSpinner.setToolTipText(Bundle.getMessage("TipNodeAddress"));
113        panel11.add(nodeAddrStatic);
114        nodeAddrStatic.setVisible(false);
115        JPanel panel12 = new JPanel();
116        panel12.setLayout(new FlowLayout());
117        panel12.add(new JLabel(Bundle.getMessage("LabelPollTimeout") + " "));
118        panel12.add(pollTimeoutField);
119        panel12.add(new JLabel(Bundle.getMessage("LabelMilliseconds")));
120        pollTimeoutField.setToolTipText(Bundle.getMessage("TipPollTimeout"));
121        pollTimeoutField.setText("" + pollTimeoutTime);
122        JPanel panel120 = new JPanel();
123        panel120.setLayout(new FlowLayout());
124        panel120.add(new JLabel(Bundle.getMessage("LabelSendDelay") + " "));
125        panel120.add(sendDelayField);
126        panel120.add(new JLabel(Bundle.getMessage("LabelMilliseconds")));
127        sendDelayField.setToolTipText(Bundle.getMessage("TipSendDelay"));
128        sendDelayField.setText("" + sendDelay);
129//        JPanel panel13 = new JPanel();
130//        panel13.setLayout(new FlowLayout());
131//        panel13.add(new JLabel(Bundle.getMessage("LabelPulseWidth")+" "));
132//        panel13.add(pulseWidthField);
133//        pulseWidthField.setToolTipText(Bundle.getMessage("TipPulseWidth"));
134//        pulseWidthField.setText("500");
135//        panel13.add(new JLabel(Bundle.getMessage("LabelMilliseconds")));
136        JPanel panel14 = new JPanel();
137        panel14.setLayout(new FlowLayout());
138        panel14.add(new JLabel(Bundle.getMessage("LabelNumInputBits") + " "));
139        panel14.add(numInputField);
140        numInputField.setToolTipText(Bundle.getMessage("TipInputBits"));
141        numInputField.setText("" + inputBits);
142        JPanel panel15 = new JPanel();
143        panel15.setLayout(new FlowLayout());
144        panel15.add(new JLabel(Bundle.getMessage("LabelNumOutputBits") + " "));
145        panel15.add(numOutputField);
146        numOutputField.setToolTipText(Bundle.getMessage("TipOutputBits"));
147        numOutputField.setText("" + outputBits);
148
149        panel1.add(panel11);
150        panel1.add(panel12);
151        panel1.add(panel120);
152//  panel1.add(panel13);
153        panel1.add(panel14);
154        panel1.add(panel15);
155        contentPane.add(panel1);
156
157        // Set up the notes panel
158        JPanel panel3 = new JPanel();
159        panel3.setLayout(new BoxLayout(panel3, BoxLayout.Y_AXIS));
160        JPanel panel31 = new JPanel();
161        panel31.setLayout(new FlowLayout());
162        statusText1.setText(stdStatus1);
163        statusText1.setVisible(true);
164        panel31.add(statusText1);
165        JPanel panel32 = new JPanel();
166        panel32.setLayout(new FlowLayout());
167        statusText2.setText(stdStatus2);
168        statusText2.setVisible(true);
169        panel32.add(statusText2);
170        JPanel panel33 = new JPanel();
171        panel33.setLayout(new FlowLayout());
172        statusText3.setText(stdStatus3);
173        statusText3.setVisible(true);
174        panel33.add(statusText3);
175        panel3.add(panel31);
176        panel3.add(panel32);
177        panel3.add(panel33);
178        Border panel3Border = BorderFactory.createEtchedBorder();
179        Border panel3Titled = BorderFactory.createTitledBorder(panel3Border,
180                Bundle.getMessage("BoxLabelNotes"));
181        panel3.setBorder(panel3Titled);
182        contentPane.add(panel3);
183
184        // Set up buttons
185        JPanel panel4 = new JPanel();
186        panel4.setLayout(new FlowLayout());
187        addButton.setText(Bundle.getMessage("ButtonAdd"));
188        addButton.setVisible(true);
189        addButton.setToolTipText(Bundle.getMessage("TipAddButton"));
190        addButton.addActionListener(new java.awt.event.ActionListener() {
191            @Override
192            public void actionPerformed(java.awt.event.ActionEvent e) {
193                addButtonActionPerformed();
194            }
195        });
196        panel4.add(addButton);
197        editButton.setText(Bundle.getMessage("ButtonEdit"));
198        editButton.setVisible(true);
199        editButton.setToolTipText(Bundle.getMessage("TipEditButton"));
200        panel4.add(editButton);
201        editButton.addActionListener(new java.awt.event.ActionListener() {
202            @Override
203            public void actionPerformed(java.awt.event.ActionEvent e) {
204                editButtonActionPerformed();
205            }
206        });
207        panel4.add(deleteButton);
208        deleteButton.setText(Bundle.getMessage("ButtonDelete"));
209        deleteButton.setVisible(true);
210        deleteButton.setToolTipText(Bundle.getMessage("TipDeleteButton"));
211        panel4.add(deleteButton);
212        deleteButton.addActionListener(new java.awt.event.ActionListener() {
213            @Override
214            public void actionPerformed(java.awt.event.ActionEvent e) {
215                deleteButtonActionPerformed();
216            }
217        });
218        panel4.add(doneButton);
219        doneButton.setText(Bundle.getMessage("ButtonDone"));
220        doneButton.setVisible(true);
221        doneButton.setToolTipText(Bundle.getMessage("TipDoneButton"));
222        panel4.add(doneButton);
223        doneButton.addActionListener(new java.awt.event.ActionListener() {
224            @Override
225            public void actionPerformed(java.awt.event.ActionEvent e) {
226                doneButtonActionPerformed();
227            }
228        });
229        panel4.add(updateButton);
230        updateButton.setText(Bundle.getMessage("ButtonUpdate"));
231        updateButton.setVisible(true);
232        updateButton.setToolTipText(Bundle.getMessage("TipUpdateButton"));
233        panel4.add(updateButton);
234        updateButton.addActionListener(new java.awt.event.ActionListener() {
235            @Override
236            public void actionPerformed(java.awt.event.ActionEvent e) {
237                updateButtonActionPerformed();
238            }
239        });
240        updateButton.setVisible(false);
241        panel4.add(cancelButton);
242        cancelButton.setText(Bundle.getMessage("ButtonCancel"));
243        cancelButton.setVisible(true);
244        cancelButton.setToolTipText(Bundle.getMessage("TipCancelButton"));
245        panel4.add(cancelButton);
246        cancelButton.addActionListener(new java.awt.event.ActionListener() {
247            @Override
248            public void actionPerformed(java.awt.event.ActionEvent e) {
249                cancelButtonActionPerformed();
250            }
251        });
252        cancelButton.setVisible(false);
253        contentPane.add(panel4);
254
255        // pack for display
256        pack();
257    }
258
259    /**
260     * Handle Add button.
261     */
262    public void addButtonActionPerformed() {
263        // Check that a node with this address does not exist
264        int nodeAddress = readNodeAddress();
265        if (nodeAddress < 0) {
266            return;
267        }
268        // get a SerialNode corresponding to this node address if one exists
269        curNode = (SerialNode) _memo.getTrafficController().getNodeFromAddress(nodeAddress);
270        if (curNode != null) {
271            statusText1.setText(Bundle.getMessage("Error1", Integer.toString(nodeAddress)));
272            statusText1.setVisible(true);
273            errorInStatus1 = true;
274            resetNotes2();
275            return;
276        }
277        // get node information from window
278        if (!readPollTimeout()) {
279            return;
280        }
281        if (!readSendDelay()) {
282            return;
283        }
284//  if ( !readPulseWidth() ) return;
285        if (!readNumInputBits()) {
286            return;
287        }
288        if (!readNumOutputBits()) {
289            return;
290        }
291        // all ready, create the new node
292        curNode = new SerialNode(nodeAddress, 0, _memo.getTrafficController() );
293        // configure the new node
294        setNodeParameters();
295//        // register any orphan sensors that this node may have
296//        _memo.getSensorManager().registerSensorsForNode(curNode);
297        // reset after succefully adding node
298        resetNotes();
299        changedNode = true;
300        // provide user feedback
301        statusText1.setText(Bundle.getMessage("FeedBackAdd") + " "
302                + Integer.toString(nodeAddress));
303        errorInStatus1 = true;
304    }
305
306    /**
307     * Handle Edit button.
308     */
309    public void editButtonActionPerformed() {
310        // Find Serial Node address
311        nodeAddress = readNodeAddress();
312        if (nodeAddress <= 0) {
313            return;
314        }
315        // get the SerialNode corresponding to this node address
316        curNode = (SerialNode) _memo.getTrafficController().getNodeFromAddress(nodeAddress);
317        if (curNode == null) {
318            statusText1.setText(Bundle.getMessage("Error4"));
319            statusText1.setVisible(true);
320            errorInStatus1 = true;
321            resetNotes2();
322            return;
323        }
324        // Set up static node address
325        nodeAddrStatic.setText(Integer.toString(nodeAddress));
326        nodeAddrSpinner.setVisible(false);
327        nodeAddrStatic.setVisible(true);
328        // set up pulse width
329//        pulseWidth = curNode.getPulseWidth();
330//        pulseWidthField.setText(Integer.toString(pulseWidth));
331        // set up number of input and output bits
332        inputBits = InputBits.getNumInputBits();
333        numInputField.setText(Integer.toString(inputBits));
334        outputBits = OutputBits.getNumOutputBits();
335        numOutputField.setText(Integer.toString(outputBits));
336        // set up poll timeout and send delay
337        pollTimeoutTime = InputBits.getTimeoutTime();
338        pollTimeoutField.setText(Integer.toString(pollTimeoutTime));
339        sendDelay = OutputBits.getSendDelay();
340        sendDelayField.setText(Integer.toString(sendDelay));
341        // Switch buttons
342        editMode = true;
343        addButton.setVisible(false);
344        editButton.setVisible(false);
345        deleteButton.setVisible(false);
346        doneButton.setVisible(false);
347        updateButton.setVisible(true);
348        cancelButton.setVisible(true);
349        // Switch to edit notes
350        statusText1.setText(editStatus1);
351        statusText2.setText(editStatus2);
352        statusText3.setText(editStatus3);
353    }
354
355    /**
356     * Handle Delete button.
357     */
358    public void deleteButtonActionPerformed() {
359        // Find Serial Node address
360        int nodeAddress = readNodeAddress();
361        if (nodeAddress < 0) {
362            return;
363        }
364        // get the SerialNode corresponding to this node address
365        curNode = (SerialNode) _memo.getTrafficController().getNodeFromAddress(nodeAddress);
366        if (curNode == null) {
367            statusText1.setText(Bundle.getMessage("Error4"));
368            statusText1.setVisible(true);
369            errorInStatus1 = true;
370            resetNotes2();
371            return;
372        }
373        // confirm deletion with the user
374        if (JmriJOptionPane.OK_OPTION == JmriJOptionPane.showConfirmDialog(
375                this, Bundle.getMessage("ConfirmDelete1") + " " + nodeAddress + "?",
376                Bundle.getMessage("ConfirmDeleteTitle"),
377                JmriJOptionPane.OK_CANCEL_OPTION,
378                JmriJOptionPane.WARNING_MESSAGE)) {
379            // delete this node
380            _memo.getTrafficController().deleteNode(nodeAddress);
381            // provide user feedback
382            resetNotes();
383            statusText1.setText(Bundle.getMessage("FeedBackDelete") + " "
384                    + Integer.toString(nodeAddress));
385            errorInStatus1 = true;
386            changedNode = true;
387        } else {
388            // reset as needed
389            resetNotes();
390        }
391    }
392
393    /**
394     * Handle Done button.
395     */
396    public void doneButtonActionPerformed() {
397        if (editMode) {
398            // Reset
399            editMode = false;
400            curNode = null;
401            // Switch buttons
402            addButton.setVisible(true);
403            editButton.setVisible(true);
404            deleteButton.setVisible(true);
405            doneButton.setVisible(true);
406            updateButton.setVisible(false);
407            cancelButton.setVisible(false);
408            nodeAddrSpinner.setVisible(true);
409            nodeAddrStatic.setVisible(false);
410        }
411        if (changedNode && !checkEnabled) {
412            // Remind user to Save new configuration
413            JmriJOptionPane.showMessageDialog(this,
414                    Bundle.getMessage("ReminderNode1") + "\n" + Bundle.getMessage("Reminder2"),
415                    Bundle.getMessage("ReminderTitle"),
416                    JmriJOptionPane.INFORMATION_MESSAGE);
417        }
418        setVisible(false);
419        dispose();
420    }
421
422    /**
423     * Handle Update button.
424     */
425    public void updateButtonActionPerformed() {
426        // get node information from window
427        if (!readPollTimeout()) {
428            return;
429        }
430        if (!readSendDelay()) {
431            return;
432        }
433        //  if ( !readPulseWidth() ) return;
434        if (!readNumInputBits()) {
435            return;
436        }
437        if (!readNumOutputBits()) {
438            return;
439        }
440        // update node information
441        setNodeParameters();
442        changedNode = true;
443        // Reset Edit Mode
444        editMode = false;
445        curNode = null;
446        // Switch buttons
447        addButton.setVisible(true);
448        editButton.setVisible(true);
449        deleteButton.setVisible(true);
450        doneButton.setVisible(true);
451        updateButton.setVisible(false);
452        cancelButton.setVisible(false);
453        // make node address editable again
454        nodeAddrSpinner.setVisible(true);
455        nodeAddrStatic.setVisible(false);
456        // refresh notes panel
457        statusText2.setText(stdStatus2);
458        statusText3.setText(stdStatus3);
459        // provide user feedback
460        statusText1.setText(Bundle.getMessage("FeedBackUpdate") + " "
461                + Integer.toString(nodeAddress));
462        errorInStatus1 = true;
463    }
464
465    /**
466     * Handle Cancel button.
467     */
468    public void cancelButtonActionPerformed() {
469        // Reset
470        editMode = false;
471        curNode = null;
472        // Switch buttons
473        addButton.setVisible(true);
474        editButton.setVisible(true);
475        deleteButton.setVisible(true);
476        doneButton.setVisible(true);
477        updateButton.setVisible(false);
478        cancelButton.setVisible(false);
479        // make node address editable again
480        nodeAddrSpinner.setVisible(true);
481        nodeAddrStatic.setVisible(false);
482        // refresh notes panel
483        statusText1.setText(stdStatus1);
484        statusText2.setText(stdStatus2);
485        statusText3.setText(stdStatus3);
486    }
487
488    /**
489     * Close the window when the close box is clicked.
490     */
491    @Override
492    public void windowClosing(java.awt.event.WindowEvent e) {
493        doneButtonActionPerformed();
494        super.windowClosing(e);
495    }
496
497    /**
498     * Set node parameters. The node must exist, and be in 'curNode'
499     * Also, the node type must be set and in 'nodeType'
500     */
501    void setNodeParameters() {
502        // following parameters are common for all node types
503        InputBits.setTimeoutTime(pollTimeoutTime);
504        OutputBits.setSendDelay(sendDelay);
505        InputBits.setNumInputBits(inputBits);
506        OutputBits.setNumOutputBits(outputBits);
507//        curNode.setPulseWidth(pulseWidth);
508    }
509
510    /**
511     * Reset the notes error text after error display.
512     */
513    private void resetNotes() {
514        if (errorInStatus1) {
515            if (editMode) {
516                statusText1.setText(editStatus1);
517            } else {
518                statusText1.setText(stdStatus1);
519            }
520            errorInStatus1 = false;
521        }
522        resetNotes2();
523    }
524
525    /**
526     * Reset the second line of Notes area.
527     */
528    private void resetNotes2() {
529        if (errorInStatus2) {
530            if (editMode) {
531                statusText1.setText(editStatus2);
532            } else {
533                statusText2.setText(stdStatus2);
534            }
535            errorInStatus2 = false;
536        }
537    }
538
539    /**
540     * Read node address and check for legal range.
541     * Range is protected by JSpinner, error dialogs removed.
542     *
543     * @return a node address in the range 1-99.
544     */
545    private int readNodeAddress() {
546        return (Integer) nodeAddrSpinner.getValue();
547    }
548
549    /**
550     * Read receive poll reply timeout time from window.
551     * If an error is detected, a suitable error message is placed
552     * in the Notes area.
553     *
554     * @return 'true' if successful, 'false' if an error was detected
555     */
556    protected boolean readPollTimeout() {
557        // get the timeout time
558        try {
559            pollTimeoutTime = Integer.parseInt(pollTimeoutField.getText());
560        } catch (Exception e) {
561            statusText1.setText(Bundle.getMessage("Error7"));
562            statusText1.setVisible(true);
563            pollTimeoutTime = 0;
564            errorInStatus1 = true;
565            resetNotes2();
566            return (false);
567        }
568        if (pollTimeoutTime <= 0) {
569            statusText1.setText(Bundle.getMessage("Error8"));
570            statusText1.setVisible(true);
571            pollTimeoutTime = 0;
572            errorInStatus1 = true;
573            resetNotes2();
574            return (false);
575        }
576        if (pollTimeoutTime > 10000) {
577            statusText1.setText(Bundle.getMessage("Error9"));
578            statusText1.setVisible(true);
579            pollTimeoutTime = 0;
580            errorInStatus1 = true;
581            resetNotes2();
582            return (false);
583        }
584        // successful
585        return true;
586    }
587
588    /**
589     * Read send delay time from window.
590     * If an error is detected, a suitable error message
591     * is placed in the Notes area.
592     *
593     * @return 'true' if successful, 'false' if an error was detected
594     */
595    protected boolean readSendDelay() {
596        // get the timeout time
597        try {
598            sendDelay = Integer.parseInt(sendDelayField.getText());
599        } catch (Exception e) {
600            statusText1.setText(Bundle.getMessage("Error19"));
601            statusText1.setVisible(true);
602            sendDelay = 0;
603            errorInStatus1 = true;
604            resetNotes2();
605            return (false);
606        }
607        if (sendDelay < 0) {
608            statusText1.setText(Bundle.getMessage("Error20"));
609            statusText1.setVisible(true);
610            sendDelay = 0;
611            errorInStatus1 = true;
612            resetNotes2();
613            return (false);
614        }
615        if (sendDelay > 65535) {
616            statusText1.setText(Bundle.getMessage("Error21"));
617            statusText1.setVisible(true);
618            sendDelay = 0;
619            errorInStatus1 = true;
620            resetNotes2();
621            return (false);
622        }
623        // successful
624        return true;
625    }
626
627    /**
628     * Read number of input bits from window.
629     * If an error is detected, a suitable error message is
630     * placed in the Notes area.
631     *
632     * @return 'true' if successful, 'false' if an error was detected
633     */
634    protected boolean readNumInputBits() {
635        // get the input bits
636        try {
637            inputBits = Integer.parseInt(numInputField.getText());
638        } catch (Exception e) {
639            statusText1.setText(Bundle.getMessage("Error10"));
640            statusText1.setVisible(true);
641            inputBits = 0;
642            errorInStatus1 = true;
643            resetNotes2();
644            return (false);
645        }
646        if (inputBits <= 0) {
647            statusText1.setText(Bundle.getMessage("Error11"));
648            statusText1.setVisible(true);
649            inputBits = 0;
650            errorInStatus1 = true;
651            resetNotes2();
652            return (false);
653        }
654        if (inputBits > 1000) {
655            statusText1.setText(Bundle.getMessage("Error12"));
656            statusText1.setVisible(true);
657            inputBits = 0;
658            errorInStatus1 = true;
659            resetNotes2();
660            return (false);
661        }
662        // successful
663        return true;
664    }
665
666    /**
667     * Read number of output bits from window.
668     * If an error is detected, a suitable error message is placed
669     * in the Notes area.
670     *
671     * @return 'true' if successful, 'false' if an error was detected
672     */
673    protected boolean readNumOutputBits() {
674        // get the output bits
675        try {
676            outputBits = Integer.parseInt(numOutputField.getText());
677        } catch (Exception e) {
678            statusText1.setText(Bundle.getMessage("Error13"));
679            statusText1.setVisible(true);
680            outputBits = 0;
681            errorInStatus1 = true;
682            resetNotes2();
683            return (false);
684        }
685        if (outputBits <= 0) {
686            statusText1.setText(Bundle.getMessage("Error14"));
687            statusText1.setVisible(true);
688            outputBits = 0;
689            errorInStatus1 = true;
690            resetNotes2();
691            return (false);
692        }
693        if (outputBits > 8000) {
694            statusText1.setText(Bundle.getMessage("Error15"));
695            statusText1.setVisible(true);
696            outputBits = 0;
697            errorInStatus1 = true;
698            resetNotes2();
699            return (false);
700        }
701        // successful
702        return true;
703    }
704
705//    /**
706//     * Read pulse width from window.
707//     * If an error is detected, a suitable error message is placed in the
708//     * Notes area.
709//     *
710//     * @return 'true' if successful, 'false' if an error was detected
711//     */
712//    protected boolean readPulseWidth() {
713//        // get the pulse width
714//        try
715//        {
716//            pulseWidth = Integer.parseInt(pulseWidthField.getText());
717//        }
718//        catch (Exception e)
719//        {
720//            statusText1.setText(Bundle.getMessage("Error18"));
721//            statusText1.setVisible(true);
722//            pulseWidth = 500;
723//            errorInStatus1 = true;
724//            resetNotes2();
725//            return (false);
726//        }
727//        if (pulseWidth < 100) {
728//            statusText1.setText(Bundle.getMessage("Error16"));
729//            statusText1.setVisible(true);
730//            pulseWidth = 100;
731//   pulseWidthField.setText(Integer.toString(pulseWidth));
732//            errorInStatus1 = true;
733//            resetNotes2();
734//            return (false);
735//        }
736//        if (pulseWidth > 10000) {
737//            statusText1.setText(Bundle.getMessage("Error17"));
738//            statusText1.setVisible(true);
739//            pulseWidth = 500;
740//            pulseWidthField.setText(Integer.toString(pulseWidth));
741//            errorInStatus1 = true;
742//            resetNotes2();
743//            return (false);
744//        }
745//        // successful
746//        return true;
747//    }
748
749    // private final static Logger log = LoggerFactory.getLogger(NodeConfigFrame.class);
750
751}