Issue
I'm used to JavaFX but not so much FXML, my group wants to use it for a project. I am curious whether or not there is a way to make an accordion tab only expand as much as it needs to rather than taking up the whole side. I think I have seen a way to do it with actual code but just wanted to see if there was a faster way with FXML.
I have included the FXML code and a gif showing how it is functioning. I don't want the tab extending to the end of the screen. Thanks in advance.
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (c) 2015, 2019, Gluon and/or its affiliates.
All rights reserved. Use is subject to license terms.
This file is available and licensed under the following license:
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
- Neither the name of Oracle Corporation nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-->
<?import javafx.scene.control.Accordion?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.CheckBox?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.Slider?>
<?import javafx.scene.control.SplitPane?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.control.TitledPane?>
<?import javafx.scene.image.Image?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.RowConstraints?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.text.Font?>
<VBox prefHeight="853.0" prefWidth="1284.0" xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.example.project.MainController">
<children>
<AnchorPane maxHeight="-1.0" maxWidth="-1.0" prefHeight="772.0" prefWidth="1284.0" VBox.vgrow="ALWAYS">
<children>
<SplitPane dividerPositions="0.25273010920436817" prefHeight="853.0" prefWidth="1284.0">
<items>
<SplitPane dividerPositions="0.15511163337250294, 0.2491186839012926" orientation="VERTICAL" prefHeight="851.0" prefWidth="303.0">
<items>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="100.0" prefWidth="160.0">
<children>
<TextField layoutX="7.0" layoutY="86.0" prefHeight="37.0" prefWidth="236.0" />
<Button layoutX="250.0" layoutY="92.0" mnemonicParsing="false" text="Search" />
<ImageView fitHeight="91.0" fitWidth="258.0" layoutX="7.0" layoutY="8.0" pickOnBounds="true" preserveRatio="true">
<image>
<Image url="@logoLong.png" />
</image>
</ImageView>
</children>
</AnchorPane>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="100.0" prefWidth="160.0">
<children>
<Label layoutX="14.0" layoutY="14.0" prefHeight="25.0" prefWidth="212.0" text="Favorites ★">
<font>
<Font size="31.0" />
</font>
</Label>
</children>
</AnchorPane>
<Accordion prefHeight="636.0" prefWidth="69.0">
<panes>
<TitledPane prefWidth="300.0" text="Difficulty">
<content>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="193.0" prefWidth="321.0">
<children>
<CheckBox fx:id="checkEasy" layoutX="14.0" layoutY="14.0" mnemonicParsing="false" text="Easy">
<font>
<Font size="22.0" />
</font>
</CheckBox>
<CheckBox layoutX="14.0" layoutY="141.0" mnemonicParsing="false" text="Hard">
<font>
<Font size="22.0" />
</font>
</CheckBox>
<CheckBox layoutX="14.0" layoutY="79.0" mnemonicParsing="false" text="Medium">
<font>
<Font size="22.0" />
</font>
</CheckBox>
</children>
</AnchorPane>
</content>
<font>
<Font size="22.0" />
</font>
</TitledPane>
<TitledPane text="Time">
<content>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0">
<children>
<Slider layoutX="10.0" layoutY="61.0" prefHeight="26.0" prefWidth="280.0" value="50.0" />
<Label layoutX="48.0" layoutY="22.0" text="Minutes">
<font>
<Font size="20.0" />
</font>
</Label>
<Label layoutX="22.0" layoutY="21.0" text="0">
<font>
<Font size="22.0" />
</font>
</Label>
</children>
</AnchorPane>
</content>
<font>
<Font size="22.0" />
</font>
</TitledPane>
<TitledPane expanded="false" maxHeight="50.0" prefHeight="144.0" prefWidth="318.0" text="Diet">
<content>
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="0.0" minWidth="0.0" prefHeight="480.0" prefWidth="318.0">
<children>
<CheckBox layoutX="14.0" layoutY="14.0" mnemonicParsing="false" text="Vegan">
<font>
<Font size="22.0" />
</font>
</CheckBox>
<CheckBox layoutX="14.0" layoutY="62.0" mnemonicParsing="false" text="Keto">
<font>
<Font size="22.0" />
</font>
</CheckBox>
<CheckBox layoutX="14.0" layoutY="115.0" mnemonicParsing="false" text="Gluten Free">
<font>
<Font size="22.0" />
</font>
</CheckBox>
</children>
</AnchorPane>
</content>
<font>
<Font size="22.0" />
</font>
</TitledPane>
<TitledPane expanded="false" text="Calorie Range">
<content>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0">
<children>
<TextField layoutX="55.0" layoutY="41.0" prefHeight="31.0" prefWidth="75.0" />
<TextField layoutX="180.0" layoutY="41.0" prefHeight="31.0" prefWidth="75.0" />
<Label layoutX="14.0" layoutY="48.0" text="Min:">
<font>
<Font size="16.0" />
</font>
</Label>
<Label layoutX="140.0" layoutY="48.0" text="Max:">
<font>
<Font size="16.0" />
</font>
</Label>
</children>
</AnchorPane>
</content>
<font>
<Font size="22.0" />
</font>
</TitledPane>
</panes>
</Accordion>
</items>
</SplitPane>
<GridPane>
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
</GridPane>
</items>
</SplitPane>
</children>
</AnchorPane>
</children>
</VBox>
Solution
You have stuff like:
prefHeight="480.0"
even though that is not what you prefer. So your layouts take up more space than you want.
Your issues are not related to FXML. If you defined this layout in plain Java code, you would have the same issues.
Follow Zephyr’s suggestion:
Use a more adaptable layout, let the JavaFX layout engine work out how much space stuff needs rather than trying to hard-code it yourself.
Use layout panes with sizing hints like HBox and VBox, with Hgrow and Vgrow settings, instead of AnchorPanes with absolute preferred sizing.
Related:
Example
Here is a simplified version of your layout that conforms to the principles in this answer, other comments and some other recommended practices for layout.
The example just focuses on the stuff in the title panes and ignores the other elements.
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<SplitPane dividerPositions="0.3" prefHeight="600.0" prefWidth="800.0" style="-fx-font-size: 22;" xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.example.project.MainController">
<ScrollPane fitToWidth="true" hbarPolicy="NEVER">
<VBox>
<TitledPane text="Difficulty">
<VBox spacing="11">
<padding>
<Insets bottom="11" left="11" right="11" top="11" />
</padding>
<CheckBox fx:id="checkEasy" mnemonicParsing="false" text="Easy" />
<CheckBox mnemonicParsing="false" text="Hard" />
<CheckBox mnemonicParsing="false" text="Medium" />
</VBox>
</TitledPane>
<TitledPane expanded="false" text="Time">
<VBox spacing="11">
<padding>
<Insets bottom="11" left="11" right="11" top="11" />
</padding>
<Slider prefHeight="26.0" prefWidth="280.0" value="50.0" />
<HBox alignment="BASELINE_LEFT" spacing="11">
<padding>
<Insets bottom="11" left="11" right="11" top="11" />
</padding>
<Label text="0" />
<Label text="Minutes" />
</HBox>
</VBox>
</TitledPane>
<TitledPane expanded="false" text="Diet">
<VBox spacing="11">
<padding>
<Insets bottom="11" left="11" right="11" top="11" />
</padding>
<CheckBox mnemonicParsing="false" text="Vegan" />
<CheckBox mnemonicParsing="false" text="Keto" />
<CheckBox mnemonicParsing="false" text="Gluten Free" />
</VBox>
</TitledPane>
<TitledPane expanded="false" text="Calorie Range">
<GridPane hgap="11" vgap="11">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" />
<ColumnConstraints hgrow="ALWAYS" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="-Infinity" vgrow="SOMETIMES" />
<RowConstraints minHeight="-Infinity" vgrow="SOMETIMES" />
</rowConstraints>
<padding>
<Insets bottom="11" left="11" right="11" top="11" />
</padding>
<Label minWidth="-Infinity" text="Min:" />
<TextField GridPane.columnIndex="1" />
<Label minWidth="-Infinity" text="Max:" GridPane.rowIndex="1" />
<TextField GridPane.columnIndex="1" GridPane.rowIndex="1" />
</GridPane>
</TitledPane>
</VBox>
</ScrollPane>
<Pane />
</SplitPane>
Answered By - jewelsea
Answer Checked By - Marilyn (JavaFixing Volunteer)