JavaFX FilteredList, filtering based on property of items in the list

前端 未结 2 491
佛祖请我去吃肉
佛祖请我去吃肉 2020-12-21 07:45

I have a case where I need to filter a ObservableList based on some properties of the items (i.e. the condition is internal and not external). I fou

相关标签:
2条回答
  • 2020-12-21 08:20

    If you are using database loading function plus need to filter multiple fields, this solution will help.

     ObservableList<PurchaseOrder> poData = FXCollections.observableArrayList();
     FilteredList<PurchaseOrder> filteredData;
      private void load()  {
            PurchaseOrder po = new PurchaseOrder();
            try {
                poData = po.loadTable("purchase_orders", beanFields); // Database loading data
            } catch (SQLException ex) {
                Logger.getLogger(PurchaseOrdersController.class.getName()).log(Level.SEVERE, null, ex);
            }
    
            filteredData = new FilteredList<>(poData, t -> true); //Encapsulate data with filter
    
            poTable.setItems(filteredData); //Load filtered data into table
    
            //Set event trigger for all filter textboxes
            txtFilter.textProperty().addListener(obs->{
                filter(filteredData);
            });
            txtFilter2.textProperty().addListener(obs->{
                filter(filteredData);
            });
      }
    
       private void filter(FilteredList<PurchaseOrder> filteredData)
        {
                filteredData.setPredicate(PurchaseOrder -> {
                    // If all filters are empty then display all Purchase Orders
                    if ((txtFilter.getText() == null || txtFilter.getText().isEmpty()) 
                            && (txtFilter2.getText() == null || txtFilter2.getText().isEmpty())) {
                        return true;
                    }
    
                    // Convert filters to lower case
                    String lowerCaseFilter = txtFilter.getText().toLowerCase();
                    String lowerCaseFilter2 = txtFilter2.getText().toLowerCase();
    
                    //If fails any given criteria, fail completely
                    if(txtFilter.getText().length()>0)
                        if (PurchaseOrder.get("vendor_name").toLowerCase().contains(lowerCaseFilter) == false)
                            return false;
                    if(txtFilter2.getText().length()>0)
                        if (PurchaseOrder.get("PONumber").toLowerCase().contains(lowerCaseFilter2) == false)
                            return false;
    
                    return true; // Matches given criteria
                });
        }
    
    0 讨论(0)
  • 2020-12-21 08:28

    Create the underlying list with an extractor. This will enable the underlying list to fire update events when the filteredProperty() of any elements change. The FilteredList will observe these events and so will update accordingly:

    ObservableList<Item> baseList = FXCollections.observableArrayList(item -> 
        new Observable[] {item.filteredProperty()});
    FilteredList<Item> list = new FilteredList<>(baseList, t -> ! t.filteredProperty().get());
    

    Quick demo:

    import java.util.stream.IntStream;
    
    import javafx.beans.Observable;
    import javafx.beans.property.BooleanProperty;
    import javafx.beans.property.SimpleBooleanProperty;
    import javafx.beans.property.SimpleStringProperty;
    import javafx.beans.property.StringProperty;
    import javafx.collections.FXCollections;
    import javafx.collections.ListChangeListener.Change;
    import javafx.collections.ObservableList;
    import javafx.collections.transformation.FilteredList;
    
    
    public class DynamicFilteredListTest {
    
        public static void main(String[] args) {
    
            ObservableList<Item> baseList = FXCollections.observableArrayList(item -> 
                    new Observable[] {item.filteredProperty()});
    
            FilteredList<Item> list = new FilteredList<>(baseList, t -> ! t.isFiltered());
    
            list.addListener((Change<? extends Item> c) -> {
                while (c.next()) {
                    if (c.wasAdded()) {
                        System.out.println(c.getAddedSubList()+ " added to filtered list");
                    }
                    if (c.wasRemoved()) {
                        System.out.println(c.getRemoved()+ " removed from filtered list");
                    }
                }
            });
    
            System.out.println("Adding ten items to base list:\n");
    
            IntStream.rangeClosed(1, 10).mapToObj(i -> new Item("Item "+i)).forEach(baseList::add);
    
            System.out.println("\nFiltered list now:\n"+list);
    
            System.out.println("\nSetting filtered flag for alternate items in base list:\n");
    
            IntStream.range(0, 5).map(i -> 2*i).mapToObj(baseList::get).forEach(i -> i.setFiltered(true));
    
            System.out.println("\nFiltered list now:\n"+list);
        }
    
    
        public static class Item {
            private final StringProperty name = new SimpleStringProperty() ;
            private final BooleanProperty filtered = new SimpleBooleanProperty() ;
    
            public Item(String name) {
                setName(name);
            }
    
            public final StringProperty nameProperty() {
                return this.name;
            }
    
            public final String getName() {
                return this.nameProperty().get();
            }
    
            public final void setName(final String name) {
                this.nameProperty().set(name);
            }
    
            public final BooleanProperty filteredProperty() {
                return this.filtered;
            }
    
            public final boolean isFiltered() {
                return this.filteredProperty().get();
            }
    
            public final void setFiltered(final boolean filtered) {
                this.filteredProperty().set(filtered);
            }
    
            @Override
            public String toString() {
                return getName();
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题