gpt4 book ai didi

java - 如何将拖动的节点保持在其他节点前面(JavaFX 8)?

转载 作者:行者123 更新时间:2023-12-02 13:21:02 25 4
gpt4 key购买 nike

我正在尝试实现一个带有可拖动棋子的棋盘,如下所示。但是,我无法将被拖动的部分保持在其他节点前面、位于其下方或右侧。向左和向上似乎工作正常。

我试图通过声明 StackPane 来解决这个问题首先形成方格背景,然后才形成所有部分,正如我读到的那样,Java 根据 Node 的顺序分配 z 索引。 s 添加到其 Parent s。这种方法反射(reflect)如下。我还尝试创建 Group并添加 StackPaneImageView s 到它以便能够使用 toFront() 。结果只显示坐标标签。

如何实现我想要的功能?

此方法创建板:

public Parent chessBoard() {
GridPane board = new GridPane();
StackPane[][] cells = new StackPane[8][8];

// Create the board first
// (For dragging pieces to work correctly, draggable pieces must be
// added after the whole board, since z-index cannot be set explicitly
// in JavaFX.
for (int row = 0; row < 10; row++) {
for (int col = 0; col < 10; col++) {
// x and y in chess coordinate system (0-indexed)
int[] invertedY = {-1,7,6,5,4,3,2,1,0,-1};
int x = col - 1;
int y = invertedY[row];

// Coordinate labels
String[] abcLabels = {"A","B","C","D","E","F","G","H"};

if (row == 9 || row == 0) {
if (col == 0 || col == 9) continue;

Label label = new Label(abcLabels[x]);
label.setTextAlignment(TextAlignment.CENTER);
board.add(label, col, row);

continue;
} else if (col == 0 || col == 9) {
Label label = new Label(Integer.toString(y + 1));
board.add(label, col, row);

continue;
}

// Cell background color
Square square = game.getBoard().getSquare(x, y);
Color color = square.getColor() == ChessColor.BLACK
? Color.PERU : Color.BLANCHEDALMOND;

StackPane cell = cells[y][x] = new StackPane();
cell.setMaxSize(60, 60);
cell.setMinSize(60, 60);
cell.setBackground(new Background(
new BackgroundFill(color, null, null)));

board.add(cell, col, row);
}
}

// Finally, add pieces to their respective cells
for (int y = 0; y < 8; y++) {
for (int x = 0; x < 8; x++) {
Square square = game.getBoard().getSquare(x, y);
Piece occupant = square.getOccupant();

if (occupant != null) {
String path = "/resources/" + occupant + ".png";
Image image =
new Image(getClass().getResourceAsStream(path));
DraggablePieceIcon imageView =
new DraggablePieceIcon(image);
imageView.setManaged(false);
cells[y][x].getChildren().add(imageView);
}
}
}



return board;
}

此类制作可拖动的图标:

public class DraggablePieceIcon extends ImageView {
private double mouseX;
private double mouseY;

public DraggablePieceIcon(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();
});
}
}

这就是我所看到的:

enter image description here

最佳答案

您将从左到右逐行添加单元格。由于您将片段添加到单元格中,因此单元格的后代会覆盖该单元格上方或同一行左侧的单元格的内容,并且将被所有其他单元格的内容覆盖。

要解决此问题,您可以将拖动项目的父节点设为 GridPane 中的最顶层节点:

public DraggablePieceIcon(Image image) {
super(image);

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

// make cell containing this piece the top-most cell
this.getParent().toFront()
});

...
}

请注意,此解决方案将要求您实现一些逻辑,使碎片成为它们移动到的单元格的子级,并将碎片移动到这些单元格的中心。否则,如果稍后将片段拖动到这样的单元格内,则该片段可能会被其他单元格覆盖...

另一种方法是让这些片段成为 GridPane 本身的子元素。无论如何,您都允许独立于单元格来拖动碎片;单元和棋子之间的关联对于模型(即在本例中是国际象棋规则的实现)很重要,而不是对于 View ,并且通常这些部分是分开的。

关于java - 如何将拖动的节点保持在其他节点前面(JavaFX 8)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43555941/

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