如何检查Swing应用程序是否正确使用EDT(事件DIspatch线程) [英] How to check a Swing application for correct use of the EDT (Event DIspatch Thread)

查看:123
本文介绍了如何检查Swing应用程序是否正确使用EDT(事件DIspatch线程)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经找到了许多关于正确使用EDT的教程和示例,但是我想听听应该如何反过来:检查一个复杂的应用程序,它具有Swing GUI和许多涉及长网络操作的功能并找到哪里EDT使用不当。

I have found many tutorials and examples on using the EDT correctly, I would however like to hear how one should go the other way around: check a complex application which has a Swing GUI and many functionalities involving long network operations and find where the EDT is improperly used.

我发现

SwingUtilities.isEventDispatchThread()

可用于检查一段代码是否在EDT内部,所以我可以检查所有长操作都不会发生在SwingUtilities.isEventDispatchThread()返回true的地方。

could be used to check whether one piece of code is inside the EDT or not, so I could check that all long operations don't happen to be inside places where SwingUtilities.isEventDispatchThread() returns true.

是不是?我是否有更好的方法来调试整个应用程序,以寻找不正确的EDT使用?
谢谢。

Is it right? is there something better I could to in a way debug the whole application in search of incorrect use of the EDT? Thank you.

推荐答案


是不是?

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

这篇关于如何检查Swing应用程序是否正确使用EDT(事件DIspatch线程)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆