我正在尝试实现一个国际象棋游戏。板 GUI 是 stackPanes 的 gridPane(Square 类)。这些片段是 stackPanes 上的 imageView。当在一 block 上检测到拖动时,它将开始完整拖动。当释放拖动时,应该将 mouseDragReleased 事件发送到释放点处鼠标下方的 stackPane 。但事件会被发送到该片段开始的原始 stackPane。我到处都找过了,找不到解决办法。错误在哪里?
public class Square extends StackPane {
private final int rank;
private final char file;
public Square(int colorType, int rank, char file) {
super();
Color color;
if (colorType == 0)
color = Color.DARKGREEN;
else
color = Color.BEIGE;
this.rank = rank;
this.file = file;
this.setPrefSize(60, 60);
this.setBackground(new Background(new BackgroundFill(color, CornerRadii.EMPTY, Insets.EMPTY)));
this.setBorder(new Border(new BorderStroke(Color.BLACK, BorderStrokeStyle.SOLID, CornerRadii.EMPTY, new BorderWidths(1))));
setMouseEventHandlers();
}
public void initializePieceImage(ChessPiece piece) {
if (piece != null) {
PieceImageView pieceImageView = new PieceImageView(piece.getColor(), SwingFXUtils.toFXImage(piece.getImage(), null), piece.getRank(), piece.getFile());
this.getChildren().clear();
this.getChildren().add(pieceImageView);
}
}
private void setMouseEventHandlers() {
this.setOnMouseDragReleased(((MouseDragEvent event) -> {
PieceImageView newPieceImageView = (PieceImageView) event.getGestureSource();
if (ChessGame.movePiece(newPieceImageView.getRank(), newPieceImageView.getFile(), this.getRank(), this.getFile())) { // move legality check
this.getChildren().clear();
newPieceImageView.setFile(this.getFile());
newPieceImageView.setRank(this.getRank());
Square oldSquare = (Square) newPieceImageView.getParent();
this.getChildren().add(newPieceImageView);
}
}));
}
public class PieceImageView extends ImageView {
private final PlayerColor color;
private int rank;
private char file;
private double startDragX;
private double startDragY;
public PieceImageView(PlayerColor color, Image image, int rank, char file) {
super(image);
this.color = color;
this.rank = rank;
this.file = file;
if (color.equals(ChessGame.getPlayerColor()))
setMouseEventHandlers();
}
private void setMouseEventHandlers() {
this.setOnMousePressed((MouseEvent event) -> {
this.setMouseTransparent(true);
});
this.setOnMouseReleased((MouseEvent event) -> {
this.setMouseTransparent(false);
});
this.setOnDragDetected((MouseEvent event) -> {
startDragX = event.getSceneX();
startDragY = event.getSceneY();
this.getParent().toFront();
this.startFullDrag();
});
this.setOnMouseDragged((MouseEvent event) -> {
this.setTranslateX(event.getSceneX() - startDragX);
this.setTranslateY(event.getSceneY() - startDragY);
});
}
最佳答案
我通过将此行添加到 Square 构造函数中解决了该问题:
this.setPickOnBounds(false);
关于JavaFX MouseDragReleased 事件未发送到 fullDrag 中的目标节点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60452025/