Search code examples
javafxprogress-barsleepprogress

How to delay setProgress in Progress Bar in 0.1 steps until full


I am trying to make a progressBar, that will set its progress in 0.1 steps with a delay of 1000ms until it is "full".

I already found a solution how to delay one step, but cannot get it into a for loop that will set the progress in 0.1 steps until the progress equals 1 and therefore is full.

How do I need to modify the solution below to achieve that?

package project;

import javafx.application.Application;
import javafx.concurrent.Task;
import javafx.concurrent.WorkerStateEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.ProgressBar;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class Progress extends Application {

StackPane stack = new StackPane();
Scene scene = new Scene(stack, 400, 800);

// Progress Bar
ProgressBar progressBar = new ProgressBar();

public void start(Stage primaryStage) throws Exception {

    // Progress Bar
    stack.getChildren().add(progressBar);
    progressBar.setTranslateX(0);
    progressBar.setTranslateY(0);

    progressBar.setProgress(0);

    Task<Void> sleeper = new Task<Void>() {
        @Override
        protected Void call() throws Exception {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
            }
            return null;
        }
    };

    sleeper.setOnSucceeded(new EventHandler<WorkerStateEvent>() {
        @Override
        public void handle(WorkerStateEvent event) {
            progressBar.setProgress(0.1);
        }
    });

    new Thread(sleeper).start();

    primaryStage.setScene(scene);
    primaryStage.setTitle("Title");
    primaryStage.show();

}

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

}

Solution

  • Make your task perform the iteration, and update it's progress as it goes:

    Task<Void> sleeper = new Task<Void>() {
        @Override
        protected Void call() throws Exception {
    
            final int numIterations = 10 ;
            for (int i = 0 ; i < numIterations ; i++) {
                updateProgress(i, numIterations);
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                }
            }
            updateProgress(numIterations, numIterations);
            return null;
        }
    };
    

    Then just bind the progress bar's progress to the task's progress:

    progressBar.progressProperty().bind(sleeper.progressProperty());