java - 如何检查 Swing 应用程序是否正确使用了 EDT(事件调度线程)

标签 java swing user-interface thread-safety event-dispatch-thread

我找到了许多关于正确使用 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/

相关文章:

ios - 这个应用程序使用什么类型的 View Controller ?

Java - SwingWorker - 问题

cocoa - 10.8 标准共享图标 - 从哪里获得?

java - 这个子类如何隐式调用其父类的构造函数?

java - 如何为抽象类创建 Junit 测试?

java - Scala/Gradle 的 build.gradle 中包含什么

java - 修改 JPopupMenu/JMenuItem 外观

java - 使用哪个 Swing 组件?

java - 监控Web应用程序

java - 在一个 jcombobox 中进行选择启用不同的 jcombobox