Search code examples
javalistviewjavafxtextarea

JavaFX: expanding TextArea, Listview (Vgrow/Hgrow = 'ALWAYS' doesn't work)


I have a simple JavaFX application, a BorderLayout with an AnchorPane and inside two panes, one contains a HBox and a VBox with a TextArea and a ListView. I would like them to increase in width, as I increase the window size. I have tried Vgrow/Hgrow = 'ALWAYS' and Max Width/Max Height = 'MAX_VALUE' on the the controls but nothing works.- (I use Scene Builder to create the fxml)

enter image description here

The FXML is the following:

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.ListView?>
<?import javafx.scene.control.TextArea?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.Pane?>
<?import javafx.scene.layout.VBox?>

<BorderPane maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" xmlns="http://javafx.com/javafx/18" xmlns:fx="http://javafx.com/fxml/1">
   <center>
      <AnchorPane maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="200.0" BorderPane.alignment="CENTER">
         <children>
            <Pane maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="200.0" AnchorPane.leftAnchor="0.0" AnchorPane.topAnchor="0.0" />
            <Pane maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="200.0" AnchorPane.leftAnchor="0.0" AnchorPane.topAnchor="200.0">
               <children>
                  <HBox maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="200.0">
                     <children>
                        <VBox maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="200.0" HBox.hgrow="ALWAYS">
                           <children>
                              <TextArea maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="200.0" VBox.vgrow="ALWAYS" />
                              <ListView maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="200.0" VBox.vgrow="ALWAYS" />
                           </children>
                        </VBox>
                     </children>
                  </HBox>
               </children>
            </Pane>
         </children>
      </AnchorPane>
   </center>
</BorderPane>

My java application class (HelloApplication):

package com.example.demo;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.stage.Stage;

import java.io.IOException;

public class HelloApplication extends Application {
    @Override
    public void start(Stage stage) throws IOException {
        FXMLLoader fxmlLoader = new FXMLLoader(HelloApplication.class.getResource("hello-view.fxml"));
        Scene scene = new Scene(fxmlLoader.load());
        stage.setTitle("Hello!");
        stage.setScene(scene);
        stage.show();
    }

    public static void main(String[] args) {
        launch();
    }
}

UPDATE: I removed the unnecessary AnchorPane and other Panes, kept only a VBox and placed it in another BorderLayout, take a look, now seems perfect :)

enter image description here


Solution

  • Don't hard-code sizes, and don't use layout panes such as Pane and AnchorPane that rely on hard-coded sizes except in very rare circumstances.

    (You may sometimes need to set the max size to Double.MAX_VALUE to allow a control to grow beyond its preferred size, but even that is not necessary in this example, as far as I can tell.)

    Your FXML has an empty Pane and at least two redundant wrapper containers which only wrap one node (the other Pane and the AnchorPane). Remove all of these and the hard-coded values and it will work:

    <?import javafx.scene.control.ListView?>
    <?import javafx.scene.control.TextArea?>
    <?import javafx.scene.layout.*?>
    <BorderPane xmlns="http://javafx.com/javafx/18" xmlns:fx="http://javafx.com/fxml/1">
        <center>
            <HBox>
                <children>
                    <VBox HBox.hgrow="ALWAYS">
                        <children>
                            <TextArea VBox.vgrow="ALWAYS" />
                            <ListView VBox.vgrow="ALWAYS" />
                        </children>
                    </VBox>
                </children>
            </HBox>
        </center>
    </BorderPane>
    

    Depending on your real use-case, you may not need the HBox either:

    <?xml version="1.0" encoding="UTF-8"?>
    
    <?import javafx.scene.control.ListView?>
    <?import javafx.scene.control.TextArea?>
    <?import javafx.scene.layout.*?>
    <BorderPane xmlns="http://javafx.com/javafx/18" xmlns:fx="http://javafx.com/fxml/1">
        <center>
                <VBox>
                    <children>
                        <TextArea VBox.vgrow="ALWAYS" />
                        <ListView VBox.vgrow="ALWAYS" />
                    </children>
                </VBox>
        </center>
    </BorderPane>