Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaFX: How can I use correctly a ProgressIndicator in JavaFX

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

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 ?

Thanks.

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
    }
like image 384
Bran Stark Avatar asked Feb 28 '14 14:02

Bran Stark


People also ask

Which is the correct hierarchy in JavaFX application?

JavaFX application is divided hierarchically into three main components known as Stage, Scene and nodes. We need to import javafx. application. Application class in every JavaFX application.

How do I link JavaFX to Scene Builder?

In the Settings/Preferences dialog ( Ctrl+Alt+S ), select Languages & Frameworks | JavaFX. in the Path to SceneBuilder field. In the dialog that opens, select the Scene Builder application (executable file) on your computer and click OK. Apply the changes and close the dialog.

What is the correct syntax for creating a class of sample application in a JavaFX?

Group − A Group node is represented by the class named Group which belongs to the package javafx. scene, you can create a Group node by instantiating this class as shown below. Group root = new Group(); The getChildren() method of the Group class gives you an object of the ObservableList class which holds the nodes.


1 Answers

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)

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

  • Concurency in javafx
  • Service

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...

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

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>

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)

like image 189
agonist_ Avatar answered Sep 28 '22 05:09

agonist_