获取和使用应用程序已通过InputStream

时间:2012-10-04 13:32:41

标签: java apache swing inputstream event-dispatch-thread

最近,我试图将普通终端的功能实现到图形设计的基于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工作得非常好,没有任何缺陷并且给了我所有的能力,但是输入的应用程序给我带来了很多麻烦。我认为这个问题存在于System.inScanner类,Console类等的硬编码中。所以这就是我需要一些帮助(最后): 我想要么能够直接访问传递给我的应用程序的InputStream,或者有人向我解释如何实际编写InputStreamListener,当我运行外部Java应用程序时偶尔会使用InputStream(是的) ,我通过我的界面而不是cmd或终端运行它们,我试图在这里制作一个工具)。如果这太复杂了,需要在我身边进行大量的调整,或者通常是不可能的,有人可以帮助我获得传递{{1}}所以我实际上可以写一个允许我编写特定应用程序的类我的界面?

提前致谢,非常感谢您花时间阅读整篇文章! :)

1 个答案:

答案 0 :(得分: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/)。