题
我在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
如果没有,您可以找到更多信息:
不隶属于 StackOverflow