JavaFXProgressBar进度条实现实时刷新

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

实现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;
            }
        };
    }

最终结果

进度条

评论 4
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值