迭代TreeView节点 [英] Iterate TreeView nodes

查看:103
本文介绍了迭代TreeView节点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用此代码迭代所有TreeView节点。

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

for (TreeItem<DynamicTreeNodeModel> children1 : children)
                {
                    ObservableList<TreeItem<DynamicTreeNodeModel>> children2 = children1.getChildren();

                    for (TreeItem<DynamicTreeNodeModel> children3 : children2)
                    {
                        ObservableList<TreeItem<DynamicTreeNodeModel>> children4 = children3.getChildren();

                        TreeItem<DynamicTreeNodeModel> tempValue = null;

                        for (TreeItem<DynamicTreeNodeModel> children5 : children4)
                        {
                            // some logic
                        }
                    }
                }

有没有更好的方法来访问TreeView的低级节点?

Is there any better way to access low level nodes of the TreeView?

推荐答案

我创建了一个实用程序类,用于深度优先遍历TreeTableView项。它支持流,访问者模式和迭代器模式。
它可能对某人有用。

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

}

这篇关于迭代TreeView节点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆