How to make a TextField fill all the remaining width of a pane containing multiple nodes?

Viewed 997

I need to make a chat-simulating JavaFX application for my assignment (no web functionalities, just two text fields for input and two text areas for output). I need to have a “Send” button next to my text field. I cannot make the text field to fill up the width of my window without “squishing” the button at startup, similarly to how swing’s boxLayout does that?

I bound the field’s width to the parent pane’s width, subtracting the button’s width and the pane’sspacing and it works after I start resizing the window, but when the application first starts up, the button’s text is not fully visible.

public void start(Stage stage_main) throws Exception {
        //Pane creation and nesting:
        HBox pane_main = new HBox();
        Scene scene_main = new Scene(pane_main, 480, 360);
        BorderPane pane_left_parent = new BorderPane();
        BorderPane pane_right_parent = new BorderPane();
        HBox pane_left_bottom = new HBox();
        HBox pane_right_bottom = new HBox();
        pane_main.getChildren().addAll(pane_left_parent, pane_right_parent); //Focusing only on the left pane for now for testing.
        pane_left_parent.setBottom(pane_left_bottom);

        //Contents creation and nesting:
        TextArea textA_left = new TextArea("Testing...");
        Button button_left = new Button("Send");
        TextField textF_left = new TextField("Test input...");
        textF_left.prefWidthProperty().bind(pane_left_bottom.widthProperty().subtract(button_left.widthProperty()).subtract(pane_left_bottom.spacingProperty()));

        //Placing contents in panes:
        pane_left_parent.setCenter(textA_left);
        pane_left_bottom.setSpacing(3);
        pane_left_bottom.getChildren().addAll(textF_left, button_left);

        //Finishing up:
        stage_main.setScene(scene_main);
        stage_main.show();
    }

Is there any way to have the button have it’s “best” size already at startup without manually setting any widths in pixels, just like in swing?

1 Answers

Don't bind the prefWidth to the parent. If you want a child of an HBox to grow horizontally you can set an hgrow constraint on it:

HBox.setHgrow(theChild, Priority.ALWAYS);

Then let the HBox handle sizing and positioning the child node. And as you noted, in order to stop the Button from shrinking as the HBox changes size you need to set its minWidth. However, you should use:

button.setMinWidth(Region.USE_PREF_SIZE);

If you use getWidth() you might accidentally call it before the Button actually has a non-zero width. Plus, using USE_PREF_SIZE means the minWidth will stay up-to-date with the prefWidth (if you change it for whatever reason).


Some links:

Related