web-dev-qa-db-ja.com

出力ストリームをTextAreaに設定する方法

プログラムのGUIパネルを作成しようとしていますが、通常はコマンドプロンプトに出力されるすべてのものを、TextAreaオブジェクトに出力したいと思います。ほとんどの部分でGUIパネルをフォーマットしていますが、テキストをTextAreaに印刷することはできませんが、ファイルは次のとおりです。

package guipanel;

import javax.swing.*;
import Java.awt.*;
import Java.io.*;


/**
 *
 * @author Dan
 */
public class GUIPanel extends JFrame { 
    public GUIPanel() {
        initComponents();
    }
    private void setOutputStream(boolean catchErrors) {
        System.setOut(aPrintStream); 
        setVisible(true);
        requestFocus();
        if (catchErrors) {
               System.setErr(aPrintStream);
        }
    }
    private void addTabs(JTabbedPane jTabbedPane1) {
        JPanel jPanel1 = new JPanel();
        JPanel jPanel2 = new JPanel();
        JPanel jPanel3 = new JPanel();
        JPanel jPanel4 = new JPanel();
        jTabbedPane1.add("Main", textArea1);
        jTabbedPane1.add("Commands", jPanel);
        jTabbedPane1.add("Rules", jPanel1);
        jTabbedPane1.add("Links", jPanel2);
        jTabbedPane1.add("Information", jPanel3);
        jTabbedPane1.add("Shutdown", jPanel4);
        setOutputStream(true);
    }
    @SuppressWarnings("unchecked")
    private void initComponents() {

        textArea1 = new Java.awt.TextArea();
        jTabbedPane1 = new javax.swing.JTabbedPane();
        jMenuBar1 = new javax.swing.JMenuBar();
        jMenu1 = new javax.swing.JMenu();
        jMenu2 = new javax.swing.JMenu();

        textArea1.setPreferredSize(new Java.awt.Dimension(432, 343));
        textArea1.getAccessibleContext().setAccessibleParent(jTabbedPane1);

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("Evolution-X 639");
        setBounds(new Java.awt.Rectangle(0, 0, 400, 450));
        setResizable(false);
        getContentPane().setLayout(new Java.awt.FlowLayout());

        addTabs(jTabbedPane1);
        getContentPane().add(jTabbedPane1);

        jMenu1.setText("File");
        jMenuBar1.add(jMenu1);

        jMenu2.setText("Edit");
        jMenuBar1.add(jMenu2);

        setJMenuBar(jMenuBar1);

        pack();
    }
    public static void main(String args[]) {
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            Java.util.logging.Logger.getLogger(GUIPanel.class.getName()).log(Java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            Java.util.logging.Logger.getLogger(GUIPanel.class.getName()).log(Java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            Java.util.logging.Logger.getLogger(GUIPanel.class.getName()).log(Java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            Java.util.logging.Logger.getLogger(GUIPanel.class.getName()).log(Java.util.logging.Level.SEVERE, null, ex);
        }
        Java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new GUIPanel().setVisible(true);
            }
        });
    }
    private JMenu jMenu1;
    private JMenu jMenu2;
    private JMenuBar jMenuBar1;
    private JTabbedPane jTabbedPane1;
    private TextArea textArea1;
    private JPanel jPanel = new JPanel();
    private PrintStream aPrintStream  =
       new PrintStream(
         new FilterOutputStream(
           new ByteArrayOutputStream()));
}
9
Dan

印刷ストリームを、制御可能な出力ストリームにリダイレクトする必要があります...

これは、私が仕事のために取り組んでいるアプリケーションのために開発した概念の例です。これを使用して、ユーザーサイトで実行されているときに出力コンソールを表示し、標準出力に送信されているものを確認できるようにします...ログを修正するまで;)

基本的に、カスタムOutputStreamを印刷ストリームとコンソールの間に配置して出力をキャプチャしますが、それでもコンテンツをコンソールに印刷できます。これは、コマンドラインまたはIDEからプログラムを実行している場合に役立ちます。必要に応じて、これを停止するスイッチを配置できます...

enter image description here

public class TestRedirect {

    public static void main(String[] args) {
        new TestRedirect();
    }

    public TestRedirect() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException ex) {
                } catch (InstantiationException ex) {
                } catch (IllegalAccessException ex) {
                } catch (UnsupportedLookAndFeelException ex) {
                }

                CapturePane capturePane = new CapturePane();
                JFrame frame = new JFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(capturePane);
                frame.setSize(200, 200);
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);

                PrintStream ps = System.out;
                System.setOut(new PrintStream(new StreamCapturer("STDOUT", capturePane, ps)));

                System.out.println("Hello, this is a test");
                System.out.println("Wave if you can see me");
            }            
        });
    }

    public class CapturePane extends JPanel implements Consumer {

        private JTextArea output;

        public CapturePane() {
            setLayout(new BorderLayout());
            output = new JTextArea();
            add(new JScrollPane(output));
        }

        @Override
        public void appendText(final String text) {
            if (EventQueue.isDispatchThread()) {
                output.append(text);
                output.setCaretPosition(output.getText().length());
            } else {

                EventQueue.invokeLater(new Runnable() {
                    @Override
                    public void run() {
                        appendText(text);
                    }
                });

            }
        }        
    }

    public interface Consumer {        
        public void appendText(String text);        
    }

    public class StreamCapturer extends OutputStream {

        private StringBuilder buffer;
        private String prefix;
        private Consumer consumer;
        private PrintStream old;

        public StreamCapturer(String prefix, Consumer consumer, PrintStream old) {
            this.prefix = prefix;
            buffer = new StringBuilder(128);
            buffer.append("[").append(prefix).append("] ");
            this.old = old;
            this.consumer = consumer;
        }

        @Override
        public void write(int b) throws IOException {
            char c = (char) b;
            String value = Character.toString(c);
            buffer.append(value);
            if (value.equals("\n")) {
                consumer.appendText(buffer.toString());
                buffer.delete(0, buffer.length());
                buffer.append("[").append(prefix).append("] ");
            }
            old.print(c);
        }        
    }    
}

enter image description hereenter image description here

実例で更新。 Windows 7、Java 6およびMacOS Lion Java 7

21
MadProgrammer

MadProgrammerのソリューションは本当に素晴らしいです、そして私は彼に基づいています。ただし、Loopkinが指摘しているように、特殊文字は処理しません(正確には、すべての非ASCII文字で失敗します)。

Loopkinのソリューションは私にはうまくいきませんでしたが、私はついにその仕事をする2つのソリューションを思いつきました。

解決策1:1バイト文字ごとに処理します(最大U + 00FF)

この単純なソリューションは、U + 00FFまでのすべての文字(すべての1バイト文字)を処理します。次のように定義されるwrite()を除いて、すべてがMadProgrammerと同じです。

_@Override
public void write(int b) throws IOException {
    buffer.append(Character.toChars((b + 256) % 256));
    if ((char) b == '\n') {
        textArea.append(str);
        textArea.setCaretPosition(textArea.getDocument().getLength());
        buffer.delete(0, buffer.length());
    }
    old.write(b);
}
_

私はそれを必要としなかったので、私は接頭辞のものを入れていません。

解決策2:標準出力のようにすべてのオブジェクトを処理します

結局、すべての文字を含めることにしたので、PrintStreamを直接拡張し、プレフィックス/インデントを元に戻しました。問題は、プライベートメソッドwrite(String s)をオーバーライドできなかったため、すべてのprint()メソッドをオーバーライドしたことです。

_public class PrintStreamCapturer extends PrintStream {

    private JTextArea text;
    private boolean atLineStart;
    private String indent;

    public PrintStreamCapturer(JTextArea textArea, PrintStream capturedStream, String indent) {
        super(capturedStream);
        this.text = textArea;
        this.indent = indent;
        this.atLineStart = true;
    }

    public PrintStreamCapturer(JTextArea textArea, PrintStream capturedStream) {
        this(textArea, capturedStream, "");
    }

    private void writeToTextArea(String str) {
        if (text != null) {
            synchronized (text) {
                text.setCaretPosition(text.getDocument().getLength());
                text.append(str);
            }
        }
    }

    private void write(String str) {
        String[] s = str.split("\n", -1);
        if (s.length == 0)
            return;
        for (int i = 0; i < s.length - 1; i++) {
            writeWithPotentialIndent(s[i]);
            writeWithPotentialIndent("\n");
            atLineStart = true;
        }
        String last = s[s.length - 1];
        if (!last.equals("")) {
            writeWithPotentialIndent(last);
        }
    }

    private void writeWithPotentialIndent(String s) {
        if (atLineStart) {
            writeToTextArea(indent + s);
            atLineStart = false;
        } else {
            writeToTextArea(s);
        }
    }

    private void newLine() {
        write("\n");
    }

    @Override
    public void print(boolean b) {
        synchronized (this) {
            super.print(b);
            write(String.valueOf(b));
        }
    }

    @Override
    public void print(char c) {
        synchronized (this) {
            super.print(c);
            write(String.valueOf(c));
        }
    }

    @Override
    public void print(char[] s) {
        synchronized (this) {
            super.print(s);
            write(String.valueOf(s));
        }
    }

    @Override
    public void print(double d) {
        synchronized (this) {
            super.print(d);
            write(String.valueOf(d));
        }
    }

    @Override
    public void print(float f) {
        synchronized (this) {
            super.print(f);
            write(String.valueOf(f));
        }
    }

    @Override
    public void print(int i) {
        synchronized (this) {
            super.print(i);
            write(String.valueOf(i));
        }
    }

    @Override
    public void print(long l) {
        synchronized (this) {
            super.print(l);
            write(String.valueOf(l));
        }
    }

    @Override
    public void print(Object o) {
        synchronized (this) {
            super.print(o);
            write(String.valueOf(o));
        }
    }

    @Override
    public void print(String s) {
        synchronized (this) {
            super.print(s);
            if (s == null) {
                write("null");
            } else {
                write(s);
            }
        }
    }

    @Override
    public void println() {
        synchronized (this) {
            newLine();
            super.println();
        }
    }

    @Override
    public void println(boolean x) {
        synchronized (this) {
            print(x);
            newLine();
            super.println();
        }
    }

    @Override
    public void println(char x) {
        synchronized (this) {
            print(x);
            newLine();
            super.println();
        }
    }

    @Override
    public void println(int x) {
        synchronized (this) {
            print(x);
            newLine();
            super.println();
        }
    }

    @Override
    public void println(long x) {
        synchronized (this) {
            print(x);
            newLine();
            super.println();
        }
    }

    @Override
    public void println(float x) {
        synchronized (this) {
            print(x);
            newLine();
            super.println();
        }
    }

    @Override
    public void println(double x) {
        synchronized (this) {
            print(x);
            newLine();
            super.println();
        }
    }

    @Override
    public void println(char x[]) {
        synchronized (this) {
            print(x);
            newLine();
            super.println();
        }
    }

    @Override
    public void println(String x) {
        synchronized (this) {
            print(x);
            newLine();
            super.println();
        }
    }

    @Override
    public void println(Object x) {
        String s = String.valueOf(x);
        synchronized (this) {
            print(s);
            newLine();
            super.println();
        }
    }
}
_

シンプルにするためにConsumerアスペクトを削除しましたが、実際に必要なものはすべてここにあります。このクラスの使用方法は次のとおりです。

_System.setOut(new PrintStreamCapturer(logTextArea, System.out));
System.setErr(new PrintStreamCapturer(logTextArea, System.err, "[ERROR] "));
_
5
Joffrey

MadProgrammerからの回答は気に入っていますが、UTF-8文字では機能しないと思います。

代わりに、StreamCapturerにByteArrayOutputStreamを拡張させ、これを書き込み実装として使用します。

    @Override
    public void write(int b){
        if ('\n' == (char) b) {
            consumer.appendText(toString());
            reset();
        }
        else {
            super.write(b);
        }
        old.write(b);
    }

実装ではプレフィックス部分が必要ないため、プレフィックス部分をスキップしています。コードをありがとう、それは大きな助けになりました!

3
loopkin

NOOBS用の元のMadProgrammerのコードを更新するだけです-JTextAreaパラメーターをコンストラクターに渡します。

new RedirectText(Main.window.textArea1);
0
Erikas