den*_*ini 5 java user-interface swing thread-safety event-dispatch-thread
我已经找到了许多关于正确使用EDT的教程和示例,但是我想听听应该如何反过来:检查一个复杂的应用程序,它具有Swing GUI和许多涉及长网络操作的功能,并找到EDT所在的位置使用不当.
我发现了
SwingUtilities.isEventDispatchThread()
Run Code Online (Sandbox Code Playgroud)
可以用来检查一段代码是否在EDT中,所以我可以检查所有长操作都不会发生在SwingUtilities.isEventDispatchThread()返回true的地方.
这样对吗?是否有更好的方法可以调试整个应用程序以寻找错误使用EDT?谢谢.
这样对吗?
是的,检查值SwingUtilities.isEventDispatchThread()是查看代码是否在事件调度线程(EDT)上的一种方法.
另一种方式是显示或打印Thread.currentThread().getName().EDT几乎总是名为"AWT-EventQueue-0".
这段漂亮的代码来自文章Debugging Swing,最后的摘要.但是,它不是一个完整的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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1827 次 |
| 最近记录: |