Home:ALL Converter>How to force Java FX scene refresh?

How to force Java FX scene refresh?

Ask Time:2013-01-20T17:10:42         Author:Nikopol

Json Formatter

I have an Java FX scene with a start button and several rectangles which represent the tiles of a map. I also have drawn a sphere which represents my explorer (it has to explore the map), but I am having difficulties with running the animation.

In my OnMouseClicked handler for the start button, I start an algorithm for exploring the map which changes the position of the sphere and the colors of the tiles which have been visited. The problem is that the scene won't update itself while the algorithm is running, so I only get to see how the final scene will look like (after the algorithm has stopped running). How can I force a scene update so I can see all the color changes sequentially?

Later edit:

import javafx.application.Application;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.event.EventType;
import javafx.geometry.Insets;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.image.Image;
import javafx.scene.layout.HBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;

public class Test extends Application {

private static final double boxOuterSize = 50;
private static final double boxInnerSize = 48;
private static final double boxCornerRadius = 20;

private Stage applicationStage;
private Scene applicationScene;

private static double   sceneWidth  = 1024;
private static double   sceneHeight = 800;
private static HBox     container = new HBox();
private static Group    root = new Group();
private Rectangle[] rectangles = new Rectangle[10];

@Override
public void start(Stage mainStage) throws Exception {

    applicationStage = mainStage;
    container.setSpacing(10);
    container.setPadding(new Insets(10, 10, 10, 10));

    try {
        applicationScene = new Scene(container, sceneWidth, sceneHeight);
        applicationScene.addEventHandler(EventType.ROOT,(EventHandler<? super Event>)this);
        applicationScene.setFill(Color.WHITE);

    } catch (Exception exception) {
        System.out.println ("exception : "+exception.getMessage());
    }

    applicationStage.setTitle("HurtLockerRobot - Tema 3 IA");
    applicationStage.getIcons().add(new Image("icon.png"));
    applicationStage.setScene(applicationScene);

    for(int i=0; i<10; i++) {
        Rectangle r = new Rectangle();
        r.setFill(Color.BLUE);
        r.setX(i * boxOuterSize);
        r.setY(0);
        r.setWidth(boxInnerSize);
        r.setHeight(boxInnerSize);
        r.setArcHeight(boxCornerRadius);
        r.setArcWidth(boxCornerRadius);
        r.setSmooth(true);
        rectangles[i] = r;
        root.getChildren().add(rectangles[i]);
    }

    container.getChildren().add(root);
    Button startButton = new Button("Start");
    startButton.setOnMouseClicked(new EventHandler<Event>() {
        @Override
        public void handle(Event arg0) {
            for(int i=0; i<10; i++) {
                rectangles[i].setFill(Color.RED);
                // TODO: some kind of scene refresh here
            }
        }
    });
    container.getChildren().add(startButton);

    applicationStage.show();
}

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

Initially all the rectangles are blue. The behavior I want to obtain here is to see the rectangles changing colors sequentially. The problem is that I only get to see the end result (all the rectangles change their color at the same time).

Author:Nikopol,eproduced under the CC 4.0 BY-SA copyright license with a link to the original source and this disclaimer.
Link to original article:https://stackoverflow.com/questions/14423109/how-to-force-java-fx-scene-refresh
ItachiUchiha :

This is an old question and it caught my eye since this is a very general issue faced by people new to JavaFX.\n\nThe problem that OP is facing is because he updates all the rectangles at once, without waiting. \n\nOP can wait by either creating a new Thread, put the thread on sleep for an estimated seconds for every iteration of the loop and then update the color of the rectangle on JavaFX application thread by using Platform.runLater.\n\n@Override\npublic void handle(Event arg0) {\n new Thread(() -> {\n for(int i=0; i<10; i++) {\n try {\n Thread.sleep(1000); // Wait for 1 sec before updating the color\n } catch (InterruptedException e) {\n e.printStackTrace();\n }\n int finalI = i;\n Platform.runLater(() -> rectangles[finalI].setFill(Color.RED));// Update on JavaFX Application Thread\n }\n}).start();\n\n\nThe above snippet is more of a traditional way of doing things. If we want to use the \"JavaFX\" ways of doing things, we can achieve the same by using an Animation.\n\nBelow is a code snippet which will wait for x-seconds before changing the color of the rectangle. It doesn't need any extra thread since the wait is handled by PauseTransition applied for each rectangle.\n\nstartButton.setOnMouseClicked(new EventHandler<Event>() {\n @Override\n public void handle(Event arg0) {\n for(int i=0; i<10; i++) {\n PauseTransition pauseTransition = new PauseTransition(Duration.seconds(i));\n int finalI = i;\n pauseTransition.setOnFinished(event -> rectangles[finalI].setFill(Color.RED));\n pauseTransition.play();\n }\n }\n});\n\n\nIt creates a PauseTransition for each rectangle and depending on its index in the array rectangles, it waits for the same number of seconds before updating the color.",
2016-08-16T08:58:56
yy