使用TextField的JavaFX TableView过滤器 [英] JavaFX TableView filter using TextField

查看:167
本文介绍了使用TextField的JavaFX TableView过滤器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想编写一个方法,我传递一个文本字段(filterField),一个来自tableview(数据)和tableview(table)的数据,以便过滤所有表数据,检查每次在文本字段中释放键时,如果键入的字符串包含在表的任何单元格中.

I want to code a method where I pass a textfield (filterField), data from a tableview (data) and tableview (table) in order to filter all the table data, checking each time a key is released in the textfield, if the string typed is contained in any cell of the table.

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

This method is to be generic and used for different type of tables with different column headers.

为此,我正在使用以下代码:

To do so I´m using the following code:

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);
}

仅当文本字段中的字符串与表中任何单元格的值完全匹配时,此代码才返回值.

This code only returns the values when the string in the textfield matches exactly the value of any cell in the table.

即使在单元格包含更多字符的情况下,我仍需要它返回包含键入时在其中键入的字符串的表的任何单元格.类似于以下内容: JavaFX 8 TableView排序和过滤

I would need it to return any cell of the table that contains the string typed in it while typing, even if the cell contains more characters. Something similar to this: JavaFX 8 TableView Sorting and Filtering

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

I would also need it to return values not depending on lowercase or uppercase values.

推荐答案

应该使用text属性中的更改,而不是使用KeyEvent.

Rather than using a KeyEvent, you should listen to changes in the text property.

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

TableColumns can be used to retrieve the values for the cells which can be used in the predicate.

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);
}

如果您的列包含列表的值,则可以通过以下方式简化代码:

If your columns contain the values of the list, you could simplify the code a bit though:

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);
}

请注意,以上所有代码段均未收到对项目所做的更改的通知.

Note that none of the above code snippets are notified of changes done to items.

这篇关于使用TextField的JavaFX TableView过滤器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆