2017-03-22 4 views
0

TreeItemとしてネストされたパスを表現する方法はありますか? (:ので全部はできるだけ汎用的でなければなりません前に、私は文字列を知らないほか):私が途中でてるのでJavaFX TreeViewへのネストされたパス

input1 
input2.sub1 
input2.sub2 
input2.sub2.subsub1 
input2.sub3 
input3 
input3.sub1 
input3.sub1.subsub1 
input3.sub1.subsub1.subsubsub1 
input3.sub2 

これは、いくつかの文字列としての私の入力であります瞬間、残念ながらソースコードを投稿できません。しかし、尋ねる前に、私はTreeView(複雑に思える)に直接パスを転送するか、Javaで何らかの種類のツリー表現(主に再帰的メソッドを持つすべて)を持つなど、いくつかのアプローチを試みました。

添付のスクリーンショットは、私が一般的な方法で達成しようとしているものを示しています。事前に TreeView

どうもありがとう - ドイツ:)から希望する最高の

答えて

1

あなたは区切り文字(.)によって、それぞれを分割し、文字列のリストを繰り返し処理して、アイテムを追加して、ツリーを検索することができます必要に応じて。次のようなものがあります:

List<String> paths = ... ; 
TreeItem<String> root = new TreeItem<>("root"); 
for (String path : paths) { 
    TreeItem<String> current = root ; 
    for (String component : path.split("\\.")) { 
     current = getOrCreateChild(current, component); 
    } 
} 

// ... 

private TreeItem<String> getOrCreateChild(TreeItem<String> parent, String value) { 

    for (TreeItem<String> child : parent.getChildren()) { 
     if (value.equals(child.getValue())) { 
      return child ; 
     } 
    } 
    TreeItem<String> newChild = new TreeItem<>(value); 
    parent.getChildren().add(newChild); 
    return newChild ; 
} 

ここでは特に何も特別なことはありませんが、どのタイプでもこれを行うことができます。

import java.util.Arrays; 
import java.util.List; 
import java.util.function.Function; 

import javafx.application.Application; 
import javafx.scene.Scene; 
import javafx.scene.control.TreeItem; 
import javafx.scene.control.TreeView; 
import javafx.stage.Stage; 

public class TreeFromPaths extends Application { 

    private final List<String> paths = Arrays.asList(
      "input1", 
      "input2.sub1", 
      "input2.sub2", 
      "input2.sub2.subsub1", 
      "input2.sub3", 
      "input3", 
      "input3.sub1", 
      "input3.sub1.subsub1", 
      "input3.sub1.subsub1.subsubsub1", 
      "input3.sub2" 
    ); 

    private <S,T> TreeView<T> createTree(
      List<S> paths, 
      Function<S, ? extends Iterable<T>> pathSplitter, 
      T rootValue) { 

     TreeItem<T> root = new TreeItem<>(rootValue); 
     populateTree(paths, pathSplitter, root); 
     TreeView<T> tree = new TreeView<>(root); 
     tree.setShowRoot(false); 
     return tree; 
    } 

    private <S,T> void populateTree(
      List<S> paths, 
      Function<S, ? extends Iterable<T>> pathSplitter, 
      TreeItem<T> root) { 

     for (S path : paths) { 
      TreeItem<T> current = root ; 
      for (T component : pathSplitter.apply(path)) { 
       current = getOrCreateChild(current, component); 
      } 
     } 
    } 

    private <T> TreeItem<T> getOrCreateChild(TreeItem<T> parent, T value) { 
     for (TreeItem<T> child : parent.getChildren()) { 
      if (value.equals(child.getValue())) { 
       return child ; 
      } 
     } 
     TreeItem<T> newChild = new TreeItem<>(value); 
     parent.getChildren().add(newChild); 
     return newChild ; 
    } 

    @Override 
    public void start(Stage primaryStage) { 

     Function<String, List<String>> pathSplitter = 
      path -> Arrays.asList(path.split("\\.")); 

     TreeView<String> treeView = createTree(paths, pathSplitter, "root"); 

     primaryStage.setScene(new Scene(treeView, 400, 400)); 
     primaryStage.show(); 
    } 


    public static void main(String[] args) { 
     launch(args); 
    } 
} 
+0

Genius!本当にありがとう!それは完璧に機能し、私の問題に応じて非常にコンパクトなソリューションです。 – pixelstuermer

1

ストアマップ内の項目「パス」あなたは、それらを見て存在し、既存のノードを使用していないノードを作成することができるように:ここではメソッドのジェネリックバージョンを使用していますSSCCEです。これを行う最も簡単な方法は再帰的な方法です:

private static TreeItem<String> getItem(Map<String, TreeItem<String>> items, TreeItem<String> root, String itemPath) { 
    TreeItem<String> result = items.get(itemPath); 

    if (result == null) { 
     // new item needs to be created 

     int index = itemPath.lastIndexOf('.'); 

     result = new TreeItem<>(itemPath.substring(index + 1)); 
     items.put(itemPath, result); 

     if (index == -1) { 
      // no more subpaths => connect to root 
      root.getChildren().add(result); 
     } else { 
      // find/create parent 
      TreeItem<String> parent = getItem(items, root, itemPath.substring(0, index)); 

      parent.getChildren().add(result); 
     } 
    } 

    return result; 

} 

@Override 
public void start(Stage primaryStage) throws Exception { 
    List<String> paths = Arrays.asList(
      "input1", 
      "input2.sub1", 
      "input2.sub2", 
      "input2.sub2.subsub1", 
      "input2.sub3", 
      "input3", 
      "input3.sub1", 
      "input3.sub1.subsub1", 
      "input3.sub1.subsub1.subsubsub1", 
      "input3.sub2"); 

    TreeItem<String> root = new TreeItem<>(); 
    Map<String, TreeItem<String>> items = new HashMap<>(); 

    for (String path : paths) { 
     getItem(items, root, path); 
    } 

    TreeView<String> treeView = new TreeView<>(root); 
    treeView.setShowRoot(false); 
    Scene scene = new Scene(treeView); 
    primaryStage.setScene(scene); 
    primaryStage.show(); 
} 
関連する問題