java - 使用 Jsch 将 java textarea 作为输入流以交互模式运行 shell 命令

标签 java swing applet awt jsch

嗨,我正在使用 Jsch 来运行我的 shell 命令。我想让它具有交互性。我正在使用 java textarea 来显示脚本的输出。该脚本还需要一些用户输入。 我怎样才能让这个文本区域接受用户输入并运行命令

public void init(){
try{
  JSch jsch=new JSch();

  Panel panel = new Panel();
  TextArea log = new TextArea();
  panel.add(log);
  add(panel);
  PrintStream printStream = new PrintStream(new CustomOutputStream(log));
  System.setOut(printStream);
  System.setErr(printStream);

  Session session=jsch.getSession("akumar", "banas", 22);
  String passwd = "*****";
  Properties config = new Properties(); 
  config.put("StrictHostKeyChecking", "no");
  session.setConfig(config);
  session.setPassword(passwd);
  session.connect(30000);   // making a connection with timeout.

  Channel channel=session.openChannel("shell");
  channel.setInputStream(System.in);
  channel.setOutputStream(System.out);
  channel.connect(3*1000);

  printStream.println("sftp akumar@banas");

  printStream.flush();

}
catch(Exception e){
  System.out.println(e);
}
  }

// This is the code for making textarea as output stream

 public class CustomOutputStream extends OutputStream {
    private TextArea textArea;

    public CustomOutputStream(TextArea textArea) {
        this.textArea = textArea;
    }

    @Override
    public void write(int b) throws IOException {
        // redirects data to the text area
        textArea.append(String.valueOf((char)b));
        // scrolls the text area to the end of data
        textArea.setCaretPosition(textArea.getText().length());
    }
}

最佳答案

这是一种使用 BlockingQueue 将数据从 JTextField 的 actionListener 传递到 CustomInputStream 的方法。

public class Main extends JFrame {

    public Main() {
        init();
    }

    public void init() {
        try {
            JSch jsch = new JSch();

            JPanel panel = new JPanel();
            panel.setPreferredSize(new Dimension(200, 200));
            JTextArea log = new JTextArea();
            JTextField cmd = new JTextField();
            panel.setLayout(new BorderLayout());
            JScrollPane scrollPane = new JScrollPane(log);
            panel.add(scrollPane, BorderLayout.CENTER);
            panel.add(cmd, BorderLayout.SOUTH);
            add(panel);

            Session session = jsch.getSession("akumar", "banas", 22);
            String passwd = "******";
            Properties config = new Properties();
            config.put("StrictHostKeyChecking", "no");
            session.setConfig(config);
            session.setPassword(passwd);
            session.connect(30000);   // making a connection with timeout.

            Channel channel = session.openChannel("shell");
            channel.setInputStream(new CustomInputStream(cmd));
            channel.setOutputStream(new CustomOutputStream(log));
            channel.connect(3 * 1000);
            pack();

        } catch (Exception e) {
            System.out.println(e);
        }
    }

    public class CustomInputStream extends InputStream implements ActionListener {

        final JTextField field;
        final BlockingQueue<String> q;

        public CustomInputStream(JTextField field) {
            this.field = field;
            q = new LinkedBlockingQueue<>();
            field.addActionListener(this);
        }

        private String s;
        int pos;

        @Override
        public int read() throws IOException {
            while (null == s || s.length() <= pos) {
                try {
                    s = q.take();
                    pos = 0;
                } catch (InterruptedException ex) {
                    Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
            int ret = (int) s.charAt(pos);
            pos++;
            return ret;
        }

        @Override
        public boolean markSupported() {
            return false;
        }

        @Override
        public int read(byte[] b, int off, int len) throws IOException {
            int bytes_copied = 0;
            while (bytes_copied < 1) {
                while (null == s || s.length() <= pos) {
                    try {
                        s = q.take();
                        System.out.println("s = " + s);
                        pos = 0;
                    } catch (InterruptedException ex) {
                        Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
                int bytes_to_copy = len < s.length()-pos ? len : s.length()-pos;
                System.arraycopy(s.getBytes(), pos, b, off, bytes_to_copy);
                pos += bytes_to_copy;
                bytes_copied += bytes_to_copy;
            }
            return bytes_copied;
        }

        @Override
        public int read(byte[] b) throws IOException {
            return read(b, 0, b.length); //To change body of generated methods, choose Tools | Templates.
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            q.add(field.getText() + "\r\n");
            field.setText("");
        }

    }

// This is the code for making textarea as output stream
    public class CustomOutputStream extends OutputStream {

        private JTextArea textArea;

        public CustomOutputStream(JTextArea textArea) {
            this.textArea = textArea;
        }

        @Override
        public void write(int b) throws IOException {
            // redirects data to the text area
            textArea.append(String.valueOf((char) b));
            // scrolls the text area to the end of data
            textArea.setCaretPosition(textArea.getText().length());
        }

        @Override
        public void write(byte[] b, int off, int len) throws IOException {
            String s = new String(b,off,len);
            textArea.append(s);
            textArea.setCaretPosition(textArea.getText().length());
        }

        @Override
        public void write(byte[] b) throws IOException {
            this.write(b, 0, b.length);
        }
    }

    public static void main(String[] args) {
        java.awt.EventQueue.invokeLater(() -> {
            new Main().setVisible(true);
        });
    }
}

关于java - 使用 Jsch 将 java textarea 作为输入流以交互模式运行 shell 命令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33067009/

相关文章:

java - JFrame 标题重绘

java - 从文本字段矩阵获取文本

java - 小程序中的值意外更改

java - 如何实现 BFS(而不是我的解决方案,使用树结构)

java - 将 pdf 与 itext 结合 - 横向页面呈现为纵向

java - 创建一个完全透明的JFrame

java - 使用 javascript 检查小程序在 chrome 中是否处于 Activity 状态

java - 如何让小程序将图像传输到 Web 服务器

java - 如何使用 Java Sound 缓冲和播放 OGG 文件中的声音数据

java - 从托管 bean 事件 JSF 重定向