Iterate TreeView nodes

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

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

for (TreeItem children1 : children)
                {
                    Observa         


        
相关标签:
2条回答
  • 2021-01-21 21:53

    You can just use a recursive method, which checks if the current node has children or not. If it has, it calls the same method again, else it prints the node.

    import javafx.application.Application;
    import javafx.scene.Scene;
    import javafx.scene.control.TreeItem;
    import javafx.scene.control.TreeView;
    import javafx.scene.layout.StackPane;
    import javafx.stage.Stage;
    
    public class IterateTree extends Application {
    
    
        public static void main(String[] args) {
            launch(args);
        }
    
        @Override
        public void start(Stage primaryStage) {
            primaryStage.setTitle("Tree View Sample");        
    
            TreeItem<String> rootItem = new TreeItem<String> ("Inbox");
            rootItem.setExpanded(true);
            for (int i = 1; i < 5; i++) {
                rootItem.getChildren().add(createTreeItem(i));
            }        
            TreeView<String> tree = new TreeView<String> (rootItem);        
            StackPane root = new StackPane();
            root.getChildren().add(tree);
            primaryStage.setScene(new Scene(root, 300, 250));
            primaryStage.show();
            // print children
            printChildren(rootItem);
        }
    
        private TreeItem<String> createTreeItem(int num) {
            TreeItem<String> rootItem = new TreeItem<String> ("Group " + num);
            for (int i = 1; i < 6; i++) {
                TreeItem<String> item = new TreeItem<String> ("Message" + i);            
                rootItem.getChildren().add(item);
            }
            return rootItem;
        }
    
        private void printChildren(TreeItem<String> root){
            System.out.println("Current Parent :" + root.getValue());
            for(TreeItem<String> child: root.getChildren()){
                if(child.getChildren().isEmpty()){
                    System.out.println(child.getValue());
                } else {
                    printChildren(child);
                }
            }
        }
    }
    
    0 讨论(0)
  • 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 <T>
     *            The type of the tree items.
     */
    public class TreeTableViewWalker<T> {
    
        /**
         * Utility class to hold a tuple
         */
        public class Tuple<E, F> {
            E first;
            F second;
    
            public Tuple(E first, F second) {
                this.first = first;
                this.second = second;
            }
    
            public E getFirst() {
                return first;
            }
    
            public Tuple<E, F> setFirst(E first) {
                return new Tuple<>(first, second);
            }
    
            public F getSecond() {
                return second;
            }
    
            public Tuple<E, F> setSecond(F second) {
                return new Tuple<>(first, second);
            }
    
            @Override
            public String toString() {
                return "Tuple [first=" + first + ", second=" + second + "]";
            }
        }
    
        // The walk state stack
        private Deque<Tuple<TreeItem<T>, Integer>> stack = new ArrayDeque<>();
    
        /**
         * Initialize the walker.
         *
         * @param tree
         *            The tree to walk
         */
        public TreeTableViewWalker(TreeTableView<T> 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<T> next() {
            if (!hasNext()) {
                throw new IllegalStateException("");
            }
            TreeItem<T> nxt = stack.peek().getFirst();
            move();
            return nxt;
        }
    
        private void move() {
            Tuple<TreeItem<T>, Integer> n = stack.pop();
            ObservableList<TreeItem<T>> 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<TreeItem<T>> stream() {
            return StreamSupport.stream(new Spliterator<TreeItem<T>>() {
    
                @Override
                public int characteristics() {
                    return 0;
                }
    
                @Override
                public long estimateSize() {
                    return Long.MAX_VALUE;
                }
    
                @Override
                public boolean tryAdvance(Consumer<? super TreeItem<T>> action) {
                    if (hasNext()) {
                        action.accept(next());
                        return true;
                    } else {
                        return false;
                    }
                }
    
                @Override
                public Spliterator<TreeItem<T>> 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 <T> void visit(TreeTableView<T> tree, Consumer<TreeItem<T>> visitor) {
            TreeTableViewWalker<T> 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 <T> void visitItems(TreeTableView<T> tree, Consumer<T> visitor) {
            TreeTableViewWalker<T> tw = new TreeTableViewWalker<>(tree);
            while (tw.hasNext()) {
                visitor.accept(tw.next().getValue());
            }
        }
    
    }
    
    0 讨论(0)
提交回复
热议问题