001package jmri.jmrix.marklin.swing.packetgen;
002
003import java.awt.Dimension;
004import java.awt.FlowLayout;
005import java.awt.GridLayout;
006import java.util.Objects;
007
008import javax.swing.Box;
009import javax.swing.BoxLayout;
010import javax.swing.JButton;
011import javax.swing.JLabel;
012import javax.swing.JPanel;
013import javax.swing.JTextField;
014
015import jmri.jmrix.marklin.MarklinListener;
016import jmri.jmrix.marklin.MarklinMessage;
017import jmri.jmrix.marklin.MarklinReply;
018import jmri.jmrix.marklin.MarklinSystemConnectionMemo;
019import jmri.util.swing.JmriJOptionPane;
020
021/**
022 * Frame for user input of Marklin messages
023 *
024 * @author Bob Jacobsen Copyright (C) 2001, 2008
025 * @author Dan Boudreau Copyright (C) 2007
026 */
027public class PacketGenPanel extends jmri.jmrix.marklin.swing.MarklinPanel implements MarklinListener {
028
029    // member declarations
030    JLabel entryLabel = new JLabel();
031    JLabel replyLabel = new JLabel();
032    JButton sendButton = new JButton();
033    JTextField packetTextField = new JTextField(20);
034    JTextField packetReplyField = new JTextField(20);
035
036    public PacketGenPanel() {
037        super();
038    }
039
040    /** 
041     * {@inheritDoc}
042     */
043    @Override
044    public void initComponents() {
045        setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
046        // the following code sets the frame's initial state
047
048        JPanel entrybox = new JPanel();
049        entryLabel.setText(Bundle.getMessage("CommandLabel"));
050        entryLabel.setVisible(true);
051
052        replyLabel.setText(Bundle.getMessage("ReplyLabel"));
053        replyLabel.setVisible(true);
054
055        sendButton.setText(Bundle.getMessage("ButtonSend"));
056        sendButton.setVisible(true);
057        sendButton.setToolTipText(Bundle.getMessage("SendToolTip"));
058
059        packetTextField.setText("");
060        packetTextField.setToolTipText(Bundle.getMessage("EnterHexToolTip"));
061        packetTextField.setMaximumSize(new Dimension(packetTextField
062                .getMaximumSize().width, packetTextField.getPreferredSize().height));
063
064        entrybox.setLayout(new GridLayout(2, 2));
065        entrybox.add(entryLabel);
066        entrybox.add(packetTextField);
067        entrybox.add(replyLabel);
068
069        JPanel buttonbox = new JPanel();
070        FlowLayout buttonLayout = new FlowLayout(FlowLayout.TRAILING);
071        buttonbox.setLayout(buttonLayout);
072        buttonbox.add(sendButton);
073        entrybox.add(buttonbox);
074        //packetReplyField.setEditable(false); // keep field editable to allow user to select and copy the reply
075        add(entrybox);
076        add(packetReplyField);
077        add(Box.createVerticalGlue());
078
079        sendButton.addActionListener(this::sendButtonActionPerformed);
080    }
081
082    /** 
083     * {@inheritDoc}
084     */
085    @Override
086    public String getHelpTarget() {
087        return "package.jmri.jmrix.marklin.swing.packetgen.PacketGenFrame";
088    }
089
090    /** 
091     * {@inheritDoc}
092     */
093    @Override
094    public String getTitle() {
095        return Bundle.getMessage("SendCommandTitle");
096    }
097
098    /** 
099     * {@inheritDoc}
100     */
101    @Override
102    public void initComponents(MarklinSystemConnectionMemo memo) {
103        super.initComponents(memo);
104        memo.getTrafficController().addMarklinListener(this);
105    }
106
107    public void sendButtonActionPerformed(java.awt.event.ActionEvent e) {
108        String text = packetTextField.getText();
109        // TODO check input + feedback on error. Too easy to cause NPE
110        if (text != null && !Objects.equals(text, "")) {
111            if (text.length() == 0) {
112                return; // no work
113            }
114            log.info("Entry[{}]", text);
115            if (text.startsWith("0x")) { //We want to send a hex message
116
117                text = text.replaceAll("\\s", "");
118                text = text.substring(2);
119                String[] arr = text.split(",");
120                byte[] msgArray = new byte[arr.length];
121                int pos = 0;
122                for (String s : arr) {
123                    msgArray[pos++] = (byte) (Integer.parseInt(s, 16) & 0xFF);
124                }
125
126                MarklinMessage m = new MarklinMessage(msgArray);
127                if ( memo != null ) {
128                    memo.getTrafficController().sendMarklinMessage(m, this);
129                }
130            } else {
131                log.error("Only hex commands are supported");
132                JmriJOptionPane.showMessageDialog(null, Bundle.getMessage("HexOnlyDialog"),
133                        Bundle.getMessage("WarningTitle"), JmriJOptionPane.ERROR_MESSAGE);
134            }
135        }
136    }
137
138    /** 
139     * {@inheritDoc}
140     * Ignore messages
141     */
142    @Override
143    public void message(MarklinMessage m) {
144    }
145
146    /** 
147     * {@inheritDoc}
148     */
149    @Override
150    public void reply(MarklinReply r) {
151        packetReplyField.setText(r.toString());
152    }
153    
154    @Override
155    public void dispose() {
156        if ( memo != null ) {
157            memo.getTrafficController().removeMarklinListener(this);
158        }
159        super.dispose();
160    }
161
162    private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(PacketGenPanel.class);
163}