Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fill width in a Pane

There is a Pane as root and a GridPane as its child. The root resizes with the stage. How can I achieve that the GridPane gets automatically resized with the root to fill the width? Any width should possible. Is it possible without property binding?

This is the situation:

  1. A Pane root (yellow) is the root of the Scene so it fills the width and height of the Stage.
  2. A GridPane (green) with one row and 3 colums as child of root.
  3. The row should have a fixed height.
  4. The first and third column should have a constant size
  5. The middle column should grow to maximum
  6. The GridPane should fill the width of its parent

Unfortunately the GridPane does not fill the width: GridPane should fill the width of its parent

Code:

@Override
public void start(Stage primaryStage) throws Exception {
    // Resizes with the stage
    final Pane root = new Pane();
    root.setStyle("-fx-background-color: yellow");

    // grid: 1 row, 3 colums
    // should have a constant height and should grow in width to fill parent pane
    final GridPane gridPane = new GridPane();
    root.getChildren().add(gridPane);
    gridPane.setStyle("-fx-background-color: green");
    gridPane.setGridLinesVisible(true);

    final RowConstraints row = new RowConstraints(100); // constant height = 100
    final ColumnConstraints col1 = new ColumnConstraints(100, Control.USE_COMPUTED_SIZE, Control.USE_COMPUTED_SIZE);
    // should grow as much as possible in width
    final ColumnConstraints col2 = new ColumnConstraints(200, Control.USE_COMPUTED_SIZE, Double.MAX_VALUE);
    final ColumnConstraints col3 = new ColumnConstraints(100, Control.USE_COMPUTED_SIZE, Control.USE_COMPUTED_SIZE);
    gridPane.getRowConstraints().add(row);
    gridPane.getColumnConstraints().addAll(col1, col2, col3);

    final Scene scene = new Scene(root);
    primaryStage.setScene(scene);
    primaryStage.setWidth(600);
    primaryStage.setHeight(400);
    primaryStage.show();
}
like image 786
Vertex Avatar asked Oct 29 '15 12:10

Vertex


2 Answers

The size of nodes inside panes is controlled by the way the individual pane implements its layout: i.e. the size of a node is effectively determined by its parent. So the overall size of your grid pane is controlled by the layout implementation of Pane.

Pane actually does minimal layout work: it effectively just positions everything at (0,0) and sizes it to its preferred size. So your grid pane gets its preferred width, which is the sum of the preferred widths of the columns.

So to get your grid pane to grow, you either need to change its preferred width, or use a layout pane that allows you to control how it grows.

For example:

gridPane.prefWidthProperty().bind(root.widthProperty());

will make the grid pane grow to the width of root. This will just add extra space to the right of all three columns, so additionally setting

col2.setHgrow(Priority.ALWAYS);

will let col2 have the extra width.

Alternatively, using an AnchorPane for root:

// Pane root = new Pane();
AnchorPane root = new AnchorPane();

and setting

AnchorPane.setLeftAnchor(gridPane, 0.0);
AnchorPane.setRightAnchor(gridPane, 0.0);

(again with the col2 hgrow set) will have the same effect.

Or you could do

VBox root = new VBox();
root.setFillWidth(true);

(for example: there are many solutions).

The choice of solution depends on what other nodes, if any, you have inside the root pane.

like image 57
James_D Avatar answered Nov 08 '22 12:11

James_D


Pane does not automatically layouts its children. Try to use VBox instead. It will fill the width of available space by (if possible) resizing its childdren. This way the GridPane will resize on stage width changes.

Now, you can manage the gridpane columns how they share the space. According to your description it is enough to set

col2.setHgrow( Priority.ALWAYS );
like image 44
Uluk Biy Avatar answered Nov 08 '22 13:11

Uluk Biy