How to create random circle locations when Button is pressed in JavaFX?

Rose :

I'm trying to learn Java from a Udemy course and I was asked to create an assignment before moving into the following sections.

The assignment is to write a JavaFX application that displays a circle and a button and every time said button is pressed the circle should be moved to random locations.

So far I have create a code that counts how many times I have clicked the button, now I would like to move the circle along with the counting:

public class CircleJumper extends Application {

    // Declare Variables
    private int count;
    private Circle initCircle;
    private Button initButton;
    private Text countText;

    /*
    *
    * Write function here
    *
    */
    @Override
    public void start(Stage primaryStage){

        // Initiate Variables
        count = 0;
        initCircle = new Circle(30, -50, 30);
        initButton = new Button("Click Me!");
        countText = new Text("Clicks: 0");
        // Here its where I built the click counter
        initButton.setOnAction((event) -> {
            count++;
            countText.setText("Pushes: " + count);
        });        
        ;
        Group baseDemo = new Group(initButton, countText);

        FlowPane pane = new FlowPane(baseDemo, initCircle);
        pane.setAlignment(Pos.CENTER);
        pane.setHgap(20);
        pane.setStyle("-fx-background-color: cyan");

        Scene scene = new Scene(pane, 600, 300);

        primaryStage.setTitle("Draw a Circle when Button is Pressed");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // TODO code application logic here
        launch(args);
    }

}

UPDATE: I decided to declare my variable count to be = Math.random(); and created a circle. After that, the click of the button should get the generated Math.random and put it inside the setTranslate, am I right?

    public void start(Stage primaryStage){

        // Initiate Variables
        count = Math.random();
        initCircle = new Circle(30, 50, 30);
        initButton = new Button("Click Me!");

        Group circlePos = new Group(initCircle);
        circlePos.setTranslateX(10);
        circlePos.setTranslateY(10);

        initButton.setOnAction((event) -> {
            count++;
            circlePos.setTranslateY(count);
            circlePos.setTranslateX(count);
        });

        Group baseDemo = new Group(initButton);

        FlowPane pane = new FlowPane(baseDemo, initCircle);
        pane.setAlignment(Pos.CENTER);
        pane.setHgap(20);
        pane.setStyle("-fx-background-color: cyan");

        Scene scene = new Scene(pane, 600, 300);

        primaryStage.setTitle("Draw a Circle when Button is Pressed");
        primaryStage.setScene(scene);
        primaryStage.show();
    }
jewelsea :

Try it yourself first, but I'll post a solution so that you can see how it is done, in case you get stuck.

  1. Create a random in your application init method
  2. Where you increase the click count, get a couple of ints using random.nextInt(bound) from the random.
  3. Set circle centerX and centerY to your random values.
  4. Done.

OK, well not quite done, the problem you will find when you try it (which you should) is that it won't work, the circle won't seem to center on the x and y values you set. This is because the Circle is in a layout pane (FlowPane), which will ignore your manual layout settings (though not translate values). The solution is to put the circle in the Group (as the first item, so that it is under everything), then put the flow pane in the group, and in the FlowPane you have your button and click counter.

You might wish to reserve translateX/Y for animation not for layout, though it could be used to move shapes around and is also OK to use for that reason.

import javafx.application.Application;
import javafx.scene.*;
import javafx.scene.control.Button;
import javafx.scene.layout.FlowPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.text.Text;
import javafx.stage.Stage;

import java.util.Random;

public class CircleJumper extends Application {
    private static final double MAX_X = 600;
    private static final double MAX_Y = 300;

    private int clickCount = 0;
    private Random random;

    @Override
    public void init() {
        random = new Random();
    }

    @Override
    public void start(Stage stage){
        Circle circle = new Circle(MAX_X / 2, MAX_Y / 2, 30);
        Button button = new Button("Click Me!");
        Text clickCountText = new Text("Clicks: " + clickCount);

        button.setOnAction((event) -> {
            clickCount++;
            clickCountText.setText("Clicks: " + clickCount);

            circle.setCenterX(random.nextInt((int) MAX_X));
            circle.setCenterY(random.nextInt((int) MAX_Y));
        });        

        Group layout = new Group(
                circle,
                new FlowPane(button, clickCountText)
        );

        stage.setScene(new Scene(layout, MAX_X, MAX_Y, Color.CYAN));
        stage.setResizable(false);
        stage.show();
    }

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

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=328172&siteId=1