001package jmri.jmrix.dcc4pc.swing.packetgen;
002
003import java.awt.Dimension;
004import javax.swing.BoxLayout;
005import javax.swing.JButton;
006import javax.swing.JCheckBox;
007import javax.swing.JLabel;
008import javax.swing.JTextField;
009
010import jmri.jmrix.dcc4pc.Dcc4PcMessage;
011import jmri.jmrix.dcc4pc.Dcc4PcSystemConnectionMemo;
012import jmri.jmrix.dcc4pc.Dcc4PcTrafficController;
013import jmri.jmrix.dcc4pc.swing.Dcc4PcPanelInterface;
014import org.slf4j.Logger;
015import org.slf4j.LoggerFactory;
016
017/**
018 * Frame for user input of Dcc4Pc messages
019 *
020 * @author Bob Jacobsen Copyright (C) 2001, 2008
021 * @author Dan Boudreau Copyright (C) 2007
022 * @author Kevin Dickerson Copyright (C) 2015
023 */
024public class PacketGenPanel extends jmri.jmrix.dcc4pc.swing.Dcc4PcPanel implements Dcc4PcPanelInterface {
025
026    // member declarations
027    JLabel jLabel1 = new JLabel();
028    JButton sendButton = new JButton();
029    JTextField packetTextField = new JTextField(20);
030    JCheckBox childBoardBox = new JCheckBox("Child Board");
031    public PacketGenPanel() {
032        super();
033    }
034
035    /**
036     * {@inheritDoc}
037     */
038    @Override
039    public void initComponents() {
040        setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
041        // the following code sets the frame's initial state
042        {
043            jLabel1.setText("Command: ");
044            jLabel1.setVisible(true);
045
046            sendButton.setText("Send");
047            sendButton.setVisible(true);
048            sendButton.setToolTipText("Send packet");
049
050            packetTextField.setText("");
051            packetTextField.setToolTipText("Enter command");
052            packetTextField.setMaximumSize(new Dimension(packetTextField
053                    .getMaximumSize().width, packetTextField.getPreferredSize().height));
054
055            childBoardBox.setSelected(false);
056                    
057            add(jLabel1);
058            add(packetTextField);
059            add(childBoardBox);
060            add(sendButton);
061
062            sendButton.addActionListener(this::sendButtonActionPerformed);
063        }
064    }
065
066    /**
067     * {@inheritDoc}
068     */
069    @Override
070    public String getHelpTarget() {
071        return "package.jmri.jmrix.dcc4pc.swing.packetgen.PacketGenFrame";
072    }
073
074    /**
075     * {@inheritDoc}
076     */
077    @Override
078    public String getTitle() {
079        return "Send DCC4PC command";
080    }
081
082    public void sendButtonActionPerformed(java.awt.event.ActionEvent e) {
083
084        String text = packetTextField.getText();
085        if (text.startsWith("0x")) {
086            hexStringToByteArray(text);
087            return;
088        }
089        setChildBoardAndSend(new Dcc4PcMessage(text));
090    }
091
092    private void setChildBoardAndSend(Dcc4PcMessage m){
093        m.setForChildBoard(childBoardBox.isSelected());
094        if ( memo == null ) {
095            log.error("no System Connection Memo Found when sending {}", m);
096            return;
097        }
098        Dcc4PcTrafficController tc = memo.getDcc4PcTrafficController();
099        if( tc != null){
100            tc.sendDcc4PcMessage(m, null);
101        } else {
102            log.error("no Traffic Controller for sys conn {} Found when sending {}", memo.getUserName(), m);
103        }
104    }
105
106    public void hexStringToByteArray(String s) {
107        s = s.substring(2);
108        int len = s.length();
109        byte[] data = new byte[len / 2];
110        int loc = 0;
111        Dcc4PcMessage m = new Dcc4PcMessage((len / 2));
112        for (int i = 0; i < data.length; i++) {
113            int val = (byte) ((Character.digit(s.charAt(loc), 16) << 4)
114                    + Character.digit(s.charAt(loc + 1), 16));
115            m.setElement(i, val);
116            loc = loc + 2;
117        }
118        setChildBoardAndSend(m);
119    }
120
121    private final static Logger log = LoggerFactory.getLogger(PacketGenPanel.class);
122    /**
123     * Nested class to create one of these using old-style defaults
124     */
125    static public class Default extends jmri.jmrix.dcc4pc.swing.Dcc4PcNamedPaneAction {
126
127        public Default() {
128            super("Dcc4PC Command Monitor",
129                    new jmri.util.swing.sdi.JmriJFrameInterface(),
130                    PacketGenPanel.class.getName(),
131                    jmri.InstanceManager.getDefault(Dcc4PcSystemConnectionMemo.class));
132        }
133    }
134
135}