我使用此代码迭代所有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 :(得分:3)
您可以使用递归方法,该方法检查当前节点是否有子节点。如果有,则再次调用相同的方法,否则打印节点。
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 :(得分: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());
}
}
}