JavaFX:如何在JavaFX中正确使用ProgressIndicator [英] JavaFX: How can I use correctly a ProgressIndicator in JavaFX

查看:522
本文介绍了JavaFX:如何在JavaFX中正确使用ProgressIndicator的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是JavaFX中的新人。
我的JavaFX应用程序有问题,我需要在数据库查询之前启动ProgressIndicator(类型INDETERMINATE)。
这是我的代码的一部分:

I´m newbe in JavaFX. I have a problem with my JavaFX application, I need to start my ProgressIndicator (type INDETERMINATE) before a database query. This is part of my code:

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

完成后,我需要将微调器设置为FALSE,但只有在数据库查询完成时才会显示微调器。我该如何解决这个问题?

When finished, I need to set spinner to FALSE but the spinner only is showed when database query is finished. How can I solve this ?

谢谢。

我这样做,但没有解决:

I do this, but not resolved:

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)

You have to do your database stuff into an other thread, cause if the operation take time it will freez the JavaFX thread (The GUI)

在JavaFx中,您可以使用服务和任务来执行后台操作。你应该阅读

In JavaFx you can use Service and Task to do background stuff. You should read

  • Concurency in javafx
  • Service

通过执行数据库的东西进入一项服务,你将能够轻松地监控它,因为服务提供了必要的服务,并且有像onSuccedeed,onFailed等方法...

By executing your database stuff into a service, you will be able to monitor it easely cause Service provide the necessary to do that, and have method like onSuccedeed, onFailed...

真的看看如果你想正确地做JavaFx,这是一个必不可少的部分。

Really have a look to that, is an essential part if you want to do JavaFx correctly.

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



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



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



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添加到一个节点,仅用于示例)

I do that example quickly it's basic but I think it's what you want. (I don't add my progressIndicator to a node it's just for the example)

这篇关于JavaFX:如何在JavaFX中正确使用ProgressIndicator的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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