Iterate TreeView nodes

后端 未结 2 1642
醉酒成梦
醉酒成梦 2021-01-21 21:12

I\'m using this code to iterate all TreeView nodes.

for (TreeItem children1 : children)
                {
                    Observa         


        
2条回答
  •  终归单人心
    2021-01-21 22:02

    I made a utility class for traversing TreeTableView items depth-first. It supports streaming, visitor pattern and iterator pattern. It may be useful for someone.

    /**
     * Tree table item walker.
     *
     * @author bvissy
     *
     * @param 
     *            The type of the tree items.
     */
    public class TreeTableViewWalker {
    
        /**
         * Utility class to hold a tuple
         */
        public class Tuple {
            E first;
            F second;
    
            public Tuple(E first, F second) {
                this.first = first;
                this.second = second;
            }
    
            public E getFirst() {
                return first;
            }
    
            public Tuple setFirst(E first) {
                return new Tuple<>(first, second);
            }
    
            public F getSecond() {
                return second;
            }
    
            public Tuple setSecond(F second) {
                return new Tuple<>(first, second);
            }
    
            @Override
            public String toString() {
                return "Tuple [first=" + first + ", second=" + second + "]";
            }
        }
    
        // The walk state stack
        private Deque, Integer>> stack = new ArrayDeque<>();
    
        /**
         * Initialize the walker.
         *
         * @param tree
         *            The tree to walk
         */
        public TreeTableViewWalker(TreeTableView tree) {
            super();
            if (tree.getRoot() != null) {
                stack.push(new Tuple<>(tree.getRoot(), -1));
            }
        }
    
        /**
         * @return True if has unserved items.
         */
        public boolean hasNext() {
            return !stack.isEmpty();
        }
    
        /**
         * @return The next tree item in depth walk order. The parent is returned
         *         before any of its children.
         */
        public TreeItem next() {
            if (!hasNext()) {
                throw new IllegalStateException("");
            }
            TreeItem nxt = stack.peek().getFirst();
            move();
            return nxt;
        }
    
        private void move() {
            Tuple, Integer> n = stack.pop();
            ObservableList> ch = n.getFirst().getChildren();
            int idx = n.getSecond() + 1;
            if (ch.size() <= idx) {
                if (stack.isEmpty()) {
                    return;
                } else {
                    move();
                }
            } else {
                stack.push(n.setSecond(idx));
                stack.push(new Tuple<>(ch.get(idx), -1));
            }
        }
    
        /**
         * @return A stream of all (remaining) items. Note, that the walker could
         *         traverse only once over items.
         */
        public Stream> stream() {
            return StreamSupport.stream(new Spliterator>() {
    
                @Override
                public int characteristics() {
                    return 0;
                }
    
                @Override
                public long estimateSize() {
                    return Long.MAX_VALUE;
                }
    
                @Override
                public boolean tryAdvance(Consumer> action) {
                    if (hasNext()) {
                        action.accept(next());
                        return true;
                    } else {
                        return false;
                    }
                }
    
                @Override
                public Spliterator> trySplit() {
                    return null;
                }
            }, false);
        }
    
        /**
         * Walks over the tree and calls the consumer for each tree item.
         *
         * @param tree
         *            The tree to visit.
         * @param visitor
         *            The visitor.
         */
        public static  void visit(TreeTableView tree, Consumer> visitor) {
            TreeTableViewWalker tw = new TreeTableViewWalker<>(tree);
            while (tw.hasNext()) {
                visitor.accept(tw.next());
            }
        }
    
        /**
         * Walks over the tree and calls the consumer for each item value.
         *
         * @param tree
         *            The tree to visit.
         * @param visitor
         *            The visitor.
         */
        public static  void visitItems(TreeTableView tree, Consumer visitor) {
            TreeTableViewWalker tw = new TreeTableViewWalker<>(tree);
            while (tw.hasNext()) {
                visitor.accept(tw.next().getValue());
            }
        }
    
    }
    

提交回复
热议问题