gpt4 book ai didi

java - 尝试使用 JavaFX 通过鼠标创建形状

转载 作者:行者123 更新时间:2023-12-02 02:32:15 26 4
gpt4 key购买 nike

我正在尝试创建一个使用 JavaFX 的 Java 应用程序,允许用户通过选择单选按钮选项然后在 BorderPane 区域中单击并拖动来创建形状来创建形状。

到目前为止,我走在正确的道路上。我遇到的问题是如何正确定位它们。我希望有人能帮助我弄清楚为什么形状没有在我期望的地方创建。

目前,我创建的第一个形状被放置在 BorderPane 中心部分的 HBox 的左上角,无论我单击哪里开始创建。拖动鼠标似乎可以根据光标准确调整框的大小。

随后尝试创建形状会导致创建的形状偏离光标位置,并且拖动将调整大小,但也不与光标相关。

这是我的代码。我删除了与当前问题无关的部分,希望使其更具可读性:

public class Main extends Application{
public static String shapeType = "";
public static String color = "";

static Rectangle customRectangle = null;

public void start(Stage mainStage) throws Exception{
Group root = new Group();
Scene scene = new Scene(root, 600, 400);

BorderPane borderPane = new BorderPane();

.....

HBox canvas = new HBox();
Group canvasGroup = new Group();
canvas.getChildren().add(canvasGroup);

canvas.setStyle("-fx-background-color: yellow");

borderPane.setTop(shapeOptions);
borderPane.setLeft(colorOptions);
borderPane.setCenter(canvas);

canvas.addEventFilter(MouseEvent.ANY, new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
if(event.getEventType() == MouseEvent.MOUSE_PRESSED && shapeType != ""){
switch(shapeType){
case "rectangle":
createCustomRectangle(event, color, canvasGroup);
}
}
if(event.getEventType() == MouseEvent.MOUSE_DRAGGED){
switch (shapeType){
case "rectangle":
editCustomRectangle(event);
}
}
}
});

root.getChildren().add(borderPane);
mainStage.setScene(scene);
mainStage.show();
}

public static void createCustomRectangle(MouseEvent event, String color, Group canvasGroup){
customRectangle = new Rectangle(0, 0, 10,10);
customRectangle.relocate(event.getX(), event.getY());

customRectangle.setFill(Color.RED);
canvasGroup.getChildren().add(customRectangle);
}

public static void editCustomRectangle(MouseEvent event){
customRectangle.setWidth(event.getX() - customRectangle.getTranslateX());
customRectangle.setHeight(event.getY() - customRectangle.getTranslateY());
}

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

我还想附上几张图片以使我的问题更清楚。这里尝试创建第一个形状: Clicking and dragging to create first shape

这里尝试创建一个后续形状: Clicking and dragging to create another shape

希望描述、代码和图像足以传达正在发生的事情。任何帮助将不胜感激。

谢谢!

最佳答案

让我们开始一次解决每个问题。首先,一个友好的建议是,尝试以一种有助于读者理解其含义和身份的方式命名变量(当我第一次看到 canvas 变量时,我认为它是一个真正的 Canvas )。

现在你的布局是这样的:

BorderPane 
TOP
- Something
CENTER
- HBox
- Group
- Rectangle
- Rectangle
- ...
Left
- Something
Bottom
- Something
  1. HBox 获取所有可用高度并根据其子项计算其宽度。所以为了把所有的BorderPane 内的可用空间,您需要实际指定它或将其 PreferredWidthProperty 与BorderPane 的 width 属性。

  2. 从 Group 类的文档中您可以看到:

Any transform, effect, or state applied to a Group will be applied to all children of that group. Such transforms and effects will NOT be included in this Group's layout bounds, however, if transforms and effects are set directly on children of this Group, those will be included in this Group's layout bounds.

因此,当您重新定位节点(实际的矩形)时,relocate() 方法只需设置translateX 和translateY 值,并且该转换也会应用于组的布局边界。要解决此问题,您可以将 Group 更改为 AnchorPane。

  • 调整矩形大小的方式不正确。当第一次单击事件发生时,您需要获取第一次鼠标单击坐标,然后在拖动事件中,您将获取新坐标,计算 X 和 Y 的增量值,然后将该值添加到矩形的宽度和高度中最后更新拖动事件监听器上的firstX和firstY变量:

    deltaX = event.getX() - firstX;
    deltaY = event.getY() - firstY;

    customRectangle.setWidth(customRectangle.getWidth + deltaX);
    customRectangle.setHeight(customRectangle.getHeight + deltaY);
  • 这是上述示例:

    import javafx.application.Application;
    import javafx.event.EventHandler;
    import javafx.scene.Scene;
    import javafx.scene.input.MouseEvent;
    import javafx.scene.layout.AnchorPane;
    import javafx.scene.layout.BorderPane;
    import javafx.scene.layout.HBox;
    import javafx.scene.paint.Color;
    import javafx.scene.shape.Rectangle;
    import javafx.stage.Stage;

    public class Main extends Application {
    public static String shapeType = "";
    public static String color = "";

    private static Rectangle customRectangle = null;

    private double firstX = 0;
    private double firstY = 0;

    public void start(Stage mainStage) throws Exception {

    BorderPane mainPane = new BorderPane();

    HBox centerPane = new HBox();

    centerPane.prefWidthProperty().bind(mainPane.widthProperty());
    centerPane.prefHeightProperty().bind(mainPane.heightProperty());

    AnchorPane anchorPane = new AnchorPane();

    anchorPane.prefWidthProperty().bind(centerPane.widthProperty());
    anchorPane.prefHeightProperty().bind(centerPane.heightProperty());

    centerPane.getChildren().add(anchorPane);

    centerPane.setStyle("-fx-background-color: yellow");

    shapeType = "rectangle";

    mainPane.setCenter(centerPane);

    centerPane.addEventFilter(MouseEvent.ANY, new EventHandler<MouseEvent>() {
    @Override
    public void handle(MouseEvent event) {

    if (event.getEventType() == MouseEvent.MOUSE_PRESSED && shapeType != "") {
    switch (shapeType) {
    case "rectangle":
    firstX = event.getX();
    firstY = event.getY();
    createCustomRectangle(event, color, anchorPane);
    }
    }
    if (event.getEventType() == MouseEvent.MOUSE_DRAGGED) {
    switch (shapeType) {
    case "rectangle":
    editCustomRectangle(event);
    firstX = event.getX();
    firstY = event.getY();
    }
    }
    }
    });

    Scene scene = new Scene(mainPane, 600, 400);
    mainStage.setScene(scene);
    mainStage.show();
    }

    public void createCustomRectangle(MouseEvent event, String color, AnchorPane canvasGroup) {
    customRectangle = new Rectangle(0, 0, 10, 10); // or just set the actual X and Y from the start
    customRectangle.relocate(event.getX(), event.getY());

    customRectangle.setFill(Color.RED);
    canvasGroup.getChildren().add(customRectangle);
    }

    public void editCustomRectangle(MouseEvent event) {

    double deltaX = event.getX() - firstX;
    double deltaY = event.getY() - firstY;

    double width = customRectangle.getWidth() + deltaX;
    double height = customRectangle.getHeight() + deltaY;

    customRectangle.setWidth(width);
    customRectangle.setHeight(height);
    }

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

    关于java - 尝试使用 JavaFX 通过鼠标创建形状,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46913118/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com