JavaFX:根据 2 次鼠标点击在 canvas 上绘制一个矩形
JavaFX: Draw a rectangle on canvas based on 2 mouse clicks
我正在尝试创建一个程序,它应该根据鼠标左键单击两次在 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();
}
}
我不知道鼠标点击应该模拟矩形的哪个角是否重要,也许有人有什么想法?
致以最诚挚的问候,新年快乐
只需将第一次点击点保存在一个成员变量中,然后在用户进行第二次点击时使用并重新设置。
注意:下面的示例代码使用 Java 13+ 中的 switch expression。如果 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);
}
}
我正在尝试创建一个程序,它应该根据鼠标左键单击两次在 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();
}
}
我不知道鼠标点击应该模拟矩形的哪个角是否重要,也许有人有什么想法?
致以最诚挚的问候,新年快乐
只需将第一次点击点保存在一个成员变量中,然后在用户进行第二次点击时使用并重新设置。
注意:下面的示例代码使用 Java 13+ 中的 switch expression。如果 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);
}
}