簡體   English   中英

JavaFX:如何在JavaFX中正確使用ProgressIndicator

[英]JavaFX: How can I use correctly a ProgressIndicator in JavaFX

我是Java中的新手。 我的JavaFX應用程序有問題,我需要在數據庫查詢之前啟動我的ProgressIndicator(類型為INDETERMINATE)。 這是我的代碼的一部分:

spinner.setVisible(true);
passCripto = cripto.criptoPass(pass);
MyDao dao = new MyDaoImpl();
boolean isLoginOk = dao.isUserOk(user, passCripto);
boolean isStatusOk = dao.idStatusUser(user);

完成后,我需要將微調器設置為FALSE,但只有在數據庫查詢完成時才會顯示微調器。 我怎么解決這個問題?

謝謝。

我這樣做,但沒有解決:

Task<Boolean> taskValidaLogin = new Task<Boolean>() {
    @Override
    protected Boolean call() throws Exception {
        boolean validaLogin = ACDCDao.validaUsuario(usuario, senhaCripto);

        return validaLogin;
    }
};

Task<Boolean> taskValidaStatus = new Task<Boolean>() {
    @Override
    protected Boolean call() throws Exception {
        boolean validaStatus = ACDCDao.validaStatusUsuario(usuario);

        return validaStatus;
    }
};

new Thread(taskValidaLogin).start();
new Thread(taskValidaStatus).start();
if (taskValidaLogin.getValue()) {
    if (taskValidaStatus.getValue()) {
        //do something
    }

你必須將你的數據庫東西放到另一個線程中,因為如果操作需要時間,它將凍結JavaFX線程(GUI)

在JavaFx中,您可以使用服務和任務來執行后台操作。 你應該讀

通過將數據庫內容執行到服務中,您將能夠輕松地監視它,因為Service提供了必要的操作,並且具有onSuccedeed,onFailed等方法...

真的看看,如果你想正確地做JavaFx,這是一個必不可少的部分。

Main.java

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class Main extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception {
        Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
        primaryStage.setTitle("Hello World");
        primaryStage.setScene(new Scene(root, 300, 275));
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

ServiceExample.java

import javafx.concurrent.Service;
import javafx.concurrent.Task;

public class ServiceExample extends Service<String> {
    @Override
    protected Task<String> createTask() {
        return new Task<String>() {
            @Override
            protected String call() throws Exception {
                //DO YOU HARD STUFF HERE
                String res = "toto";
                Thread.sleep(5000);
                return res;
            }
        };
    }
}

Controller.java

import javafx.concurrent.WorkerStateEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.scene.control.ProgressIndicator;

public class Controller {

    @FXML
    private ProgressIndicator progressIndicator;

    public void initialize() {
        final ServiceExample serviceExample = new ServiceExample();

        //Here you tell your progress indicator is visible only when the service is runing
        progressIndicator.visibleProperty().bind(serviceExample.runningProperty());
        serviceExample.setOnSucceeded(new EventHandler<WorkerStateEvent>() {
            @Override
            public void handle(WorkerStateEvent workerStateEvent) {
                String result = serviceExample.getValue();   //here you get the return value of your service
            }
        });

        serviceExample.setOnFailed(new EventHandler<WorkerStateEvent>() {
            @Override
            public void handle(WorkerStateEvent workerStateEvent) {
                //DO stuff on failed
            }
        });
        serviceExample.restart(); //here you start your service
    }
}

sample.fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.ProgressIndicator?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane prefHeight="200.0" prefWidth="200.0" xmlns:fx="http://javafx.com/fxml/1"
            xmlns="http://javafx.com/javafx/2.2" fx:controller="Controller">
    <ProgressIndicator fx:id="progressIndicator" layoutX="78.0" layoutY="55.0"/>
</AnchorPane>

我很快就做了這個例子,但我覺得這就是你想要的。 (我不將我的progressIndicator添加到一個節點,僅用於示例)

spinner.setVisible(true); ,通過將微調器設置為不確定值(-1)來啟動微調旋轉器。 spinner.setProgress(-1d);

然后我想當任務完成時你想要它停止。 有兩個事件要使用,成功和失敗。 這意味着任務失敗,而不是登錄。 這是一個成功的例子。

taskValidaStatus.setOnSucceeded(new EventHandler<WorkerStateEvent>() {
    @Override
    public void handle(WorkerStateEvent event) {
        spinner.setProgress(0d);
        //and now you can check valida here after the task is finished
        if (taskValidaLogin.getValue()) {
            if (taskValidaStatus.getValue()) {
            //do something
            }
    }
});
//now start the tasks after they're all set up.
new Thread(taskValidaLogin).start();
new Thread(taskValidaStatus).start();

我沒有測試這段代碼,因為你沒有提供一個有效的例子。

還有另一個問題,即validaLogin可能尚未完成。 我只檢查過一個線程是否完成。 你應該做的是在其他線程onSucceeded事件中啟動一個線程。 我不確定你需要的順序,但在taskLogin onSucceeded中可能看起來像這樣。

        if (taskValidaLogin.getValue()) {
            new Thread(taskValidaStatus).start();
        }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM