Search code examples
javajavafxfxml

How to set a layout to ocupy the entire window in JavaFX?


Here is my FXML file:

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

<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ListView?>
<?import javafx.scene.control.Menu?>
<?import javafx.scene.control.MenuBar?>
<?import javafx.scene.control.MenuItem?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.StackPane?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.text.Font?>

<VBox prefHeight="Infinity" prefWidth="936.0" xmlns="http://javafx.com/javafx/15.0.1" xmlns:fx="http://javafx.com/fxml/1">
  <children>
    <MenuBar VBox.vgrow="NEVER">
      <menus>
        <Menu mnemonicParsing="false" text="File">
          <items>
            <MenuItem mnemonicParsing="false" text="Add Files…" />
            <MenuItem mnemonicParsing="false" text="Save As…" />
            <MenuItem mnemonicParsing="false" text="Quit" />
          </items>
        </Menu>
        <Menu mnemonicParsing="false" text="Help">
          <items>
            <MenuItem mnemonicParsing="false" text="About This App" />
          </items>
        </Menu>
      </menus>
    </MenuBar>
      <HBox maxHeight="Infinity" maxWidth="Infinity" prefHeight="429.0" prefWidth="1048.0">
         <children>
            <StackPane prefHeight="Infinity" prefWidth="681.0">
               <children>
                  <ListView maxHeight="Infinity" maxWidth="Infinity" prefHeight="Infinity" prefWidth="690.0" />
                  <Button mnemonicParsing="false" text="Add Files...">
                     <font>
                        <Font size="15.0" />
                     </font>
                  </Button>
               </children>
            </StackPane>
            <VBox prefHeight="300.0" prefWidth="130.0">
               <children>
                  <ImageView accessibleRoleDescription="Preview" accessibleText="Preview" fitHeight="172.0" fitWidth="364.0" pickOnBounds="true" preserveRatio="true" />
                  <VBox prefHeight="78.0" prefWidth="48.0">
                     <children>
                        <Button mnemonicParsing="false" prefHeight="30.0" prefWidth="120.0" text="Move Down" />
                        <Button mnemonicParsing="false" prefHeight="30.0" prefWidth="120.0" text="Move Up" />
                        <Button mnemonicParsing="false" prefHeight="30.0" prefWidth="120.0" text="Remove" />
                     </children>
                  </VBox>
               </children>
            </VBox>
         </children>
      </HBox>
  </children>
</VBox>

When I resize the window the ListView does not cover all the screen:

My Output

I want it to stick to the bottom of the screen when I resize it. Is there any attribute that could do that for me? And on which element should I apply it? If my FXML is too long, use a simple one to explain how to do it.


Solution

  • If you hard-code widths (and heights) of elements, you can't expect them to be resized by the layout pane. Remove all hardcoded widths and heights; the only exceptions are if you have elements (such as the buttons) whose default maxWidth is Region.USE_PREF_SIZE, and you want them to be able to grow; here you can set the maxWidth to Infinity. Then configure your layout panes to allow them to lay things out the way you actually want.

    The following does what I think you are trying to do:

    <?xml version="1.0" encoding="UTF-8"?>
    
    <?import javafx.scene.control.Button?>
    <?import javafx.scene.control.ListView?>
    <?import javafx.scene.control.Menu?>
    <?import javafx.scene.control.MenuBar?>
    <?import javafx.scene.control.MenuItem?>
    <?import javafx.scene.image.ImageView?>
    <?import javafx.scene.layout.HBox?>
    <?import javafx.scene.layout.StackPane?>
    <?import javafx.scene.layout.VBox?>
    <?import javafx.scene.text.Font?>
    
    <VBox xmlns="http://javafx.com/javafx/15.0.1" xmlns:fx="http://javafx.com/fxml/1">
      <children>
        <MenuBar VBox.vgrow="NEVER">
          <menus>
            <Menu mnemonicParsing="false" text="File">
              <items>
                <MenuItem mnemonicParsing="false" text="Add Files…" />
                <MenuItem mnemonicParsing="false" text="Save As…" />
                <MenuItem mnemonicParsing="false" text="Quit" />
              </items>
            </Menu>
            <Menu mnemonicParsing="false" text="Help">
              <items>
                <MenuItem mnemonicParsing="false" text="About This App" />
              </items>
            </Menu>
          </menus>
        </MenuBar>
          <HBox VBox.vgrow="ALWAYS">
             <children>
                <StackPane HBox.hgrow="ALWAYS">
                   <children>
                      <ListView />
                      <Button mnemonicParsing="false" text="Add Files...">
                         <font>
                            <Font size="15.0" />
                         </font>
                      </Button>
                   </children>
                </StackPane>
                <VBox HBox.hgrow="NEVER" fillWidth="false">
                   <children>
                      <ImageView accessibleRoleDescription="Preview" accessibleText="Preview" fitHeight="172.0" fitWidth="364.0" pickOnBounds="true" preserveRatio="true" />
                      <VBox fillWidth="true">
                         <children>
                            <Button mnemonicParsing="false" text="Move Down" maxWidth="Infinity" />
                            <Button mnemonicParsing="false" text="Move Up"  maxWidth="Infinity" />
                            <Button mnemonicParsing="false" text="Remove"  maxWidth="Infinity" />
                         </children>
                      </VBox>
                   </children>
                </VBox>
             </children>
          </HBox>
      </children>
    </VBox>