【问题标题】:Get a list of all TreeCell objects that currently exist in a TreeView获取当前存在于 TreeView 中的所有 TreeCell 对象的列表
【发布时间】:2015-09-01 15:04:17
【问题描述】:

我知道TreeCell 对象是由TreeView 使用单元工厂动态生成的。

有没有办法获取当前存在的所有TreeCell 对象的列表?

我想我可以通过修改单元工厂来跟踪它们。如,每当我创建一个新单元格时,将其添加到某个列表中。但是,一旦 TreeView 处理它们(因为它们消失了),我不确定如何从列表中删除单元格。

【问题讨论】:

  • 简而言之,不,没有(至少,没有公共 API)。为什么你认为你想这样做? (请注意,当它们消失时,它们通常会被重复使用,而不是被丢弃,但两者都不能保证。)
  • @James_D 有时,我的应用程序需要根据多种因素更改 TreeView 中所有单元格的样式(字体/颜色/等)。这对于新生成的单元格来说没有问题,因为我可以使用所需的样式生成它们,但是对于旧的已经存在的单元格,它们将保留它们创建时的样式,并且需要以某种方式进行更新。
  • 所以你的问题真的是:“当单元格显示后属性发生变化时,如何动态更新TreeCell 的样式?”。保存单元列表不是这样做的方法:您应该让单元工厂生成观察适当属性的单元。我建议您编辑您的问题以提出此问题...添加一些代码可能会有所帮助。
  • 实际上:如果您要更改 所有 单元格的样式,可能只需更改 TreeView 本身的样式类,然后使用您的 CSS 文件以将样式应用于作为 TreeView 不同类的子节点的单元格。但是你需要解释你真正想要做什么。

标签: java javafx treeview treecell


【解决方案1】:

我的解决方案是使用weak references:

[A] 弱引用是不保护被引用对象不被垃圾收集器收集的引用[.]

所以,将它添加到您的控制器中:

private final Set<MyTreeCell> myTreeCells = Collections.newSetFromMap(new WeakHashMap<>());

让你的 CellFactory 看起来像这样:

myTreeView.setCellFactory((treeItem) -> {
        MyTreeCell c = new MyTreeCell(icf);
        Platform.runLater(() -> myTreeCells.add(c));
        return c;
    });

现在,myTreeCells 将始终包含当前存在的 TreeCell。

更新

还有另一种非常丑陋的解决方案,使用反射来获取 TreeCells 列表。请注意,据我所知,此列表是 JavaFX 的 TreeCell 列表在某个时间点的快照。它没有被支持。

@SuppressWarnings({ "unchecked" })
private Set<MyTreeCell> getListOfTreeCells() {
    try {
        final Field f = VirtualContainerBase.class.getDeclaredField("flow");
        f.setAccessible(true);
        final Field g = VirtualFlow.class.getDeclaredField("cells");
        g.setAccessible(true);
        final Set<MyTreeCell> s = new HashSet<>();
        s.addAll((ArrayLinkedList<MyTreeCell>) g
                .get((f.get((myTreeView.skinProperty().get())))));
        return s;
    }
    catch (NoSuchFieldException | SecurityException | IllegalArgumentException
            | IllegalAccessException e) {
        e.printStackTrace();
    }
    return null;
}

【讨论】:

  • 哈哈哈伙计,我喜欢反射示例 xD 我觉得 javafx 迫使你做这样的事情,因为他们的设计选择很差。仅仅为树项设置样式就非常困难,这真的令人沮丧。
【解决方案2】:
treeView.lookupAll(".tree-cell");

这将返回一组可以转换为 TreeCells 的节点。

【讨论】:

  • 谢谢伙计,工作就像一个魅力。我认为这是最佳解决方案。
猜你喜欢
  • 2013-07-16
  • 2010-10-08
  • 1970-01-01
  • 1970-01-01
  • 2023-03-22
  • 1970-01-01
  • 2018-04-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多