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

我是JavaFX中的新手。 我的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 taskValidaLogin = new Task() { @Override protected Boolean call() throws Exception { boolean validaLogin = ACDCDao.validaUsuario(usuario, senhaCripto); return validaLogin; } }; Task taskValidaStatus = new Task() { @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中,您可以使用服务和任务来执行后台操作。 你应该读

  • 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 { @Override protected Task createTask() { return new Task() { @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() { @Override public void handle(WorkerStateEvent workerStateEvent) { String result = serviceExample.getValue(); //here you get the return value of your service } }); serviceExample.setOnFailed(new EventHandler() { @Override public void handle(WorkerStateEvent workerStateEvent) { //DO stuff on failed } }); serviceExample.restart(); //here you start your service } } 

sample.fxml

       

我很快就做了这个例子,但我觉得这就是你想要的。 (我不将我的progressIndicator添加到一个节点,仅用于示例)

spinner.setVisible(true); ,通过将旋转器设置为不确定值(-1)来启动旋转器旋转。 spinner.setProgress(-1d);

然后我想当任务完成后你想要它停止。 有两个事件要使用,成功和失败。 这意味着任务失败,而不是登录。 这是一个成功的例子。

 taskValidaStatus.setOnSucceeded(new EventHandler() { @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(); }