JavaFX SplitPane 动态调整子组件大小

huangapple go评论73阅读模式
英文:

JavaFX SplitPane dynamically resize children

问题

我有一个SplitPane,其中包含两个项目,分别是VBoxScrollPane。在VBox中,我有一些可以折叠的TitledPane子项,可以因此减小VBox的高度,或者这是我所认为的。但问题是,只有VBox内部元素被收缩在其中,而实际的VBox子项高度保持不变。

我希望VBox的高度能够动态变化,而SplitPane的分隔符会自动填补VBox缩小的空隙,以便ScrollPane填充该空隙。

<SplitPane fx:id="infoSplitPane" orientation="VERTICAL" dividerPositions="0.35">
    <items>
        <VBox fx:id="campaignInfoVBox" spacing="10" VBox.vgrow="ALWAYS">
            <children>
                <Label text="Campaign Information" style="-fx-font-size: 120%" />                                         
                <SplitPane fx:id="campaignInfoSplitPane" orientation="VERTICAL">
                    <items>
                        <TitledPane fx:id="campaignTestsFlow" text="Campaign Tests Flow">
                            <TableView fx:id="testCasesTableView" minHeight="52" maxHeight="Infinity" VBox.vgrow="ALWAYS">
                                <columnResizePolicy>
                                    <TableView fx:constant="CONSTRAINED_RESIZE_POLICY" />
                                </columnResizePolicy>
                            </TableView>
                        </TitledPane>
                        <TitledPane fx:id="campaignActionsInfo" text="Campaign Actions Information">
                            <SplitPane fx:id="campaignTablesSplitPane" orientation="VERTICAL" VBox.vgrow="ALWAYS">
                                <items>
                                    <RunnerActionsTreeTableView fx:id="campaignSetupTable" name="Campaign Setup" VBox.vgrow="SOMETIMES" />
                                    <RunnerActionsTreeTableView fx:id="campaignTearDownTable" name="Campaign Tear Down" VBox.vgrow="ALWAYS" />
                                </items>
                            </SplitPane>
                        </TitledPane>
                    </items>
                </SplitPane>
            </children>
        </VBox>
        <ScrollPane fx:id="testInfoScrollPane" fitToWidth="true" VBox.vgrow="ALWAYS">
            <content>
                <VBox spacing="0" VBox.vgrow="ALWAYS">
                    <GridPane hgap="5.0" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="0.0" minWidth="0.0" vgap="5.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="10.0" AnchorPane.rightAnchor="10.0" AnchorPane.topAnchor="0.0">
                        <children>                                                                                    
                            <VBox fx:id="titledPaneVbox" GridPane.rowIndex="13" GridPane.columnSpan="2">
                                <TitledPane fx:id="variablesTitlePane" maxHeight="1.7976931348623157E308" text="Variables Information" VBox.vgrow="ALWAYS" >
                                    <content>
                                        <TableView fx:id="variablesTable" maxHeight="Infinity" maxWidth="Infinity"  GridPane.hgrow="ALWAYS" GridPane.vgrow="ALWAYS"  />
                                    </content>
                                </TitledPane>
                                <TitledPane fx:id="eventsTitlePane" maxHeight="1.7976931348623157E308" text="Events Information" VBox.vgrow="ALWAYS"  GridPane.columnSpan="2">
                                    <content>
                                        <TableView fx:id="eventsTable" maxHeight="Infinity" maxWidth="Infinity" GridPane.hgrow="ALWAYS" GridPane.vgrow="ALWAYS"/>
                                    </content>
                                </TitledPane>
                            </VBox>
                            <Button fx:id="testCaseDirButton" text="Logs Folder" maxWidth="Infinity" GridPane.rowIndex="14" GridPane.hgrow="ALWAYS" GridPane.columnSpan="2" />
                        </children>
                    </GridPane>
                </VBox>
            </content>
        </ScrollPane>
    </items>
</SplitPane>

所以基本上我需要testInfoScrollPane在其TitledPane子项折叠时,自动调整到campaignInfoVBox的底部边距。

英文:

I have a SplitPane and within it two items which are VBox and ScrollPane. In the VBox I have some TitledPane children that can be collapsed and therefore minimize the VBox height, or this is what I thought will happen. But the issue is that only the inner elements of the VBox are being shrunk inside it and the actual VBox child height stays the same.

I want the VBox to dynamically change in height and the divider of the SplitPane to automatically fill the gap of the shrunk VBox so that the ScrollPane will fill that gap.

&lt;SplitPane fx:id=&quot;infoSplitPane&quot; orientation=&quot;VERTICAL&quot; dividerPositions=&quot;0.35&quot;&gt;
&lt;items&gt;
&lt;VBox fx:id=&quot;campaignInfoVBox&quot; spacing=&quot;10&quot; VBox.vgrow=&quot;ALWAYS&quot;&gt;
&lt;children&gt;
&lt;Label text=&quot;Campaign Information&quot; style=&quot;-fx-font-size: 120%&quot; /&gt;                                         
&lt;SplitPane fx:id=&quot;campaignInfoSplitPane&quot; orientation=&quot;VERTICAL&quot;&gt;
&lt;items&gt;
&lt;TitledPane fx:id=&quot;campaignTestsFlow&quot; text=&quot;Campaign Tests Flow&quot;&gt;
&lt;TableView fx:id=&quot;testCasesTableView&quot; minHeight=&quot;52&quot; maxHeight=&quot;Infinity&quot; VBox.vgrow=&quot;ALWAYS&quot;&gt;
&lt;columnResizePolicy&gt;
&lt;TableView fx:constant=&quot;CONSTRAINED_RESIZE_POLICY&quot; /&gt;
&lt;/columnResizePolicy&gt;
&lt;/TableView&gt;
&lt;/TitledPane&gt;
&lt;TitledPane fx:id=&quot;campaignActionsInfo&quot; text=&quot;Campaign Actions Information&quot;&gt;
&lt;SplitPane fx:id=&quot;campaignTablesSplitPane&quot; orientation=&quot;VERTICAL&quot; VBox.vgrow=&quot;ALWAYS&quot;&gt;
&lt;items&gt;
&lt;RunnerActionsTreeTableView fx:id=&quot;campaignSetupTable&quot; name=&quot;Campaign Setup&quot; VBox.vgrow=&quot;SOMETIMES&quot; /&gt;
&lt;RunnerActionsTreeTableView fx:id=&quot;campaignTearDownTable&quot; name=&quot;Campaign Tear Down&quot; VBox.vgrow=&quot;ALWAYS&quot; /&gt;
&lt;/items&gt;
&lt;/SplitPane&gt;
&lt;/TitledPane&gt;
&lt;/items&gt;
&lt;/SplitPane&gt;
&lt;/children&gt;
&lt;/VBox&gt;
&lt;ScrollPane fx:id=&quot;testInfoScrollPane&quot; fitToWidth=&quot;true&quot; VBox.vgrow=&quot;ALWAYS&quot;&gt;
&lt;content&gt;
&lt;VBox spacing=&quot;0&quot; VBox.vgrow=&quot;ALWAYS&quot;&gt;
&lt;GridPane hgap=&quot;5.0&quot; maxHeight=&quot;1.7976931348623157E308&quot; maxWidth=&quot;1.7976931348623157E308&quot; minHeight=&quot;0.0&quot; minWidth=&quot;0.0&quot; vgap=&quot;5.0&quot; AnchorPane.bottomAnchor=&quot;0.0&quot; AnchorPane.leftAnchor=&quot;10.0&quot; AnchorPane.rightAnchor=&quot;10.0&quot; AnchorPane.topAnchor=&quot;0.0&quot;&gt;
&lt;children&gt;                                                                                    
&lt;VBox fx:id=&quot;titledPaneVbox&quot;  GridPane.rowIndex=&quot;13&quot; GridPane.columnSpan=&quot;2&quot;&gt;
&lt;TitledPane fx:id=&quot;variablesTitlePane&quot; maxHeight=&quot;1.7976931348623157E308&quot; text=&quot;Variables Information&quot; VBox.vgrow=&quot;ALWAYS&quot; &gt;
&lt;content&gt;
&lt;TableView fx:id=&quot;variablesTable&quot; maxHeight=&quot;Infinity&quot; maxWidth=&quot;Infinity&quot;  GridPane.hgrow=&quot;ALWAYS&quot; GridPane.vgrow=&quot;ALWAYS&quot;  /&gt;
&lt;/content&gt;
&lt;/TitledPane&gt;
&lt;TitledPane fx:id=&quot;eventsTitlePane&quot; maxHeight=&quot;1.7976931348623157E308&quot; text=&quot;Events Information&quot; VBox.vgrow=&quot;ALWAYS&quot;  GridPane.columnSpan=&quot;2&quot;&gt;
&lt;content&gt;
&lt;TableView fx:id=&quot;eventsTable&quot; maxHeight=&quot;Infinity&quot; maxWidth=&quot;Infinity&quot; GridPane.hgrow=&quot;ALWAYS&quot; GridPane.vgrow=&quot;ALWAYS&quot;/&gt;
&lt;/content&gt;
&lt;/TitledPane&gt;
&lt;/VBox&gt;
&lt;Button fx:id=&quot;testCaseDirButton&quot; text=&quot;Logs Folder&quot; maxWidth=&quot;Infinity&quot; GridPane.rowIndex=&quot;14&quot; GridPane.hgrow=&quot;ALWAYS&quot; GridPane.columnSpan=&quot;2&quot; /&gt;
&lt;/children&gt;
&lt;/GridPane&gt;
&lt;/VBox&gt;
&lt;/content&gt;
&lt;/ScrollPane&gt;
&lt;/items&gt;
&lt;/SplitPane&gt;

So basically what I need it the testInfoScrollPane to adjust itself to campaignInfoVBox bottom margin when it is being shrunk automatically when its TitledPane children are collapsing.

答案1

得分: 1

我认为你需要将VBoxmaxHeight属性设置为其内容的prefHeight。这样,VBox永远不会超出其内容的大小。

你可以尝试下面的代码:

如果是在Java代码中:

campaignInfoVBox.setMaxHeight(Region.USE_PREF_SIZE);

如果是在FXML代码中:

<VBox fx:id="campaignInfoVBox" spacing="10" VBox.vgrow="ALWAYS" maxHeight="-Infinity">

以下是演示修复的快速演示:

JavaFX SplitPane 动态调整子组件大小

import javafx.application.Application;
import javafx.geometry.Orientation;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.SplitPane;
import javafx.scene.control.TitledPane;
import javafx.scene.layout.Priority;
import javafx.scene.layout.Region;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class SplitPaneFitContentDemo extends Application {

    @Override
    public void start(final Stage stage) throws Exception {
        StackPane content = new StackPane();
        content.setMinSize(200, 800);
        content.setStyle("-fx-background-color:linear-gradient(to bottom, yellow, red);");
        ScrollPane scrollPane = new ScrollPane(content);

        VBox pane = new VBox();
        // 尝试设置下面的属性。在FXML中,对于VBox,它应该具有属性maxHeight="-Infinity"
        pane.setMaxHeight(Region.USE_PREF_SIZE);
        for (int i = 1; i < 3; i++) {
            VBox tpContent = new VBox(10, new Button("Button A" + i), new Button("Button B" + i));
            TitledPane tp = new TitledPane("Title " + i, tpContent);
            tp.setMaxHeight(Double.POSITIVE_INFINITY);
            VBox.setVgrow(tp, Priority.ALWAYS);
            pane.getChildren().add(tp);
        }

        SplitPane splitPane = new SplitPane(pane, scrollPane);
        splitPane.setOrientation(Orientation.VERTICAL);
        splitPane.setDividerPositions(0.35);

        StackPane root = new StackPane(splitPane);
        Scene scene = new Scene(root, 300, 400);
        stage.setScene(scene);
        stage.setTitle("SplitPane");
        stage.show();
    }
}

更新:
当应用于提供的FXML中时,它的工作方式如下。

JavaFX SplitPane 动态调整子组件大小

英文:

I believe you need to set the maxHeight attribute of VBox to the prefHeight of its contents. That way, the VBox can never grow beyond the size of its contents.

You can try the below code:

If in java code:

campaignInfoVBox.setMaxHeight(Region.USE_PREF_SIZE);

If in FXML code:

&lt;VBox fx:id=&quot;campaignInfoVBox&quot; spacing=&quot;10&quot; VBox.vgrow=&quot;ALWAYS&quot; maxHeight=&quot;-Infinity&quot;&gt;

Below is a quick demo that demonstrates the fix:

JavaFX SplitPane 动态调整子组件大小

import javafx.application.Application;
import javafx.geometry.Orientation;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.SplitPane;
import javafx.scene.control.TitledPane;
import javafx.scene.layout.Priority;
import javafx.scene.layout.Region;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class SplitPaneFitContentDemo extends Application {
@Override
public void start(final Stage stage) throws Exception {
StackPane content = new StackPane();
content.setMinSize(200, 800);
content.setStyle(&quot;-fx-background-color:linear-gradient(to bottom, yellow, red);&quot;);
ScrollPane scrollPane = new ScrollPane(content);
VBox pane = new VBox();
// Try setting the below one. In FXML, for the VBox it should have the attribute maxHeight=&quot;-Infinity&quot;
pane.setMaxHeight(Region.USE_PREF_SIZE);
for (int i = 1; i &lt; 3; i++) {
VBox tpContent = new VBox(10, new Button(&quot;Button A&quot; + i), new Button(&quot;Button B&quot; + i));
TitledPane tp = new TitledPane(&quot;Title &quot; + i, tpContent);
tp.setMaxHeight(Double.POSITIVE_INFINITY);
VBox.setVgrow(tp, Priority.ALWAYS);
pane.getChildren().add(tp);
}
SplitPane splitPane = new SplitPane(pane, scrollPane);
splitPane.setOrientation(Orientation.VERTICAL);
splitPane.setDividerPositions(0.35);
StackPane root = new StackPane(splitPane);
Scene scene = new Scene(root, 300, 400);
stage.setScene(scene);
stage.setTitle(&quot;SplitPane&quot;);
stage.show();
}
}

UPDATE:
When applied the attribute in the provided FXML, this is how it works.

JavaFX SplitPane 动态调整子组件大小

huangapple
  • 本文由 发表于 2023年7月20日 16:09:44
  • 转载请务必保留本文链接:https://go.coder-hub.com/76727861.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定