Any ideas on how to represent nested paths within as TreeItems?
This is my input as several Strings (besides: I don't know the strings before so the whole thing should be as generic as possible):
input1
input2.sub1
input2.sub2
input2.sub2.subsub1
input2.sub3
input3
input3.sub1
input3.sub1.subsub1
input3.sub1.subsub1.subsubsub1
input3.sub2
Since I'm on the way at the moment, I cannot post any source code unfortunately. But before asking, I tried several approaches such as transferring the paths directly to the TreeView (seems complicated) or having some sort of tree representation in java first (mostly everything with recursive methods).
The attached screenshots shows what I try to achieve in a generic way.
Thanks a lot in advance — best wishes from Germany :)
答案 0 :(得分: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 ;
}
请注意,这里的字符串没什么特别之处,你可以用任何类型做到这一点。这是一个使用该方法的通用版本的SSCCE:
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);
}
}
答案 1 :(得分:1)
将项目“path”存储在地图中,以便您可以查找它们,创建不存在的节点并使用现有节点。最简单的方法是使用递归方法:
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();
}