Javafx 迭代树视图节点

Javafx 迭代树视图节点,javafx,javafx-2,javafx-8,Javafx,Javafx 2,Javafx 8,我正在使用这段代码迭代所有TreeView节点 for (TreeItem<DynamicTreeNodeModel> children1 : children) { ObservableList<TreeItem<DynamicTreeNodeModel>> children2 = children1.getChildren(); for (Tr

我正在使用这段代码迭代所有TreeView节点

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
                        }
                    }
                }
for(TreeItem children1:children)
{
ObservableList children2=children1.getChildren();
对于(TreeItem children3:children2)
{
ObservableList children4=children3.getChildren();
treeitempValue=null;
对于(TreeItem children5:children4)
{
//一些逻辑
}
}
}

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

您可以使用递归方法,检查当前节点是否有子节点。如果有,它将再次调用相同的方法,否则将打印节点

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);
            }
        }
    }
}
导入javafx.application.application;
导入javafx.scene.scene;
导入javafx.scene.control.TreeItem;
导入javafx.scene.control.TreeView;
导入javafx.scene.layout.StackPane;
导入javafx.stage.stage;
公共类IterateTree扩展应用程序{
公共静态void main(字符串[]args){
发射(args);
}
@凌驾
公共无效开始(阶段primaryStage){
setTitle(“树视图示例”);
TreeItem rootItem=新的TreeItem(“收件箱”);
setExpanded(true);
对于(int i=1;i<5;i++){
getChildren().add(createTreeItem(i));
}        
TreeView树=新的TreeView(rootItem);
StackPane root=新的StackPane();
root.getChildren().add(树);
原始阶段。设置场景(新场景(根,300250));
primaryStage.show();
//打印子对象
打印子项(根项);
}
私有树Item createTreeItem(int num){
TreeItem rootItem=新的TreeItem(“组”+num);
对于(int i=1;i<6;i++){
TreeItem=新的TreeItem(“消息”+i);
rootItem.getChildren().add(项);
}
返回根项目;
}
私有void printChildren(TreeItem root){
System.out.println(“当前父项:+root.getValue());
for(TreeItem子项:root.getChildren()){
if(child.getChildren().isEmpty()){
System.out.println(child.getValue());
}否则{
儿童(儿童);
}
}
}
}

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

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

}
/**
*树表项目步行者。
*
*@author bvisy
*
*@param
*树项目的类型。
*/
公共类TreeTableViewWalker{
/**
*用于保存元组的实用程序类
*/
公共类元组{
E首先;
F秒;
公共元组(E第一,F第二){
this.first=first;
这个秒=秒;
}
公共E getFirst(){
先返回;
}
公共元组集合优先(E优先){
返回新的元组(第一、第二);
}
公共F getSecond(){
返回第二;
}
公共元组设置秒(F秒){
返回新的元组(第一、第二);
}
@凌驾
公共字符串toString(){
返回“Tuple[first=“+first+”,second=“+second+”];
}
}
//行走状态堆栈
private Deque stack=new ArrayDeque();
/**
*初始化步行器。
*
*@param树
*这棵树需要走
*/
公共TreeTableViewWalker(TreeTableView树){
超级();
if(tree.getRoot()!=null){
push(新元组(tree.getRoot(),-1));
}
}
/**
*@如果有未服务的项目,则返回True。
*/
公共布尔hasNext(){
return!stack.isEmpty();
}
/**
*@按深度行走顺序返回下一个树项目。返回父项
*在它的孩子面前。
*/
公共树下一页(){
如果(!hasNext()){
抛出新的非法状态异常(“”);
}
TreeItem nxt=stack.peek().getFirst();
move();
返回nxt;
}
私人空位移动(){
Tuple n=stack.pop();
ObservableList ch=n.getFirst().getChildren();
int idx=n.getSecond()+1;

如果(ch.size()使用递归方法。搜索“树遍历”,然后为树实现适当的算法一对相关问题:和