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