Search code examples
javajavafxvboxgridpane

GridPane not spanning the whole VBox


Screenshot

I'm trying to create a an invoice which I can later print. I'm using VBoxes and GridPanes to do it. The number of columns in the middle GridPane is variable. I'm building it using a loop. I've tried many different things to make the GridPane (GREEN border) span the whole VBox (RED border) but nothing seems to work.

After giving the borders, I realized that the Grids are in fact spanning the whole VBoxes but the columns aren't occupying the whole space. I can't give column constraints since I'm not aware of the number of columns of the middle Grid and I have to keep in under 500px.

Below is the relevant code.

final int width = 500;
BorderPane borderpane = new BorderPane();

VBox vboxTop = vboxForPrinting('l');
VBox vboxMiddle = vboxForPrinting('r');
VBox vboxBottom = vboxForPrinting('r');
GridPane gridpaneTop = new GridPane();
GridPane gridpaneMiddle = new GridPane();
GridPane gridpaneBottom = new GridPane();

borderpane.setPrefWidth(width);
vboxTop.setFillWidth(true);
vboxMiddle.setFillWidth(true);
vboxBottom.setFillWidth(true);

// Some code

vboxTop.getChildren().add(gridpaneTop);
vboxMiddle.getChildren().add(gridpaneMiddle);
vboxBottom.getChildren().add(gridpaneBottom);

borderpane.setTop(vboxTop);
borderpane.setCenter(vboxMiddle);
borderpane.setBottom(vboxBottom);

The function vboxForPrinting() is given below:

public VBox vboxForPrinting(char align) {
    VBox vbox = new VBox();
    switch (align) {
        case 'r':
        case 'R':
            vbox.setAlignment(Pos.CENTER_RIGHT);
            break;
        case 'l':
        case 'L':
            vbox.setAlignment(Pos.CENTER_LEFT);
            break;
        default:
            vbox.setAlignment(Pos.CENTER);
    }
    vbox.setPadding(new Insets(5));
    vbox.setSpacing(5);
    vbox.setFillWidth(true);
    return vbox;
}

Solution

  • You can apply setHgrow() for the particular child of the gridpane which will intern grow and occupy the remaining available space.

    From the javadocs:

    Sets the horizontal grow priority for the child when contained by a gridpane. If set, the gridpane will use the priority to allocate the child additional horizontal space if the gridpane is resized larger than it's preferred width. Setting the value to null will remove the constraint.

    GridPane.setHgrow(name, Priority.ALWAYS);
    

    where, name is a Label which you want to grow and occupy the rest of the empty place.

    If you want all the fields or columns to grow either you can apply this to all of them or you can create a ColumnConstraints and apply them to one/multiple columns.

    The code below should work :

    ColumnConstraints columnConstraints = new ColumnConstraints();
    columnConstraints.setFillWidth(true);
    columnConstraints.setHgrow(Priority.ALWAYS);
    gridPane.getColumnConstraints().add(columnConstraints);
    

    Coming to your concern,

    I can't give column constraints since I'm not aware of the number of columns of the middle Grid and I have to keep in under 500px.

    Well you don't need to keep a track of the number of columns , the hgrow will only allow the child to grow if there is additional space available.