英文:
JavaFX SplitPane dynamically resize children
问题
我有一个SplitPane
,其中包含两个项目,分别是VBox
和ScrollPane
。在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.
<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>
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
我认为你需要将VBox
的maxHeight
属性设置为其内容的prefHeight
。这样,VBox
永远不会超出其内容的大小。
你可以尝试下面的代码:
如果是在Java代码中:
campaignInfoVBox.setMaxHeight(Region.USE_PREF_SIZE);
如果是在FXML代码中:
<VBox fx:id="campaignInfoVBox" spacing="10" VBox.vgrow="ALWAYS" maxHeight="-Infinity">
以下是演示修复的快速演示:
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中时,它的工作方式如下。
英文:
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:
<VBox fx:id="campaignInfoVBox" spacing="10" VBox.vgrow="ALWAYS" maxHeight="-Infinity">
Below is a quick demo that demonstrates the fix:
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();
// Try setting the below one. In FXML, for the VBox it should have the attribute 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();
}
}
UPDATE:
When applied the attribute in the provided FXML, this is how it works.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论