/*
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
package javax.swing;
import java.util.ArrayList;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
/**
* RowFilter
is used to filter out entries from the
* model so that they are not shown in the view. For example, a
* RowFilter
associated with a JTable
might
* only allow rows that contain a column with a specific string. The
* meaning of entry depends on the component type.
* For example, when a filter is
* associated with a JTable
, an entry corresponds to a
* row; when associated with a JTree
, an entry corresponds
* to a node.
*
* Subclasses must override the include
method to
* indicate whether the entry should be shown in the
* view. The Entry
argument can be used to obtain the values in
* each of the columns in that entry. The following example shows an
* include
method that allows only entries containing one or
* more values starting with the string "a":
*
* RowFilter<Object,Object> startsWithAFilter = new RowFilter<Object,Object>() { * public boolean include(Entry<? extends Object, ? extends Object> entry) { * for (int i = entry.getValueCount() - 1; i >= 0; i--) { * if (entry.getStringValue(i).startsWith("a")) { * // The value starts with "a", include it * return true; * } * } * // None of the columns start with "a"; return false so that this * // entry is not shown * return false; * } * }; **
RowFilter
has two formal type parameters that allow
* you to create a RowFilter
for a specific model. For
* example, the following assumes a specific model that is wrapping
* objects of type Person
. Only Person
s
* with an age over 20 will be shown:
* * RowFilter<PersonModel,Integer> ageFilter = new RowFilter<PersonModel,Integer>() { * public boolean include(Entry<? extends PersonModel, ? extends Integer> entry) { * PersonModel personModel = entry.getModel(); * Person person = personModel.getPerson(entry.getIdentifier()); * if (person.getAge() > 20) { * // Returning true indicates this row should be shown. * return true; * } * // Age is <= 20, don't show it. * return false; * } * }; * PersonModel model = createPersonModel(); * TableRowSorter<PersonModel> sorter = new TableRowSorter<PersonModel>(model); * sorter.setRowFilter(ageFilter); ** * @param
PersonModel
* @param the type of the identifier; when using
* TableRowSorter
this will be Integer
* @see javax.swing.table.TableRowSorter
* @since 1.6
*/
public abstract class RowFilterRowFilter
s.
*
* @see RowFilter
* @since 1.6
*/
public enum ComparisonType {
/**
* Indicates that entries with a value before the supplied
* value should be included.
*/
BEFORE,
/**
* Indicates that entries with a value after the supplied
* value should be included.
*/
AFTER,
/**
* Indicates that entries with a value equal to the supplied
* value should be included.
*/
EQUAL,
/**
* Indicates that entries with a value not equal to the supplied
* value should be included.
*/
NOT_EQUAL
}
/**
* Throws an IllegalArgumentException if any of the values in
* columns are {@literal <} 0.
*/
private static void checkIndices(int[] columns) {
for (int i = columns.length - 1; i >= 0; i--) {
if (columns[i] < 0) {
throw new IllegalArgumentException("Index must be >= 0");
}
}
}
/**
* Returns a RowFilter
that uses a regular
* expression to determine which entries to include. Only entries
* with at least one matching value are included. For
* example, the following creates a RowFilter
that
* includes entries with at least one value starting with
* "a":
* * RowFilter.regexFilter("^a"); **
* The returned filter uses {@link java.util.regex.Matcher#find}
* to test for inclusion. To test for exact matches use the
* characters '^' and '$' to match the beginning and end of the
* string respectively. For example, "^foo$" includes only rows whose
* string is exactly "foo" and not, for example, "food". See
* {@link java.util.regex.Pattern} for a complete description of
* the supported regular-expression constructs.
*
* @param regex the regular expression to filter on
* @param indices the indices of the values to check. If not supplied all
* values are evaluated
* @return a
* The following example creates a
* The following example creates a
* The
* This implementation calls RowFilter
implementing the specified criteria
* @throws NullPointerException if regex
is
* null
* @throws IllegalArgumentException if any of the indices
* are < 0
* @throws PatternSyntaxException if regex
is
* not a valid regular expression.
* @see java.util.regex.Pattern
*/
public static RowFilter
that includes entries that
* have at least one Date
value meeting the specified
* criteria. For example, the following RowFilter
includes
* only entries with at least one date value after the current date:
*
* RowFilter.dateFilter(ComparisonType.AFTER, new Date());
*
*
* @param type the type of comparison to perform
* @param date the date to compare against
* @param indices the indices of the values to check. If not supplied all
* values are evaluated
* @return a RowFilter
implementing the specified criteria
* @throws NullPointerException if date
is
* null
* @throws IllegalArgumentException if any of the indices
* are < 0 or type
is
* null
* @see java.util.Calendar
* @see java.util.Date
*/
public static RowFilter
that includes entries that
* have at least one Number
value meeting the
* specified criteria. For example, the following
* filter will only include entries with at
* least one number value equal to 10:
*
* RowFilter.numberFilter(ComparisonType.EQUAL, 10);
*
*
* @param type the type of comparison to perform
* @param indices the indices of the values to check. If not supplied all
* values are evaluated
* @return a RowFilter
implementing the specified criteria
* @throws IllegalArgumentException if any of the indices
* are < 0, type
is null
* or number
is null
*/
public static RowFilter
that includes entries if any
* of the supplied filters includes the entry.
* RowFilter
that will
* include any entries containing the string "foo" or the string
* "bar":
*
* List<RowFilter<Object,Object>> filters = new ArrayList<RowFilter<Object,Object>>(2);
* filters.add(RowFilter.regexFilter("foo"));
* filters.add(RowFilter.regexFilter("bar"));
* RowFilter<Object,Object> fooBarFilter = RowFilter.orFilter(filters);
*
*
* @param filters the RowFilter
s to test
* @throws IllegalArgumentException if any of the filters
* are null
* @throws NullPointerException if filters
is null
* @return a RowFilter
implementing the specified criteria
* @see java.util.Arrays#asList
*/
public static RowFilter
that includes entries if all
* of the supplied filters include the entry.
* RowFilter
that will
* include any entries containing the string "foo" and the string
* "bar":
*
* List<RowFilter<Object,Object>> filters = new ArrayList<RowFilter<Object,Object>>(2);
* filters.add(RowFilter.regexFilter("foo"));
* filters.add(RowFilter.regexFilter("bar"));
* RowFilter<Object,Object> fooBarFilter = RowFilter.andFilter(filters);
*
*
* @param filters the RowFilter
s to test
* @return a RowFilter
implementing the specified criteria
* @throws IllegalArgumentException if any of the filters
* are null
* @throws NullPointerException if filters
is null
* @see java.util.Arrays#asList
*/
public static RowFilter
that includes entries if the
* supplied filter does not include the entry.
*
* @param filter the RowFilter
to negate
* @return a RowFilter
implementing the specified criteria
* @throws IllegalArgumentException if filter
is
* null
*/
public static entry
argument is valid only for the duration of
* the invocation. Using entry
after the call returns
* results in undefined behavior.
*
* @param entry a non-null
object that wraps the underlying
* object from the model
* @return true if the entry should be shown
*/
public abstract boolean include(Entry extends M, ? extends I> entry);
//
// WARNING:
// Because of the method signature of dateFilter/numberFilter/regexFilter
// we can NEVER add a method to RowFilter that returns M,I. If we were
// to do so it would be possible to get a ClassCastException during normal
// usage.
//
/**
* An Entry
object is passed to instances of
* RowFilter
, allowing the filter to get the value of the
* entry's data, and thus to determine whether the entry should be shown.
* An Entry
object contains information about the model
* as well as methods for getting the underlying values from the model.
*
* @param PersonModel
* @param the type of the identifier; when using
* TableRowSorter
this will be Integer
* @see javax.swing.RowFilter
* @see javax.swing.DefaultRowSorter#setRowFilter(javax.swing.RowFilter)
* @since 1.6
*/
public static abstract class EntryEntry
.
*/
public Entry() {
}
/**
* Returns the underlying model.
*
* @return the model containing the data that this entry represents
*/
public abstract M getModel();
/**
* Returns the number of values in the entry. For
* example, when used with a table this corresponds to the
* number of columns.
*
* @return number of values in the object being filtered
*/
public abstract int getValueCount();
/**
* Returns the value at the specified index. This may return
* null
. When used with a table, index
* corresponds to the column number in the model.
*
* @param index the index of the value to get
* @return value at the specified index
* @throws IndexOutOfBoundsException if index < 0 or
* >= getValueCount
*/
public abstract Object getValue(int index);
/**
* Returns the string value at the specified index. If
* filtering is being done based on String
values
* this method is preferred to that of getValue
* as getValue(index).toString()
may return a
* different result than getStringValue(index)
.
* getValue(index).toString()
* after checking for null
. Subclasses that provide
* different string conversion should override this method if
* necessary.
*
* @param index the index of the value to get
* @return {@code non-null} string at the specified index
* @throws IndexOutOfBoundsException if index < 0 ||
* >= getValueCount
*/
public String getStringValue(int index) {
Object value = getValue(index);
return (value == null) ? "" : value.toString();
}
/**
* Returns the identifer (in the model) of the entry.
* For a table this corresponds to the index of the row in the model,
* expressed as an Integer
.
*
* @return a model-based (not view-based) identifier for
* this entry
*/
public abstract I getIdentifier();
}
private static abstract class GeneralFilter extends RowFilter