我试图更新一个 ProgressBar
for循环中的值。它的进度应该每100毫秒更新一次,但不幸的是它没有工作!代码如下:
pb = new ProgressBar(0);
Button btn = new Button("Start!");
btn.setOnAction(new EventHandler<ActionEvent>(){
@Override
public void handle(ActionEvent event) {
for(int i = 0; i <=100; i++){
position = i;
Platform.runLater(new Runnable(){
@Override
public void run() {
pb.setProgress(position);
System.out.println("Index: "+position);
}
});
try{
Thread.sleep(100);
}catch(Exception e){ System.err.println(e); }
}
}
});
问题1:我希望上面的代码每100毫秒更新一次progressbar,但它没有起作用。为什么?
问题2:我打过电话 System.out.println("Index: "+position);
在循环中。我假设输出应该是 1..2..3..4...
但我错了。输出如下所示:
Index: 100
Index: 100
Index: 100
Index: 100
Index: 100
Index: 100
Index: 100
2条答案
按热度按时间0sgqnhkj1#
背景
Platform.runLater()
被调用以在JavaFX Application thread
当你在另一条线上时。当您已经在javafx应用程序线程上添加队列中的所有这些项目时,每100毫秒运行一次,因为该线程已经在忙于运行循环和睡眠:)因此,它在线程可以自由执行队列中的所有内容后(即完成循环后)运行队列中的所有内容。
还有一个问题,progressbar有一个progressproperty,其值可以介于0和1之间,其中0表示0%,1表示100%。如果要更新进度条,则需要使用0.1到1.0之间的值设置进度。
如何修复
您应该在按钮的操作上启动一个新线程,并让它处理循环。你可以用
Platform.runLater
在这个线程中,不阻塞javafx应用程序线程。我将运行以下内容:
注意:这个答案更强调op哪里出了问题,以及他如何纠正错误。如果您使用的是javafx,您会希望使用更好的方法,即使用
Task
及其updateProgress()
更新@kleopatra在其解决方案中所述progressbar的进度。5lwkijsr2#
通过手动计算和设置工具栏的progressproperty来重新发明控制盘的另一种方法是使用任务:它有一个progressproperty,可以自动计算相对数量并保证在fx应用程序线程上更新,这样就可以安全地将任何与场景相关的属性绑定到。
比如:
显然,这是最简单的代码片段——请参阅task,以了解取消/中断线程的示例。