我正在使用带有侦听器的 TextField 来过滤 TableView。如果 newText 与 ID 或名称的一部分匹配,我有 if 语句设置谓词。
搜索功能就像我想要的那样工作。
但是,我的项目指南要求我在搜索不匹配 TableView 中的任何对象时创建某种形式的输出。
我创建了一个标签并将可见性设置为 false 开始。我在谓词逻辑中的每个 if 语句之后放置了代码以将 Label 设置为可见,以便它仅显示所有语句是否有效。然后,我在谓词逻辑的开头放置了一条线,将其设置回 false ,因此在每个侦听器更改时,它都会被重置。
我有一个问题,如果我的搜索返回列表中的最后一项,那很好并且标签不出现,但是如果搜索没有返回列表中的最后一项,那么即使搜索,标签也会变得可见显示排序列表中的项目。
以下是我的代码,我附上了“错误”的截图。
FilteredList<Part> filteredParts = new FilteredList<>(Inventory.getAllParts(), p -> true); partFilter.textProperty().addListener((ob, ol, newValue) -> { filteredParts.setPredicate(text -> { //each time listener is updated sets label visibility to false partSearchMismatch.setVisible(false); //If searchbar is empty or null it displays all parts if (newValue == null || newValue.isEmpty()){ return true; } //if text matches partID String lowerCaseFilter = newValue.toLowerCase(); if(String.valueOf(text.getId()).contains(lowerCaseFilter)){ return true; } //if text matches part name if(text.getName().toLowerCase().contains(lowerCaseFilter)){ return true; } partSearchMismatch.setVisible(true); //if no matches, displays label return false; //no match }); }); //Wraps filtered list in sorted list SortedList<Part> sortedParts = new SortedList<>(filteredParts); //Binds sorted list comparator to the parts table comparator sortedParts.comparatorProperty().bind(partsTable.comparatorProperty()); partsTable.setItems(sortedParts);
以下是表中的基础样本数据
与列表中的第一个对象匹配但标签仍然显示的搜索图像
与列表中的第二个对象匹配但标签仍然显示的搜索图像
只要表中的最后一个对象包含在搜索中,标签的图像就会工作
我的项目指南要求我在搜索与 TableView 中的任何对象都不匹配时创建某种形式的输出。
默认情况下会发生这种情况,当过滤后的表没有任何匹配的过滤器时,该表将显示一个占位符。占位符节点是可配置的,因此您可以将其设置为显示任何您想要的内容。
您不需要额外的标签和逻辑来显示表格中不会显示任何内容,除非您对此有额外的要求。
好的,这是我在表格中看到的占位符文本,上面写着“表格中没有内容”?我应该能够将其设置为提及搜索未返回任何内容的内容。谢谢你。我仍然很好奇我在标签上做错了什么
谓词是一个布尔函数,它应该在没有副作用的情况下执行。您在过滤列表上设置谓词,但您不知道或无法控制过滤列表何时选择执行该代码。谓词可以执行多次以过滤列表中的每个单独项目。如果您将副作用放在谓词中,例如设置标签可见性,那么您真的不知道会发生什么,除非操作是幂等的(它们不是)。
相反,让谓词评估 lambda 输入对象以查看它是否应该被过滤,只返回 true 或 false 并且什么都不做。
将谓词的输入参数命名为 astext表示您并不真正理解它。输入参数是 a ,观察列表的一个元素,它不是文本,因此命名它而不是Part是有意义的。此外(这只是样式,而不是功能),为了帮助使代码更易于阅读,请在侦听器中为新文本使用描述性名称(例如,或而不是)。part``text``filterText``newSearchText``newValue
text
Part
part``text``filterText``newSearchText``newValue
有关使用过滤列表和文本字段搜索表的具体示例,请参阅 Eden 编码教程:
正如 Slaw 在评论中指出的那样:
如果占位符不够,我会尝试使用绑定。 就像是: java label.visibleProperty().bind( Bindings.isEmpty(filteredParts) .and( partFilter.textProperty().isNotEmpty() ) ) );
如果占位符不够,我会尝试使用绑定。
就像是:
java label.visibleProperty().bind( Bindings.isEmpty(filteredParts) .and( partFilter.textProperty().isNotEmpty() ) ) );
或者,您可以将标签通知设置的逻辑移出谓词,但将其保留在搜索文本字段的更改侦听器中(这本质上与绑定的工作类似)。