Search code examples
user-interfacejavafxlayoutscenebuilder

How to manually set TitlePane height or make it adapt to its content


I would like to get a layout like this: goal

Multiple titled panes, each one with a different content.

The problem is that by default not all elements inside the titledPane are visible (ScreenShot1, the HBox with ChoiceBox, Label and Spinner aren't visible), and if I try to specify a prefHeight for the TitledPane (which is not recommended by the docs) a blank space remain when the titled pane is closed (ScreenShot2).

How can I make a titled pane adapt to its content or specify a preferredHeight without creating blank spaces on close?

Here is the code:

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

<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ChoiceBox?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.ScrollPane?>
<?import javafx.scene.control.Spinner?>
<?import javafx.scene.control.SplitPane?>
<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.control.TitledPane?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.StackPane?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.text.Font?>

<StackPane prefHeight="989.0" prefWidth="1240.0" xmlns="http://javafx.com/javafx/16" xmlns:fx="http://javafx.com/fxml/1">
   <children>
      <AnchorPane StackPane.alignment="TOP_LEFT">
         <children>
            <SplitPane dividerPositions="0.55" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
              <items>
                <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0">
                     <children>
                        <ScrollPane fitToWidth="true" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
                           <content>
                              <VBox>
                                 <children>
                                  <TitledPane alignment="TOP_LEFT" contentDisplay="TOP" nodeOrientation="LEFT_TO_RIGHT" text="TITLED PANE 1">
                                       <content>
                                          <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0">
                                             <children>
                                                <VBox prefHeight="200.0" prefWidth="100.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0">
                                                   <children>
                                                      <TableView minHeight="200.0" prefHeight="171.0" prefWidth="297.0">
                                                         <columns>
                                                            <TableColumn prefWidth="87.0" text="C1" />
                                                            <TableColumn minWidth="0.0" prefWidth="63.0" text="C2" />
                                                         </columns>
                                                      </TableView>
                                                      <HBox prefHeight="100.0" prefWidth="200.0">
                                                         <children>
                                                            <ChoiceBox prefWidth="150.0" />
                                                            <Label text="some label" />
                                                            <Spinner />
                                                         </children>
                                                      </HBox>
                                                   </children>
                                                </VBox>
                                             </children>
                                          </AnchorPane>
                                       </content>
                                  </TitledPane>
                                  <TitledPane alignment="TOP_LEFT" contentDisplay="TOP" nodeOrientation="LEFT_TO_RIGHT" text="TITLED PANE 2">
                                       <content>
                                          <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0">
                                             <children>
                                                <TableView layoutX="14.0" layoutY="14.0" prefHeight="171.0" prefWidth="297.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0">
                                                   <columns>
                                                      <TableColumn prefWidth="87.0" text="C1" />
                                                      <TableColumn minWidth="0.0" prefWidth="63.0" text="C2" />
                                                   </columns>
                                                </TableView>
                                             </children>
                                          </AnchorPane>
                                       </content>
                                  </TitledPane>
                                  <TitledPane alignment="TOP_LEFT" contentDisplay="TOP" nodeOrientation="LEFT_TO_RIGHT" text="TITLED PANE 3">
                                       <content>
                                          <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0">
                                             <children>
                                                <TableView layoutX="14.0" layoutY="14.0" prefHeight="171.0" prefWidth="297.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0">
                                                   <columns>
                                                      <TableColumn prefWidth="87.0" text="C1" />
                                                      <TableColumn minWidth="0.0" prefWidth="63.0" text="C2" />
                                                   </columns>
                                                </TableView>
                                             </children>
                                          </AnchorPane>
                                       </content>
                                  </TitledPane>
                                    <TitledPane alignment="TOP_LEFT" contentDisplay="TOP" nodeOrientation="LEFT_TO_RIGHT" text="TITLED PANE 4">
                                       <content>
                                          <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="480.0">
                                             <children>
                                                <TableView layoutX="14.0" layoutY="14.0" prefHeight="171.0" prefWidth="297.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0">
                                                   <columns>
                                                      <TableColumn prefWidth="87.0" text="C1" />
                                                      <TableColumn minWidth="0.0" prefWidth="63.0" text="C2" />
                                                   </columns>
                                                </TableView>
                                             </children>
                                          </AnchorPane>
                                       </content>
                                    </TitledPane>
                                 </children>
                              </VBox>
                           </content>
                        </ScrollPane>
                     </children>
                  </AnchorPane>
                <AnchorPane minHeight="0.0" minWidth="0.0" />
              </items>
            </SplitPane>
         </children>
         <padding>
            <Insets bottom="80.0" />
         </padding>
      </AnchorPane>
      <VBox alignment="CENTER" maxHeight="80.0" style="-fx-background-color: grey;" StackPane.alignment="BOTTOM_CENTER">
         <children>
            <Button mnemonicParsing="false" text="FIXED BUTTON">
               <font>
                  <Font size="24.0" />
               </font>
            </Button>
         </children>
      </VBox>
   </children>
</StackPane>

Solution

  • I think you just need to put the VBox as the content node of the first TitledPane. In Scene Buider right mouse click on the AnchorPane and choose "Unwrap". The part of the FXML should look like this then:

    <TitledPane alignment="TOP_LEFT" contentDisplay="TOP" nodeOrientation="LEFT_TO_RIGHT" text="TITLED PANE 1">
        <content>
              <VBox prefHeight="200.0" prefWidth="100.0"> <!-- VBox direct content node instead of AnchorPane -->
                  <children>
                      <TableView minHeight="200.0" prefHeight="171.0" prefWidth="297.0">
                          <columns>
                              <TableColumn prefWidth="87.0" text="C1" />
                              <TableColumn minWidth="0.0" prefWidth="63.0" text="C2" />
                          </columns>
                      </TableView>
                      <HBox prefHeight="100.0" prefWidth="200.0">
                          <children>
                              <ChoiceBox prefWidth="150.0" />
                              <Label text="some label" />
                              <Spinner />
                          </children>
                      </HBox>
                  </children>
              </VBox>
        </content>
    </TitledPane>