【问题标题】:Fix an unresponsive GUI due to JTextArea?修复由于 JTextArea 而导致的无响应 GUI?
【发布时间】:2012-06-05 02:02:40
【问题描述】:

我正在设计一个具有JEditorPane 的程序,用户可以在其中输入和编译Java 代码。然后他们可以在新进程中运行他们的程序,然后他们的输出将显示在JTextArea 中。我通过扩展JTextArea 并将其添加为成员来实现这一点:

private OutputStream writer = new OutputStream() {
    public void write(int b) {
        Console.this.append(String.valueOf((char) b));
    }
};

然后我有一个简单的getStream() 方法,它返回这个OutputStream 包装在PrintWriter 中,并使用PrintWriter 调用System.setOut()System.setErr()

现在问题来了:如果用户编译一个程序,其中大量输出一次发送到控制台(例如,System.out.println() 调用的无限循环),整个 GUI 挂起。我试图通过使用SwingWorker 处理append() 调用来解决此问题,但似乎没有任何效果。

即使大量文本被写入JTextArea,是否有办法保持 GUI 响应?我假设问题的一部分是在append() 调用之后更新 GUI 所花费的时间。有没有办法稍微延迟写入JTextArea,以便用户可以单击按钮终止进程?

【问题讨论】:

  • 我希望我是错的,但我不确定我们是否有足够的信息能够给你一个明确的正确答案。例如,我真的无法仅凭宽泛的描述猜测您的 GUI 为何挂起,除了您可能仍在踩 EDT。附加到 JTextArea 吗?然后你不想在后台线程中调用它。而是应该在 EDT 上。
  • 但这不会阻止我猜测! :)
  • 我在 EDT 上写作,至少根据 Eclipse 调试器。还有其他信息可以提供帮助吗?
  • 您似乎正在缓慢地在 EDT 上写入每个单独的字符,这是一个问题。我认为您需要使用 StringBuilder 来缓冲 EDT 的注销。
  • 如需尽快获得更好的帮助,请发帖SSCCE

标签: java swing user-interface jtextarea event-dispatching


【解决方案1】:

我想知道您的问题是否是您在 OutputStream 中的写入方式。也许您应该写入 EDT 的 StringBuilder 对象off,然后当出现“\n”时,将 EDT 上的字符串附加到 JTextArea。

类似这样的:

// this is all called in a background thread
public void write(int b) throws IOException {

  if (b == '\r')
     return;

  if (b == '\n') {
     final String text = sb.toString() + "\n";
     SwingUtilities.invokeLater(new Runnable() {
        // except this is queued onto the event thread.
        public void run() {
           textArea.append(text);
        }
     });
     sb.setLength(0);

     return;
  }

  sb.append((char) b);
}

【讨论】:

  • 这修复了 GUI 完全冻结的问题,但仍然存在明显的延迟。我认为我们走在正确的轨道上。
  • @euclio:为了获得更好的帮助,请考虑按照 Andrew 的建议创建一个 SSCCE。这意味着创建一个 small 可编译和可运行的程序来演示您的问题,我们可以在不需要外部依赖项(数据库、文件等)的情况下运行和测试自己。创建它需要您付出相当多的努力,但为了您和我们的利益,这都是值得的。请查看链接以了解有关这意味着什么的更多详细信息。
猜你喜欢
  • 2015-01-10
  • 1970-01-01
  • 2013-10-14
  • 2015-04-23
  • 1970-01-01
  • 1970-01-01
  • 2015-01-10
  • 2021-05-15
  • 1970-01-01
相关资源
最近更新 更多