Динамический размер содержимого GridPane к свойствам их родителя - PullRequest
0 голосов
/ 14 января 2019

Я создаю клон «тройки» для своего назначения, и одно из свойств должно было иметь динамически изменяемый размер GridPane в зависимости от количества столбцов и строк, как мне этого добиться?

Я смотрел на добавление ColumnConstraints, а также RowConstraints, учитывая их ширину в процентах от общего размера GridPane, деленную на количество столбцов:

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

В Scene Builder по умолчанию GridPane имеет размер 4x4; кажется, что эти элементы очень хорошо меняют размеры, но когда, скажем, загружен размер 4x5, кажется, что он хочет показывать только 4x4 (в стиле), а остальные оставшиеся листы выглядят «странно».

Вот как это выглядит: 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);
    }       
}

Я ожидаю, что он заполнит все мои GridPane соответственно, но вместо этого он действует и показывает мне результат, показанный на изображениях.

Edit:

Я заставил его работать, однако, когда у меня есть различающиеся строки (например, 4x5), это еще не совсем определило размер.

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);
    }       
}

1 Ответ

0 голосов
/ 15 января 2019

Если я правильно понял, вы хотите изменить размер строк и столбцов, чтобы все столбцы имели одинаковую ширину, а все строки - одинаковую высоту. Если это правильно, это звучит неправильно:

Я смотрел на добавление columnConstraints, а также rowConstraints, учитывая их ширину в процентах от общего размера области сетки, деленную на количество столбцов

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

Процентная ширина / высота является относительным измерением. Вы не хотите рассчитывать это на основе текущей ширины / высоты. Например, если бы у вас было 4 строки, каждая строка имела бы 25% высоты.

Тем не менее, я не думаю, что вам нужно возиться с настройками ширины или высоты в ограничениях. Просто установите свойства RowConstraints.vgrow и ColumnConstraints.hgrow на Priority.ALWAYS. Вот пример:

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();
  }

}
...