1

I am trying to draw random circles with random x/y centers, but the result of my code is only one circle at the center of the stage (window).

I use Task class to update my UI every 1 second.

This is my code:

package javafxupdateui;

import javafx.application.Application;
import javafx.application.Platform;
import javafx.concurrent.Task;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;

public class JavaFXUpdateUI extends Application {

    private Stage window;
    private StackPane layout;
    private Scene scene;

    @Override
    public void start(Stage primaryStage) {
        window = primaryStage;
        window.setTitle("JavaFX - Update UI");

        layout = new StackPane();
        scene = new Scene(layout, 500, 500);
        window.setScene(scene);
        window.show();

        Thread th = new Thread(task);
        th.setDaemon(true);
        th.start();
    }

    Task task = new Task<Void>() {
        @Override
        protected Void call() throws Exception {
            while (true) {
                Platform.runLater(new Runnable() {
                    @Override
                    public void run() {
                            drawCircles();
                    }
                });

                Thread.sleep(1000);
            }
        }
    };

    public void drawCircles() {
        Circle circle;
        float x = (float)(Math.random()*501);
        float y = (float)(Math.random()*501);
        circle = new Circle(x, y, 25, Color.RED);
        layout.getChildren().add(circle);
        scene.setRoot(layout);
        window.setScene(scene);
    }

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

The result of the above code is: Result GUI

sha
  • 13
  • 5

1 Answers1

1

What is going wrong

StackPane is a layout pane, it centers everything by default. As you want to manually place the circles at random locations, you don't want to use a pane which manages the layout for you.

How to fix it

Use a Pane or a Group instead of StackPane. Neither Pane nor Group manage the layout of items for you, so children you add to them at specific locations will remain at those locations.

Aside

You might wish to use a Timeline for your periodic updates rather than a Task with runLater (though the later will still work OK, with a Timeline you don't have to deal with additional complexities of concurrent code).

Community
  • 1
  • 1
jewelsea
  • 150,031
  • 14
  • 366
  • 406