Java Swing的revalidate()和repaint()问题

5
我有一个小型的Java桌面应用程序,需要通过单击“+”和“-”按钮来动态添加和删除字段。我已经通过在ActionListener中调用revalidate()和repaint()来使其工作,并在所有父容器上向上一直到JFrame。
这似乎已经解决了问题,但偶尔它不起作用,JPanels无法正确地调整大小。这种情况偶尔发生且似乎是随机的,让我相信这可能是并发问题。我尝试从事件分派线程启动父容器,但这并没有解决问题。
这实际上是一个并发问题吗?还是我走错了路?有人知道发生了什么以及如何解决吗?
非常感谢
-SwingNoob

1
间歇性错误通常确实暗示着并发问题,但我认为没有人能够根据所提供的信息给出一个确定的答案。 - Hovercraft Full Of Eels
1
@mre:请澄清您的评论,因为根据我的经验和阅读,当删除项目时需要在容器上调用“revalidate”和“repaint”,而添加组件时有时需要调用“revalidate”和“repaint”。 - Hovercraft Full Of Eels
1
@ Hovercraft,我撤回我的声明 - 你实际上是正确的。@ John,对于我的困惑,我道歉...请忽略我上面发表的评论。 - mre
1
@john,如果你提供一小段相关的代码片段会很有帮助。 - mre
1
@Hovercraft Full Of Eels,@mre 嗯,10:1 这大概是关于 invokeLater() 的 :-) - mKorbel
显示剩余2条评论
2个回答

5

这并不是回答优秀示例的问题,OP的问题可能与LayoutManager和代码中的某些未知因素有关。

1/ 如果您向容器添加了新的JComponent,则必须调用

validate();
repaint(); //lay with LayoutManager required that 

2/ 如果从容器中删除或添加JComponents,则必须调用

revalidate();
repaint(); // lay with LayoutManager required that 

3/ 看起来重新验证也包括验证,


我不确定是否需要调用 repaint()。我写了一些示例代码,看起来只需要调用 validate(),无论是删除还是添加组件。但是,当然,这可能完全取决于具体情况。 :) - mre
@mre的意见是,如果你只是移除或添加一个JComponents,那么你可以冒险使用严格的MVC GUI架构来保证byteCode的安全性,否则这不是个好主意,因为一行代码而危及byteCode的安全性…另外,是的,repaint对GC来说非常懒惰,这是一种未经描述的炼金术。 - mKorbel
在我正在查看的第2个案例中,只需调用repaint而不是revalidate和repaint即可。 - Juan C Nuno

2

从AWT/EDT线程启动容器还不够。

您需要在AWT/EDT线程上执行每个容器的布局更改。

因此,如果您确保添加和删除是以这种方式完成的,则不需要revalidate()或repaint()。


我也称之为awt(自1999年以来) - bestsss

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接