JavaFXProgressBar进度条实现实时刷新

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

最终结果

进度条

posted @ 2020-12-23 16:56  Curtain'H  阅读(381)  评论(0)    收藏  举报  来源