JavaFX:通过点击两次鼠标在 Canvas 上绘制一个矩形

标签 java javafx canvas drawing rectangles

我正在尝试创建一个程序,它应该根据两次鼠标左键单击在 Canvas 上绘制一个矩形,并通过一次右键单击清除 Canvas 。

应该以某种方式创建矩形,其中第一次鼠标单击模拟矩形的一个角,下一次鼠标单击模拟与第一次鼠标单击相比的矩形的对角角。

我被困在如何存储第一次鼠标单击的坐标,然后充分利用第二次鼠标单击的坐标,因为每个定义的矩形仅基于一组坐标创建,即上层坐标矩形的左角。

现在,我的所有代码所做的就是绘制固定大小的矩形(50x25),这显然不是我想要的。这只是为了看看清除部分是否有效。

这是我到目前为止所得到的:

package application;

import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;

public class DrawRectangle extends Application {

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

    @Override
    public void start(Stage primaryStage) {
        primaryStage.setTitle("Title");
        Canvas canv = new Canvas(500, 400);
        GraphicsContext gc = canv.getGraphicsContext2D();

        EventHandler<MouseEvent> event = new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent event) {
                if (event.getButton() == MouseButton.PRIMARY) {
                    double x = event.getX();
                    double y = event.getY();                    
                    gc.setFill(Color.BLUE);
                    gc.fillRect(x, y, 50, 25);
                }
            }
        };

        canv.addEventHandler(MouseEvent.MOUSE_CLICKED, event);

        EventHandler<MouseEvent> event2 = new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent event2) {
                if (event2.getButton() == MouseButton.SECONDARY) {
                gc.clearRect(0, 0, 500, 400);
                }
            }
        };

        canv.addEventHandler(MouseEvent.MOUSE_CLICKED, event2);

        StackPane root = new StackPane();
        root.getChildren().add(canv);

        primaryStage.setScene(new Scene(root, 500, 400));
        primaryStage.show();
    }
}

我不知道鼠标单击应该模拟矩形的哪些角是否重要,也许有人有任何想法?

致以诚挚的问候,新年快乐

最佳答案

只需将第一个点击点保存在成员变量中,然后使用它并在用户进行第二个点击点时重置它。

注意:下面的示例代码使用 switch expression从 Java 13+ 开始。如果 switch 表达式在您的 Java 版本中不可用,请将其转换为标准 switch 语句或 if/else 子句。

import javafx.application.Application;
import javafx.geometry.*;
import javafx.scene.Scene;
import javafx.scene.canvas.*;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

public class DrawRectangle extends Application {

    private static final int W = 500;
    private static final int H = 400;

    private Point2D savedPoint = null;

    @Override
    public void start(Stage stage) {
        Canvas canvas = new Canvas(W, H);
        GraphicsContext gc = canvas.getGraphicsContext2D();

        canvas.setOnMouseClicked(event -> {
            switch (event.getButton()) {
                case PRIMARY   -> handlePrimaryClick(gc, event);
                case SECONDARY -> gc.clearRect(0, 0, W, H);
            }
        });

        stage.setResizable(false);
        stage.setScene(new Scene(new StackPane(canvas), W, H));
        stage.show();
    }

    private void handlePrimaryClick(GraphicsContext gc, MouseEvent event) {
        Point2D clickPoint = new Point2D(event.getX(), event.getY());

        if (savedPoint == null) {
            savedPoint = clickPoint;
        } else {
            Rectangle2D rectangle2D = getRect(savedPoint, clickPoint);

            gc.setFill(Color.BLUE);
            gc.fillRect(
                    rectangle2D.getMinX(),
                    rectangle2D.getMinY(),
                    rectangle2D.getWidth(),
                    rectangle2D.getHeight()
            );

            savedPoint = null;
        }
    }

    private Rectangle2D getRect(Point2D p1, Point2D p2) {
        return new Rectangle2D(
                Math.min(p1.getX(), p2.getX()),
                Math.min(p1.getY(), p2.getY()),
                Math.abs(p1.getX() - p2.getX()),
                Math.abs(p1.getY() - p2.getY())
        );
    }

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

关于JavaFX:通过点击两次鼠标在 Canvas 上绘制一个矩形,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59534336/

相关文章:

java - 如何更改createTempFile中的默认名称?

java - 将 String 与 Switch 语句一起使用?

java - Android 的 PreferenceScreen 替代方案

java - MVC模式: What happen when exists views with data about two or more models?

Javafx,有没有办法检查按钮的状态并根据其状态执行 if 语句?

java - 如何让2个动画连续运行

javascript - phonegap 中不显示远程图像源

java - 拖动时增加 TableRow 的高度

java - 如何在 JavaFX Canvas 上禁用抗锯齿功能?

javascript - 如何在 Canvas 中绘制从页面加载的图像