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    private final JLabel entryLabel = new JLabel();
031    private final JLabel replyLabel = new JLabel();
032    private final JButton sendButton = new JButton();
033    private final JTextField packetTextField = new JTextField(20);
034    private final 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        entryLabel.setLabelFor(packetTextField);
052
053        replyLabel.setText(Bundle.getMessage("ReplyLabel"));
054        replyLabel.setVisible(true);
055        replyLabel.setLabelFor(packetReplyField);
056
057        sendButton.setText(Bundle.getMessage("ButtonSend"));
058        sendButton.setVisible(true);
059        sendButton.setToolTipText(Bundle.getMessage("SendToolTip"));
060
061        packetTextField.setText("");
062        packetTextField.setToolTipText(Bundle.getMessage("EnterHexToolTip"));
063        packetTextField.setMaximumSize(new Dimension(packetTextField
064                .getMaximumSize().width, packetTextField.getPreferredSize().height));
065
066        entrybox.setLayout(new GridLayout(2, 2));
067        entrybox.add(entryLabel);
068        entrybox.add(packetTextField);
069        entrybox.add(replyLabel);
070
071        JPanel buttonbox = new JPanel();
072        FlowLayout buttonLayout = new FlowLayout(FlowLayout.TRAILING);
073        buttonbox.setLayout(buttonLayout);
074        buttonbox.add(sendButton);
075        entrybox.add(buttonbox);
076        //packetReplyField.setEditable(false); // keep field editable to allow user to select and copy the reply
077        add(entrybox);
078        add(packetReplyField);
079        add(Box.createVerticalGlue());
080
081        sendButton.addActionListener(this::sendButtonActionPerformed);
082    }
083
084    /** 
085     * {@inheritDoc}
086     */
087    @Override
088    public String getHelpTarget() {
089        return "package.jmri.jmrix.marklin.swing.packetgen.PacketGenFrame";
090    }
091
092    /** 
093     * {@inheritDoc}
094     */
095    @Override
096    public String getTitle() {
097        return Bundle.getMessage("SendCommandTitle");
098    }
099
100    /** 
101     * {@inheritDoc}
102     */
103    @Override
104    public void initComponents(MarklinSystemConnectionMemo memo) {
105        super.initComponents(memo);
106        memo.getTrafficController().addMarklinListener(this);
107    }
108
109    public void sendButtonActionPerformed(java.awt.event.ActionEvent e) {
110        String text = packetTextField.getText();
111        // TODO check input + feedback on error. Too easy to cause NPE
112        if (text != null && !Objects.equals(text, "")) {
113            if (text.length() == 0) {
114                return; // no work
115            }
116            log.info("Entry[{}]", text);
117            if (text.startsWith("0x")) { //We want to send a hex message
118
119                text = text.replaceAll("\\s", "");
120                text = text.substring(2);
121                String[] arr = text.split(",");
122                byte[] msgArray = new byte[arr.length];
123                int pos = 0;
124                for (String s : arr) {
125                    msgArray[pos++] = (byte) (Integer.parseInt(s, 16) & 0xFF);
126                }
127
128                MarklinMessage m = new MarklinMessage(msgArray);
129                if ( memo != null ) {
130                    memo.getTrafficController().sendMarklinMessage(m, this);
131                }
132            } else {
133                log.error("Only hex commands are supported");
134                JmriJOptionPane.showMessageDialog(this, Bundle.getMessage("HexOnlyDialog"),
135                        Bundle.getMessage("WarningTitle"), JmriJOptionPane.ERROR_MESSAGE);
136            }
137        }
138    }
139
140    /** 
141     * {@inheritDoc}
142     * Ignore messages
143     */
144    @Override
145    public void message(MarklinMessage m) {
146    }
147
148    /** 
149     * {@inheritDoc}
150     */
151    @Override
152    public void reply(MarklinReply r) {
153        packetReplyField.setText(r.toString());
154    }
155    
156    @Override
157    public void dispose() {
158        if ( memo != null ) {
159            memo.getTrafficController().removeMarklinListener(this);
160        }
161        super.dispose();
162    }
163
164    private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(PacketGenPanel.class);
165}