当前位置: 首页 > 知识库问答 >
问题:

JavaFX:基于2次鼠标单击在画布上绘制矩形

燕建中
2023-03-14

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

创建矩形的方式应该是,第一次鼠标点击模拟矩形的一个角,下一次鼠标点击与第一次鼠标点击相比模拟矩形的对角线角。

我被困在如何存储第一次鼠标点击的坐标,然后把第二次鼠标点击用好,因为每个定义的矩形只基于一组坐标创建,这是矩形的左上角。

现在,我的代码所做的只是绘制固定大小的矩形(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();
    }
}

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

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

共有1个答案

赵骏奇
2023-03-14

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

注意:下面的示例代码使用了来自Java 13+的开关表达式。如果您的Java版本中没有switch表达式,请将其转换为标准的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);
    }
}
 类似资料:
  • 在HTML和JavaScript中,这应该是一个非常简单的任务。我有一个图标栏,目前有一个单一的可点击链接,新的框。在图标栏下面,我有一张画布。我的目标是在用户每次按下new Box按钮时,在画布上绘制一个新的矩形。 现在,我的图标栏和画布正确显示,我可以单击图标栏的“新建框”链接,但画布上没有出现矩形,尽管我已将其参数指定为:。 null null

  • 问题内容: 如标题所示,我很难在JApplet中绘制一些矩形(填充的)。确切的目标是拥有一张50x50的表格,并在您 点击目标单元格时将其填充(可以通过绘制一个填充的矩形来完成)。我已经完成了有关起点坐标的数学运算, 但是由于某些原因,我无法在MouseClicked方法中绘制新矩形。有什么建议? 问题答案: 这是一个相对简单的概念(没有冒犯性)。 首先,请勿将代码与JApplet和混合使用JFr

  • 我在画布上处理鼠标事件时遇到问题。我想用鼠标来绘制它,我已经想出了这些事件处理程序,但当我开始绘制时,它们什么都不做。 你能帮我告诉我遗漏了什么或者如何重写它以便它开始工作吗?

  • 类Canvas扩展java.awt.Canvas实现MouseListener,MouseMotionListener{//Constants for shapes public static final int CIRCLE=1;public static final int RECTANGLE=2; }

  • 问题内容: 我必须在鼠标移动时画线,单击鼠标后,应该继续画线,直到双击为止。说点A,点B和点C。在点A上单击鼠标时,应开始画线。当在B点上单击鼠标时,除非双击,否则上一条线应该与新线一起从B点开始绘制。C点应相同,依此类推,直到双击鼠标为止。经过研究,我编写了下面的代码,它工作得很好,但是它可以用于拖动NOT MOUSE MOVE事件,我试图将代码转移到mouseMoved事件,但是上一行消失了。

  • 问题内容: 我只想在鼠标单击后绘制圆圈。由于paintComponent方法调用了自身,因此首先绘制圆而无需单击。 问题答案: 您的代码存在一些问题: 你永远不会打电话 你只需要一个和 请注意,当您调整框架大小时,某些圆圈将消失,并且总体上以奇怪的方式表现。 我会将所有s 存储在用户单击的位置,然后在方法内部遍历该列表。这样您就可以通话,而圈子不会消失。 更改后的工作代码: