Home > Back-end >  Changing location of shapes to a random location when mouse-clicked (javafx)
Changing location of shapes to a random location when mouse-clicked (javafx)

Time:07-16

I need exactly what the title says. I've made 10 circles with different radius sizes, now I just need to make them shift their locations when I click on the scene with the mouse. I tried finding the solution here but none of the questions contain exactly what I need. Here's my code:

Random random = new Random();

    int x = 0;
    int y = 0;
    int radius = 0;

    @Override
    public void start(Stage primaryStage) {

        Group root = new Group();

        for (int i = 0; i <= 10; i  ) {

            Circle circle = new Circle(x, y, radius);
            {
                radius = random.nextInt(66)   10;
                x = random.nextInt(600 - 2 * radius)   radius;
                y = random.nextInt(400 - 2 * radius)   radius;
            }
            circle.setFill(Color.BLACK);
            circle.setStroke(Color.BLUE);

            root.getChildren().add(circle);
        }
        Scene scene = new Scene(root, 800, 500, Color.BEIGE);
        Stage stage = new Stage();
        stage.setScene(scene);
        stage.show();
    }

CodePudding user response:

Set a click mouse event handler on the scene.

When the click event is triggered, loop through the children of the group and set the x and y properties of each circle to a random value.

If desired, rather than relying on the group's children and a cast, you could instead store the circles in a separate list and loop through that when the event is received.

Requires a minimum Java version of 16.

import javafx.application.Application;
import javafx.scene.*;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;

import java.io.IOException;
import java.util.concurrent.ThreadLocalRandom;

public class CircleApp extends Application {
    private static final int N_CIRCLES = 10;
    private static final int MIN_RADIUS = 10;
    private static final int MAX_RADIUS = 66;
    private static final int SCENE_WIDTH = 800;
    private static final int SCENE_HEIGHT = 500;

    @Override
    public void start(Stage stage) throws IOException {
        Group circleGroup = new Group();

        for (int i = 0; i <= N_CIRCLES; i  ) {
            circleGroup.getChildren().add(
                    createCircle()
            );
        }

        Scene scene = new Scene(
                circleGroup,
                SCENE_WIDTH, SCENE_HEIGHT,
                Color.BEIGE
        );
        stage.setScene(scene);
        stage.setResizable(false);
        stage.show();

        scene.setOnMouseClicked(e ->
                relocateCircles(circleGroup)
        );
    }

    public Circle createCircle() {
        double radius = randomInRange(
                MIN_RADIUS,
                MAX_RADIUS
        );
        double x = randomXLocation(radius);
        double y = randomYLocation(radius);

        Circle circle = new Circle(x, y, radius);
        circle.setFill(Color.BLACK);
        circle.setStroke(Color.BLUE);

        return circle;
    }

    private void relocateCircles(Group group) {
        for (Node node: group.getChildren()) {
            if (node instanceof Circle circle) {
                circle.setCenterX(
                        randomXLocation(
                                circle.getRadius()
                        )
                );
                circle.setCenterY(
                        randomYLocation(
                                circle.getRadius()
                        )
                );
            }
        }
    }
    
    private double randomXLocation(double radius) {
        return randomInRange(
            radius,
            SCENE_WIDTH - radius
        );
    }

    private double randomYLocation(double radius) {
        return randomInRange(
            radius,
            SCENE_HEIGHT - radius
        );
    }

    private double randomInRange(double min, double max) {
        return Math.round(
                ThreadLocalRandom.current().nextDouble(
                        min,
                        max
                )
        );
    }
}

For more complex shapes or a general solution for all node types, set the translateX and translateY values on the node rather than setting the centerX and centerY values of a circle (as centerX and centerY would not be available for other node types).

CodePudding user response:

translate x y with mouse event

Iterate through .getChildren().forEach() to get a child node of Group and translate it to random x y position . forEach() return a node object ,so it's not nescessary to cast it in this case

random positions

public class App extends Application {
    Random random = new Random();

    @Override
    public void start(Stage stage) {
          int x = 0;
    int y = 0;
    int radius = 0;
  Circle c = new Circle(30);
 Group root = new Group(c);
  
        for (int i = 0; i <= 10; i  ) {
           

            Circle circle = new Circle(x, y, radius);
            {
                radius = random.nextInt(66)   10;
                x = random.nextInt(600 - 2 * radius)   radius;
                y = random.nextInt(400 - 2 * radius)   radius;
            }
            circle.setFill(Color.BLACK);
            circle.setStroke(Color.BLUE);

            root.getChildren().add(circle);
        }
        Scene scene = new Scene(root, 800, 500, Color.BEIGE);
        
        scene.setOnMouseClicked(e->{
        
        root.getChildren().forEach((n) -> {
            n.setTranslateX(random.nextInt(0,800));
            n.setTranslateY(random.nextInt(0,500));
        });
        
        });
        
        stage.setScene(scene);
        stage.show();
    }

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

}
  • Related