001package jmri.jmrix.ieee802154.xbee.swing.nodeconfig;
002
003import com.digi.xbee.api.RemoteXBeeDevice;
004import com.digi.xbee.api.exceptions.TimeoutException;
005import com.digi.xbee.api.exceptions.XBeeException;
006import com.digi.xbee.api.models.XBee16BitAddress;
007import com.digi.xbee.api.models.XBee64BitAddress;
008
009import java.awt.Container;
010import java.awt.FlowLayout;
011import java.awt.event.WindowEvent;
012import javax.swing.BoxLayout;
013import javax.swing.JLabel;
014import javax.swing.JPanel;
015
016import jmri.jmrix.ieee802154.xbee.XBeeNode;
017import jmri.jmrix.ieee802154.xbee.XBeeTrafficController;
018import jmri.util.swing.JmriJOptionPane;
019
020/**
021 * Frame for Adding new Nodes
022 *
023 * @author Bob Jacobsen Copyright (C) 2004
024 * @author Dave Duchamp Copyright (C) 2004
025 * @author Paul Bender Copyright (C) 2013,2016
026 */
027public class XBeeAddNodeFrame extends jmri.jmrix.ieee802154.swing.nodeconfig.AddNodeFrame {
028
029    private XBeeTrafficController xtc = null;
030    private final javax.swing.JTextField nodeIdentifierField = new javax.swing.JTextField();
031    private XBeeNodeConfigFrame parent = null;
032
033
034    /**
035     * Constructor method
036     *
037     * @param tc the XBeeTrafficController associated with this connection.
038     * @param source the XBeeNodeConfigFrame that started this add.
039     */
040    public XBeeAddNodeFrame(XBeeTrafficController tc,XBeeNodeConfigFrame source) {
041        super(tc);
042        xtc = tc;
043        parent = source;
044    }
045
046    /**
047     * Initialize the config window
048     */
049    @Override
050    public void initComponents() {
051        setTitle(Bundle.getMessage("AddNodeWindowTitle"));
052        Container contentPane = getContentPane();
053        contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.Y_AXIS));
054
055        // Set up node address and node type
056        JPanel panel = new JPanel();
057        panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
058        panel.add(new JLabel(Bundle.getMessage("LabelNodeAddress") + " "));
059        panel.add(nodeAddrField);
060        nodeAddrField.setToolTipText(Bundle.getMessage("TipNodeAddress"));
061        panel.add(new JLabel(Bundle.getMessage("LabelNodeAddress64") + " "));
062        panel.add(nodeAddr64Field);
063        nodeAddr64Field.setToolTipText(Bundle.getMessage("TipNodeAddress64"));
064        panel.add(new JLabel(Bundle.getMessage("LabelNodeIdentifier") + " "));
065        panel.add(nodeIdentifierField);
066        nodeIdentifierField.setToolTipText(Bundle.getMessage("TipNodeIdentifier"));
067
068        initAddressBoxes();
069        contentPane.add(panel);
070
071        // Set up buttons
072        JPanel panel4 = new JPanel();
073        panel4.setLayout(new FlowLayout());
074        addButton.setText(Bundle.getMessage("ButtonAdd"));
075        addButton.setVisible(true);
076        addButton.setToolTipText(Bundle.getMessage("TipAddButton"));
077        addButton.addActionListener((java.awt.event.ActionEvent e) -> addButtonActionPerformed());
078        panel4.add(addButton);
079        panel4.add(cancelButton);
080        cancelButton.setText(Bundle.getMessage("ButtonCancel"));
081        cancelButton.setVisible(true);
082        cancelButton.setToolTipText(Bundle.getMessage("TipCancelButton"));
083        panel4.add(cancelButton);
084        cancelButton.addActionListener((java.awt.event.ActionEvent e) -> cancelButtonActionPerformed());
085        contentPane.add(panel4);
086
087        // pack for display
088        pack();
089    }
090
091    /**
092     * Method to handle add button
093     */
094    @Override
095    public void addButtonActionPerformed() {
096        if(nodeAddr64Field.getText().equals("") &&
097           nodeAddrField.getText().equals("")) {
098           // no address, just return.
099           return;
100        }
101        // Check that a node with this address does not exist
102        // if the 64 bit address field is blank, use the "Unknown" address".
103        XBee64BitAddress guid;
104        if(!(nodeAddr64Field.getText().equals(""))) {
105           byte[] GUID = jmri.util.StringUtil.bytesFromHexString(nodeAddr64Field.getText());
106           guid = new XBee64BitAddress(GUID);
107        } else {
108           guid = XBee64BitAddress.UNKNOWN_ADDRESS;
109        }
110        // if the 16 bit address field is blank, use the "Unknown" address".
111        XBee16BitAddress address;
112        if(!(nodeAddrField.getText().equals(""))){
113           byte[] addr = jmri.util.StringUtil.bytesFromHexString(nodeAddrField.getText());
114           address = new XBee16BitAddress(addr);
115        } else {
116           address = XBee16BitAddress.UNKNOWN_ADDRESS;
117        }
118        String Identifier = nodeIdentifierField.getText();
119        // create the RemoteXBeeDevice for the node.
120        RemoteXBeeDevice remoteDevice = new RemoteXBeeDevice(xtc.getXBee(),
121              guid,address,Identifier);
122        // get a XBeeNode corresponding to this node address if one exists
123        curNode = (XBeeNode) xtc.getNodeFromXBeeDevice(remoteDevice);
124        if (curNode != null) {
125            JmriJOptionPane.showMessageDialog(this,Bundle.getMessage("Error1",remoteDevice),
126                Bundle.getMessage("AddNodeErrorTitle"),JmriJOptionPane.ERROR_MESSAGE);
127            return;
128        }
129        try {
130            // and then add it to the network
131            xtc.getXBee().getNetwork().addRemoteDevice(remoteDevice);
132            // create node (they register themselves)
133            XBeeNode node = new XBeeNode(remoteDevice);
134
135            xtc.registerNode(node);
136            parent.nodeListChanged();
137        } catch (TimeoutException toe) {
138            log.error("Timeout adding node {}.",remoteDevice);
139            JmriJOptionPane.showMessageDialog(this,Bundle.getMessage("Error3"),
140                Bundle.getMessage("AddNodeErrorTitle"),JmriJOptionPane.ERROR_MESSAGE);
141            log.error("Error creating XBee Node, constructor returned null");
142            return;
143        } catch (XBeeException xbe) {
144            log.error("Exception adding node {}.",remoteDevice);
145            JmriJOptionPane.showMessageDialog(this,Bundle.getMessage("Error3"),
146                Bundle.getMessage("AddNodeErrorTitle"),JmriJOptionPane.ERROR_MESSAGE);
147            log.error("Error creating XBee Node, constructor returned null");
148            return;
149        }
150
151        this.dispatchEvent(new WindowEvent(this, WindowEvent.WINDOW_CLOSING));
152    }
153
154    /**
155     * Method to handle cancel button
156     */
157    @Override
158    public void cancelButtonActionPerformed() {
159        // Reset
160        curNode = null;
161        // Switch buttons
162        addButton.setVisible(true);
163        cancelButton.setVisible(false);
164        this.dispatchEvent(new WindowEvent(this, WindowEvent.WINDOW_CLOSING));
165    }
166
167    // Initilize the text boxes for the addresses.
168    @Override
169    protected void initAddressBoxes() {
170        nodeAddrField.setText("");
171        nodeAddr64Field.setText("");
172        nodeIdentifierField.setText("");
173    }
174
175    private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(XBeeAddNodeFrame.class);
176
177}