如何在JavaFX中获取父节点中的所有节点?

时间:2014-07-27 23:43:25

标签: java recursion javafx javafx-8

在C#中,我找到了一个非常好的方法,允许你从指定的控件中获取所有后代和所有的后代。

我正在为JavaFX寻找类似的方法。

我看到Parent类是我想要使用的类,因为它是从中派生所有带子项的Node类的类。

这就是我到目前为止所做的事情(我还没有真正在google上找到像&#34这样的搜索内容; JavaFX从场景中获取所有节点"):

public static ArrayList<Node> GetAllNodes(Parent root){
    ArrayList<Node> Descendents = new ArrayList<>();
    root.getChildrenUnmodifiable().stream().forEach(N -> {
        if (!Descendents.contains(N)) Descendents.add(N);
        if (N.getClass() == Parent.class) Descendents.addAll(
            GetAllNodes((Parent)N)
        );
    });
}

那么如何判断N是父母(或从父母延伸)?我这样做了吗?它似乎没有工作......它从根(父)节点抓取所有节点,但不从其中包含子节点的节点抓取。我觉得这可能是一个可以得到答案的东西,但我只是问这个问题......错了。我该怎么做呢?

5 个答案:

答案 0 :(得分:16)

public static ArrayList<Node> getAllNodes(Parent root) {
    ArrayList<Node> nodes = new ArrayList<Node>();
    addAllDescendents(root, nodes);
    return nodes;
}

private static void addAllDescendents(Parent parent, ArrayList<Node> nodes) {
    for (Node node : parent.getChildrenUnmodifiable()) {
        nodes.add(node);
        if (node instanceof Parent)
            addAllDescendents((Parent)node, nodes);
    }
}

答案 1 :(得分:1)

不幸的是,这不会获得大多数容器组件的子节点。如果您尝试使用TabPane作为父级,则不会找到任何子级,但您可以使用getTabs()找到其中的标签。同样是SplitPane和其他。所以每个容器都需要特定的方法。

您可以使用node.lookupAll("*"),但它也无法查看。

解决方案可能是&#34;原型&#34; pattern - 使用getChildren()方法的公共接口创建一个元类,该方法在子类中实现 - 每种类型一个。

方法示例为here

答案 2 :(得分:1)

我用这个,

public class NodeUtils {

    public static <T extends Pane> List<Node> paneNodes(T parent) {
        return paneNodes(parent, new ArrayList<Node>());
    }

    private static <T extends Pane> List<Node> paneNodes(T parent, List<Node> nodes) {
        for (Node node : parent.getChildren()) {
            if (node instanceof Pane) {
                paneNodes((Pane) node, nodes);
            } else {
                nodes.add(node);
            }
        }

        return nodes;
    }
}

用法,

List<Node> nodes = NodeUtils.paneNodes(aVBoxOrAnotherContainer);

此源代码使用现有节点的引用。它不会克隆它们。

答案 3 :(得分:0)

这似乎获得了所有节点。 (在科特林)

fun getAllNodes(root: Parent): ArrayList<Node> {
    var nodes = ArrayList<Node>()
    fun recurseNodes(node: Node) {
        nodes.add(node)
        if(node is Parent)
            for(child in node.childrenUnmodifiable) {
                recurseNodes(child)
            }
    }
    recurseNodes(root)
    return nodes
}

答案 4 :(得分:0)

这对我有用:

public class FXUtil {

    public static final List<Node> getAllChildren(final Parent parent) {
        final List<Node> result = new LinkedList<>();

        if (parent != null) {

            final List<Node> childrenLvl1 = parent.getChildrenUnmodifiable();
            result.addAll(childrenLvl1);

            final List<Node> childrenLvl2 =
                    childrenLvl1.stream()
                                .filter(c -> c instanceof Parent)
                                .map(c -> (Parent) c)
                                .map(FXUtil::getAllChildren)
                                .flatMap(List::stream)
                                .collect(Collectors.toList());
            result.addAll(childrenLvl2);
        }

        return result;
    }

}