使用TextField的JavaFX TableView过滤器

使用TextField的JavaFX TableView过滤器,javafx,filter,tableview,Javafx,Filter,Tableview,我想编写一个方法,在这个方法中,我传递一个textfield(filterField)、一个tableview(data)和tableview(table)中的数据,以便过滤所有的表数据,每次在textfield中释放一个键时检查输入的字符串是否包含在表的任何单元格中 此方法是通用的,用于具有不同列标题的不同类型的表 为此,我使用以下代码: public void addTextFilter(ObservableList<List<Object>> allData,

我想编写一个方法,在这个方法中,我传递一个textfield(filterField)、一个tableview(data)和tableview(table)中的数据,以便过滤所有的表数据,每次在textfield中释放一个键时检查输入的字符串是否包含在表的任何单元格中

此方法是通用的,用于具有不同列标题的不同类型的表

为此,我使用以下代码:

public void addTextFilter(ObservableList<List<Object>> allData, 
                           JFXTextField filterField, TableView<List<Object>> table) {

    FilteredList<List<Object>> filteredData  = new FilteredList<>(allData, p -> true);
    filterField.setOnKeyReleased(e -> 
    {
         filteredData.setPredicate(p  -> 
         {
             if (filterField.getText() == null || filterField.getText().isEmpty()){
                 return true;
             }else {
                 return p.contains(filterField.getText()); 
             }
         });


    });

    SortedList<List<Object>> sortedData = new SortedList<>(filteredData);
    sortedData.comparatorProperty().bind(table.comparatorProperty());
    table.setItems(sortedData);
}
public void addTextFilter(ObservableList allData,
JFXTextField filterField,TableView表格){
FilteredList filteredData=新的FilteredList(所有数据,p->true);
filterField.setOnKeyReleased(e->
{
filteredData.setPredicate(p->
{
if(filterField.getText()==null | | filterField.getText().isEmpty()){
返回true;
}否则{
返回p.contains(filterField.getText());
}
});
});
SortedList sortedData=新的SortedList(filteredData);
sortedData.comparatorProperty().bind(table.comparatorProperty());
表.设置项目(分类数据);
}
此代码仅在textfield中的字符串与表中任何单元格的值完全匹配时返回值

我需要它返回表中包含键入字符串的任何单元格,即使该单元格包含更多字符。类似于此:


我还需要它返回不依赖于小写或大写值的值。

本教程很好,使用了TextField的可观察值:textProperty,而不是Texfield本身。根据你的情况调整一下

它将减少耦合,并正确使用可观察对象,您将不依赖于图形事件(如果用户从鼠标而不是键盘单击并粘贴会怎么样?->更健壮

public void addTextFilter(ObservableList<List<Object>> allData, 
                       StringProperty textProperty, TableView<List<Object>> table)     {


  FilteredList<List<Object>> filteredData  = new FilteredList<>(allData, p -> true);
  // Use textProperty
  textProperty.addListener((observable, oldValue, newValue) -> {
        filteredData.setPredicate(person -> {
            // If filter text is empty, display all persons.
            if (newValue == null || newValue.isEmpty()) {
                return true;
            }

            // Compare first name and last name of every person with filter text.
            String lowerCaseFilter = newValue.toLowerCase();

            if (person.getFirstName().toLowerCase().contains(lowerCaseFilter)) {
                return true; // Filter matches first name.
            } else if     (person.getLastName().toLowerCase().contains(lowerCaseFilter)) {
                return true; // Filter matches last name.
            }
            return false; // Does not match.
        });
    });

  SortedList<List<Object>> sortedData = new SortedList<>(filteredData);
  sortedData.comparatorProperty().bind(table.comparatorProperty());
  table.setItems(sortedData);
}
public void addTextFilter(ObservableList allData,
StringProperty(文本属性,表格视图表格){
FilteredList filteredData=新的FilteredList(所有数据,p->true);
//使用textProperty
textProperty.addListener((可观察、旧值、新值)->{
filteredData.setPredicate(person->{
//如果筛选文本为空,则显示所有人员。
if(newValue==null | | newValue.isEmpty()){
返回true;
}
//将每个人的名字和姓氏与筛选文本进行比较。
字符串lowerCaseFilter=newValue.toLowerCase();
if(person.getFirstName().toLowerCase().contains(lowerCaseFilter)){
返回true;//筛选器与名字匹配。
}else if(person.getLastName().toLowerCase().contains(lowerCaseFilter)){
返回true;//筛选器与姓氏匹配。
}
返回false;//不匹配。
});
});
SortedList sortedData=新的SortedList(filteredData);
sortedData.comparatorProperty().bind(table.comparatorProperty());
表.设置项目(分类数据);
}

不要使用
键事件
,您应该收听
文本
属性中的更改

TableColumn
s可用于检索谓词中可使用的单元格值

public static <T> void addTextFilter(ObservableList<T> allData,
        JFXTextField filterField, TableView<T> table) {

    final List<TableColumn<T, ?>> columns = table.getColumns();

    FilteredList<T> filteredData = new FilteredList<>(allData);
    filteredData.predicateProperty().bind(Bindings.createObjectBinding(() -> {
        String text = filterField.getText();

        if (text == null || text.isEmpty()) {
            return null;
        }
        final String filterText = text.toLowerCase();

        return o -> {
            for (TableColumn<T, ?> col : columns) {
                ObservableValue<?> observable = col.getCellObservableValue(o);
                if (observable != null) {
                    Object value = observable.getValue();
                    if (value != null && value.toString().toLowerCase().equals(filterText)) {
                        return true;
                    }
                }
            }
            return false;
        };
    }, filterField.textProperty()));

    SortedList<T> sortedData = new SortedList<>(filteredData);
    sortedData.comparatorProperty().bind(table.comparatorProperty());
    table.setItems(sortedData);
}
publicstaticvoidaddtextfilter(可观察列表allData,
JFXTextField filterField,TableView表格){
最终列表列=table.getColumns();
FilteredList filteredData=新的FilteredList(所有数据);
filteredData.predicateProperty().bind(Bindings.createObjectBinding(()->{
String text=filterField.getText();
if(text==null | | text.isEmpty()){
返回null;
}
最后一个字符串filterText=text.toLowerCase();
返回o->{
for(表格列:列){
ObservableValue observable=列getCellObservableValue(o);
如果(可观察!=null){
对象值=可观察的。getValue();
if(value!=null&&value.toString().toLowerCase().equals(filterText)){
返回true;
}
}
}
返回false;
};
},filterField.textProperty());
SortedList sortedData=新的SortedList(filteredData);
sortedData.comparatorProperty().bind(table.comparatorProperty());
表.设置项目(分类数据);
}
如果列包含列表的值,则可以稍微简化代码:

public static void addTextFilter(ObservableList<List<Object>> allData,
        JFXTextField filterField, TableView<List<Object>> table) {

    final List<TableColumn<List<Object>, ?>> columns = table.getColumns();

    FilteredList<List<Object>> filteredData = new FilteredList<>(allData);
    filteredData.predicateProperty().bind(Bindings.createObjectBinding(() -> {
        String text = filterField.getText();

        if (text == null || text.isEmpty()) {
            return null;
        }
        final String filterText = text.toLowerCase();

        return o -> {
            for (Object value : columns) {
                if (value != null && value.toString().toLowerCase().equals(filterText)) {
                    return true;
                }
            }
            return false;
        };
    }, filterField.textProperty()));

    SortedList<List<Object>> sortedData = new SortedList<>(filteredData);
    sortedData.comparatorProperty().bind(table.comparatorProperty());
    table.setItems(sortedData);
}
publicstaticvoidaddtextfilter(可观察列表allData,
JFXTextField filterField,TableView表格){
最终列表列=table.getColumns();
FilteredList filteredData=新的FilteredList(所有数据);
filteredData.predicateProperty().bind(Bindings.createObjectBinding(()->{
String text=filterField.getText();
if(text==null | | text.isEmpty()){
返回null;
}
最后一个字符串filterText=text.toLowerCase();
返回o->{
用于(对象值:列){
if(value!=null&&value.toString().toLowerCase().equals(filterText)){
返回true;
}
}
返回false;
};
},filterField.textProperty());
SortedList sortedData=新的SortedList(filteredData);
sortedData.comparatorProperty().bind(table.comparatorProperty());
表.设置项目(分类数据);
}

请注意,上面的代码片段都没有被通知对项目所做的更改。

我对此感到非常自豪,我认为这是我第一次回答有关StackOverflow的问题

此代码将允许您搜索部分匹配。因此,如果您键入字母
d
,它将删除任何没有字母d的行

此代码还允许您在表的每一行中搜索多个单词(用空格分隔)。所以如果这个词
public static void addTextFilterB(ObservableList<List<Object>> allData,
                                  TextField filterField, TableView<List<Object>> table) {

    FilteredList<List<Object>> filteredData  = new FilteredList<>(allData, p -> true);
    filterField.setOnKeyReleased(e ->
    {
        filteredData.setPredicate(p  ->
        {
            if (filterField.getText() == null || filterField.getText().isEmpty()){
                return true;
            }else {
                String pToString = p.toString().toLowerCase().replace(", "," ");
                String textIwantB = filterField.getText();
                String[] parts = textIwantB.toLowerCase().split(" ");

                if(p.contains(textIwantB)){
                    System.out.println("p.: " + p);

                }

                int counter = 0;
                for (int i = 0; i < parts.length; i ++) {
                    if (parts[i] != null)
                        if(!(pToString.contains(parts[i]))){
                            System.out.println("this one is eliminated: " + pToString);
                            return false;
                        }
                        counter++;
                }

                System.out.println("counter: " + counter);




                return pToString.contains(parts[0]);
            }
        });


    });

    SortedList<List<Object>> sortedData = new SortedList<>(filteredData);
    sortedData.comparatorProperty().bind(table.comparatorProperty());
    table.setItems(sortedData);
}