0

How can I select a shape (a circle, rectangle etc.) so only the selected shape is edited when I click some buttons?

This is the code:

package application;

import javafx.application.Application;
import javafx.stage.Stage;
import javafx.geometry.*;
import javafx.scene.Scene;
import javafx.scene.Group;
import javafx.scene.shape.*;
import javafx.scene.control.Button;
import javafx.scene.image.ImageView;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;
import javafx.scene.text.Text;
import java.util.Random;

public class CirclesAndSquares extends Application {

    @Override
    public void start(Stage primaryStage) {
        /** set up the pane and boxes*/
        BorderPane pane = new BorderPane();
        HBox top = new HBox();
        top.setAlignment(Pos.CENTER);
        HBox bottom = new HBox();
        bottom.autosize();
        bottom.setAlignment(Pos.CENTER);
        VBox left = new VBox();
        left.autosize();
        left.setAlignment(Pos.CENTER);
        VBox right = new VBox();
        right.autosize();
        right.setAlignment(Pos.CENTER);
        Pane center = new Pane();
        center.autosize();
        center.setStyle("-fx-border-color: black");

        /** set and place the buttons */
        Button btnRed = new Button("Red");
        Button btnGrn = new Button("Green");
        left.getChildren().addAll(btnRed, btnGrn);
        Button btnRot = new Button("Rotate");
        right.getChildren().add(btnRot);
        Button btnSqr = new Button("Square");
        Button btnCrcl = new Button("Circle");
        bottom.getChildren().addAll(btnSqr, btnCrcl);
        pane.setLeft(left);
        pane.setRight(right);
        pane.setTop(top);
        pane.setBottom(bottom);
        pane.setCenter(center);

        /** Draw circle and square */
        Rectangle square = new Rectangle();
        center.getChildren().add(square);
        Circle circle = new Circle();
        center.getChildren().add(circle);
        Shape shape;

        btnCrcl.setOnAction(e -> {
            circle.setRadius(50);
            circle.setStroke(Color.BLACK);
            circle.setFill(null);
            circle.setCenterX(circle.getRadius()+5 + Math.random()*(center.getWidth() - 2*circle.getRadius()-5));
            circle.setCenterY(circle.getRadius()+5 + Math.random()*(center.getHeight() - 2*circle.getRadius()-5));
        } );

        btnSqr.setOnAction(e -> {
            square.setHeight(100);
            square.setWidth(100);
            square.setStroke(Color.BLACK);
            square.setFill(null);
            square.setX(Math.random()*(center.getWidth() - square.getWidth()));
            square.setY(Math.random()*(center.getHeight() - square.getHeight()));
        } );



        Scene scene = new Scene(pane,400,400);
        scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
        primaryStage.setTitle("Draw square and circle");
        primaryStage.setScene(scene);
        primaryStage.show();

        btnRed.setOnAction(e -> {
            if (true) {
                System.out.println("true");
                circle.setFill(Color.RED);}
        } );

    }


    class CustomPane extends StackPane {
          public CustomPane(Button btn) {
            getChildren().addAll(btn);
            setStyle("-fx-border-color: red");
            setPadding(new Insets(11.5, 12.5, 13.5, 14.5));
          }

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

This is how it looks like:

enter image description here

When I click on "Red" I want the "selected shape" to be filled with red.

And selecting a shape should be done by clicking the "circle" button or "square" button,

or by clicking on the shapes on the pane.

How do I make a shape "selected"?

Is there some simple way to do it in JavaFX?

Coder88
  • 1,015
  • 3
  • 10
  • 23
  • 3
    implement logic that keeps track of which node was last clicked – kleopatra Feb 19 '20 at 23:42
  • @kleopatra `circle.setOnMouseClicked(e -> { circle.setFill(Color.RED); });` I used this, but this just change colors, not keeps track on which one is selected. Defining a varible in this scope doesn't work. – Coder88 Feb 19 '20 at 23:46
  • 4
    "Defining a varible in this scope doesn't work." => then don't define the variable to track the currently selected shape in that scope, define it outside of the lambda block (e.g. as a member of the enclosing class). – jewelsea Feb 20 '20 at 00:43
  • 2
    Possible duplicate: [How to implement selection of Nodes in JavaFX](https://stackoverflow.com/questions/40917005/how-to-implement-selection-of-nodes-in-javafx). – jewelsea Feb 20 '20 at 00:46
  • 1
    Note that click handlers may not do the trick in case of non-filled shapes. Hitting the border exactly can be tricky. Picking on the bounds can yield inaccurate results; basically everything that is not a rectangle with edges parallel to the axes will possibly yield false positives. – fabian Feb 20 '20 at 06:24
  • @jewelsea it doesn't work. I defined a variable outside lambda block, but its value can't be changed inside the block. – Coder88 Feb 20 '20 at 12:19
  • 1
    @Coder88 Did you define the variable as I suggested, as [a member of the enclosing class (a field)](https://docs.oracle.com/javase/tutorial/java/javaOO/variables.html)? If so, then it should work. If, instead, you defined a local variable and you try to change to variable value within a lambda, then [it won't work](https://stackoverflow.com/questions/25055392/lambdas-local-variables-need-final-instance-variables-dont). – jewelsea Feb 20 '20 at 21:34

0 Answers0