我有一个“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而得到了 - 但为什么它可以工作?如何调整我的代码以使其正常工作?
答案 0 :(得分:2)
invokeAndWait
,否则会导致a.m.例外,
小心地使用invokeAndWait
,因为可以冻结整个Swing GUI,由RepaintManager
的异常锁定(并非在所有情况下只创建GUI,重新启动,刷新一些方法),然后应用程序需要重启,
需要invokeAndWait
来测试if (EventQueue.isDispatchThread()) {
/ if (SwingUtilities.isEventDispatchThread()) {
是否真实,setText("")
/ append(""
}没有任何副作用,输出是在EDT上完成的,但是包含在invokeLater
使用SwingWorker
,已实施方法process
,publish
,setProcess
和done
,所有提及的方法均已通知EDT by default
,
SwingWorker
被指定只运行一次,重复(在某段时间内)使用Executor
SwingWorker
或Runnable#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()
,因此您可以将输出输出到控制台。