Javafx中过滤的列表搜索上的可见性
我正在使用带有侦听器的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
Image of search that matches first object in list but label showing anyways
Image of search that matches second object in list but label showing anyways
Image of label working as long as last object in table is included in search
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
默认情况下,当过滤的表没有任何匹配过滤器时,该表将显示占位符。占位符节点是可配置的,因此您可以将其设置为显示所需的任何内容。
您不需要额外的标签和逻辑就可以证明表中没有显示任何内容,除非您对此有其他要求。
谓词是布尔功能,但应执行无副作用。您在过滤后的列表上设置了谓词,但是您不知道或没有控制过滤列表何时选择执行该代码。谓词可以执行多次以过滤列表中的每个单独项目。如果您将副作用在谓词中添加如设置标签可见性,则除非操作为 didempotent (不是)。
取而代之的是,让谓词评估lambda输入对象,以查看是否应该过滤,只是返回true或false,什么也不做。
您将输入参数命名为谓词为
文本
表示您并不真正了解它。输入参数是part
,是观察到的列表的元素,不是文本,因此将其命名part
而不是文本>文本。此外(这只是样式,而不是功能性的),以帮助使代码易于阅读,使用侦听器中新文本的描述性名称(例如
filterText
或newsearchtextext
而不是newValue
)。有关使用过滤列表和文本字段搜索表的具体示例,请参见Eden编码教程:
如图所指出的那样:
或者您可以将标签通知设置的逻辑移出谓词,但将其保留在搜索文本字段的更改侦听器中(这实际上与绑定相似)。
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.
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 aPart
, an element of the observed list, it is not text, so it would make sense to name itpart
and nottext
. 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
ornewSearchText
rather thannewValue
).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:
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).