为什么会发生 EDT 违规?
我开始使用 CheckThreadViolationRepaintManager
来检测 EDT 违规。
它抱怨:
partner = getParameter("partner",generatePartnerSelectionPanel(),Design.partnerSelectionDuration);
因为它不喜欢 generatePartnerSelectionPanel()
,因为它不喜欢此方法中的 JPanel panel = new JPanel();
。但我不明白为什么会有问题。
更详细地说,generatePartnerSelectionPanel()
生成一个 JPanel(我不在 EDT 中执行此操作),但随后在 getParameter
中,我将 JPanel 添加到主 JFrame 中,然后我执行它位于 EDT 中(使用 invokeLater
)。
那么,为什么会有问题呢?
I started to use CheckThreadViolationRepaintManager
to detect EDT violations.
It complains about:
partner = getParameter("partner",generatePartnerSelectionPanel(),Design.partnerSelectionDuration);
Because it does not like generatePartnerSelectionPanel()
because it does not like JPanel panel = new JPanel();
in this method. But I cannot find out why there should be a problem around that.
In more details, generatePartnerSelectionPanel()
generates a JPanel (I do it not in the EDT) but then, in the getParameter
I add the JPanel to the main JFrame and I do it in the EDT (using invokeLater
).
So, why there should be a problem?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
EDT 违规并不意味着一定确实出了问题,它意味着您尝试在 EDT 之外的线程上执行与 GUI 相关的操作(在这种情况下可能出错)。
创建新的 Swing 组件包含在“做一些与 GUI 相关的事情”中,因此会发出有关违规的警告。
这 论坛对为什么不建议在其他线程上创建 Swing 组件进行了相当多的讨论。
An EDT violation doesn't mean something necessarily did go wrong, it means you tried to do a GUI related action on a thread other than the EDT (a situation where something might go wrong).
Creating a new Swing component is covered by "doing something GUI related", hence the warning about the violation.
This forum has quite a discussion on why it's not recommended to create Swing components on other threads.
通常,如果您在 main 中交给您的线程中创建任何 GUI 组件,就会发生这种情况。
现在,实际上,只要您在意识到它之后不对其进行修改,就不会发生任何不好的事情(
setVisible(true)
或pack()
将实现框架),但是 Sun 发现了一些他们声称可以实现的边缘情况,因此这可能会导致问题。因此,为了完全正确,您的主窗口应在内部构造一个
invokeLater
或invokeAndWait
。实际上,我想知道在
invokeLater
之后退出主线程是否可能允许您的整个应用程序退出(因为窗口几乎肯定还没有时间出现)...您可能想要使用invokeAndWait
除非你的主线程不退出。Usually this will happen if you create any GUI components in the thread handed to you in main.
Now, in reality nothing bad will ever happen as long as you don't modify it after you've realized it (
setVisible(true)
orpack()
will realize a frame), BUT Sun found some edge case that they claim make it so this can cause a problem.So to be perfectly correct have your main construct your first window inside an
invokeLater
orinvokeAndWait
.Actually, I wonder if exiting your main thread right after the
invokeLater
might allow your entire app to exit (since the window almost certainly hasn't had time to come up yet)... You might want to useinvokeAndWait
unless your main thread doesn't exit.Swing 是线程敌对的。即使组件未实现,它仍然可以访问共享资源或调用EventQueue.invokeLater。曾经有一段时间,人们普遍认为 Swing 组件可以创建出来,但这是不正确的。
Swing is thread-hostile. Even if a component is not realised, it may still access shared resources or call
EventQueue.invokeLater
. There was a period when it was widely stated that Swing components could be created off the, but that was incorrect.除了使用 CheckThreadViolationRepaintManager 之外,我还使用面向方面的解决方案来检测何时从 EDT 构造任何 Swing 组件。如果您使用 AspectJ,这是一种解决 EDT 违规问题的优雅方法。
有关详细信息,请参阅此博客文章:
调试 Swing,最终总结(来自 archive.org)
In addition to using the
CheckThreadViolationRepaintManager
I've been using an Aspect Oriented solution to detect when any Swing components are constructed off of the EDT. This is an elegant way to troubleshooting EDT violations if you use AspectJ.See this blog post for details:
Debugging Swing, the final summary (from archive.org)