摆动按钮不会立即反应!我怎么能改变呢?

时间:2009-01-07 18:14:48

标签: java swing

我用Netbeans的可视化编辑器构建了一个表单。当我按下其中一个按钮时,它应该执行以下操作:

  • 将其设为已停用
  • 执行需要一些时间的任务
  • 当任务完成时,按钮将再次启用

但是,会发生以下情况:

  • 按钮保持按下状态,直到任务完成
  • 当任务完成时,按钮的启用/禁用将非常快(它们会发生,但你不会注意到它们)

这种行为不是我想要的。我尝试在JButton上使用重绘,在JFrame上,甚至在包含按钮的JPanel上,但我似乎无法让它做我想要的。一些提示?

4 个答案:

答案 0 :(得分:13)

当您在按钮回调中工作时,您将停止GUI绘制线程,直到它完成。

您需要做的是生成一个线程来执行长时间运行的任务,然后让该线程使用SwingUtilities.invokeLater()在完成时更新UI。不使用invokeLater不是线程安全的,并且通常是坏的mojo。

一个基本的例子是:

button.setEnabled(false);
new Thread(new Runnable() {
 public void run() {
  // Do heavy lifting here
  SwingUtilies.invokeLater(new Runnable() {
   public void run() {
    button.setEnabled(true);
   }
  });
 }
}).start();

答案 1 :(得分:8)

当你在按钮回调中做事时,你实际上是在停止gui绘画线程 - 不只是按钮,而是任何gui绘画。 (尝试用另一个窗口覆盖界面,然后再次曝光 - 在任务完成之前不会重新绘制!)

您需要做的是生成一个线程来执行长时间运行的任务,然后让该线程使用SwingUtilities.invokeLater()来启用按钮。 invokeLater强制按钮启用在gui绘制线程中发生。

您可能希望在长时间运行的线程运行时设置忙碌光标或以其他方式锁定接口。

答案 2 :(得分:4)

来自Sun的Concurrency in Swing tutorial非常值得一读。优秀的解释和背景阅读,包括事件调度线程,使用工作线程等

答案 3 :(得分:2)

您需要在不同的线程中执行需要一些时间的任务。

按钮阻塞的原因是因为工作是在绘制按钮的同一个线程中完成的。完成工作后,按钮可以完成你告诉它的其余部分。

如果使用不同的线程,线程将执行任务,而绘图代码可以继续绘制表单。