我正在寻找一种自动方法来检测我的代码中违反Swing的单线程策略。我正在寻找一些类似AOP代码的内容,当你在swing应用程序运行时你将它放入虚拟机中并让它记录在EDT之外修改swing组件的任何地方。
我不是AOP人,但我想在每个java.swing。*类周围创建一个AOP代理,看起来像
AOP_before(Method m, Object args[]) {
if (!isEventDispatchThread(Thread.currentThread()) {
logStack(new RuntimeException("violation!"));
}
invoke(m, args);
}
有人知道这样做的项目或实用程序吗?
答案 0 :(得分:8)
我没有使用过这个特定的那个,但这个CheckThreadViolationRepaintManager应该可以解决这个问题。
它确实需要添加:
RepaintManager.setCurrentManager(new CheckThreadViolationRepaintManager());
到你的代码。
答案 1 :(得分:3)
我发现了一篇描述some solutions的4年博客帖子,但是如果你找到一个可以检测到最多EDT违规行为的帖子,我会非常感兴趣。在检测所有违规行为时,RepaintManager似乎不是防弹的。
答案 2 :(得分:3)
为了后人,这里是TofuBeer发现的CheckThreadViolationRepaintManager的简化版本。
RepaintManager.setCurrentManager(new RepaintManager() {
public synchronized void addInvalidComponent( JComponent component ) {
check( component );
super.addInvalidComponent( component );
}
public void addDirtyRegion( JComponent component, int x, int y, int w, int h ) {
check( component );
super.addDirtyRegion( component, x, y, w, h );
}
private void check( JComponent c ) {
if( !SwingUtilities.isEventDispatchThread() && c.isShowing() ) {
new Throwable("EDT required!").printStackTrace();
}
}
});
只需在main方法中调用它,只要在非EDT线程上更改组件,就会记录堆栈跟踪。