具有多个打开窗格的JavaFX手风琴

具有多个打开窗格的JavaFX手风琴,javafx,accordion,Javafx,Accordion,在JavaFX中,一个手风琴是否可以有一个以上的打开窗格?否,JavaFX 2.2一次只能有一个打开窗格 我为一个功能创建了一个增强请求(),它允许您一次打开手风琴中的多个窗格,但是该功能请求目前尚未实现 同时,您可以通过创建多个实例并将它们放置在一个容器中,非常轻松地构建一个类似的控件 如有必要,您可以将包含窗格的VBox包装在中,以便在所有展开窗格的区域溢出可用区域时,其内容都可以使用 我创建了一个(图标是linkware from:) 我的要求略有不同 手风琴可以扩展或管理嵌入视图的视图空

在JavaFX中,一个手风琴是否可以有一个以上的打开窗格?

否,JavaFX 2.2一次只能有一个打开窗格

我为一个功能创建了一个增强请求(),它允许您一次打开手风琴中的多个窗格,但是该功能请求目前尚未实现

同时,您可以通过创建多个实例并将它们放置在一个容器中,非常轻松地构建一个类似的控件

如有必要,您可以将包含窗格的
VBox
包装在中,以便在所有展开窗格的区域溢出可用区域时,其内容都可以使用

我创建了一个(图标是linkware from:)


我的要求略有不同

  • 手风琴可以扩展或管理嵌入视图的视图空间
  • 整个视图可以放在滚动视图中
  • 如果手风琴的大小是固定的,则每个框完全扩展到整个视图的大小;如果手风琴不是固定视图,则每个框扩展到内容的大小
  • 虽然在我的情况下,我不能完成所有的3。在测试2中,我找到了以下修复方法:

    1) 使用滚动窗格,内有VBox,内有标题窗口。 2) 确保标题窗格设置为VBox.grow=“有时”。 3) 添加一个VBox作为最后一个元素并设置VBox.vgrow=“ALWAYS”-这会将标题窗格推高到其最小大小。其他人都提供了代码示例,如果您想使用fxml,或者不想使用Java,直接使用元素也可以(使用SceneBuilder生成):

    我们绑定到每个窗格的
    expandedProperty()
    ,并动态绑定和解除绑定
    prefheightroperty()

    }

    如果我们被显示,我们要求与VBox一样大,如果我们没有显示,我们要求尽可能小。这样做的好处是,布局会根据当前显示的标题窗格的数量自动计算出可用的高度,这正好导致我们想要的行为

    我将在这里详细介绍:


    将现有答案中的最佳答案与简化相结合,您可以通过在滚动窗格VBox中创建多个标题面板,然后将“最大高度”属性与侦听器绑定来复制多个打开的手风琴(在XML上执行此操作意味着即使在折叠窗格时也会保留空间)


    是的,JavaFX特定的jira问题跟踪系统已经停止。据我所知,来自该系统的问题和功能请求被转移到正式的JDK问题跟踪系统,但我不知道如何在该系统中查找或链接相关问题。我建议与开发人员联系,看看他们是否有兴趣将StackedTitledPanes控件添加到他们的库中,而不是通过该控件的正式JDK功能请求过程。我在新的Java bug跟踪系统中找到了该问题的问题链接,并更新了此答案以引用它:
    private VBox createStackedTitledPanes() {
      final VBox stackedTitledPanes = new VBox();
      stackedTitledPanes.getChildren().setAll(
        new TitledPane("Pane 1",  contentNode1),
        new TitledPane("Pane 2",  contentNode2),
        new TitledPane("Pane 3",  contentNode3)
      );
      ((TitledPane) stackedTitledPanes.getChildren().get(0)).setExpanded(true);
    
      return stackedTitledPanes;
    }
    
    <ScrollPane fitToHeight="true" fitToWidth="true" prefHeight="200.0" prefWidth="200.0" BorderPane.alignment="CENTER">
         <content>
            <VBox fx:id="leftVBox" maxHeight="1.7976931348623157E308" prefHeight="200.0" prefWidth="100.0">
               <children>
                  <TitledPane fx:id="titledPanelOne" animated="false" expanded="false" style="-fx-background-color: red;" text="Pane One" VBox.vgrow="SOMETIMES">
                     <content>
                        <ListView fx:id="listViewOne" maxHeight="1.7976931348623157E308" prefHeight="200.0" prefWidth="200.0" />
                     </content>
                  </TitledPane>
                  <TitledPane fx:id="titledPanelTwo" animated="false" expanded="false" style="-fx-background-color: green;" text="Pane Two" VBox.vgrow="SOMETIMES">
                     <content>
                        <ListView fx:id="listViewTwo" maxHeight="1.7976931348623157E308" prefHeight="200.0" prefWidth="200.0" />
                     </content>
                  </TitledPane>
                  <VBox prefHeight="0.0" prefWidth="0.0" VBox.vgrow="ALWAYS" />
               </children>
            </VBox>
         </content>
     </ScrollPane>
    
    public class Controller implements Initializable {
      //... controller code
      @Override
      public void initialize(URL location, ResourceBundle resources) {
        //...
        variablesViewPane.maxHeightProperty().bind(leftVBox.heightProperty());
        historyViewPane.maxHeightProperty().bind(leftVBox.heightProperty());
      }
    }
    
    private static void bindExpanded(TitledPane pane, ReadOnlyDoubleProperty prop) {
      pane.expandedProperty().addListener((observable, oldValue, newValue) -> {
        if(newValue) {
          pane.prefHeightProperty().bind(prop);
        } else {
          pane.prefHeightProperty().unbind();
          pane.prefHeightProperty().set(0);
        }
      });
    
    <ScrollPane fitToHeight="true" fitToWidth="true">
        <AnchorPane id="Content">
            <VBox AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
                <!-- Setting maxHeight="Infinity" to all makes them all grow as we want, but then they get spaces between, when collapsed (so we do it in code) -->
                <TitledPane fx:id="pane1" animated="false" VBox.vgrow="ALWAYS" expanded="false" text="Pane 1">...</TitledPane>
                <TitledPane fx:id="pane2" animated="false" VBox.vgrow="ALWAYS" maxHeight="Infinity" text="Pane 2 (starts expanded)">...</TitledPane>
                <TitledPane fx:id="pane3" animated="false" VBox.vgrow="ALWAYS" expanded="false" text="Pane 3">...</TitledPane>
            </VBox>
        </AnchorPane>
    </ScrollPane>
    
    pane1.expandedProperty().addListener((observable, oldValue, newValue) -> {
        //make it fill space when expanded but not reserve space when collapsed
        if (newValue) {
            pane1.maxHeightProperty().set(Double.POSITIVE_INFINITY);
        } else {
            pane1.maxHeightProperty().set(Double.NEGATIVE_INFINITY);
        }
     });