我找到了许多关于正确使用 EDT 的教程和示例,但是我想听听如何反过来:检查一个具有 Swing GUI 和许多涉及长网络操作的功能的复杂应用程序,并找到在哪里EDT 使用不当。
我发现了
SwingUtilities.isEventDispatchThread()
可用于检查一段代码是否在 EDT 内,因此我可以检查所有长操作是否恰好在 SwingUtilities.isEventDispatchThread() 返回 true 的地方。
是吗?有什么更好的方法可以调试整个应用程序以寻找对 EDT 的不正确使用? 谢谢。
最佳答案
Is it right?
是的,检查 SwingUtilities.isEventDispatchThread()
的值是一种查看您的代码是否在事件调度线程 (EDT) 上的方法。
另一种方法是显示或打印 Thread.currentThread().getName()
。 EDT 几乎总是具有名称“AWT-EventQueue-0”。
这段漂亮的代码来自文章Debugging Swing, the final summary .但是,它不是一个完整的 Swing 调试器。此代码仅检查重绘违规。
文中列举了其他比较完善的调试方法。
import javax.swing.JComponent;
import javax.swing.RepaintManager;
import javax.swing.SwingUtilities;
public class CheckThreadViolationRepaintManager extends RepaintManager {
// it is recommended to pass the complete check
private boolean completeCheck = true;
public boolean isCompleteCheck() {
return completeCheck;
}
public void setCompleteCheck(boolean completeCheck) {
this.completeCheck = completeCheck;
}
public synchronized void addInvalidComponent(JComponent component) {
checkThreadViolations(component);
super.addInvalidComponent(component);
}
public void addDirtyRegion(JComponent component, int x, int y, int w, int h) {
checkThreadViolations(component);
super.addDirtyRegion(component, x, y, w, h);
}
private void checkThreadViolations(JComponent c) {
if (!SwingUtilities.isEventDispatchThread()
&& (completeCheck || c.isShowing())) {
Exception exception = new Exception();
boolean repaint = false;
boolean fromSwing = false;
StackTraceElement[] stackTrace = exception.getStackTrace();
for (StackTraceElement st : stackTrace) {
if (repaint && st.getClassName().startsWith("javax.swing.")) {
fromSwing = true;
}
if ("repaint".equals(st.getMethodName())) {
repaint = true;
}
}
if (repaint && !fromSwing) {
// no problems here, since repaint() is thread safe
return;
}
exception.printStackTrace();
}
}
}
关于java - 如何检查 Swing 应用程序是否正确使用了 EDT(事件调度线程),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17760204/