I am developing a project which has a pane to create an Event(Meeting) in my program.
This pane has a ListView of Rooms which needs to constantly be updated using a list of available filters in the interface (TextView's, CheckBox's, DateTimePicker, Spinner), for example if I write "1" in the name textview and set capacity to 10 it is supposed to apply that 2 filters to the listview and only show the rooms which name contains "1" and capacity=10.
What I have done is adding a listener to each of the control's text or value property, but the problem is when I apply more than 1 filter it doesn't apply the 2 filters together, and I will need to apply multiple.
This is the code I've done for 2 of the filters, but like I said I will need more.
listRooms = new ListView<>();
FilteredList<Room> filteredList= new FilteredList<>(roomsList, data -> true);
txtRoomName.textProperty().addListener(obs->{
String filter = txtRoomName.getText();
if(filter == null || filter.length() == 0) {
filteredList.setPredicate(s -> true);
}
else {
filteredList.setPredicate(s -> s.getName().contains(filter));
}
});
spCapacity.valueProperty().addListener(obs->{
int filter = spCapacity.getValue();
if(filter == 0) {
filteredList.setPredicate(s -> true);
}
else {
filteredList.setPredicate(s -> s.getCapacity() == filter);
}
});
Make a method to generate the predicate. Collect ALL of the filter criteria there, regardless of which one changed:
txtRoomName.textProperty().addListener(obs->{
calculatePredicate();
});
spCapacity.valueProperty().addListener(obs->{
calculatePredicate();
});
private void calculatePredicate() {
String filterTxt = txtRoomName.getText();
int filterCap = spCapacity.getValue();
filteredList.setPredicate(s -> {
boolean txtMatch = filterTxt == null || filterTxt.isEmpty() || s.getName().contains(filterTxt);
boolean capMatch = filterCap == 0 || s.getCapacity() == filterCap;
return txtMatch && capMatch;
});
}