在运行时SwingvalidationEvent Dispatch Thread上的代码

是否有任何库可以检测代码以validation在事件调度线程上调用Swing组件上调用的方法? 编写一些用于执行此操作的基本代码可能不会太困难,但我确信有其他人处理的边缘情况。 我在运行时寻找这个,而不是unit testing。

FEST框架有一个工具来检测EDT的Swing使用情况。 它基本上是您安装的RepaintManager。 该框架面向测试,但RepaintManager可以在部署时使用。

  • 请参阅FEST – Swing的事件调度线程

或者,要检查所有方法(例如getter和setter仅供EDT访问),可以使用AspectJ和加载时编织将SwingUtilities.isDisaptchThread()建议添加到swing组件(以及JDK Swing组件)上的每个方法。 )

@Aspect public class EDTCheck { @Pointcut("call (* javax.swing..*+.*(..)) || " + "call (javax.swing..*+.new(..))") public void swingMethods() {} @Pointcut("call (* com.mystuff.swing..*+.*(..)) || " + "call (com.mystuff.swing..*+.new(..))") public void mySwingMethods() {} @Pointcut("call (* javax.swing..*+.add*Listener(..)) || " + "call (* javax.swing..*+.remove*Listener(..)) || " + "call (void javax.swing.JComponent+.setText(java.lang.String))") public void safeMethods() {} @Before("(swingMethods() || mySwingMethods()) && !safeMethods()") public void checkCallingThread(JoinPoint.StaticPart thisJoinPointStatic) { if(!SwingUtilities.isDispatchThread()) { System.out.println( "Swing single thread rule violation: " + thisJoinPointStatic); Thread.dumpStack(); // or you might throw an unchecked exception } } } 

(稍微修改了文章 – 添加了mySwingMethods切入点,并使用SwingUtiliites.isDispatchThread()。实际上它与EventQueue.isDispatchThread()相同,但抽象更清晰。)

  • 请参阅使用AspectJ检测违反Swing单线程规则

我在http://today.java.net/pub/a/today/2005/04/19/desktoplive.html上看到了Scott Delap的一个简单而聪明的方法(尽管不完全是防弹)。

正如在上面的mdma的FEST答案中暗示的那样,可以使用自定义RepaintManger,只需覆盖这些方法即可

 addInvalidComponent(JComponent component) 

 addDirtyRegion(JComponent component, int x, int y, int w, int h) 

并使用

 SwingUtilities.isEventDispatchThread() 

要检查我们是否使用AWT,您可以通过添加a来相当容易地将其集成到JUnit中

 org.JUnit.Assert.fail("AWT Thread Violation") 

在你的检查程序中。

这里的逻辑是大多数(但不是全部)Swing操作会导致重绘,最终在RepaintManager中调用这些方法,因此我们可以捕获这些并进行检查。

Alexander Potochkin在这里有各种各样的方法: http ://weblogs.java.net/blog/alexfromsun/archive/2006/02/debugging_swing.html

从编码的角度来看,清楚地将EDT代码与非EDT代码分开。 像瘟疫一样避免使用SwingWorker

要声明您在EDT上(插入!关闭),请添加以下行:

 assert java.awt.EventQueue.isDispatchThread(); 

你需要-ea / -enableassertions这件事。 但是,它主要用作可执行注释。

您只需要以下代码:

 void method() { if (!SwingUtilities.isEventDispatchThread()) { SwingUtilities.invokeAndWait(new Runnable() { public void run() { method(); } ); return; } // do method code here, guaranteed to be in EDT } 

此外,使用Substance作为您的LAF将帮助您找出在EDT上没有执行Swing相关内容的地方。 它有适当的检查以确保任何Swing内容在正确的线程上完成,或者它因exception而失败。