001package jmri.jmrix.grapevine.packetgen;
002
003import java.awt.Dimension;
004import java.awt.FlowLayout;
005
006import javax.swing.BoxLayout;
007import javax.swing.JLabel;
008import javax.swing.JPanel;
009import javax.swing.JSeparator;
010import javax.swing.JSpinner;
011import javax.swing.SpinnerNumberModel;
012import javax.swing.JTextField;
013
014import jmri.jmrix.grapevine.SerialMessage;
015import jmri.jmrix.grapevine.SerialReply;
016import jmri.jmrix.grapevine.GrapevineSystemConnectionMemo;
017import jmri.util.StringUtil;
018import jmri.util.swing.JmriJOptionPane;
019
020/**
021 * Frame for user input of serial messages.
022 *
023 * @author Bob Jacobsen Copyright (C) 2002, 2003, 2006, 2007, 2008, 2018
024 */
025public class SerialPacketGenFrame extends jmri.util.JmriJFrame implements jmri.jmrix.grapevine.SerialListener {
026
027    private GrapevineSystemConnectionMemo memo = null;
028
029    // member declarations
030    javax.swing.JLabel jLabel1 = new javax.swing.JLabel();
031    javax.swing.JButton sendButton = new javax.swing.JButton();
032    JTextField packetTextField = new JTextField(12);
033
034    javax.swing.JButton parityButton = new javax.swing.JButton(Bundle.getMessage("ButtonSetParity"));
035
036    javax.swing.JButton pollButton = new javax.swing.JButton(Bundle.getMessage("ButtonQueryNode"));
037    protected JSpinner nodeAddrSpinner = new JSpinner(new SpinnerNumberModel(1, 1, 100, 1));
038
039    public SerialPacketGenFrame(GrapevineSystemConnectionMemo _memo) {
040        super();
041        memo = _memo;
042    }
043
044    /**
045     * {@inheritDoc}
046     */
047    @Override
048    public void initComponents() {
049        // the following code sets the frame's initial state
050
051        jLabel1.setText(Bundle.getMessage("CommandLabel"));
052        jLabel1.setVisible(true);
053
054        sendButton.setText(Bundle.getMessage("ButtonSend"));
055        sendButton.setVisible(true);
056        sendButton.setToolTipText(Bundle.getMessage("TooltipSendPacket"));
057
058        packetTextField.setText("");
059        packetTextField.setToolTipText(Bundle.getMessage("EnterHexToolTip"));
060        packetTextField.setMaximumSize(
061                new Dimension(packetTextField.getMaximumSize().width,
062                        packetTextField.getPreferredSize().height
063                )
064        );
065
066        setTitle(Bundle.getMessage("SendXCommandTitle", Bundle.getMessage("MenuSystem")));
067        getContentPane().setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS));
068
069        getContentPane().add(jLabel1);
070        getContentPane().add(packetTextField);
071        JPanel p1 = new JPanel();
072        p1.setLayout(new BoxLayout(p1, BoxLayout.X_AXIS));
073        p1.add(parityButton);
074        p1.add(sendButton);
075        getContentPane().add(p1);
076
077        sendButton.addActionListener(new java.awt.event.ActionListener() {
078            @Override
079            public void actionPerformed(java.awt.event.ActionEvent e) {
080                sendButtonActionPerformed(e);
081            }
082        });
083
084        parityButton.addActionListener(new java.awt.event.ActionListener() {
085            @Override
086            public void actionPerformed(java.awt.event.ActionEvent e) {
087                parityButtonActionPerformed(e);
088            }
089        });
090
091        getContentPane().add(new JSeparator(JSeparator.HORIZONTAL));
092
093        // add poll message buttons
094        JPanel pane3 = new JPanel();
095        pane3.setLayout(new FlowLayout());
096
097        pane3.add(new JLabel(Bundle.getMessage("LabelNodeAddress")));
098
099        pane3.add(nodeAddrSpinner);
100        nodeAddrSpinner.setToolTipText(Bundle.getMessage("TooltipNodeAddress"));
101
102        pane3.add(pollButton);
103        getContentPane().add(pane3);
104
105        pollButton.addActionListener(new java.awt.event.ActionListener() {
106            @Override
107            public void actionPerformed(java.awt.event.ActionEvent e) {
108                pollButtonActionPerformed(e);
109            }
110        });
111        pollButton.setToolTipText(Bundle.getMessage("PollToolTip"));
112
113        // add help menu to window
114        addHelpMenu("package.jmri.jmrix.grapevine.packetgen.SerialPacketGenFrame", true);
115
116        // pack for display
117        pack();
118    }
119
120    public void pollButtonActionPerformed(java.awt.event.ActionEvent e) {
121        SerialMessage msg = SerialMessage.getPoll((Integer) nodeAddrSpinner.getValue());
122        memo.getTrafficController().sendSerialMessage(msg, this);
123    }
124
125    public void sendButtonActionPerformed(java.awt.event.ActionEvent e) {
126        String input = packetTextField.getText();
127        // TODO check input + feedback on error. Too easy to cause NPE
128        memo.getTrafficController().sendSerialMessage(createPacket(input), this);
129    }
130
131    public void parityButtonActionPerformed(java.awt.event.ActionEvent e) {
132        String input = packetTextField.getText();
133        // TODO check input + feedback on error. Too easy to cause NPE
134        SerialMessage m = createPacket(input);
135        if (m == null) {
136            return;
137        }
138        m.setParity();
139        packetTextField.setText(m.toString());
140    }
141
142    SerialMessage createPacket(String s) {
143        // gather bytes in result
144        byte b[] = StringUtil.bytesFromHexString(s);
145        if (b.length != 4) {
146            log.warn("Grapevine createPacket not 4 bytes");
147            JmriJOptionPane.showMessageDialog(this,
148                    Bundle.getMessage("ErrorInvalidMessageLength"),
149                    Bundle.getMessage("ErrorTitle"),
150                    JmriJOptionPane.ERROR_MESSAGE);
151            return null; // no such thing as message with other than 4 bytes
152        }
153        SerialMessage m = new SerialMessage();
154        for (int i = 0; i < b.length; i++) {
155            m.setElement(i, b[i]);
156        }
157        return m;
158    }
159
160    /**
161     * {@inheritDoc}
162     */
163    @Override
164    public void message(SerialMessage m) {
165    } // ignore replies
166
167    /**
168     * {@inheritDoc}
169     */
170    @Override
171    public void reply(SerialReply r) {
172    } // ignore replies
173
174    private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(SerialPacketGenFrame.class);
175
176}