[英]Nested Paths to JavaFX TreeView
關於如何將嵌套路徑表示為TreeItems的任何想法?
這是我輸入的幾個字符串(此外:我之前不知道字符串,所以整個過程應該盡可能通用):
input1
input2.sub1
input2.sub2
input2.sub2.subsub1
input2.sub3
input3
input3.sub1
input3.sub1.subsub1
input3.sub1.subsub1.subsubsub1
input3.sub2
由於目前正在路上,很遺憾,我無法發布任何源代碼。 但是在詢問之前,我嘗試了幾種方法,例如將路徑直接傳輸到TreeView(似乎很復雜),或者首先在Java中使用某種樹表示形式(大多數都是使用遞歸方法)。
所附的屏幕截圖顯示了我嘗試以通用方式實現的目標。
在此先感謝您-德國的良好祝願:)
您可以遍歷字符串列表,用定界符( .
)分隔每個字符串,然后搜索樹,並根據需要添加項目。 就像是:
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);
}
}
將項目“路徑”存儲在地圖中,以便您可以查找它們,創建不存在的節點以及使用現有節點。 最簡單的方法是遞歸方法:
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();
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.