在swing上执行一些操作之后,更新ui的正确方法是什么?
例如,单击一个按钮后,调用一个方法,该方法可能几乎是即时的,也可能需要几秒钟。实际上,所有的应用程序逻辑都是通过web服务远程完成的,所以等待应用程序响应是正常的。
我的按钮事件处理程序可能如下所示:
myButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
//callWebService();
//do stuff
//updateUI(); // <----- repaint? revalidate? what?
}
});
我当前的实现调用updateui方法,该方法在内部调用validate()和repaint(),以保存ui的父组件。这是可行的,但有时我可以看到屏幕闪烁。我做错了吗?有更好的方法吗?
4条答案
按热度按时间k2fxgqgv1#
正确的方法是
SwingWorker
,但如果要手动执行,则必须实现以下模式:对于重新喷漆/重新验证问题,通常
revalidate()
那么repaint()
. 当然,这仅对手动绘制的组件有效。对于重用的组件,只需调用它们的值更改方法。guykilcj2#
您通常不必做任何事情:如果您使用swing组件方法或其模型的方法,则会触发必要的事件,gui应该自动更新自身。
如果您定义了自己的模型(并且忘记了触发必要的事件,但是这是模型中的一个bug,应该在那里修复)。
yxyvkwin3#
将长时间运行的任务转移到其他线程。将事件发送回awt事件调度线程(edt)以使用
java.awt.EventQueue.invokeLater
.gupuwyp24#
我个人会用swingworker来做这个,尽管有一些其他的评论/答案:
尽管保持ui的响应性并不是最初问题的一部分,但无论如何这样做是一种很好的做法(我想不出一个好的理由来用冗长的处理来锁定edt)
它提供了一个
done()
方法,当任务完成时,该方法将在默认情况下在edt上执行,省去了在edt中手动 Package 东西的需要invokeLater()
它更具可扩展性,提供了一个框架,以便在以后需要时可以方便地添加进度等信息。我最近看到很多人普遍讨厌荡秋千,我不明白为什么。它是一个设计良好的、可扩展的类,专门用于这样的目的,效果很好。是的,你可以用线程把事情包起来,然后启动它们,让它们用其他方法包起来
invokeLater()
,但既然有更好的免费车轮,为什么还要重新发明呢?