JavaFX - 折叠 VBox

问题描述 投票:0回答:1

我有一个包含

VBox
MFXToggleButtons
。我想折叠并展开
VBox
中的这个
height
,使其完全消失。这样就创建了一个设置窗口,当该窗口展开时,可以移动表单上的其他对象。 但是,当您尝试在
height
中指定任何
VBox
时,没有任何变化。据我了解,这是因为
VBox
内的物体不允许它减少。

我的

VBox

            <VBox>
                <MFXToggleButton selected="true" text="Installed" >
                    <VBox.margin>
                        <Insets top="20" bottom="5" left="10"  />
                    </VBox.margin>
                </MFXToggleButton>
                <MFXToggleButton selected="true" text="Releases">
                    <VBox.margin>
                        <Insets top="10" bottom="5" left="10" />
                    </VBox.margin>
                </MFXToggleButton>
                <MFXToggleButton selected="true" text="Modified">
                    <VBox.margin>
                        <Insets top="10" bottom="5" left="10" />
                    </VBox.margin>
                </MFXToggleButton>
                <MFXToggleButton selected="false" text="Snapshots">
                    <VBox.margin>
                        <Insets top="10" bottom="5" left="10" />
                    </VBox.margin>
                </MFXToggleButton>
                <MFXToggleButton selected="false" text="Olds">
                    <VBox.margin>
                        <Insets top="10" bottom="20" left="10" />
                    </VBox.margin>
                </MFXToggleButton>
            </VBox>

我已经尝试过使用其他容器并降低

MFXToggleButton
本身的高度。但它没有给我任何结果。

java javafx fxml materialfx
1个回答
0
投票

首先请注意,您所描述的功能已由

TitledPane
实现。通常,当内置功能满足您的需要时,您应该使用它,而不是尝试自己实现它。

如果您想编写自己的动画来折叠窗格,您可以为

maxHeightProperty()
的值设置动画。要折叠它,您应该将最大高度从当前高度设置为零。要再次展开它,请使用
prefHeight(width)
计算首选高度,并将最大高度从零动画化到首选高度。在“展开”动画结束时,您可能希望将最大高度设置为
Region.USE_PREF_HEIGHT
,以便在内容发生变化时它可以继续遵循其首选高度。

请注意,如果子节点溢出分配给它们的边界,则并非所有容器都会剪辑子节点的内容。因此,您可能需要显式提供一个剪辑并将其绑定到内容的边界。

这是一个简单的例子:

hello-view.fxml

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

<?import io.github.palexdev.materialfx.controls.*?>
<?import javafx.geometry.*?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.shape.Rectangle?>
<VBox spacing="20.0" xmlns:fx="http://javafx.com/fxml"
      fx:controller="com.example.demo.HelloController">
    <padding>
        <Insets bottom="20.0" left="20.0" right="20.0" top="20.0"/>
    </padding>
    <Button text="Expand/Collapse" onAction="#expand"/>
    <VBox fx:id="expandContent" minHeight="0">
        <clip><Rectangle fx:id="expandClip"/></clip>
        <MFXToggleButton selected="true" text="Installed" >
            <VBox.margin>
                <Insets top="20" bottom="5" left="10"  />
            </VBox.margin>
        </MFXToggleButton>
        <MFXToggleButton selected="true" text="Releases">
            <VBox.margin>
                <Insets top="10" bottom="5" left="10" />
            </VBox.margin>
        </MFXToggleButton>
        <MFXToggleButton selected="true" text="Modified">
            <VBox.margin>
                <Insets top="10" bottom="5" left="10" />
            </VBox.margin>
        </MFXToggleButton>
        <MFXToggleButton selected="false" text="Snapshots">
            <VBox.margin>
                <Insets top="10" bottom="5" left="10" />
            </VBox.margin>
        </MFXToggleButton>
        <MFXToggleButton selected="false" text="Olds">
            <VBox.margin>
                <Insets top="10" bottom="20" left="10" />
            </VBox.margin>
        </MFXToggleButton>
    </VBox>
    <Label fx:id="welcomeText"/>
    <Button text="Hello!" onAction="#onHelloButtonClick"/>
</VBox>

HelloController.java

package com.example.demo;

import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.fxml.FXML;
import javafx.scene.control.Label;
import javafx.scene.layout.Region;
import javafx.scene.layout.VBox;
import javafx.scene.shape.Rectangle;
import javafx.util.Duration;

public class HelloController {
    @FXML
    private Label welcomeText;

    @FXML
    private VBox expandContent;
    private boolean expanded = true;
    @FXML
    private Rectangle expandClip;

    @FXML
    private void initialize() {
        expandClip.widthProperty().bind(expandContent.widthProperty());
        expandClip.heightProperty().bind(expandContent.heightProperty());
    }

    @FXML
    protected void onHelloButtonClick() {
        welcomeText.setText("Welcome to JavaFX Application!");
    }

    @FXML
    private void expand() {
        if (expanded) {
            // animate collapse:
            double currentHeight = expandContent.getHeight();
            Timeline timeline = new Timeline(
                    new KeyFrame(Duration.ZERO, new KeyValue(expandContent.maxHeightProperty(), currentHeight)),
                    new KeyFrame(Duration.seconds(0.5), new KeyValue(expandContent.maxHeightProperty(), 0))
            );
            timeline.setOnFinished(e -> {
                expanded = false;
            });
            timeline.play();
        } else {
            // animate expand:

            // compute the preferred height of the content:
            double prefHeight = expandContent.prefHeight(expandContent.getWidth());
            // animate the max height from zero to the pref height:
            Timeline timeline = new Timeline(
                    new KeyFrame(Duration.ZERO, new KeyValue(expandContent.maxHeightProperty(), 0)),
                    new KeyFrame(Duration.seconds(0.5), new KeyValue(expandContent.maxHeightProperty(), prefHeight))
            );
            // when done, set the flag, and set the max height to the sentinel value
            // this latter part is necessary to allow the content to continue to respect
            // the pref height if the scene graph changes, etc.
            timeline.setOnFinished(e -> {
                expanded = true;
                expandContent.setMaxHeight(Region.USE_PREF_SIZE);
            });
            timeline.play();
        }

    }
}

HelloApplication.java

package com.example.demo;

import io.github.palexdev.materialfx.css.themes.MFXThemeManager;
import io.github.palexdev.materialfx.css.themes.Themes;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.stage.Stage;

import java.io.IOException;

public class HelloApplication extends Application {
    @Override
    public void start(Stage stage) throws IOException {
        FXMLLoader fxmlLoader = new FXMLLoader(HelloApplication.class.getResource("hello-view.fxml"));
        Scene scene = new Scene(fxmlLoader.load());
        MFXThemeManager.addOn(scene, Themes.DEFAULT, Themes.LEGACY);
        stage.setTitle("Hello!");
        stage.setScene(scene);
        stage.show();
    }

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

扩展:

崩溃了:

© www.soinside.com 2019 - 2024. All rights reserved.