基于子项的TabPane动态大小调整

时间:2016-02-11 21:23:49

标签: javafx javafx-8

我有一个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向下延伸

1 个答案:

答案 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将根据需要显示和删除)。