【发布时间】:2015-04-29 23:34:20
【问题描述】:
在 Swing 中调试一个奇怪的行为时,我发现了这个工具: CheckThreadViolationRepaintManager 由 Alex Ruiz 编辑的版本。 (在回答我的问题之前,您必须了解该课程的作用,谢谢)
我在我的代码中发现了线程冲突,但我不明白为什么,因为我到处都使用 SwingUtilities.invokeAndWait()。
这是导致线程冲突的代码。只有最后一行导致错误:
protected void display() {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
asyncDisplay();
}
});
}
private void asyncDisplay(){
System.out.println("is in edt: " + SwingUtilities.isEventDispatchThread());
this.printedComponent.setVisible(true);
this.printedComponent.setOpaque(false);
this.setVisible(true);
}
结果:
is in edt: true
exception: java.lang.Exception
java.lang.Exception
at fr.numvision.common.CheckThreadViolationRepaintManager.checkThreadViolations(CheckThreadViolationRepaintManager.java:31)
at fr.numvision.common.CheckThreadViolationRepaintManager.addDirtyRegion(CheckThreadViolationRepaintManager.java:25)
at javax.swing.JComponent.repaint(JComponent.java:4795)
at java.awt.Component.imageUpdate(Component.java:3516)
at javax.swing.JLabel.imageUpdate(JLabel.java:900)
at sun.awt.image.ImageWatched$WeakLink.newInfo(ImageWatched.java:132)
at sun.awt.image.ImageWatched.newInfo(ImageWatched.java:170)
at sun.awt.image.ImageRepresentation.setPixels(ImageRepresentation.java:533)
at sun.awt.image.ImageDecoder.setPixels(ImageDecoder.java:126)
at sun.awt.image.GifImageDecoder.sendPixels(GifImageDecoder.java:447)
at sun.awt.image.GifImageDecoder.parseImage(Native Method)
at sun.awt.image.GifImageDecoder.readImage(GifImageDecoder.java:596)
at sun.awt.image.GifImageDecoder.produceImage(GifImageDecoder.java:212)
at sun.awt.image.InputStreamImageSource.doFetch(InputStreamImageSource.java:269)
at sun.awt.image.ImageFetcher.fetchloop(ImageFetcher.java:205)
at sun.awt.image.ImageFetcher.run(ImageFetcher.java:169)
我真的不明白为什么 this.setVisible(true); 会导致线程冲突(这是一个 JComponent)而 this.printedComponent.setVisible(true); 不会。
谢谢,
【问题讨论】:
-
如果调用
setVisible的线程不是 EDT,则会导致违规。最后一行可能导致它的原因,因为它可能是将组件连接到本机对等点并启动重绘过程滚动的方法,但这都是猜测工作,需要一个可运行的示例来确定 -
@MadProgrammer 请阅读 OPs 问题和我的 cmets 由 Marko Topolnik 回答
-
你有
CheckThreadViolationRepaintManager类以及它是如何安装的? -
考虑提供一个runnable example 来证明您的问题。这将导致更少的混乱和更好的响应。另外,请记住,对
repaint的调用不必在 EDT 的上下文中进行。因为将 post 的绘制事件重新绘制到事件队列中,所以实际的绘制操作将在 EDT 内发生... -
你在任何地方使用
ImageIcon吗?
标签: java swing event-dispatch-thread invokeandwait repaintmanager