Java 修复由于JTextArea导致的无响应GUI?

Java 修复由于JTextArea导致的无响应GUI?,java,swing,user-interface,jtextarea,event-dispatching,Java,Swing,User Interface,Jtextarea,Event Dispatching,我正在设计一个程序,它有一个JEditorPane,用户可以在其中输入和编译Java代码。然后,他们可以在新进程中运行程序,然后他们的输出将显示在JTextArea中。我通过扩展JTextArea并将其添加为成员来实现这一点: private OutputStream writer = new OutputStream() { public void write(int b) { Console.this.append(String.valueOf((char) b));

我正在设计一个程序,它有一个
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
,以便用户可以单击按钮终止该过程?

我想知道您在输出流中的写入方式是否存在问题。也许您应该在EDT之外写入StringBuilder对象,然后当出现“\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);
}

我想知道你的问题是否在于你在输出流中的书写方式。也许您应该在EDT之外写入StringBuilder对象,然后当出现“\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挂起,而你可能仍然在使用EDT。追加是否附加到JTextArea?那么你不想在后台线程中调用它。相反,这应该在美国东部夏令时上。但这不会阻止我猜测!:)至少根据Eclipse调试器,我正在EDT上写作。还有其他信息可以帮助你吗?你似乎在EDT上写每个字符都很慢,这是一个问题。我认为您需要使用StringBuilder来缓冲您对EDT的注销。为了更快地获得更好的帮助,请发布一篇文章。我希望我是错的,但我不确定我们是否有足够的信息来为您提供明确的正确答案。例如,我真的不能仅仅基于广泛的描述猜测为什么你的GUI挂起,而你可能仍然在使用EDT。追加是否附加到JTextArea?那么你不想在后台线程中调用它。相反,这应该在美国东部夏令时上。但这不会阻止我猜测!:)至少根据Eclipse调试器,我正在EDT上写作。还有其他信息可以帮助你吗?你似乎在EDT上写每个字符都很慢,这是一个问题。我认为您需要使用StringBuilder来缓冲您对EDT的注销。为了更快地获得更好的帮助,请发布一个。这将修复GUI完全冻结的问题,但仍然存在明显的延迟。我认为我们在正确的轨道上。欧几里奥:为了更好的帮助,考虑一下创造一个安得烈建议。这意味着创建一个小的可编译和可运行程序来演示您的问题,我们可以自己运行和测试,而不需要外部依赖项(数据库、文件等)。这需要你付出相当多的努力才能创造出来,但无论是为了你还是为了我们,这都是值得的。请查看该链接以了解更多关于这需要做什么的详细信息。这修复了GUI完全冻结的问题,但仍然存在明显的延迟。我认为我们在正确的轨道上。欧几里奥:为了更好的帮助,考虑一下创造一个安得烈建议。这意味着创建一个小的可编译和可运行程序来演示您的问题,我们可以自己运行和测试,而不需要外部依赖项(数据库、文件等)。这需要你付出相当多的努力才能创造出来,但无论是为了你还是为了我们,这都是值得的。请查看链接,了解更多关于这需要什么的详细信息。