方形单元格的方形 GridPane
Square GridPane of square cells
我的目标是创建一个可调整大小的 GridView,它始终是方形的并且包含相同数量的行和列,使它们的单元格也是方形的,类似于黑白棋或国际象棋棋盘。
这是一个小插图,网格在内容窗格上水平居中。
我已经尝试过多种不同的绑定变体和布局,但我不能完全正确。这是我的控制器(到目前为止):
public class Controller {
public HBox contentPane;
public void initialize() {
final int sideLength = 10;
final GridPane gridPane = new GridPane();
gridPane.setStyle("-fx-border-color: red; -fx-border-insets: 2");
HBox.setHgrow(gridPane, Priority.ALWAYS);
for (int i = 0; i < sideLength; i++) {
final ColumnConstraints columnConstraints = new ColumnConstraints(Control.USE_PREF_SIZE, 10, Double.MAX_VALUE);
columnConstraints.setHgrow(Priority.ALWAYS);
gridPane.getColumnConstraints()
.add(columnConstraints);
final RowConstraints rowConstraints = new RowConstraints(Control.USE_PREF_SIZE, 10, Double.MAX_VALUE);
rowConstraints.setVgrow(Priority.ALWAYS);
gridPane.getRowConstraints()
.add(rowConstraints);
}
contentPane.getChildren().add(gridPane);
for (int i = 0; i < sideLength; i++) {
for (int j = 0; j < sideLength; j++) {
final GameCell child = new GameCell();
GridPane.setRowIndex(child, i);
GridPane.setColumnIndex(child, j);
gridPane.getChildren().add(child);
}
}
}
}
还有应该包含形状的单元格,但我现在只有 Circle
只是为了测试它:
public class GameCell extends VBox {
private final Circle circle;
public GameCell() {
circle = new Circle();
setMinSize(0, 0);
setPrefSize(Control.USE_COMPUTED_SIZE, Control.USE_COMPUTED_SIZE);
getChildren().add(circle);
final ChangeListener<Number> listener = (observable, oldValue, newValue) ->
circle.setRadius((int) (Math.min(this.getWidth(), this.getHeight()) / 2));
widthProperty().addListener(listener);
heightProperty().addListener(listener);
}
}
这是目前的样子:
通过大量修补解决了它,这是我的解决方案以供将来参考:
游戏单元格:
public class GameCell extends Pane {
public GameCell() {
final Circle circle = new Circle(10);
circle.radiusProperty().bind(Bindings.divide(widthProperty(), 4));
circle.centerXProperty().bind(widthProperty().divide(2));
circle.centerYProperty().bind(widthProperty().divide(2));
getChildren().add(circle);
}
}
游戏窗格:
public class GamePane extends HBox {
public GamePane() {
final VBox vBox = new VBox();
vBox.alignmentProperty().set(Pos.CENTER);
alignmentProperty().set(Pos.CENTER);
final GridPane gridPane = new GridPane();
final NumberBinding binding = Bindings.min(widthProperty(), heightProperty());
gridPane.setMinSize(200, 200);
vBox.prefWidthProperty().bind(binding);
vBox.prefHeightProperty().bind(binding);
vBox.setMaxSize(Control.USE_PREF_SIZE, Control.USE_PREF_SIZE);
vBox.setFillWidth(true);
VBox.setVgrow(gridPane, Priority.ALWAYS);
final int sideLength = 8;
for (int i = 0; i < sideLength; i++) {
final ColumnConstraints columnConstraints = new ColumnConstraints(Control.USE_PREF_SIZE, Control.USE_COMPUTED_SIZE, Double.MAX_VALUE);
columnConstraints.setHgrow(Priority.SOMETIMES);
gridPane.getColumnConstraints().add(columnConstraints);
final RowConstraints rowConstraints = new RowConstraints(Control.USE_PREF_SIZE, Control.USE_COMPUTED_SIZE, Double.MAX_VALUE);
rowConstraints.setVgrow(Priority.SOMETIMES);
gridPane.getRowConstraints().add(rowConstraints);
}
vBox.getChildren().add(gridPane);
getChildren().add(vBox);
HBox.setHgrow(this, Priority.ALWAYS);
for (int i = 0; i < sideLength; i++) {
for (int j = 0; j < sideLength; j++) {
final Pane child = new GameCell();
GridPane.setRowIndex(child, i);
GridPane.setColumnIndex(child, j);
gridPane.getChildren().add(child);
}
}
}
}
这为我解决了 GridPane 的方形问题,似乎比原来的答案简单了一些。它使用 Kotlin 和 TornadoFX 构建器,但无论哪种方式,要点都应该是可读的。
val size = doubleProperty(16.0)
val grid = gridpane {
maxHeightProperty().bind(size)
maxWidthProperty().bind(size)
}
val root = vbox(alignment = Pos.CENTER) {
size.bind(Bindings.min(widthProperty(), heightProperty()))
grid.vgrow = Priority.ALWAYS
add(grid)
}
我的目标是创建一个可调整大小的 GridView,它始终是方形的并且包含相同数量的行和列,使它们的单元格也是方形的,类似于黑白棋或国际象棋棋盘。
这是一个小插图,网格在内容窗格上水平居中。
我已经尝试过多种不同的绑定变体和布局,但我不能完全正确。这是我的控制器(到目前为止):
public class Controller {
public HBox contentPane;
public void initialize() {
final int sideLength = 10;
final GridPane gridPane = new GridPane();
gridPane.setStyle("-fx-border-color: red; -fx-border-insets: 2");
HBox.setHgrow(gridPane, Priority.ALWAYS);
for (int i = 0; i < sideLength; i++) {
final ColumnConstraints columnConstraints = new ColumnConstraints(Control.USE_PREF_SIZE, 10, Double.MAX_VALUE);
columnConstraints.setHgrow(Priority.ALWAYS);
gridPane.getColumnConstraints()
.add(columnConstraints);
final RowConstraints rowConstraints = new RowConstraints(Control.USE_PREF_SIZE, 10, Double.MAX_VALUE);
rowConstraints.setVgrow(Priority.ALWAYS);
gridPane.getRowConstraints()
.add(rowConstraints);
}
contentPane.getChildren().add(gridPane);
for (int i = 0; i < sideLength; i++) {
for (int j = 0; j < sideLength; j++) {
final GameCell child = new GameCell();
GridPane.setRowIndex(child, i);
GridPane.setColumnIndex(child, j);
gridPane.getChildren().add(child);
}
}
}
}
还有应该包含形状的单元格,但我现在只有 Circle
只是为了测试它:
public class GameCell extends VBox {
private final Circle circle;
public GameCell() {
circle = new Circle();
setMinSize(0, 0);
setPrefSize(Control.USE_COMPUTED_SIZE, Control.USE_COMPUTED_SIZE);
getChildren().add(circle);
final ChangeListener<Number> listener = (observable, oldValue, newValue) ->
circle.setRadius((int) (Math.min(this.getWidth(), this.getHeight()) / 2));
widthProperty().addListener(listener);
heightProperty().addListener(listener);
}
}
这是目前的样子:
通过大量修补解决了它,这是我的解决方案以供将来参考:
游戏单元格:
public class GameCell extends Pane {
public GameCell() {
final Circle circle = new Circle(10);
circle.radiusProperty().bind(Bindings.divide(widthProperty(), 4));
circle.centerXProperty().bind(widthProperty().divide(2));
circle.centerYProperty().bind(widthProperty().divide(2));
getChildren().add(circle);
}
}
游戏窗格:
public class GamePane extends HBox {
public GamePane() {
final VBox vBox = new VBox();
vBox.alignmentProperty().set(Pos.CENTER);
alignmentProperty().set(Pos.CENTER);
final GridPane gridPane = new GridPane();
final NumberBinding binding = Bindings.min(widthProperty(), heightProperty());
gridPane.setMinSize(200, 200);
vBox.prefWidthProperty().bind(binding);
vBox.prefHeightProperty().bind(binding);
vBox.setMaxSize(Control.USE_PREF_SIZE, Control.USE_PREF_SIZE);
vBox.setFillWidth(true);
VBox.setVgrow(gridPane, Priority.ALWAYS);
final int sideLength = 8;
for (int i = 0; i < sideLength; i++) {
final ColumnConstraints columnConstraints = new ColumnConstraints(Control.USE_PREF_SIZE, Control.USE_COMPUTED_SIZE, Double.MAX_VALUE);
columnConstraints.setHgrow(Priority.SOMETIMES);
gridPane.getColumnConstraints().add(columnConstraints);
final RowConstraints rowConstraints = new RowConstraints(Control.USE_PREF_SIZE, Control.USE_COMPUTED_SIZE, Double.MAX_VALUE);
rowConstraints.setVgrow(Priority.SOMETIMES);
gridPane.getRowConstraints().add(rowConstraints);
}
vBox.getChildren().add(gridPane);
getChildren().add(vBox);
HBox.setHgrow(this, Priority.ALWAYS);
for (int i = 0; i < sideLength; i++) {
for (int j = 0; j < sideLength; j++) {
final Pane child = new GameCell();
GridPane.setRowIndex(child, i);
GridPane.setColumnIndex(child, j);
gridPane.getChildren().add(child);
}
}
}
}
这为我解决了 GridPane 的方形问题,似乎比原来的答案简单了一些。它使用 Kotlin 和 TornadoFX 构建器,但无论哪种方式,要点都应该是可读的。
val size = doubleProperty(16.0)
val grid = gridpane {
maxHeightProperty().bind(size)
maxWidthProperty().bind(size)
}
val root = vbox(alignment = Pos.CENTER) {
size.bind(Bindings.min(widthProperty(), heightProperty()))
grid.vgrow = Priority.ALWAYS
add(grid)
}