Ko Ga
Ko Ga

Reputation: 906

Filtering ObservableList with CheckBox in JavaFX

I'm building a log reader with JavaFX as a side project and have gotten to a dead end when trying to implement filtering on the TableView.

What I have is a few CheckBoxes (LHS of the picture) that will basically act as the filters for what the TableView will display:

Window

Once the Submit button is clicked, a background thread is opened to read the and parse the files. Once the operation terminates, the result of each log read is inserted into the global ObservableList<Log>:

 public class Test_Filters extends Application {...

 private ObservableList<LogTest> logs = FXCollections.observableArrayList();

...}

What I'm having trouble with is how to deal with:

  1. A situation where more than one filter CheckBox is checked.
  2. A situation where the CheckBox is unchecked.

For 1., I was wondering what's the best way to deal with this. Let's say I have x filters selected. This would mean that I have to basically filter out x values from the ObservaleList:

logTable.setItems(logTable.getItems().filtered(log -> !log.getSource().equals(checkBox.getText())));

Upvotes: 4

Views: 4791

Answers (1)

M. le Rutte
M. le Rutte

Reputation: 3563

You can use JavaFX's FilteredList, which accepts a Predicate. You can update the predicate on each filter, combining them as you want.

 FilteredList<LogTest> items = new FilteredList<>(originalItems);
 tableView.setItems(items);

 ... on update of filter UI items
 Predicate<LogTest> containsFoo = i -> i.getName().contains("foo");
 Predicate<LogTest> isSevere = i -> i.getLevel() == Level.SEVERE;
 Predicate<LogTest> filter = containsFoo.or(isSevere);

 items.setPredicate(filter);

If you want to show all records again simply set the predicate to null:

 items.setPredicate(null);

Using the FilteredList you don't need to re-read the log records, as the filter is applied immediately on the existing items.

Upvotes: 10

Related Questions