小编典典

JavaFX 中过滤列表搜索的标签可见性

all

我正在使用带有侦听器的 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);

以下是表中的基础样本数据

图像1

与列表中的第一个对象匹配但标签仍然显示的搜索图像

图2

与列表中的第二个对象匹配但标签仍然显示的搜索图像

图3

只要表中的最后一个对象包含在搜索中,标签的图像就会工作

图4


阅读 76

收藏
2022-06-29

共1个答案

小编典典

我的项目指南要求我在搜索与 TableView 中的任何对象都不匹配时创建某种形式的输出。

默认情况下会发生这种情况,当过滤后的表没有任何匹配的过滤器时,该表将显示一个占位符。占位符节点是可配置的,因此您可以将其设置为显示任何您想要的内容。

您不需要额外的标签和逻辑来显示表格中不会显示任何内容,除非您对此有额外的要求。

好的,这是我在表格中看到的占位符文本,上面写着“表格中没有内容”?我应该能够将其设置为提及搜索未返回任何内容的内容。谢谢你。我仍然很好奇我在标签上做错了什么

谓词是一个布尔函数,它应该在没有副作用的情况下执行。您在过滤列表上设置谓词,但您不知道或无法控制过滤列表何时选择执行该代码。谓词可以执行多次以过滤列表中的每个单独项目。如果您将副作用放在谓词中,例如设置标签可见性,那么您真的不知道会发生什么,除非操作是幂等的(它们不是)。

相反,让谓词评估 lambda 输入对象以查看它是否应该被过滤,只返回 true 或 false 并且什么都不做。

将谓词的输入参数命名为 astext表示您并不真正理解它。输入参数是 a ,观察列表的一个元素,它不是文本,因此命名它而不是Part是有意义的。此外(这只是样式,而不是功能),为了帮助使代码更易于阅读,请在侦听器中为新文本使用描述性名称(例如,或而不是)。part``text``filterText``newSearchText``newValue

有关使用过滤列表和文本字段搜索表的具体示例,请参阅 Eden 编码教程:

正如 Slaw 在评论中指出的那样:

如果占位符不够,我会尝试使用绑定。

就像是:

java label.visibleProperty().bind( Bindings.isEmpty(filteredParts) .and( partFilter.textProperty().isNotEmpty() ) ) );

或者,您可以将标签通知设置的逻辑移出谓词,但将其保留在搜索文本字段的更改侦听器中(这本质上与绑定的工作类似)。

2022-06-29