我在Jframe内部构建了一个UI。其中一个按钮启动了一个长时间的调用(仍在同一Java过程中),在执行过程中,UI被冷冻。

我认为,为了清楚地表明,事情仍在运行,我可以在弹出窗口中显示一个进度栏,以便可以将用户保持在程序正在做什么的情况下。

因此,我正在创建一个新的Jdialog,向其添加JProgressbar,并随着事情的发生而进行更新。问题是对话框的内容没有更新。我对其标题的更改立即显示出来,以及我输出的任何内容,但在UI本身中没有任何内容。

我可以发出强制重新粉刷的命令吗?

这是本节的核心:

  killWindow = new JDialog();
  killWindow.setUndecorated(true);
  killWindow.setTitle("stopping tests - 0 of " + numActive);
  killProgress = new JProgressBar(0, numActive);
  killWindow.add(killProgress);
  killProgress.setStringPainted(true);
  killWindow.pack();
  killWindow.setLocationRelativeTo(frame);
  killWindow.setVisible(true);

然后,随着我们的进步...:

  killProgress.setValue(++killedTests);                    // not seen!
  killProgress.setString("Killing test on " + nickname()); // not seen!
  log("Killed another test, " + killedTests + " so far");  // visible in real time
  killWindow.setTitle("stopping tests - " + killedTests +
                      " of " + killProgress.getMaximum()); // visible in real time

我想念什么?我尝试在这里进行谷歌搜索和搜索,但真的没有看到任何明显的东西吗?

有帮助吗?

解决方案

您必须在另一个线程中执行长期运行的任务。

该线程称为“ AWT事件调度线程”,负责UI组件的更新。如果忙于执行长期运行的任务 惯于 更新UI(也不刷新您对话)。

您可以考虑使用 摇摆 或a Swingworker.

来自摇摆人 文档 这是一个样本

final JLabel label;
class MeaningOfLifeFinder extends SwingWorker<String, Object> {
   @Override
   public String doInBackground() {
       return findTheMeaningOfLife();
   }

   @Override
   protected void done() {
       try { 
           label.setText(get());
       } catch (Exception ignore) {
       }
   }
}

(new MeaningOfLifeFinder()).execute();

通过在其他线程中运行长任务,您允许AWT事件调度线程显示响应式UI。

您可以看一下这个”Java教程的课程“更好地理解这些概念。

其他提示

听起来您可能会在事件调度线程(EDT)上运行长期运行的任务。看看摇摆工人。如果您使用的是1.6,则内置为:

http://java.sun.com/javase/6/docs/api/javax/swing/swingworker.html

如果没有,您可以找到更多信息:

http://en.wikipedia.org/wiki/swingworker

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top