Kyle
Kyle

Reputation: 99

JTable Row Filter based on list of table model row integers

I'm building a query screen for my data table. I've done the work and consolidated the rows I want to show on the table based on user criteria.

How can I apply a row filter to a table based on the rows of the model? For instance: I want to show rows 3,6,7,8,9 which are stored in an ArrayList<Integer> list.

I am currently not grasping the RowFilter class. I'm not sure what to do or how to use it here:

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

Upvotes: 0

Views: 825

Answers (2)

Kyle
Kyle

Reputation: 99

After studying and trying to grasp how the RowFilter Class works, i got my table to sort the way i want it to, it seems. I still need to do more testing but it looks like it is working. I still do not fully grasp the RowFilter Class so i would love some feedback.

Here is my code: where ArrayList<Integer> filteredRows = new ArrayList<>(); contains the row numbers i want to show. To my understanding, the filter automatically iterates over my table model and the identifier is the row number the filter is currently processing. So at first glance if the identifier equals any of the row numbers i have stored, then show it.

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

Upvotes: 0

DevilsHnd - 退した
DevilsHnd - 退した

Reputation: 9192

Perhaps you will find the provided method below somewhat useful. I use it to filter JTables. What you need to do is make use of the 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();
    }
}

Upvotes: 1

Related Questions