swing,如何正确更新ui

ttygqcqt  于 2021-06-30  发布在  Java
关注(0)|答案(4)|浏览(436)

在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的父组件。这是可行的,但有时我可以看到屏幕闪烁。我做错了吗?有更好的方法吗?

k2fxgqgv

k2fxgqgv1#

正确的方法是 SwingWorker ,但如果要手动执行,则必须实现以下模式:

@Override public void actionPerformed(java.awt.event.ActionEvent evt) {
  new Thread() {
    @Override public void run () {
      //callWebService();
      //do stuff
      SwingUtilities.invokeLater(new Runnable(){
        @Override public void run() {
          //updateUI(); // <----- repaint? revalidate? what?
        }
      });
    }
  }.start();
}

对于重新喷漆/重新验证问题,通常 revalidate() 那么 repaint() . 当然,这仅对手动绘制的组件有效。对于重用的组件,只需调用它们的值更改方法。

guykilcj

guykilcj2#

您通常不必做任何事情:如果您使用swing组件方法或其模型的方法,则会触发必要的事件,gui应该自动更新自身。
如果您定义了自己的模型(并且忘记了触发必要的事件,但是这是模型中的一个bug,应该在那里修复)。

yxyvkwin

yxyvkwin3#

将长时间运行的任务转移到其他线程。将事件发送回awt事件调度线程(edt)以使用 java.awt.EventQueue.invokeLater .

gupuwyp2

gupuwyp24#

我个人会用swingworker来做这个,尽管有一些其他的评论/答案:
尽管保持ui的响应性并不是最初问题的一部分,但无论如何这样做是一种很好的做法(我想不出一个好的理由来用冗长的处理来锁定edt)
它提供了一个 done() 方法,当任务完成时,该方法将在默认情况下在edt上执行,省去了在edt中手动 Package 东西的需要 invokeLater() 它更具可扩展性,提供了一个框架,以便在以后需要时可以方便地添加进度等信息。
我最近看到很多人普遍讨厌荡秋千,我不明白为什么。它是一个设计良好的、可扩展的类,专门用于这样的目的,效果很好。是的,你可以用线程把事情包起来,然后启动它们,让它们用其他方法包起来 invokeLater() ,但既然有更好的免费车轮,为什么还要重新发明呢?

相关问题