I am creating a "threes" clone for my assignment and one of the properties was to have a dynamically sizable GridPane
depending on the number of columns and rows, how can I achieve this?
I've looked at adding ColumnConstraints
as well as RowConstraints
, given them a percentile width of the total GridPane
size divided by the number of columns:
// width = total / number of columns
// height = total / number of rows
In Scene Builder the GridPane
has by default a 4x4 size; these elements seem to resize just fine but when say a 4x5 size is loaded it seems to only want to show 4x4 (styled) and the other remaining tiles look "weird".
Here's what it looks like: https://i.stack.imgur.com/S9uVb.jpg
// width = total / number of columns
// height = total / number of rows
gridPane.setGridLinesVisible(false);
gridPane.setAlignment(Pos.TOP_LEFT);
gridPane.getChildren().clear();
RowConstraints rowConstraint = new RowConstraints();
rowConstraint.setPercentHeight(300 / game.getBoardSizeY());
ColumnConstraints colConstraint = new ColumnConstraints();
colConstraint.setPercentWidth(350 / game.getBoardSizeX());
for(int x= 0; x < game.getBoardSizeX(); x++) {
gridPane.getColumnConstraints().add(colConstraint);
for(int y = 0; y < game.getBoardSizeY(); y++) {
gridPane.getRowConstraints().add(rowConstraint);
Tile tile = game.getBoard().getPos(x, y);
Pane pane = new Pane();
String lblText = "";
String itemClass = "";
if(tile.getValue() != 0) {
lblText = String.valueOf(tile.getValue());
}
int tileVal = tile.getValue();
if(tileVal == 1) {
itemClass = "blueTile";
}else if (tileVal == 2) {
itemClass = "redTile";
}else if (tileVal >= 3 ) {
itemClass = "whiteTile";
}else {
itemClass = "defaultTile";
}
Label lblVal = new Label(lblText);
pane.getStyleClass().addAll("tile", itemClass);
lblVal.layoutXProperty().bind(pane.widthProperty().subtract(lblVal.widthProperty()).divide(2));
pane.getChildren().add(lblVal);
gridPane.add(pane, x, y);
}
}
I expect it to fill my entire GridPane
accordingly but instead it acts up and shows me the result shown in the images.
Edit:
I've gotten it to work however when I have differentiating rows (like 4x5 for example) it doesn't quite work out the sizing yet.
gridPane.setGridLinesVisible(false);
gridPane.setAlignment(Pos.TOP_LEFT);
gridPane.getChildren().clear();
gridPane.getChildren().removeAll();
gridPane.getColumnConstraints().clear();
gridPane.getRowConstraints().clear();
RowConstraints rowConstraint = new RowConstraints();
rowConstraint.setPercentHeight(350 / game.getBoardSizeY());
ColumnConstraints colConstraint = new ColumnConstraints();
colConstraint.setPercentWidth(300 / game.getBoardSizeX());
for(int x= 0; x < game.getBoardSizeX(); x++) {
gridPane.getColumnConstraints().add(colConstraint);
gridPane.getRowConstraints().add(rowConstraint);
for(int y = 0; y < game.getBoardSizeY(); y++) {
Tile tile = game.getBoard().getPos(x, y);
Pane pane = new Pane();
String lblText = "";
String itemClass = "";
if(tile.getValue() != 0) {
lblText = String.valueOf(tile.getValue());
}
int tileVal = tile.getValue();
if(tileVal == 1) {
itemClass = "blueTile";
}else if (tileVal == 2) {
itemClass = "redTile";
}else if (tileVal >= 3 ) {
itemClass = "whiteTile";
}else {
itemClass = "defaultTile";
}
Label lblVal = new Label(lblText);
pane.getStyleClass().addAll("tile", itemClass);
lblVal.layoutXProperty().bind(pane.widthProperty().subtract(lblVal.widthProperty()).divide(2));
pane.getChildren().add(lblVal);
gridPane.add(pane, x, y);
}
}
If I understood correctly, you want the rows and columns to resize so that all columns have the same width and all rows have the same height. If that's correct, this sounds wrong:
The percentile width/height is a relative measurement. You don't wan't to calculate that based on the current width/height. For instance, if you had 4 rows you'd have each row be 25% of the height.
That said, I don't believe you need to mess around with the width or height settings on the constraints. Just set the
RowConstraints.vgrow
andColumnConstraints.hgrow
properties toPriority.ALWAYS
. Here's an example: