JavaFX 异步任务执行+进度条显示

发布时间:2020-10-20

概述

JavaFX异步任务执行及进度条显示。

详细

概述

使用JavaFX中的进度条组件展示Java FX应用中异步执行任务的进度。

点击开始任务按钮,异步执行任务,并使用进度条展示任务进度和进度文本内容;任务执行完成,隐藏进度条,显示任务执行成功文本。

详细

一、运行效果

二、窗口界面实现

//JavaFX程序必须继承javafx.application.Application类,重写start方法
public class MainApp extends Application {
    private ProgressIndicator progressBar;//进度条组件
    private Label label;//文本组件
    private Button button;//按钮组件
    private Stage primaryStage;//程序窗口
    private GridPane grid;//网格布局组件
    
    public static void main(String[] args) {
        launch(args);
    }
    @Override
    public void start(Stage primaryStage) throws Exception {
        this.primaryStage = primaryStage;
        grid = new GridPane();
        grid.setPadding(new Insets(5, 10, 10, 10));
        grid.setHgap(10);
        grid.setVgap(10);
        grid.setAlignment(Pos.CENTER);
        button = new Button();
        button.setText("点击开始任务");
        //设置按钮的鼠标点击事件
        button.setOnMouseClicked(event -> {
            runTask(new MyTask());
            System.out.println("执行任务");
        });
//        progressBar = new ProgressBar();
        progressBar = new ProgressIndicator();
        label = new Label();
        progressBar.setVisible(false);
        progressBar.setDisable(true);
        label.setVisible(false);
        label.setDisable(true);
        grid.addColumn(0,button,progressBar,label);
        //设置GridPane网格内ChildNode水平垂直居中
        for (Node n : grid.getChildren()) {
            Integer row = GridPane.getRowIndex(n);
            Integer column = GridPane.getColumnIndex(n);
            GridPane.setHalignment(n, HPos.CENTER);
            GridPane.setValignment(n,VPos.CENTER);
        }
        GridPane.setMargin(button, new Insets(5, 0, 0, 0));
        GridPane.setMargin(progressBar, new Insets(5, 0, 0, 0));
        GridPane.setMargin(label, new Insets(5, 0, 0, 0));
        //窗口的组件显示界面
        Scene scene = new Scene(grid);
        primaryStage.setScene(scene);
        primaryStage.setMinWidth(500);
        primaryStage.setMinHeight(300);
        Rectangle2D screenBounds = Screen.getPrimary().getVisualBounds();
        primaryStage.setWidth(screenBounds.getWidth() * 0.15);
        primaryStage.setHeight(screenBounds.getHeight() * 0.15);
        primaryStage.setTitle("Async task");
        //显示窗口
        primaryStage.show();
    }
    //异步任务实现
    
}

三、异步任务实现

    /**
     * 异步执行任务
     * @param task
     */
    private void runTask(Task task) {
        progressBar.setVisible(true);
        progressBar.setDisable(false);
        label.setText("正在准备任务。。。");
        Service<Integer> service = new Service<Integer>() {
            @Override
            protected Task<Integer> createTask() {
                return task;
            }
        };
        //最主要的是这一步
        progressBar.progressProperty().bind(task.progressProperty());
        //使用service.getxxx()和使用回调函数中的newValue获取到的值是一样的
        task.messageProperty().addListener((observable, oldValue, newValue) -> {
            label.setText(service.getMessage());
        });
        task.valueProperty().addListener((observable, oldValue, newValue) -> {
            label.setTextFill(Color.GRAY);
            if ((int)newValue == 100 || (int)newValue == 1){
                label.setTextFill(Color.GREEN);
                taskComplete();
            }
            if ((int) newValue == -1){
                label.setTextFill(Color.RED);
                taskOnError();
            }
        });
        service.restart();
    }

    /**
     * 执行任务出错
     */
    private void taskOnError() {

    }

    /**
     * 完成
     */
    private void taskComplete() {
        progressBar.setDisable(true);
        progressBar.setVisible(false);
    }

    private class MyTask extends Task{
        @Override
        protected Object call() throws Exception {
            //更新任务信息
            updateMessage("任务开始...");
            //更新任务返回值
            updateValue(0);
            Thread.sleep(2000);
            try {
                //这里使用while循环表示执行的任务,每循环一次更新一次label
                int i = 0;
                while (i++ < 100) {
                    updateProgress(i, 100);
                    updateMessage("任务正在执行,已完成:" + i + "% !");
                    updateValue(i);
                    Thread.sleep(50);
                }
                updateMessage("创建成功!");
                return 1;
            } catch (Exception e) {
                updateMessage("任务出错!");
                updateValue(-1);
                updateProgress(-1, 1);
                return -1;
            }
        }
    }

四、项目结构

源码是可运行的java文件

image.png


本实例支付的费用只是购买源码的费用,如有疑问欢迎在文末留言交流,如需作者在线代码指导、定制等,在作者开启付费服务后,可以点击“购买服务”进行实时联系,请知悉,谢谢
手机上随时阅读、收藏该文章 ?请扫下方二维码