javafxcollapsabledisclosure

Disclosure Pane in JavaFX


I am currently searching for a solution in JavaFX to achieve a behavior like the DisclosurePanel in GWT see http://samples.gwtproject.org/samples/Showcase/Showcase.html#!CwDisclosurePanel.

I already tried to build something with a TitledPane but it doesn't look or work well.

I am working with FXML:

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

<?import javafx.scene.text.*?>
<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>

<VBox minWidth="260.0" spacing="10.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
    <children>
        <FlowPane>
            <children>
                <Label text="Packages">
                    <font>
                        <Font name="System Bold" size="14.0" />
                    </font>
                </Label>
                <TitledPane animated="true" expanded="false">
                    <content>
                        <VBox spacing="10.0">
                            <children>
                                <CheckBox mnemonicParsing="false" text="Filter 1" />
                                <CheckBox mnemonicParsing="false" text="Filter 2" />
                                <CheckBox mnemonicParsing="false" text="Filter 3" />
                            </children>
                        </VBox>
                    </content>
                    <graphic>
                    </graphic>
               <FlowPane.margin>
                  <Insets left="20.0" />
               </FlowPane.margin>
                </TitledPane>
            </children>
        </FlowPane>
        <TreeView fx:id="dataPackagesTree" prefWidth="250.0" VBox.vgrow="ALWAYS">
        </TreeView>
    </children>
    <padding>
        <Insets bottom="5.0" left="5.0" right="10.0" top="0.0" />
    </padding>
</VBox>

The according Java code is only a starter in this example.

package javafx.example;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class Main extends Application {
    @Override
    public void start(Stage primaryStage) {
        try {
            VBox root = (VBox) FXMLLoader.load(getClass().getResource("Sample.fxml"));
            Scene scene = new Scene(root, 300, 400);
            primaryStage.setScene(scene);
            primaryStage.show();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        launch(args);
    }
}

What I want is that the TitledPane overlays the TreeView. So that the content of the TitledPane is in front of the TreeView and does not push the TreeView down.

I can't post a picture of the prototype, not enough reputation yet, sorry.

Every idea is appreciated. Thanks in advance.

Best regards.


Solution

  • Just replace the VBox with a StackPane. StackPane lays out its children in a back-to-front stack i.e all the children have a z-order. The children being the TreeView and FlowPane, with the later being on top of the former.

    TreeView is wrapped in an AnchorPane, giving enough space to the FlowPane to be visible.

    FXML

    <?xml version="1.0" encoding="UTF-8"?>
    
    <?import javafx.geometry.Insets?>
    <?import javafx.scene.control.*?>
    <?import javafx.scene.layout.*?>
    <?import javafx.scene.text.Font?>
    <StackPane xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
       <children>
          <AnchorPane prefHeight="204.0" prefWidth="400.0">
             <children>
                <TreeView fx:id="dataPackagesTree" prefHeight="200.0" prefWidth="200.0" AnchorPane.topAnchor="30.0" />
             </children>
          </AnchorPane>
           <FlowPane rowValignment="TOP">
               <children>
                   <Label alignment="TOP_LEFT" text="Packages">
                       <font>
                           <Font name="System Bold" size="14.0" />
                       </font>
                   </Label>
                   <TitledPane animated="true" expanded="false">
                       <content>
                           <VBox spacing="10.0">
                               <children>
                                   <CheckBox mnemonicParsing="false" text="Filter 1" />
                                   <CheckBox mnemonicParsing="false" text="Filter 2" />
                                   <CheckBox mnemonicParsing="false" text="Filter 3" />
                               </children>
                           </VBox>
                       </content>
                       <graphic>
                       </graphic>
                       <FlowPane.margin>
                           <Insets left="20.0" />
                       </FlowPane.margin>
                   </TitledPane>
               </children>
           </FlowPane>
       </children>
    </StackPane>
    

    Changes in Main Class

    try {
            // VBox root = (VBox) FXMLLoader.load(getClass().getResource("Sample.fxml"));
            StackPane root = (StackPane) FXMLLoader.load(getClass().getResource("Sample.fxml"));
            Scene scene = new Scene(root, 300, 400);
            primaryStage.setScene(scene);
            primaryStage.show();
        } catch (Exception e) {
            e.printStackTrace();
        }
    

    Final Output

    enter image description here