不,您不能使用多于一个填充Rectangle
。理论上你可以使用具有多种背景的Region
,但这可能是一个坏主意。最有可能你会想至少有一些为片以下的功能,这是行不通的,如果你不做出个自己的节点:
我建议使用StackPane
,并把董事会在后台把Pane
在它上面放置件。只需使用ImageView
即可。
实施例:
@Override
public void start(Stage primaryStage) {
GridPane board = new GridPane();
Region[][] fields = new Region[8][8];
for (int i = 0; i < fields.length; i++) {
Region[] flds = fields[i];
for (int j = 0; j < flds.length; j++) {
Region field = new Region();
flds[j] = field;
field.setBackground(new Background(new BackgroundFill((i + j) % 2 == 0 ? Color.WHITE : Color.BLACK, CornerRadii.EMPTY, Insets.EMPTY)));
}
board.addRow(i, flds);
}
// use 1/8 of the size of the Grid for each field
RowConstraints rowConstraints = new RowConstraints();
rowConstraints.setPercentHeight(100d/8);
ColumnConstraints columnConstraints = new ColumnConstraints();
columnConstraints.setPercentWidth(100d/8);
for (int i = 0; i < 8; i++) {
board.getColumnConstraints().add(columnConstraints);
board.getRowConstraints().add(rowConstraints);
}
Pane piecePane = new Pane();
StackPane root = new StackPane(board, piecePane);
NumberBinding boardSize = Bindings.min(root.widthProperty(), root.heightProperty());
ImageView queen = new ImageView("https://upload.wikimedia.org/wikipedia/commons/thumb/4/47/Chess_qdt45.svg/480px-Chess_qdt45.svg.png");
DropShadow shadow = new DropShadow(BlurType.GAUSSIAN, Color.WHITE, 2, 1, 0, 0);
// drop shadow for black piece on black field
queen.setEffect(shadow);
// trigger move to topleft field on mouse click
queen.setOnMouseClicked(evt -> {
Node source = (Node) evt.getSource();
TranslateTransition animation = new TranslateTransition(Duration.seconds(0.5), source);
Region targetRegion = fields[0][0];
final PositionChangeListener listener = (PositionChangeListener) source.getUserData();
listener.setField(null);
animation.setByX(targetRegion.getLayoutX() - source.getLayoutX());
animation.setByY(targetRegion.getLayoutY() - source.getLayoutY());
animation.setOnFinished(e -> {
source.setTranslateX(0);
source.setTranslateY(0);
listener.setField(targetRegion);
});
animation.play();
});
PositionChangeListener changeListener = new PositionChangeListener(queen);
queen.setUserData(changeListener);
changeListener.setField(fields[4][3]);
// board size should be as large as possible but at most the min of the parent sizes
board.setPrefSize(Double.MAX_VALUE, Double.MAX_VALUE);
board.maxWidthProperty().bind(boardSize);
board.maxHeightProperty().bind(boardSize);
// same size for piecePane
piecePane.setPrefSize(Double.MAX_VALUE, Double.MAX_VALUE);
piecePane.maxWidthProperty().bind(boardSize);
piecePane.maxHeightProperty().bind(boardSize);
// add piece to piecePane
piecePane.getChildren().add(queen);
Scene scene = new Scene(root, 400, 400);
primaryStage.setScene(scene);
primaryStage.show();
}
private static class PositionChangeListener implements ChangeListener<Bounds> {
private final ImageView piece;
public PositionChangeListener(ImageView piece) {
this.piece = piece;
}
private Region currentField;
public void setField(Region newRegion) {
// register/unregister listeners to bounds changes of associated field
if (currentField != null) {
currentField.boundsInParentProperty().removeListener(this);
}
currentField = newRegion;
if (newRegion != null) {
newRegion.boundsInParentProperty().addListener(this);
changed(null, null, newRegion.getBoundsInParent());
}
}
@Override
public void changed(ObservableValue<? extends Bounds> observable, Bounds oldValue, Bounds newValue) {
// align piece with field
piece.setLayoutX(newValue.getMinX());
piece.setLayoutY(newValue.getMinY());
piece.setFitHeight(newValue.getHeight());
piece.setFitWidth(newValue.getWidth());
}
}
感谢您的回答。我一直在为此进行研究,但我不认为自己能够做到,但我只是想确保。我真的很喜欢你使用StackPane的建议,我会尝试一下。 – theAnon
fabian,我一直没有搞乱这段代码一段时间,我只是有一个快速的问题,如果我想添加一个MouseListener到每个单独的广场,并看看如果该广场是一个合法的举动某一块,成为添加监听器的最佳地点?我一直在努力想象它在过去的几天里,没有任何我已经尝试似乎工作。顺便谢谢你的这个例子,我已经从中学到了很多东西! – theAnon