JavaFX: setHgrow(...) doesn't work

Tonkel picture Tonkel · Feb 18, 2014 · Viewed 14.6k times · Source

I couldn't get the Elements in my HBox to grow, so I downloaded the following example code from java2s.com. It serves as a minimal not working example:

package fxtest;

import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

public class Fxtest extends Application {
    public static void main(String[] args) {
        Application.launch(args);
    }

    @Override
    public void start(Stage primaryStage) {
        primaryStage.setTitle("");
        Group root = new Group();
        Scene scene = new Scene(root, 600, 250, Color.WHITE);

        HBox hbox = new HBox();
        TextField field = new TextField();
        HBox.setHgrow(field, Priority.ALWAYS);
        hbox.getChildren().addAll(new Label("Search:"), field, new Button("Go"));


        root.getChildren().add(hbox);
        primaryStage.setScene(scene);
        primaryStage.show();
    }
}

The result looks like this.

If I understand it correctly, the TextField should grow, shouldn't it?

My Java Version is 1.7.0_51

My JavaFX Version is 2.2.51-b13

Do you know why it isn't working/what I have to do? Thanks!

Answer

jewelsea picture jewelsea · Feb 18, 2014

Why HBox.setHgrow doesn't work for you

You use a Group as the root node of your scene and groups are not resizable, so the group size does not adjust to the scene's size.

A Group will take on the collective bounds of its children and is not directly resizable.

By default, a Group will "auto-size" its managed resizable children to their preferred sizes during the layout pass

In general, you very rarely want to use a Group as the root node for a scene.

How to Fix it

Use only resizable nodes in your scene (Pane subclasses or Control subclasses).

Sample

Substitute your start method with the method below which removes the Group root node and instead makes the HBox the root node for the scene:

public void start(Stage primaryStage) {
    HBox hbox = new HBox(10);
    TextField field = new TextField();
    HBox.setHgrow(field, Priority.ALWAYS);
    hbox.setAlignment(Pos.BASELINE_LEFT);
    hbox.getChildren().addAll(
        new Label("Search:"), field, new Button("Go")
    );
    hbox.setPadding(new Insets(10));

    Scene scene = new Scene(hbox, 600, 250, Color.WHITE);
    primaryStage.setScene(scene);
    primaryStage.show();
}

Output of the sample after resizing the window (you can see that the search text field grows and shrinks to fit available space as requested):

grow

shrink