Javafx Task-从方法更新进度 [英] Javafx Task - update progress from a method

查看:141
本文介绍了Javafx Task-从方法更新进度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在JavaFX应用程序中,我希望根据我在另一个类中实现的一些工作逻辑来更新状态栏.

In a JavaFX application I wish to update a status bar according to some work logic which I've implemented in an other class.

我无法弄清楚如何结合我的愿望,将工作逻辑传递给方法(而不是将其写在任务中)并了解工作进度百分比.

I can't figure out how to combine my desire to pass to work logic to the method (and not to write it inside the task) and to know about the work progress percentage.

这是带有Task的控制器的示例:

This is an example of the controller with the Task:

public class FXMLDocumentController implements Initializable {

    @FXML private Label label;    
    @FXML ProgressBar progressBar;

    @FXML
    private void handleButtonAction(ActionEvent event) {

        Service<Void> myService = new Service<Void>() {

            @Override
            protected Task<Void> createTask() {
                return new Task<Void>() {

                    @Override
                    protected Void call() throws Exception {
                        try {
                            DatabaseFunctionality.performWorkOnDb();

                            //updateProgress(1, 1);
                        } catch (InterruptedException ex) {
                            Logger.getLogger(FXMLDocumentController.class.getName()).log(Level.SEVERE, null, ex);
                        }

                        return null;
                    }
                }; 
            }            
        };

        progressBar.progressProperty().bind(myService.progressProperty());
        myService.restart();
    }

    @Override
    public void initialize(URL url, ResourceBundle rb) {
        // TODO
    }        
}

这是助手类:

public class DatabaseFunctionality {

    public static void performWorkOnDb () throws InterruptedException {
        for (int i = 1; i <= 100; i++) {
            System.out.println("i=" + i);
            Thread.sleep(100);

            //Update progress
        }        
    }    
}

谢谢

推荐答案

您在这里有几个选择.一种方法是按照Uluk的建议进行操作,并在您的DatabaseFunctionality类中公开一个可观察的属性:

You have a couple of options here. One is to do as Uluk suggests and expose an observable property in your DatabaseFunctionality class:

public class DatabaseFunctionality {

    private final ReadOnlyDoubleWrapper progress = new ReadOnlyDoubleWrapper();

    public double getProgress() {
        return progressProperty().get();
    }

    public ReadOnlyDoubleProperty progressProperty() {
        return progress ;
    }

    public void performWorkOnDb() throws Exception {
        for (int i = 1; i <= 100; i++) {
            System.out.println("i=" + i);
            Thread.sleep(100);

            progress.set(1.0*i / 100);
        }        
    }   
}

现在,在您的Task中,您可以观察该属性并更新任务的进度:

And now in your Task, you can observe that property and update the task's progress:

Service<Void> myService = new Service<Void>() {

    @Override
    protected Task<Void> createTask() {
        return new Task<Void>() {

            @Override
            protected Void call() throws Exception {
                try {
                    DatabaseFunctionality dbFunc = new DatabaseFunctionality();
                    dbFunc.progressProperty().addListener((obs, oldProgress, newProgress) -> 
                        updateProgress(newProgress.doubleValue(), 1));

                    dbaseFunc.performWorkOnDb();

                } catch (InterruptedException ex) {
                    Logger.getLogger(FXMLDocumentController.class.getName()).log(Level.SEVERE, null, ex);
                }

                return null;
            }
        }; 
    }            
};

另一个选择(如果您不希望数据访问对象依赖JavaFX属性API)是向数据访问对象传递回调以更新进度. BiConsumer<Integer, Integer> 适用这个:

Another option (in case you don't want your data access object to depend on the JavaFX properties API) is to pass the data access object a callback to update the progress. A BiConsumer<Integer, Integer> would work for this:

public class DatabaseFunctionality {

    private BiConsumer<Integer, Integer> progressUpdate ;

    public void setProgressUpdate(BiConsumer<Integer, Integer> progressUpdate) {
        this.progressUpdate = progressUpdate ;
    }

    public void performWorkOnDb() throws Exception {
        for (int i = 1; i <= 100; i++) {
            System.out.println("i=" + i);
            Thread.sleep(100);

            if (progressUpdate != null) {
                progressUpdate.accept(i, 100);
            }
        }        
    }   
}

然后

Service<Void> myService = new Service<Void>() {

    @Override
    protected Task<Void> createTask() {
        return new Task<Void>() {

            @Override
            protected Void call() throws Exception {
                try {
                    DatabaseFunctionality dbFunc = new DatabaseFunctionality();
                    dbFunc.setProgressUpdate((workDone, totalWork) -> 
                        updateProgress(workDone, totalWork));

                    dbaseFunc.performWorkOnDb();

                } catch (InterruptedException ex) {
                    Logger.getLogger(FXMLDocumentController.class.getName()).log(Level.SEVERE, null, ex);
                }

                return null;
            }
        }; 
    }            
};

这篇关于Javafx Task-从方法更新进度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆