我试图让JProgressBar
每100秒增加1,而目前我在while语句中使用Thread.sleep(100)
,如下所示:
try {
while (i<=100){
doTime();
}
} catch (InterruptedException ex) {
Logger.getLogger(SplashScreen.class.getName()).log(Level.SEVERE, null, ex);
}
public void doTime() throws InterruptedException{
jLabel1.setText("sleeping");
Thread.sleep(100);
jLabel1.setText("start");
i++;
pb.setValue(i);
pb.repaint();
}
如果我通过执行System.out.println
进行调试,它会实时显示,但是摆动GUI会冻结,直到它退出while循环,任何人都可以帮忙吗?
谢谢
亚光
答案 0 :(得分:5)
如推导所述,您应该使用SwingWorker。来自它的javadoc:
“SwingWorker专为需要在后台线程中运行长时间运行任务并在完成或处理时提供UI更新的情况而设计。 SwingWorker的子类必须实现doInBackground()方法执行后台计算。“
在java教程中对ProgressBarDemo.java稍作改动,你几乎可以得到你想要的东西。
public Void doInBackground() {
Random random = new Random();
int progress = 0;
//Initialize progress property.
setProgress(0);
while (progress < 100) {
//Sleep for up to one second.
try {
//original code: Thread.sleep(random.nextInt(1000));
Thread.sleep(10);
} catch (InterruptedException ignore) {}
//Make random progress.
//originalcode: progress += random.nextInt(10);
progress++;
setProgress(Math.min(progress, 100));
}
return null;
}
答案 1 :(得分:2)
问题是你正在睡觉Swing Event线程。您将需要创建一个用于运行循环的新线程,然后让该循环更新swing事件线程上的进度条。
我会使用Swing Worker thread作为循环。然后使用invokeLater更新进度条。
答案 2 :(得分:1)
除了推导说,你正在睡觉100毫秒。这意味着你只是每十分之一秒更新一次,而不是每百分之一更新一次。
答案 3 :(得分:1)
如果在事件调度线程(EDT)中调用doTime()
,它应该调用UI代码(jLabel1.setText()
和其他人),那么它应该不完全打电话给sleep()
。您不想冻结您的UI。
正确的方法是使用timer在正确的时刻(例如,每10毫秒)唤醒并更新进度。 Jala 的代码也是一个很好的答案,它是正式的Swing方式(定时器的级别低于SwingWorkers)。