我有一个JavaFX层次结构,在细分时基本上看起来像这样:
Parent // Tested with ScrollPane and AnchorPane, both work this way.
| // The important part is that TabPane ISN'T the base Node
| // So its sizing is under its own control, not the Window's
| - TabPane
| | - Tab
| | | - VBox
VBox的内容使其动态改变高度。不幸的是,TabPane不会自动响应重新调整大小。 I worked out how to get the TabPane to grow here,后来搜索显示this issue on bugs.openjdk,似乎也提到了这一点。
不幸的是,这里仍然存在问题,并且通过给TabPane -fx-background-color
明确了这一点。使用更改选项卡的手动/自动解决方法或我的解决方法来调用TabPane#requestLayout
,虽然TabPane正常增长,但它无法收缩。
(注意:如果你没有告诉VBox有maxHeight="-Infinity"
(USE_PREF_SIZE
),VBox将是不减小尺寸的罪魁祸首。然而,有了这个设置,VBox将缩小离开TabPane大于其内容。)
Scenic View显示我的测试用例(下面)的层次结构看起来更像是这样:
AnchorPane
| - TabPane "tabPane"
| | - TabContentRegion
| | - TabContentRegion
| | | - VBox "vBox"
| | | | - Button
| | | | - Button
| | - TabHeaderArea
| | | - (Generated Stuff)
在重新调整VBox的大小时,Scenic View确认VBox的layouBounds
/ boundsInParent
随着大小的增加和大小的减小而改变,但仅包含TabContentRegion的Bounds
当VBox变得大于TabContentRegion时改变。
TL; DR:是否有办法(变通办法或官方)使TabPane / TabContentRegion保持与其子项相同的维度(不占用任何外来空间),即使重新调整大小儿?
View the full MCVE here,在下面删节:
FXML.fxml
<AnchorPane fx:controller="test.FXMLController"><children>
<TabPane fx:id="tabPane" style="-fx-background-color:#000000;"><tabs><Tab>
<VBox fx:id="vBox" maxHeight="-Infinity"><children>
<Button onAction="#addElement" />
<Button onAction="#remElement" />
</children></VBox>
</Tab></tabs></TabPane>
</children></AnchorPane>
FXMLController.java
@FXML VBox vBox;
@FXML TabPane tabPane;
@FXML void addElement() {
vBox.getChildren().add(0, new Label("Hello World"));
tabPane.requestLayout();
}
@FXML void remElement() {
if (vBox.getChildren().size() > 2) {
vBox.getChildren().remove(0);
tabPane.requestLayout(); // Doesn't seem to do anything
}
}
测试用例使用TabPane#requestLayout
来增加TabPane,但提供了两个选项卡,以便您可以在它们之间手动选项卡,以查看不允许TabPane缩小。
Here's another example that's closer to my use case and maybe a bit clearer on what exactly is going on.这里TabPane位于ScrollPane中,一旦TabPane扩展到ScrollPane的高度之外,即使它再次缩小,ScrollPane仍然允许用户像以前一样向下滚动,因为TabPane向下延伸
答案 0 :(得分:1)
在 ScrollPane 中 TabPane 的上一个示例中,我进行了以下更改:
将 ChangeListener 添加到 TableView ,当更改pref-height时,它会告诉 TabPane :
table.prefHeightProperty().addListener(new ChangeListener<Number>() {
@Override
public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
tabs.setPrefHeight(table.getPrefHeight() + 75.0d);
}
});
注释掉requestLayout()中的方法调用:
@FXML
void addPerson() {
table.getItems().add(new Person());
// updateTabPaneSize(tabs);
}
@FXML
void remPerson() {
if (table.getItems().size() > 0) {
table.getItems().remove(0);
// updateTabPaneSize(tabs);
}
}
通过此更改,TabPane的高度将随着TableView的每次更改而更新,这些更改也会更新ScrollPane(Scroller将根据需要显示和删除)。