Java 使用texfield搜索/过滤树视图
我一直试图找到一个答案,但这似乎是一个地狱般的复杂做 我想做的是,我有一个树视图和一个文本字段,我想能够搜索,所以只有树视图中的树项匹配文本字段上显示的内容 例如,如果有人在文本字段中写入“lat”,则树视图会显示“latency”、“latio”等文件夹 treeview填充代码如下所示Java 使用texfield搜索/过滤树视图,java,javafx,treeview,Java,Javafx,Treeview,我一直试图找到一个答案,但这似乎是一个地狱般的复杂做 我想做的是,我有一个树视图和一个文本字段,我想能够搜索,所以只有树视图中的树项匹配文本字段上显示的内容 例如,如果有人在文本字段中写入“lat”,则树视图会显示“latency”、“latio”等文件夹 treeview填充代码如下所示 @FXML private void fillTreeView() { // The tree needs a root, and it needs to be a DocumentObject
@FXML
private void fillTreeView() {
// The tree needs a root, and it needs to be a DocumentObject
// so we create an empty folder and hide it
TreeItem<DocumentObject<?>> treeRoot = new TreeItem<>(new Folder());
for (Folder folder : logic.getFolderList()) {
TreeItem<DocumentObject<?>> folderNode = new TreeItem<>(folder);
for (FileReference file : folder.getFileList()) {
TreeItem<DocumentObject<?>> fileNode = new TreeItem<>(file);
folderNode.getChildren().add(fileNode);
}
treeRoot.getChildren().add(folderNode);
treeRoot.setExpanded(true);
}
treeNav.setRoot(treeRoot);
treeNav.setShowRoot(false);
}
@FXML
私有void fillTreeView(){
//树需要一个根,它需要一个DocumentObject
//所以我们创建一个空文件夹并隐藏它
TreeItem>folderNode=新的TreeItem(文件夹);
对于(文件引用文件:folder.getFileList()){
TreeItem如果您只筛选根节点的直接子节点,那么它相当简单。只需将顶级节点保留在一个单独的可观察列表
,在其周围包装一个过滤器列表
,然后使用绑定.bindContent()
以确保根节点的子节点列表包含与过滤器数据列表相同的元素
假设您的DocumentObject
有一个方法,比如说getName()
,它返回要对其应用筛选器的文本,并且您有一个名为TextField
的TextField
,用户在其中键入筛选器文本,这看起来像:
@FXML
private void fillTreeView() {
// The tree needs a root, and it needs to be a DocumentObject
// so we create an empty folder and hide it
TreeItem<DocumentObject<?>> treeRoot = new TreeItem<>(new Folder());
ObservableList<TreeItem<DocumentObject<?>>> firstLevel = FXCollections.observableArrayList();
for (Folder folder : logic.getFolderList()) {
TreeItem<DocumentObject<?>> folderNode = new TreeItem<>(folder);
for (FileReference file : folder.getFileList()) {
TreeItem<DocumentObject<?>> fileNode = new TreeItem<>(file);
folderNode.getChildren().add(fileNode);
}
firstLevel.add(folderNode);
}
treeRoot.setExpanded(true);
FilteredList<TreeItem<DocumentObject<?>>> filteredList = new FilteredList<>(firstLevel, item -> true);
filteredList.predicateProperty().bind(Bindings.createObjectBinding(() -> {
String filter = textField.getText();
if (filter.isEmpty()) return item -> true ;
return item -> item.getValue().getName().startsWith(filter) ; // your implementation may vary...
}, textField.textProperty());
Bindings.bindContent(treeRoot.getChildren(), filteredList);
treeNav.setRoot(treeRoot);
treeNav.setShowRoot(false);
}
@FXML
私有void fillTreeView(){
//树需要一个根,它需要一个DocumentObject
//所以我们创建一个空文件夹并隐藏它
TreeItem>>firstLevel=FXCollections.observableArrayList();
对于(文件夹:logic.getFolderList()){
TreeItem>fileNode=新的TreeItem(文件);
folderNode.getChildren().add(fileNode);
}
添加(folderNode);
}
treeRoot.setExpanded(true);
FilteredList如果您只筛选根节点的直接子节点,这相当简单。只需将顶级节点保留在一个单独的ObservableList
中,在其周围包装一个FilteredList
,然后使用Bindings.bindContent()
以确保根节点的子节点列表包含与过滤器数据列表相同的元素
假设您的DocumentObject
有一个方法,比如说getName()
,它返回要对其应用筛选器的文本,并且您有一个名为TextField
的TextField
,用户在其中键入筛选器文本,这看起来像:
@FXML
private void fillTreeView() {
// The tree needs a root, and it needs to be a DocumentObject
// so we create an empty folder and hide it
TreeItem<DocumentObject<?>> treeRoot = new TreeItem<>(new Folder());
ObservableList<TreeItem<DocumentObject<?>>> firstLevel = FXCollections.observableArrayList();
for (Folder folder : logic.getFolderList()) {
TreeItem<DocumentObject<?>> folderNode = new TreeItem<>(folder);
for (FileReference file : folder.getFileList()) {
TreeItem<DocumentObject<?>> fileNode = new TreeItem<>(file);
folderNode.getChildren().add(fileNode);
}
firstLevel.add(folderNode);
}
treeRoot.setExpanded(true);
FilteredList<TreeItem<DocumentObject<?>>> filteredList = new FilteredList<>(firstLevel, item -> true);
filteredList.predicateProperty().bind(Bindings.createObjectBinding(() -> {
String filter = textField.getText();
if (filter.isEmpty()) return item -> true ;
return item -> item.getValue().getName().startsWith(filter) ; // your implementation may vary...
}, textField.textProperty());
Bindings.bindContent(treeRoot.getChildren(), filteredList);
treeNav.setRoot(treeRoot);
treeNav.setShowRoot(false);
}
@FXML
私有void fillTreeView(){
//树需要一个根,它需要一个DocumentObject
//所以我们创建一个空文件夹并隐藏它
TreeItem>>firstLevel=FXCollections.observableArrayList();
对于(文件夹:logic.getFolderList()){
TreeItem>fileNode=新的TreeItem(文件);
folderNode.getChildren().add(fileNode);
}
添加(folderNode);
}
treeRoot.setExpanded(true);
FilteredList一些代码会很好。@Sedrick补充了treeview是如何构建的。但是我甚至不知道如何开始搜索/过滤它,因为你的树总是只有两个深?我将试着看看我是否能拿出一个示例应用程序。你只是在一个级别上过滤吗?(即,只是过滤根节点的直接子节点?)如果是这样的话,那还不算太糟。或者你想过滤整个树:那更复杂。一些代码会很棒。@Sedrick补充了treeview是如何构建的。但是我甚至不知道我们该如何开始搜索/过滤它,因为你的树总是只有两层深?我将试着看看我是否能想出一个示例应用程序。你只是过滤吗在一个级别上?(即仅过滤根节点的直接子节点?)如果是这样,这还不算太糟。或者您想过滤整个树:这更复杂。您可能知道kware.net/?p=204…这是一种工作方式,尽管脏(反射性地用filteredList替换内部子列表)@kleopatra,该类有一个不使用反射的更新版本。他在注释部分的底部提到了它。@wcmatthysen没有意识到更新,感谢指针:)我无法多次启动此筛选器。我没有使用textfield的属性,只是维护一个SimpleObject属性在类中。当我通过set()更新属性的值时,筛选器似乎不会再次启动。您可能知道kware.net/?p=204…这是一种虽然脏但仍能正常工作的方法(反射性地将内部子列表替换为filteredList)@kleopatra,该类有一个不使用反射的更新版本。他在注释部分的底部提到了它。@wcmatthysen没有意识到更新,感谢指针:)我无法多次启动此筛选器。我没有使用textfield的属性,只是维护一个SimpleObject属性当我通过set()更新属性的值时,过滤器似乎不会再次启动。