如何让多个手风琴选项卡打开 FXML

How to have multiple accordion tabs open FXML

我习惯了 JavaFX 而不是 FXML,我的团队想将它用于一个项目。我很好奇是否有办法让手风琴选项卡只根据需要展开,而不是占据整个面。我想我已经看到了一种用实际代码来完成它的方法,但只是想看看是否有更快的 FXML 方法。

我已经包含了 FXML 代码和一个显示它如何工作的 gif。我不希望选项卡延伸到屏幕的末尾。提前致谢。

<?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>

你有这样的东西:

prefHeight="480.0" 

尽管那不是您喜欢的。所以您的布局占用的空间比您想要的多 space。

您的问题与 FXML 无关。如果您使用纯 Java 代码定义此布局,您会遇到同样的问题。

听从 Zephyr 的建议:

使用适应性更强的布局,让 JavaFX 布局引擎计算出需要多少 space 东西,而不是自己尝试 hard-code。

使用带有 HBox 和 VBox 等大小提示的布局窗格,以及 Hgrow 和 Vgrow 设置,而不是具有绝对首选大小的 AnchorPanes。

相关:

例子

这是您的布局的简化版本,它符合此答案中的原则、其他评论和一些其他推荐的布局做法。

该示例只关注标题窗格中的内容,而忽略其他元素。

<?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>