简体   繁体   中英

Dynamically sizing the contents of a GridPane to the properties of their parent

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://imgur.com/gallery/Qv1oWZb

// 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:

I've looked at adding columnConstraints as well as rowConstraints, given them a percentile width of the total gridpane size devided by the number of columns

 // width = total / number of columns // height = total / number of rows 

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 and ColumnConstraints.hgrow properties to Priority.ALWAYS . Here's an example:

import javafx.application.Application;
import javafx.geometry.HPos;
import javafx.geometry.Pos;
import javafx.geometry.VPos;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.ColumnConstraints;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Priority;
import javafx.scene.layout.RowConstraints;
import javafx.stage.Stage;

public class Main extends Application {

  @Override
  public void start(Stage primaryStage) {
    GridPane root = new GridPane();
    root.setAlignment(Pos.CENTER);
    root.setGridLinesVisible(true);

    for (int col = 0; col < 5; col++) {
      root.getColumnConstraints()
          .add(new ColumnConstraints(-1, -1, -1, Priority.ALWAYS, HPos.CENTER, false));
      for (int row = 0; row < 3; row++) {
        if (col == 0) {
          root.getRowConstraints()
              .add(new RowConstraints(-1, -1, -1, Priority.ALWAYS, VPos.CENTER, false));
        }
        root.add(new Label(String.format("(%d,%d)", row, col)), col, row);
      }
    }

    primaryStage.setScene(new Scene(root, 500, 300));
    primaryStage.show();
  }

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM