Jason Macville
Jason Macville

Reputation: 93

Create a draggable selection box for a sketching program in JavaFX

I'm trying to create a draggable selection box for a sketching program in JavaFX, one like this:Selection box from Paint

I'm only not sure how to do it. I initially wanted to do it like this: capture the mouse coordinates when the mouse is pressed and do it again at the end of a drag, then calculate the height and width and make a transparent button with a black border with these properties.

But, then I realized that when I do it like this, it is not possible to see the button while you are scaling the plane, unless you draw and delete a lot of buttons.

So, I wondered if there is a better way to do something like this or is my reasoning above right? Thanks

Upvotes: 0

Views: 1129

Answers (1)

James_D
James_D

Reputation: 209330

I would use a Rectangle instead of a Button. Just do what you describe, but update the size (and position) of the rectangle on mouse drag, instead of only adding it when the mouse is released.

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;

public class SelectionRectangle extends Application {

    private double mouseDownX ;
    private double mouseDownY ;

    @Override
    public void start(Stage primaryStage) {
        Rectangle selectionRectangle = new Rectangle();
        selectionRectangle.setStroke(Color.BLACK);
        selectionRectangle.setFill(Color.TRANSPARENT);
        selectionRectangle.getStrokeDashArray().addAll(5.0, 5.0);

        Pane pane = new Pane();
        pane.setMinSize(600, 600);

        pane.getChildren().add(selectionRectangle);

        pane.setOnMousePressed(e -> {
            mouseDownX = e.getX();
            mouseDownY = e.getY();
            selectionRectangle.setX(mouseDownX);
            selectionRectangle.setY(mouseDownY);
            selectionRectangle.setWidth(0);
            selectionRectangle.setHeight(0);
        });

        pane.setOnMouseDragged(e -> {
            selectionRectangle.setX(Math.min(e.getX(), mouseDownX));
            selectionRectangle.setWidth(Math.abs(e.getX() - mouseDownX));
            selectionRectangle.setY(Math.min(e.getY(), mouseDownY));
            selectionRectangle.setHeight(Math.abs(e.getY() - mouseDownY));
        });

        primaryStage.setScene(new Scene(pane));
        primaryStage.show();
    }

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

You can use a mouse released handler to figure out what's selected, by looking at the x, y, width, and height properties of the rectangle, as needed.

Upvotes: 2

Related Questions