2009-07-24 25 views
7

我有一个Java Swing UI,它不会像我认为的那样更新/重新绘制。该应用程序发送XMPP消息并在不同的线程上接收响应。处理该响应并更新UI以反映消息中包含的信息。使用invokeLater后不更新Swing UI

当接收到响应,我更新使用

javax.swing.SwingUtilities.invokeLater(new Runnable() { 
    public void run() { /* execute logic to update panel */ } 
}); 

它已经相当一段时间,因为我在Java中已经开发,但根据我在网上搜集了invokeLater排队可运行了有关执行的JPanel组件GUI线程。然而,我的GUI不会更新,除非我在应用程序中执行其他操作,导致重新绘制 - 例如调整窗口大小。我错过了什么?在更新面板的逻辑之后,我尝试了invalidate()和repaint()的各种组合,但结果仍然相同 - 在我调整窗口大小之前,GUI不会更新。

编辑:当我说更新面板,我,特别是,做的removeAll(),然后添加的JLabel屈指可数。

回答

14

从面板添加/删除组件后,你应该使用:

panel.revalidate(); // this works 99% of the time 
panel.repaint(); // sometimes needed. 

喜欢的validate(),无效()等其他的东西,是从AWT遗留下来的日子里,我相信并重新验证()做了更好的工作,并专门为Swing添加。

2

如果你的意思是“更新面板”您要添加或删除组件,那么你最好使用无效()或重新验证(),以便布局管理器捕获的变化。

here了类似的问题。

2

如果要添加或GUI事件处理过程中从面板上拆下的部件(如行动听众)调用doLayout()应该有希望解决您的问题。我发现当GUI不更新时,调用validate(),doLayout()和repaint()往往可以解决问题。

+1

实际上你不应该直接调用doLayout(),而应该调用revalidate()来代替。 – Stroboskop 2009-07-24 16:13:08

+0

@Stroboskop尽管你不应该这样做,但是文档中提到“这通常在组件验证通过时调用。”我的经验表明,在事件处理期间从容器中添加和删除组件时,此方法不会被revalidate()调用。 – Peter 2009-07-24 16:57:39