Javafx中过滤的列表搜索上的可见性

发布于 2025-02-11 21:49:25 字数 2218 浏览 1 评论 0原文

我正在使用带有侦听器的Textfield来过滤tableview。如果newText匹配ID或名称的一部分,则我有IF设置谓词的语句。

搜索功能就像我想要的一样。

但是,我的项目指南要求我在搜索不匹配表格中的任何对象时也创建某种形式的输出。

我创建了一个标签,并将可见性设置为false开始。我将代码设置为在谓词逻辑中的每个if语句之后将标签设置为可见,以便它仅显示何时何时有效。然后,我在谓词逻辑的开头放置了一条线将其设置回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);

以下是表

与列表中的第一个对象相匹配但标签显示

“

与列表中的第二个对象相匹配但标签显示

https://i.sstatic.net/thn5h.png“ rel =” nofollow noreferrer“>

标签的图像工作时间很长,只要表中的最后一个对象都包含在搜索

I'm using a TextField with a listener to filter a TableView. I've got if statements that set the predicate if newText matches part of the ID or Name.

The search functionality works like I want.

However, my project guidelines require me to also create some form of output upon a search not matching any objects in the TableView.

I created a Label and set the visibility to false to start. I placed the code to set the Label to visible after each of the if statements in the predicate logic so that it only shows if none of the statements are valid. I then placed a line setting it back to false at the beginning of the predicate logic so on each listener change it gets reset.

I am having an issue where if my search returns the last item in the list it is fine and the label doesn't appear, but if the search doesn't return the last item in the list then the label becomes visible even though the search displays items from the sorted list.

The following is my code and I've attached screenshots of the "bug".

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);

The following is the base sample data in table

image1

Image of search that matches first object in list but label showing anyways

image2

Image of search that matches second object in list but label showing anyways

image3

Image of label working as long as last object in table is included in search

image4

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

负佳期 2025-02-18 21:49:25

我的项目指南要求我在搜索时也创建某种形式的输出形式,与表观视图中的任何对象匹配。

默认情况下,当过滤的表没有任何匹配过滤器时,该表将显示占位符。占位符节点是可配置的,因此您可以将其设置为显示所需的任何内容。

您不需要额外的标签和逻辑就可以证明表中没有显示任何内容,除非您对此有其他要求。

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

谓词是布尔功能,但应执行无副作用。您在过滤后的列表上设置了谓词,但是您不知道或没有控制过滤列表何时选择执行该代码。谓词可以执行多次以过滤列表中的每个单独项目。如果您将副作用在谓词中添加如设置标签可见性,则除非操作为 didempotent (不是)。

取而代之的是,让谓词评估lambda输入对象,以查看是否应该过滤,只是返回true或false,什么也不做。

您将输入参数命名为谓词为文本表示您并不真正了解它。输入参数是part,是观察到的列表的元素,不是文本,因此将其命名part而不是文本>文本。此外(这只是样式,而不是功能性的),以帮助使代码易于阅读,使用侦听器中新文本的描述性名称(例如filterTextnewsearchtextext而不是newValue)。

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

如图所指出的那样:

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

类似:

  label.visible property()。绑定(
    bindings.isempty(滤波器)
        。和(
             partfilter.textproperty()。isonotempty()
        )
    )
);
 

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

my project guidelines require me to also create some form of output upon a search not matching any objects in the TableView.

That will happen by default, when the filtered table does not have any matches for the filter, the table will display a placeholder. The placeholder node is configurable, so you can set it display anything you want.

You don't need an additional label and logic to show that nothing would be displayed in the table unless you have an additional requirement for that.

Okay, so it's the placeholder text that I see in the table that says "no content in table"? I should just be able to set that to something that mentions the search didn't return anything. Thank you. I am still curious what I am doing wrong with the label though

The predicate is a boolean function, it should be executed without side effects. You set the predicate on the filtered list, but you don't know or have any control over when the filtered list will choose to execute that code. The predicate may be executed many times to filter each individual item in the list. If you put side effects in the predicate like setting label visibility, you don't really know what will happen unless the operations are idempotent (they aren't).

Instead, have the predicate evaluate the lambda input object to see if it should be filtered or not, only returning true or false and doing nothing else.

That you name the input parameter to the predicate as text indicates that you don't really understand it. The input parameter is a Part, an element of the observed list, it is not text, so it would make sense to name it part and not text. Also (and this is just style, not functional), to help make the code easier to read, use a descriptive name for the new text in the listener (e.g. filterText or newSearchText rather than newValue).

For a concrete example of searching a table using a filtered list and a text field, see, the Eden Coding tutorial:

As noted by Slaw in comments:

If the placeholder is not enough, I would try to use bindings.

Something like:

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

Or you can move the logic for the label notification setting out of the predicate but keep it in the change listener for the search text field (this essentially does a similar job to the binding).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文