我有一个“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: Cannot call invokeAndWait from the event dispatcher thread
我是因为 EDT 而明白这一点的——但是为什么它可以工作,我该如何调整我的代码以使其正常工作?
最佳答案
invokeAndWait
必须在EDT外调用,否则引起a.m.异常,invokeAndWait
小心,因为可以卡住整个 Swing GUI,被 RepaintManager
的异常锁定(并非在所有情况下都只创建 GUI,重新布局,刷新一些方法),然后应用程序需要重新启动,invokeAndWait
需要在 true 上测试 if (EventQueue.isDispatchThread()) {
/if (SwingUtilities.isEventDispatchThread()) {
,你可以到 setText("")
/append(""
) 没有任何副作用,输出是在 EDT 上完成的,但关于在 invokeLater
SwingWorker
,有实现方法 process
, publish
, setProcess
和 done
,所有提到的方法都通知 EDT by default
, SwingWorker
被指定只运行一次,重复(在某个时期)使用 Executor
作为 SwingWorker
或 Runnable#Thread
作为最简单、清晰且没有任何副作用,影响 关于java - 其他 JFrame 中的 JTextArea 显示实时控制台输出,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/17706140/