How do I get all nodes in a parent in JavaFX?

后端 未结 6 1488
耶瑟儿~
耶瑟儿~ 2020-12-29 09:58

In C# I found a method that was pretty sweet that allowed you to get all the descendants and all of THEIR descendants from a specified control.

I\'m looking for a si

相关标签:
6条回答
  • 2020-12-29 10:07

    This seems to get ALL nodes. (In Kotlin)

    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
    }
    
    0 讨论(0)
  • 2020-12-29 10:08

    Unfortunately this won't get subnodes for most container components. If you try a TabPane as parent, you'll find no children, but you can find tabs in it with getTabs(). The same is with SplitPane and other. So every container will require a specific approach.

    You could use node.lookupAll("*"), but it also doesn't look inside.

    The solution could be a "Prototype" pattern - creating a meta class with common interface of getChildren() method, which is realized in subclasses - one for each type.

    Approach example is given here.

    0 讨论(0)
  • 2020-12-29 10:11
    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);
        }
    }
    
    0 讨论(0)
  • 2020-12-29 10:13

    I use this,

    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;
        }
    }
    

    Usage,

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

    This source code uses the references of the existing nodes. It does not clone them.

    0 讨论(0)
  • 2020-12-29 10:18

    This works for me:

    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;
        }
    
    }
    
    0 讨论(0)
  • 2020-12-29 10:23

    I'd like to add to Hans' answer, that you have to check if parent is a SplitPane. Because SplitPanes have an empty list using getUnmodifiableChildren(), you'll have to use getItems() instead. (I do not know if there are other parents that do not provide their children via getUnmodifiableChildren(). SplitPane was the first I found...)

    0 讨论(0)
提交回复
热议问题