gpt4 book ai didi

java - 移动 JavaFx8 节点的正确方法

转载 作者:行者123 更新时间:2023-12-01 18:23:09 25 4
gpt4 key购买 nike

我正在开发一个需要在 Pane 上移动节点的应用程序。

我最近刚刚开始学习 javaFx 8,所以我对工作流程只有一点了解,但是虽然我设法让可拖动节点代码正常工作,但它使用了 node.setTranslateX() 和 .setTranslateY()。

这一切都很好,直到我尝试使节点捕捉到将场景区域划分为 10 个高度和宽度的网格。

每当我尝试使用模数来进行某种捕捉时,我都会坚持这样一个事实:我正在调用翻译转换。我想直接自己设置节点的坐标。我尝试过node.relocate(x,y)但无济于事。至于node.setX()或node.setY()。这些似乎没有多大作用。

基本上,我有两个问题:

  • 有没有办法直接设置节点的坐标?如果是,怎么做?
  • 使用鼠标拖动节点时将节点对齐到网格的正确方法是什么?

我当前的代码使用这些方法来拖动节点:

public class Boat extends ImageView {
private int size ;
private String name ;
private Double dragDeltaX, dragDeltaY;

//Constructor etc here//

this.setOnMousePressed(event -> {
this.setCursor(Cursor.CLOSED_HAND);
dragDeltaX = this.getLayoutX() + event.getX();
dragDeltaY = this.getLayoutY() + event.getY();
});

this.setOnMouseReleased(event -> {
this.setCursor(Cursor.OPEN_HAND);
this.relocate(event.getSceneX(), event.getSceneY());
});

this.setOnMouseDragged(event -> {
this.setTranslateX(event.getSceneX() - dragDeltaX);
this.setTranslateY(event.getSceneY() - dragDeltaY);
});

this.setOnMouseEntered(event -> {
this.setCursor(Cursor.OPEN_HAND);
});
}

预先感谢您的帮助,

最佳答案

在大多数 Pane 子类中,如果 Nodemanaged ,那么该节点的父 Pane 将管理其 layoutXlayoutY 属性。因此,为这些节点设置 layoutXlayoutY 不会对该节点的位置产生可见的影响。

转换(包括由 translateXtranslateY 定义的转换)在布局计算后应用于节点(无论该节点是否由其父节点管理)。

因此,管理拖动的一种方法就是操作 translateXtranslateY 属性。另一种方法是操作 layoutXlayoutY 属性(通过直接设置它们或通过调用 relocate),并确保节点不受管理由其父级。我不建议混合使用这两种技术,因为您的代码将更难遵循。

您可以在节点上将节点设为非托管 setManaged(false),或者将其放入 Pane 而不是子类之一 (Pane 不管理其子节点的布局)。

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.image.WritableImage;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

public class ImageViewDragExample extends Application {

@Override
public void start(Stage primaryStage) {
Image image = createImage();
DraggableImageView imageView = new DraggableImageView(image);

// if the node is placed in a parent that manages its child nodes,
// you must call setManaged(false);

// imageView.setManaged(false);
// StackPane root = new StackPane(imageView);

// or use a plain `Pane`, which does not manage its child nodes:
Pane root = new Pane(imageView);

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

private Image createImage() {
WritableImage image = new WritableImage(50, 50);
for (int y = 0 ; y < 50; y++) {
for (int x = 0 ; x < 50 ; x++) {
Color c ;
if ((x > 20 && x < 30) || (y > 20 && y < 30)) {
c = Color.AZURE ;
} else {
c = Color.CORNFLOWERBLUE ;
}
image.getPixelWriter().setColor(x, y, c);
}
}
return image ;
}

public static class DraggableImageView extends ImageView {
private double mouseX ;
private double mouseY ;
public DraggableImageView(Image image) {
super(image);

setOnMousePressed(event -> {
mouseX = event.getSceneX() ;
mouseY = event.getSceneY() ;
});

setOnMouseDragged(event -> {
double deltaX = event.getSceneX() - mouseX ;
double deltaY = event.getSceneY() - mouseY ;
relocate(getLayoutX() + deltaX, getLayoutY() + deltaY);
mouseX = event.getSceneX() ;
mouseY = event.getSceneY() ;
});
}
}

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

关于java - 移动 JavaFx8 节点的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27080039/

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