为了账号安全,请及时绑定邮箱和手机立即绑定

如何将输出流设置为TextArea

如何将输出流设置为TextArea

白衣染霜花 2019-08-05 15:52:54
如何将输出流设置为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();     }
查看完整描述

3 回答

?
饮歌长啸

TA贡献1951条经验 获得超3个赞

您需要将打印流重定向到您可以控制的输出流...

这是我为正在努力工作的应用程序开发的概念示例。当我们在用户站点运行时,我们使用它来调出输出控制台,这样我们就可以看到发送到标准输出的内容......直到我们修复了我们的日志记录;)

基本上它OutputStream在打印流和控制台之间放置一个自定义来捕获输出,但仍允许将内容打印到控制台。如果您从命令行或IDE运行该程序,这将非常有用。如果你想要的话,你可以设置一个开关来阻止它......

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);
        }        
    }    }

更新了工作示例。在Windows 7,Java 6和Mac OS Lion Java 7上进行测试


查看完整回答
反对 回复 2019-08-05
?
拉风的咖菲猫

TA贡献1995条经验 获得超2个赞

MadProgrammer的解决方案非常棒,我的基础是他的。但是,正如Loopkin所指出的,它不处理特殊字符(准确地说,它在每个非ASCII字符上都失败)。

Loopkin的解决方案对我不起作用,但我最终提出了两个完成这项工作的解决方案。

解决方案1:处理每1个字节的字符(最多U + 00FF)

这个简单的解决方案可以处理U + 00FF(每个1字节字符)的每个字符。一切都与MadProgrammer相同,除了write()定义为:

@Overridepublic 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] "));


查看完整回答
反对 回复 2019-08-05
  • 3 回答
  • 0 关注
  • 886 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信