【问题标题】:Dynamic sizing of TabPane based on children基于子项的 TabPane 的动态大小
【发布时间】:2016-02-11 21:23:48
【问题描述】:

我有一个 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 增长,但提供了两个选项卡,以便您可以在它们之间手动使用tab 来查看这也不允许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 向下延伸。

【问题讨论】:

    标签: javafx javafx-8


    【解决方案1】:

    ScrollPane 中的 TabPane 的上一个示例中,我做了以下更改:

    添加一个 ChangeListenerTableView,它告诉 TabPane 当 pref-height 改变时:

    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(滚动器将根据需要显示和删除)。

    【讨论】:

    • 使用绑定可以内联:tabs.prefHeightProperty().bind(table.prefHeightProperty().add(70)); 第二个例子。 (TabPane 中的 VBox 应该存在类似的解决方案。)显然,add 部分将根据其他元素发生变化。我可以发誓我试过了,但我想不会。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2021-05-18
    • 1970-01-01
    • 2014-10-27
    • 1970-01-01
    • 2018-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多