/*
* Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.swing.table;
import java.text.Collator;
import java.util.*;
import javax.swing.DefaultRowSorter;
import javax.swing.RowFilter;
import javax.swing.SortOrder;
/**
* An implementation of RowSorter
that provides sorting
* and filtering using a TableModel
.
* The following example shows adding sorting to a JTable
:
*
* TableModel myModel = createMyTableModel(); * JTable table = new JTable(myModel); * table.setRowSorter(new TableRowSorter(myModel)); ** This will do all the wiring such that when the user does the appropriate * gesture, such as clicking on the column header, the table will * visually sort. *
* JTable
's row-based methods and JTable
's
* selection model refer to the view and not the underlying
* model. Therefore, it is necessary to convert between the two. For
* example, to get the selection in terms of myModel
* you need to convert the indices:
*
* int[] selection = table.getSelectedRows(); * for (int i = 0; i < selection.length; i++) { * selection[i] = table.convertRowIndexToModel(selection[i]); * } ** Similarly to select a row in
JTable
based on
* a coordinate from the underlying model do the inverse:
* * table.setRowSelectionInterval(table.convertRowIndexToView(row), * table.convertRowIndexToView(row)); **
* The previous example assumes you have not enabled filtering. If you
* have enabled filtering convertRowIndexToView
will return
* -1 for locations that are not visible in the view.
*
* TableRowSorter
uses Comparator
s for doing
* comparisons. The following defines how a Comparator
is
* chosen for a column:
*
Comparator
has been specified for the column by the
* setComparator
method, use it.
* getColumnClass
is
* String
, use the Comparator
returned by
* Collator.getInstance()
.
* Comparable
, use a
* Comparator
that invokes the compareTo
* method.
* TableStringConverter
has been specified, use it
* to convert the values to String
s and then use the
* Comparator
returned by Collator.getInstance()
.
* Comparator
returned by
* Collator.getInstance()
on the results from
* calling toString
on the objects.
*
* In addition to sorting TableRowSorter
provides the ability
* to filter. A filter is specified using the setFilter
* method. The following example will only show rows containing the string
* "foo":
*
* TableModel myModel = createMyTableModel(); * TableRowSorter sorter = new TableRowSorter(myModel); * sorter.setRowFilter(RowFilter.regexFilter(".*foo.*")); * JTable table = new JTable(myModel); * table.setRowSorter(sorter); **
* If the underlying model structure changes (the
* modelStructureChanged
method is invoked) the following
* are reset to their default values: Comparator
s by
* column, current sort order, and whether each column is sortable. The default
* sort order is natural (the same as the model), and columns are
* sortable by default.
*
* TableRowSorter
has one formal type parameter: the type
* of the model. Passing in a type that corresponds exactly to your
* model allows you to filter based on your model without casting.
* Refer to the documentation of RowFilter
for an example
* of this.
*
* WARNING: DefaultTableModel
returns a column
* class of Object
. As such all comparisons will
* be done using toString
. This may be unnecessarily
* expensive. If the column only contains one type of value, such as
* an Integer
, you should override getColumnClass
and
* return the appropriate Class
. This will dramatically
* increase the performance of this class.
*
* @param TableModel
* @see javax.swing.JTable
* @see javax.swing.RowFilter
* @see javax.swing.table.DefaultTableModel
* @see java.text.Collator
* @see java.util.Comparator
* @since 1.6
*/
public class TableRowSorterTableRowSorter
with an empty model.
*/
public TableRowSorter() {
this(null);
}
/**
* Creates a TableRowSorter
using model
* as the underlying TableModel
.
*
* @param model the underlying TableModel
to use,
* null
is treated as an empty model
*/
public TableRowSorter(M model) {
setModel(model);
}
/**
* Sets the TableModel
to use as the underlying model
* for this TableRowSorter
. A value of null
* can be used to set an empty model.
*
* @param model the underlying model to use, or null
*/
public void setModel(M model) {
tableModel = model;
setModelWrapper(new TableRowSorterModelWrapper());
}
/**
* Sets the object responsible for converting values from the
* model to strings. If non-null
this
* is used to convert any object values, that do not have a
* registered Comparator
, to strings.
*
* @param stringConverter the object responsible for converting values
* from the model to strings
*/
public void setStringConverter(TableStringConverter stringConverter) {
this.stringConverter = stringConverter;
}
/**
* Returns the object responsible for converting values from the
* model to strings.
*
* @return object responsible for converting values to strings.
*/
public TableStringConverter getStringConverter() {
return stringConverter;
}
/**
* Returns the Comparator
for the specified
* column. If a Comparator
has not been specified using
* the setComparator
method a Comparator
* will be returned based on the column class
* (TableModel.getColumnClass
) of the specified column.
* If the column class is String
,
* Collator.getInstance
is returned. If the
* column class implements Comparable
a private
* Comparator
is returned that invokes the
* compareTo
method. Otherwise
* Collator.getInstance
is returned.
*
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
public Comparator> getComparator(int column) {
Comparator comparator = super.getComparator(column);
if (comparator != null) {
return comparator;
}
Class columnClass = getModel().getColumnClass(column);
if (columnClass == String.class) {
return Collator.getInstance();
}
if (Comparable.class.isAssignableFrom(columnClass)) {
return COMPARABLE_COMPARATOR;
}
return Collator.getInstance();
}
/**
* {@inheritDoc}
*
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
protected boolean useToString(int column) {
Comparator comparator = super.getComparator(column);
if (comparator != null) {
return false;
}
Class columnClass = getModel().getColumnClass(column);
if (columnClass == String.class) {
return false;
}
if (Comparable.class.isAssignableFrom(columnClass)) {
return false;
}
return true;
}
/**
* Implementation of DefaultRowSorter.ModelWrapper that delegates to a
* TableModel.
*/
private class TableRowSorterModelWrapper extends ModelWrapper