如何在javafx中保持进度指示器运行

时间:2017-02-21 06:46:05

标签: java javafx

我希望只有在完全更新ui后才会停止进度指示器。但它在ui方法中执行最后一行代码后停止。该指标应该如下:

1> Start the progress
2> Run the progress until all nodes are added to the scene
3> Stop after completion

我更新的方式是,我将BorderPane传递给线程并将其中心设置为gridpane,这是指针停止之后的最后一行代码。 而loginTask,如果我在Application Thread中启动它,指标就不会旋转!

borderpane.setCenter(gpane);

UI方法

{
Loading loadBar = new Loading(stage);
Task<Boolean> loginTask= checkCredTask();
loginTask.setOnSucceeded(value -> {
            loadBar.hideProgress(); });

loadBar.startTask(loginTask);
(new Thread(loginTask)).start();

}

进度条

public class Loading{

    private static Stage stage;
    private static ProgressIndicator p;
    private static Alert alert;

    public Loading(Stage s){
        stage=s;
        p=new ProgressIndicator();
        alert = new Alert(AlertType.NONE);

    }


    public void startTask(Task<Boolean> cm){
        if(p != null){
            p.setProgress(-1);
            p.progressProperty().unbind();
            p.progressProperty().bind(cm.progressProperty());
            alert.initOwner(stage);
            alert.getDialogPane().setStyle("-fx-background-color:rgba(0,0,0,0);");
            alert.getDialogPane().getScene().setFill(Color.TRANSPARENT);
            alert.initStyle(StageStyle.TRANSPARENT);
            alert.getDialogPane().setContent(p);
            alert.show();
        }
    }


    public void hideProgress(){
        alert.setResult(ButtonType.CLOSE);
    }
}

任务

private Task<Boolean> checkCredTask() {
        Task<Boolean> loginTask = new Task<Boolean>() {
        @Override
        public Boolean call() {
            Boolean result = false;
            int flag = verifyCredential();
            if (flag == 1) {
                loadUI();
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                result = true;
            } else if (flag == 2) {
                result = false;
            }
            return result;
        }
    };
    return loginTask;
    }

加载UI方法

ExecutorService execsrv = Executors.newSingleThreadExecutor();
             execsrv.execute(new AdminUI(stage,pane,mb));
             execsrv.shutdown();

1 个答案:

答案 0 :(得分:0)

您的代码甚至无法编译。 Task<Boolean> loginTask不会覆盖抽象call()方法。即使你换行

ExecutorService execsrv = Executors.newSingleThreadExecutor();
execsrv.execute(new AdminUI(stage,pane,mb));
execsrv.shutdown();

call()方法中没有任何意义,因为您正在另一个任务中执行新任务。

假设new AdminUI(stage,pane,mb)是一个长时间运行的过程并返回boolean你应该这样做:

Task<Boolean> loginTask = new Task<Boolean>() {
    @Override
    protected Boolean call() throws Exception {
        // Start the UI 
        AdminUI ui = new AdminUI(stage, pane, mb);
        return ui.getBooleanValue(); 
    }
};

修改

正如我所说,你正在AdminUI内执行loginTask任务,这是没有意义的。目前,您只等待登录任务,但不等待AdminUI任务。登录任务的完成速度比AdminUI快,这就是指标早期停止的原因。将AdminUI提取到另一个Task。这是伪代码,所以你必须自己做。

Task<Boolean> loginTask= checkCredTask();
loginTask.setOnSucceeded(value -> {
    //****** THIS IS PSEUDO CODE ***********
    //start AdminUITask
    //AdminUITask.setOnSucceeded(value -> {
        //loadBar.hideProgress();
    //});
});