adams.gui.tools.TelnetPanel.java Source code

Java tutorial

Introduction

Here is the source code for adams.gui.tools.TelnetPanel.java

Source

/*
 *   This program is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

/**
 * TelnetPanel.java
 * Copyright (C) 2013-2015 University of Waikato, Hamilton, New Zealand
 * Copyright (C) Apache Software Foundation (original TelnetClientExample)
 */
package adams.gui.tools;

import adams.core.License;
import adams.core.annotation.MixedCopyright;
import adams.gui.core.BaseButton;
import adams.gui.core.BasePanel;
import adams.gui.core.BaseTextAreaWithButtons;
import adams.gui.core.BaseTextField;
import adams.gui.core.ConsolePanel;
import adams.gui.core.Fonts;
import adams.gui.core.GUIHelper;
import com.github.fracpete.jclipboardhelper.ClipboardHelper;
import org.apache.commons.net.telnet.EchoOptionHandler;
import org.apache.commons.net.telnet.SuppressGAOptionHandler;
import org.apache.commons.net.telnet.TelnetClient;
import org.apache.commons.net.telnet.TerminalTypeOptionHandler;

import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.SpinnerNumberModel;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

/**
 * A simple telnet interface. Mainly used for testing.
 * 
 * @author  fracpete (fracpete at waikato dot ac dot nz)
 * @author Bruno D'Avanzo (original TelnetClientExample)
 * @version $Revision$
 */
@MixedCopyright(copyright = "Apache Software Foundation", author = "Bruno D'Avanzo", license = License.APACHE2, url = "http://commons.apache.org/proper/commons-net/examples/telnet/TelnetClientExample.java", note = "Code adapted from TelnetClientExample")
public class TelnetPanel extends BasePanel {

    /** for serialization. */
    private static final long serialVersionUID = 6647177121906710884L;

    /** the remote server. */
    protected BaseTextField m_TextRemote;

    /** the model of the spinner. */
    protected SpinnerNumberModel m_PortModel;

    /** the port. */
    protected JSpinner m_SpinnerPort;

    /** for connecting/disconnecting. */
    protected BaseButton m_ButtonConnection;

    /** text area for the output. */
    protected BaseTextAreaWithButtons m_TextOutput;

    /** the button for clearing the output. */
    protected BaseButton m_ButtonClear;

    /** the button for copying the selected output. */
    protected BaseButton m_ButtonCopy;

    /** the text field for the command to issue. */
    protected BaseTextField m_TextCommand;

    /** the button for executing the command. */
    protected BaseButton m_ButtonCommand;

    /** the telnet client. */
    protected TelnetClient m_Client;

    /** the command history. */
    protected List<String> m_CommandHistory;

    /** the current command index. */
    protected int m_CommandIndex;

    @Override
    protected void initialize() {
        TerminalTypeOptionHandler ttopt;
        EchoOptionHandler echoopt;
        SuppressGAOptionHandler gaopt;

        super.initialize();

        m_Client = new TelnetClient();

        ttopt = new TerminalTypeOptionHandler("VT100", false, false, true, false);
        echoopt = new EchoOptionHandler(true, false, true, false);
        gaopt = new SuppressGAOptionHandler(true, true, true, true);

        try {
            m_Client.addOptionHandler(ttopt);
            m_Client.addOptionHandler(echoopt);
            m_Client.addOptionHandler(gaopt);
        } catch (Exception e) {
            System.err.println("Error registering telnet option handlers:");
            e.printStackTrace();
        }

        m_CommandIndex = 0;
        m_CommandHistory = new ArrayList<String>();
        m_CommandHistory.add(""); // empty command to clear command text field
    }

    /**
     * For initializing the GUI.
     */
    @Override
    protected void initGUI() {
        JPanel topPanel;
        JPanel bottomPanel;
        JLabel label;

        super.initGUI();

        setLayout(new BorderLayout());

        // connection
        topPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
        add(topPanel, BorderLayout.NORTH);

        m_TextRemote = new BaseTextField(20);
        label = new JLabel("Remote");
        label.setDisplayedMnemonic('R');
        label.setLabelFor(m_TextRemote);
        topPanel.add(label);
        topPanel.add(m_TextRemote);

        m_PortModel = new SpinnerNumberModel();
        m_PortModel.setMinimum(1);
        m_PortModel.setMaximum(65536);
        m_PortModel.setStepSize(1);
        m_PortModel.setValue(23);
        m_SpinnerPort = new JSpinner(m_PortModel);
        label = new JLabel("Port");
        label.setDisplayedMnemonic('P');
        label.setLabelFor(m_SpinnerPort);
        topPanel.add(label);
        topPanel.add(m_SpinnerPort);

        m_ButtonConnection = new BaseButton();
        m_ButtonConnection.setMnemonic('n');
        m_ButtonConnection.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                handleConnectionEvent();
            }
        });
        topPanel.add(m_ButtonConnection);

        // output
        m_ButtonClear = new BaseButton("Clear", GUIHelper.getIcon("new.gif"));
        m_ButtonClear.setMnemonic('l');
        m_ButtonClear.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                m_TextOutput.setText("");
            }
        });
        m_ButtonCopy = new BaseButton("Copy", GUIHelper.getIcon("copy.gif"));
        m_ButtonCopy.setMnemonic('C');
        m_ButtonCopy.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (m_TextOutput.getSelectedText().length() > 0)
                    ClipboardHelper.copyToClipboard(m_TextOutput.getSelectedText());
                else if (m_TextOutput.getText().length() > 0)
                    ClipboardHelper.copyToClipboard(m_TextOutput.getText());
            }
        });
        m_TextOutput = new BaseTextAreaWithButtons(10, 40);
        m_TextOutput.setTextFont(Fonts.getMonospacedFont());
        m_TextOutput.addToButtonsPanel(m_ButtonClear);
        m_TextOutput.addToButtonsPanel(m_ButtonCopy);
        add(m_TextOutput, BorderLayout.CENTER);

        // commands
        bottomPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
        add(bottomPanel, BorderLayout.SOUTH);

        m_TextCommand = new BaseTextField(40);
        m_TextCommand.setFont(Fonts.getMonospacedFont());
        m_TextCommand.addKeyListener(new KeyListener() {
            @Override
            public void keyTyped(KeyEvent e) {
            }

            @Override
            public void keyReleased(KeyEvent e) {
            }

            @Override
            public void keyPressed(KeyEvent e) {
                switch (e.getKeyCode()) {
                case KeyEvent.VK_ENTER:
                    e.consume();
                    execCommand();
                    break;
                case KeyEvent.VK_UP:
                    e.consume();
                    previousCommand();
                    break;
                case KeyEvent.VK_DOWN:
                    e.consume();
                    nextCommand();
                    break;
                }
            }
        });
        label = new JLabel("Command");
        label.setDisplayedMnemonic('m');
        label.setLabelFor(m_TextCommand);
        bottomPanel.add(label);
        bottomPanel.add(m_TextCommand);

        m_ButtonCommand = new BaseButton(GUIHelper.getIcon("run.gif"));
        m_ButtonCommand.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                execCommand();
            }
        });
        bottomPanel.add(m_ButtonCommand);
    }

    /**
     * Finalizes the initialization.
     */
    @Override
    protected void finishInit() {
        super.finishInit();

        updateButtons();
    }

    /**
     * Places the previous command in the command text field, if available.
     */
    protected void previousCommand() {
        if (m_CommandIndex > 0)
            m_CommandIndex--;
        else
            m_CommandIndex = m_CommandHistory.size() - 1;
        if (m_CommandIndex < 0)
            m_CommandIndex = 0;
        if (m_CommandIndex < m_CommandHistory.size())
            m_TextCommand.setText(m_CommandHistory.get(m_CommandIndex));
    }

    /**
     * Places the next command in the command text field, if available.
     */
    protected void nextCommand() {
        if (m_CommandIndex < m_CommandHistory.size() - 1)
            m_CommandIndex++;
        else
            m_CommandIndex = 0;
        if (m_CommandIndex >= m_CommandHistory.size())
            m_CommandIndex = 0;
        if (m_CommandIndex < m_CommandHistory.size())
            m_TextCommand.setText(m_CommandHistory.get(m_CommandIndex));
    }

    /**
     * Appends the msg to the output text area.
     * 
     * @param msg      the text to append
     */
    protected void append(String msg) {
        m_TextOutput.getComponent().append(msg + (msg.endsWith("\n") ? "" : "\n"));

    }

    /**
     * Checks whether we can connect to a server.
     * 
     * @return      true if we can connect
     */
    protected boolean canConnect() {
        return (m_TextRemote.getText().trim().length() > 0);
    }

    /**
     * Connects or disconnects the client.
     */
    protected void handleConnectionEvent() {
        String msg;
        Runnable run;

        msg = "??";
        try {
            if (m_Client.isConnected()) {
                msg = "disconnect";
                m_Client.disconnect();
                updateButtons();
            } else if (canConnect()) {
                msg = "connect";
                m_Client.connect(m_TextRemote.getText(), ((Number) m_PortModel.getValue()).intValue());
                updateButtons();

                run = new Runnable() {
                    public void run() {
                        InputStream instr = m_Client.getInputStream();
                        try {
                            byte[] buff = new byte[1024];
                            int ret_read = 0;
                            do {
                                ret_read = instr.read(buff);
                                if (ret_read > 0) {
                                    append(new String(buff, 0, ret_read));
                                    updateButtons();
                                }
                            } while (ret_read >= 0);
                        } catch (IOException e) {
                            ConsolePanel.getSingleton().append(this, "Exception while reading socket:", e);
                        }
                        updateButtons();
                    }
                };
                new Thread(run).start();
            }
        } catch (Exception e) {
            append("Failed to " + msg + ": " + e);
            ConsolePanel.getSingleton().append(this, "Failed to " + msg + ":", e);
        }
    }

    /**
     * Executes, if possible, the currently entered command.
     */
    protected void execCommand() {
        String cmd;

        updateButtons();

        cmd = m_TextCommand.getText();

        if (cmd.trim().length() == 0)
            return;
        if (!m_Client.isConnected())
            return;

        try {
            m_TextCommand.setText("");
            append(cmd);
            m_CommandHistory.add(cmd);
            m_Client.getOutputStream().write(new String(cmd + "\n").getBytes());
            m_Client.getOutputStream().flush();
            updateButtons();
        } catch (Exception e) {
            append("Failed to execute command " + cmd + ": " + e);
            ConsolePanel.getSingleton().append(this, "Failed to execute command " + cmd + ": ", e);
        }
    }

    /**
     * Updates the status/text of the buttons.
     */
    protected void updateButtons() {
        if (m_Client.isConnected())
            m_ButtonConnection.setText("Disconnect");
        else
            m_ButtonConnection.setText("Connect");
    }

    /**
     * Sets the remote server.
     * 
     * @param value   the server
     */
    public void setRemote(String value) {
        m_TextRemote.setText(value);
    }

    /**
     * Returns the current remote server.
     * 
     * @return      the server
     */
    public String getRemote() {
        return m_TextRemote.getText();
    }

    /**
     * Sets the port to use.
     * 
     * @param value   the port
     */
    public void setPort(int value) {
        if ((value > 0) && (value <= 65536))
            m_PortModel.setValue(value);
        else
            System.err.println("Invalid port number: " + value);
    }

    /**
     * Returns the currently set port.
     * 
     * @return      the port
     */
    public int getPort() {
        return ((Number) m_PortModel.getValue()).intValue();
    }
}