2015-02-05 4 views
2

이 코드를 사용하여 모든 TreeView 노드를 반복합니다.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 
         } 
        } 
       } 

TreeView의 하위 노드에 액세스하는 더 좋은 방법이 있습니까?

+0

재귀 적 방법을 사용하십시오. – ItachiUchiha

+0

몇 가지 간단한 예? –

+0

"tree traversal"을 검색 한 다음 TreeItem에 대한 적절한 알고리즘을 구현하십시오. – kleopatra

답변

2

현재 노드에 자식 노드가 있는지 여부를 확인하는 재귀 적 메서드 만 사용할 수 있습니다. 존재하는 경우, 동일한 메소드를 다시 호출합니다. 그렇지 않으면 노드를 인쇄합니다.

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

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

}