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

JavaFX:如何在JavaFX中正确使用ProgressIndicator,java,thread-safety,task,javafx-8,Java,Thread Safety,Task,Javafx 8,我是JavaFX的新手。 我的JavaFX应用程序有问题,我需要在数据库查询之前启动ProgressIndicator(类型不确定)。 这是我代码的一部分: spinner.setVisible(true); passCripto = cripto.criptoPass(pass); MyDao dao = new MyDaoImpl(); boolean isLoginOk = dao.isUserOk(user, passCripto); boolean isStatusOk = dao.i

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

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
    }
Task taskValidaLogin=new Task(){
@凌驾
受保护的布尔调用()引发异常{
布尔值validaLogin=ACDCDao.validaUsuario(usuario,senhaCripto);
返回validaLogin;
}
};
Task taskValidaStatus=新任务(){
@凌驾
受保护的布尔调用()引发异常{
布尔值validaStatus=ACDCDao.validastatusuario(usuario);
返回有效状态;
}
};
新线程(taskValidaLogin.start();
新线程(taskValidaStatus).start();
if(taskValidaLogin.getValue()){
if(taskValidaStatus.getValue()){
//做点什么
}

您必须将数据库填充到另一个线程中,因为如果操作需要时间,它将释放JavaFX线程(GUI)

在JavaFx中,您可以使用服务和任务来做后台工作


通过将您的数据库内容执行到服务中,您将能够轻松地对其进行监视,因为服务提供了执行该操作的必要条件,并且具有类似onSuccedeed、onFailed之类的方法

如果您想正确地使用JavaFx,请仔细看看这一点,这是一个必不可少的部分

主类 ServiceExample.java
导入javafx.concurrent.Service;
导入javafx.concurrent.Task;
公共类ServiceExample扩展了服务{
@凌驾
受保护的任务createTask(){
返回新任务(){
@凌驾
受保护的字符串调用()引发异常{
//你喜欢这里的硬东西吗
字符串res=“toto”;
睡眠(5000);
返回res;
}
};
}
}
Controller.java
导入javafx.concurrent.WorkerStateEvent;
导入javafx.event.EventHandler;
导入javafx.fxml.fxml;
导入javafx.scene.control.ProgressIndicator;
公共类控制器{
@FXML
私人进展指标;
公共无效初始化(){
final ServiceExample ServiceExample=新ServiceExample();
//在这里,您告诉您的进度指示器只有在服务运行时才可见
progressIndicator.visibleProperty().bind(serviceExample.runningProperty());
setOnSucceeded(新的EventHandler(){
@凌驾
公共无效句柄(WorkerStateEvent WorkerStateEvent){
String result=serviceExample.getValue();//这里是服务的返回值
}
});
serviceExample.setOnFailed(新的EventHandler(){
@凌驾
公共无效句柄(WorkerStateEvent WorkerStateEvent){
//做一些失败的事情
}
});
serviceExample.restart();//在这里启动服务
}
}
sample.fxml


我很快就做了这个例子,这是基本的,但我想这是你想要的。(我不会将我的progressIndicator添加到一个节点上,这只是一个例子)

spinner.setVisible(true);
之后,通过将它设置为一个不确定的值(-1)
spinner.setProgress(-1d);

然后我猜当任务完成时,您希望它停止。有两个事件要使用,Succeed和failed。这意味着任务失败,而不是登录。下面是Succeed的示例

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();

事实上,你是对的。我有这个想法,但我现在不知道该怎么做。你有一个例子吗?谢谢。我在这个例子中迷失了。我是新手。我把代码放在哪里了?
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;
            }
        };
    }
}
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
    }
}
<?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>
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();
        if (taskValidaLogin.getValue()) {
            new Thread(taskValidaStatus).start();
        }