3

最近我试图将普通终端的功能实现到一个图形化设计的基于 Swing 的控制台项目。我喜欢这里的一些人如何使这成为可能,但我偶然发现了另一个大问题。InpuStreamListener虽然我不太喜欢这个,但有些人实际上谈到了这一点。我工作的示例代码(几乎不完全是我的,但它是我的应用程序的源代码)如下:

// Making an executor
org.apache.commons.exec.DefaultExecutor exec = new org.apache.commons.exec.DefaultExecutor();
// Creating the streams (pretty much ignore this, I just include it as a general idea of the method)
consoleOutputStream = new ConsoleOutputStream();
consoleInputStream = new JTextFieldInputStream(gsc.mainWindow.getConsoleInput().getJTextField());
// Stream Handler with the customized streams I use for the process
org.apache.commons.exec.PumpStreamHandler streamHandler = new org.apache.commons.exec.PumpStreamHandler(consoleOutputStream, consoleOutputStream, consoleInputStream);
// Setting the handler and finally making command line and executing
exec.setStreamHandler(streamHandler);
org.apache.commons.exec.CommandLine commandline = org.apache.commons.exec.CommandLine.parse(String.valueOf(arg));  
            exec.execute(commandline);

现在的事情是我通常尝试通过这种方法通过java命令运行java应用程序。OutputStream工作得很好,没有任何缺陷,并且给了我所有应该的东西,但是带有 Input 的应用程序给我带来了很多麻烦。我相信问题在于对System.inScanner类、Console类等的硬编码。所以这是我需要一些帮助的(最后):我希望能够直接访问InputStream传递给我的应用程序或有人向我解释方法如何真正写一个InputStreamListener当我运行外部java应用程序时偶尔会使用它(是的,我通过我的界面而不是cmd或终端运行它们,我正在尝试在这里制作一个工具)。如果这太复杂,需要我进行大量调整或者通常是不可能的,有人可以帮助我获得通过InputStream,这样我就可以真正编写一个类,允许我编写特定于我的界面的应用程序?

在此先感谢,甚至感谢您花时间阅读整篇文章!:)

4

1 回答 1

0

假设这些 Apache 库实现了InputStreamOutputStream接口,您可以使用PipedInputStreamPipedOutputStream来访问信息。这是一个简单的例子:

import java.awt.event.*;
import java.io.*;
import javax.swing.*;

public class InputRedirection extends Box{

    public InputRedirection() {
        super(BoxLayout.X_AXIS);

        //Remap input
        //Create the input stream to be used as standard in
        final PipedInputStream pisIN = new PipedInputStream();
        //Create an end so we can put info into standard in
        PipedOutputStream posIN = new PipedOutputStream();
        //Wrap with a writer (for ease of use)
        final BufferedWriter standardIn = new BufferedWriter(new OutputStreamWriter(posIN));
        //Set standard in to use this stream
        System.setIn(pisIN);

        //Connect the pipes
        try {
            pisIN.connect(posIN);
        } catch (IOException e2) {
            e2.printStackTrace();
        }        

        //UI element where we're entering standard in
        final JTextField field = new JTextField(20);
        ActionListener sendText = new ActionListener(){

            @Override
            public void actionPerformed(ActionEvent arg0) {
                try {
                    //Transfering the text to the Standard Input stream
                    standardIn.append(field.getText());
                    standardIn.flush();
                    field.setText("");
                    field.requestFocus();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }};

        field.addActionListener(sendText);
        add(field);

        //Why not - now it looks like a real messaging system
        JButton button = new JButton("Send");
        button.addActionListener(sendText);
        add(button);

        //Something using standard in
        //Prints everything from standard in to standard out.
        Thread standardInReader = new Thread(new Runnable(){

            @Override
            public void run() {
                boolean update = false;
                final StringBuffer s = new StringBuffer();
                while(true){
                    try {

                        BufferedInputStream stream = new BufferedInputStream(System.in);
                        while(stream.available() > 0){
                            int charCode = stream.read();
                            s.append(Character.toChars(charCode));
                            update = true;
                        }
                        if(update){
                            //Print whatever was retrieved from standard in to standard out.
                            System.out.println(s.toString());
                            s.delete(0, s.length());
                            update = false;
                        }

                    } catch (IOException e) {
                        e.printStackTrace();
                    } 
                }
            }});
        standardInReader.start();

    }

    public static void main(String[] args){
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(new InputRedirection());
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}

哦 - 使用 PipedStreams 时要考虑的一件事:只有一个线程可以写入输出,只有一个线程可以从输入中读取。否则你会遇到一些时髦的问题(有关更多详细信息,请参阅http://techtavern.wordpress.com/2008/07/16/whats-this-ioexception-write-end-dead/)。

于 2012-10-04T18:00:50.417 回答