实现JavaFXProgressBar进度条实时刷新
进度条刷新失败的原因
最近有个需求需要使用进度条, 在网上查了不少,但是详细有用的并不多 , 所以想分享一下最近一次成功的经验
JavaFX相对来说实在有些冷门了,网上的可用教程并不多,所以很多时候需要我们自己去关灯摸索着前进。
我们要知道 Java FX的主进程是JavaFX Application这个进程,这个进程掌管UI中的更新。
当我们把逻辑与UI块同时使用一个线程运行时,Java FX Application是腾不出手来进行UI更新的,所以我们在涉及ProgressBar的时候就需要多线程进行逻辑处理。
解决方案
我试过网上的很多办法,最后发现使用Task类可能是我觉得最顺手的一个了。
需要说一下的是,我演示的样例为fxml编写的形式。但纯代码形式也只是大同小异,毕竟我们寻求的只是一个解决的方案,一个思想而已
下面上代码:
这是fxml代码(视图区)
<children>
<Pane prefHeight="296.0" prefWidth="265.0">
<children>
<Button fx:id="bt1" layoutX="105.0" layoutY="34.0" mnemonicParsing="false" onAction="#startTest" text="Button" />
<ProgressBar fx:id="pb" layoutX="33.0" layoutY="123.0" prefWidth="200.0" progress="0.0" />
<TextField disable="true" fx:id="tf1" layoutX="33.0" layoutY="148.0" prefHeight="23.0" prefWidth="200.0" />
</children>
</Pane>
</children>
这是Controller代码(主逻辑区)
【当前方法为button点击事件】【负责UI控件数值绑定以及更新】
public void startTest(ActionEvent actionEvent) {
System.out.println(Thread.currentThread().getName() + "Controller");
//给进度条设置初始值
pb.setProgress(0.0);
//获取Task任务(也就是主逻辑方法)
myTask = creatTaskAndRunTask();
//绑定进度条的值属性
pb.progressProperty().unbind();
pb.progressProperty().bind(myTask.progressProperty());
//绑定TextField的值属性
tf1.textProperty().unbind();
tf1.textProperty().bind(myTask.messageProperty());
//添加Task的监听方法:如果Task的Message变化,则会经过该方法
myTask.messageProperty().addListener(new ChangeListener<String>() {
@Override
public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
//根据项目情况补充逻辑
}
});
//使用新线程启动 -- 这是重中之重
new Thread(myTask).start();
}
【这是非UI控件相关的主逻辑实现方法】
public Task creatTaskAndRunTask(){
return new Task() {
@Override
protected Object call() throws Exception {
//业务逻辑
List<File> files = FileUtil.loopFiles("E:\\IDEAProject");
System.out.println("总数为 :" + files.size());
int c = 1;
for (File f : files) {
Thread.sleep(5);
System.out.println(Thread.currentThread().getName() + "--> " +f.getName() + " --> " + c);
//Task的Message更新方法,这边修改之后,上面的监听方法会经过
updateMessage(f.getName());
//Task的Progress(进度)更新方法,进度条的进度与该属性挂钩
updateProgress(c, files.size());
c++;
}
return true;
}
};
}
最终结果

本文探讨了JavaFX中进度条刷新失败的原因,指出当逻辑与UI在同一线程时,导致UI无法更新。作者推荐使用Task类来实现多线程处理,确保进度条的实时刷新。文中提供了一个FXML形式的示例,包括Controller代码中的按钮点击事件处理和非UI逻辑实现方法。
540





