基于 table 模型行整数列表的 JTable 行过滤器

JTable Row Filter based on list of table model row integers

我正在为我的数据构建一个查询屏幕 table。我已经完成工作并根据用户标准合并了我想在 table 上显示的行。

如何根据模型的行将行过滤器应用于 table?例如:我想显示存储在 ArrayList<Integer> list.

中的第 3、6、7、8、9 行

我目前没有掌握 RowFilter class。我不确定在这里做什么或如何使用它:

RowFilter<DefaultTableModel,Integer> rf = new RowFilter<>() {
    @Override
    public boolean include(Entry entry) {
        // TODO Auto-generated method stub
        return false;
    }
};

也许您会发现下面提供的方法有些用处。我用它来过滤 JTables。您需要做的是使用 TableRowSorter class:

/**
 * Make sure the supplied JTable's DefaultTableModel already contains data
 * before calling this method.
 * <p>
 * The JTable always retains the data it is currently filled with within its
 * Table Model. <b>Knowing this we can theoretically fill the Table with all
 * database table records then use the Filter to display only the specific
 * table records we want.</b> This way we don't have to pole the database
 * for different records all the time and records acquisition is greatly
 * increased.
 * <p>
 * This method will pass the supplied Filter text across the supplied JTable
 * and will force that JTable to only display records (contained within that
 * JTable at the time) which contains that specific text. It reacts very
 * much like a search engine for the JTable.
 * <p>
 * If you want to display all records again which were originally contained
 * within the supplied JTable then just pass a Null String ("") within the
 * searchCriteria parameter of this method.
 *
 * @param table          (JTable) The JTable to run filter on.<br>
 *
 * @param searchCriteria (String) The text to filter JTable with. Passing a
 *                       Null String ("") will force the table to display
 *                       all records. Regular Expressions (RegEx) can also
 *                       be supplied within the criteria string. If the
 *                       wildcard characters <b>?</b> or <b>*</b> are
 *                       supplied within the filter criteria String without
 *                       any RegEx meta characters then the functional
 *                       purpose of these two wildcard characters are
 *                       converted to RegEx when encountered. If actual
 *                       Regular Expressions are going to be used to make up
 *                       the search criteria string then be sure to set the
 *                       <b>endorseWildcards</b> optional parameter to
 *                       boolean false since the <b>?</b> and <b>*</b>
 *                       wildcard characters have different meaning within a
 *                       Regular Expression and must be handled
 *                       differently.<br>
 *
 * @param options        (optional - Integer/Boolean):<pre>
 *
 *     byColumnNumber - (Optional - Integer - Default is -1) By default
 *                       this method filters across all table columns but
 *                       you can be column specific if you pass a column
 *                       number to this optional parameter. This parameter
 *                       accepts only a <b>Literal Column Number</b> which
 *                       means that although the first column within a
 *                       JTable is considered column 0, to this method it is
 *                       considered as column 1.
 *
 *    endorseWildcards - (boolean) Default is true (allow wildcards). If true
 *                       then when a wildcard character is encountered within
 *                       a search criteria string it is automatically converted
 *                       to its RegEx equivalent. The two wildcard characters
 *                       are almost always more than enough to carry out any
 *                       search required and is usually much easier to use than
 *                       some complex regular expressions. If endorseWildcards
 *                       is true then upper or lower letter case is ignored as
 *                       well.
 *
 *                       If you provide a true of false to this parameter then
 *                       you must provide a value (or null) to the option
 *                       <b>byColumnNumber</b> parameter.</pre>
 */
public static void filterTable(JTable table, String searchCriteria, Object... options) {
    int column = -1;
    boolean endorseWildcards = true;
    if (options.length > 0) {
        if (options[0] != null) {
            column = (int) options[0] - 1;
        }
        if (options.length >= 2) {
            if (options[1] != null) {
                endorseWildcards = (boolean) options[1];
            }
        }
    }

    String criteria = searchCriteria;
    if (endorseWildcards) {
        criteria = "(?i)" + searchCriteria.replace("?", ".?").replace("*", ".*?");
    }

    try {
        TableRowSorter<TableModel> sorter = new TableRowSorter<>(((DefaultTableModel) table.getModel()));
        sorter.setRowFilter(column < 0 ? RowFilter.regexFilter(criteria)
                : RowFilter.regexFilter(criteria, column));
        table.setRowSorter(sorter);
    }
    catch (Exception ex) {
        ex.printStackTrace();
    }
}

在研究并试图掌握 RowFilter Class 的工作原理之后,我 table 似乎按照我想要的方式进行排序。我仍然需要做更多的测试,但看起来它正在工作。我仍然没有完全掌握 RowFilter Class 所以我希望得到一些反馈。

这是我的代码:其中 ArrayList<Integer> filteredRows = new ArrayList<>(); 包含我要显示的行号。据我了解,过滤器会自动迭代我的 table 模型,标识符是过滤器当前正在处理的行号。所以乍一看,如果标识符等于我存储的任何行号,则显示它。

RowFilter<DefaultTableModel,Integer> rf = new RowFilter<>() {

    @Override
    public boolean include(Entry<? extends DefaultTableModel, ? extends Integer> entry) {
        int entryRow = entry.getIdentifier();
        for (Integer i : filteredRows) {
            if (entryRow == i) return true;
        }
        return false;
    }

};
TableRowSorter<DefaultTableModel> sorter =  new TableRowSorter<DefaultTableModel>(myTableModel);
sorter.setRowFilter(null);
sorter.setRowFilter(rf);
table.setRowSorter(sorter);