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ライブラリがInputStreamおよびOutputStreamインターフェイスを実装していると仮定すると、およびを使用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を使用するときに考慮すべきことが1つあります。出力に書き込むことができるスレッドは1つだけで、入力から読み取ることができるのは1つだけです。そうしないと、ファンキーな問題が発生します(詳細については、 http://techtavern.wordpress.com/2008/07/16/whats-this-ioexception-write-end-dead/を参照してください)。

于 2012-10-04T18:00:50.417 に答える