1

文档中说,

TreeTableView 控件旨在可视化无限数量的数据行

不幸的是,我在文档中看不到任何方法。

所有元素都存储在TreeItem<>类中并存储在内存中。虽然,一个人可以实现“无限”,ObservableList<>但我认为没有办法在嵌套的可观察列表上实现这一点。

“无限”需要按需加载数据,而不是将其存储在内存中。

那么终于可以在TreeTableView中按需显示数据了吗?

4

1 回答 1

1

正如评论中指出的那样,文档TreeItem有一个延迟填充树项的子节点的示例。

这是一个非常简单的无限树表的完整示例。在此示例中,当树项折叠时,子节点将被删除,从而允许对它们进行垃圾回收。

import java.math.BigInteger;
import java.util.function.Function;

import javafx.application.Application;
import javafx.beans.property.SimpleObjectProperty;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeTableColumn;
import javafx.scene.control.TreeTableView;
import javafx.stage.Stage;

public class UnlimitedTreeTableView extends Application {


    @Override
    public void start(Stage primaryStage) {
        TreeTableView<Item> treeTable = new TreeTableView<>();
        treeTable.setRoot(createTreeItem(BigInteger.ZERO));

        treeTable.getColumns().add(column("Item", Item::getName));
        treeTable.getColumns().add(column("Value", Item::getValue));

        primaryStage.setScene(new Scene(treeTable));
        primaryStage.show();
    }

    private TreeItem<Item> createTreeItem(BigInteger value) {
        TreeItem<Item> item = new TreeItem<Item>(new Item(String.format("Item %,d", value), value)) {

            private boolean childrenComputed = false ;

            {
                expandedProperty().addListener((obs, wasExpanded, isNowExpanded) -> {
                    if (! isNowExpanded) { // remove child nodes...
                        super.getChildren().clear();
                        childrenComputed = false ;
                    }
                });
            }

            @Override
            public ObservableList<TreeItem<Item>> getChildren() {
                if (! childrenComputed) {
                    Item item = getValue();
                    BigInteger value = item.getValue() ;
                    BigInteger valueTimes10 = value.multiply(BigInteger.TEN);
                    for (int i = 0 ; i < 10 ; i++) {
                        BigInteger v = BigInteger.valueOf(i);
                        super.getChildren().add(createTreeItem(valueTimes10.add(v)));
                    }
                    childrenComputed = true ;
                }
                return super.getChildren();
            }

            @Override
            public boolean isLeaf() {
                return false ;
            }
        };

        return item ;
    }

    private static <S,T> TreeTableColumn<S,T> column(String title, Function<S,T> property) {
        TreeTableColumn<S,T> column = new TreeTableColumn<>(title);
        column.setCellValueFactory(cellData -> 
            new SimpleObjectProperty<T>(property.apply(cellData.getValue().getValue())));
        column.setPrefWidth(200);
        return column ;
    }

    public static class Item {
        private final BigInteger value ;
        private final String name ;

        public Item(String name, BigInteger value) {
            this.name = name ;
            this.value = value ;
        }

        public BigInteger getValue() {
            return value;
        }

        public String getName() {
            return name;
        }


    }

    public static void main(String[] args) {
        launch(args);
    }
}
于 2016-06-13T12:31:32.117 回答