且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何检查Swing应用程序是否正确使用EDT(事件DIspatch线程)

更新时间:2021-12-04 22:33:56


是不是?

Is it right?

是的,检查的值SwingUtilities.isEventDispatchThread()是查看代码是否打开的一种方法是否发送事件调度线程(EDT)。

Yes, checking the value of SwingUtilities.isEventDispatchThread() is one way to see if your code is on the Event Dispatch thread (EDT) or not.

另一种方法是显示或打印 Thread.currentThread()。getName()。 EDT几乎总是有名称AWT-EventQueue-0。

Another way would be to display or print Thread.currentThread().getName(). The EDT almost always has the name "AWT-EventQueue-0".

这段精彩的代码来自文章,调试Swing,最后的总结。但是,它不是一个完整的Swing调试器。此代码仅检查重绘违规。

This nifty piece of code comes from the article, Debugging Swing, the final summary. However, it's not a complete Swing debugger. This code only checks repaint violations.

本文列出了更完整的其他调试方法。

The article lists other debugging methods that are more complete.

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();
        }
    }
}