其他JFrame中的JTextArea显示实时控制台输出

时间:2013-07-17 17:15:02

标签: java swing scheduled-tasks jtextarea swingutilities

我有一个“ConsoleFrame”,它应该将我的控制台输出实时显示给JTextArea。

我重定向了输出流:

private void redirectSystemStreams() {
    OutputStream out = new OutputStream() {
        @Override
        public void write(int b) throws IOException {
            updateTextArea(String.valueOf((char) b));
        }

        @Override
        public void write(byte[] b, int off, int len) throws IOException {
            updateTextArea(new String(b, off, len));
        }

        @Override
        public void write(byte[] b) throws IOException {
            write(b, 0, b.length);
        }
    };

    System.setOut(new PrintStream(out, true));
    System.setErr(new PrintStream(out, true));
}

并调用SwingUtilities.invokeAndWait方法追加新文本,正常工作

private void updateTextArea(final String text) {
    try {
        SwingUtilities.invokeAndWait(new Runnable() {
            @Override
            public void run() {
                txt_console.append(text);
            }
        });
    } catch (InterruptedException ex) {
    } catch (InvocationTargetException ex) {
    }
}

但它在我的新ConsoleFrame中显示了这个错误: java.lang.Error:无法从事件调度程序线程调用invokeAndWait 而且我因为EDT而得到了 - 但为什么它可以工作?如何调整我的代码以使其正常工作?

2 个答案:

答案 0 :(得分:2)

    必须从EDT中调出
  • invokeAndWait,否则会导致a.m.例外,

  • 小心地使用invokeAndWait,因为可以冻结整个Swing GUI,由RepaintManager的异常锁定(并非在所有情况下只创建GUI,重新启动,刷新一些方法),然后应用程序需要重启,

  • {li>

    需要invokeAndWait来测试if (EventQueue.isDispatchThread()) { / if (SwingUtilities.isEventDispatchThread()) {是否真实,setText("") / append(""}没有任何副作用,输出是在EDT上完成的,但是包含在invokeLater

    内的好实践
  • 使用SwingWorker,已实施方法processpublishsetProcessdone,所有提及的方法均已通知EDT by default

  • SwingWorker被指定只运行一次,重复(在某段时间内)使用Executor SwingWorkerRunnable#Thread最简单,明确没有任何副作用,影响

答案 1 :(得分:0)

您可以在任何线程中使用SwingUtilities.invokeLater(),对于错误流,即使您已经在EDT中,也最好使用它:

private void updateTextArea(final String text) {
    SwingUtilities.invokeLater(new Runnable() {
        @Override
        public void run() {
            txt_console.append(text);
        }
    });
}

您获得的特定错误来自EDT之外,然后可能会调用invokeAndWait(),因此您可以将输出输出到控制台。