114 * class of <code>Object</code>. As such all comparisons will
115 * be done using <code>toString</code>. This may be unnecessarily
116 * expensive. If the column only contains one type of value, such as
117 * an <code>Integer</code>, you should override <code>getColumnClass</code> and
118 * return the appropriate <code>Class</code>. This will dramatically
119 * increase the performance of this class.
120 *
121 * @param <M> the type of the model, which must be an implementation of
122 * <code>TableModel</code>
123 * @see javax.swing.JTable
124 * @see javax.swing.RowFilter
125 * @see javax.swing.table.DefaultTableModel
126 * @see java.text.Collator
127 * @see java.util.Comparator
128 * @since 1.6
129 */
130 public class TableRowSorter<M extends TableModel> extends DefaultRowSorter<M, Integer> {
131 /**
132 * Comparator that uses compareTo on the contents.
133 */
134 private static final Comparator COMPARABLE_COMPARATOR =
135 new ComparableComparator();
136
137 /**
138 * Underlying model.
139 */
140 private M tableModel;
141
142 /**
143 * For toString conversions.
144 */
145 private TableStringConverter stringConverter;
146
147
148 /**
149 * Creates a <code>TableRowSorter</code> with an empty model.
150 */
151 public TableRowSorter() {
152 this(null);
153 }
154
197 public TableStringConverter getStringConverter() {
198 return stringConverter;
199 }
200
201 /**
202 * Returns the <code>Comparator</code> for the specified
203 * column. If a <code>Comparator</code> has not been specified using
204 * the <code>setComparator</code> method a <code>Comparator</code>
205 * will be returned based on the column class
206 * (<code>TableModel.getColumnClass</code>) of the specified column.
207 * If the column class is <code>String</code>,
208 * <code>Collator.getInstance</code> is returned. If the
209 * column class implements <code>Comparable</code> a private
210 * <code>Comparator</code> is returned that invokes the
211 * <code>compareTo</code> method. Otherwise
212 * <code>Collator.getInstance</code> is returned.
213 *
214 * @throws IndexOutOfBoundsException {@inheritDoc}
215 */
216 public Comparator<?> getComparator(int column) {
217 Comparator comparator = super.getComparator(column);
218 if (comparator != null) {
219 return comparator;
220 }
221 Class columnClass = getModel().getColumnClass(column);
222 if (columnClass == String.class) {
223 return Collator.getInstance();
224 }
225 if (Comparable.class.isAssignableFrom(columnClass)) {
226 return COMPARABLE_COMPARATOR;
227 }
228 return Collator.getInstance();
229 }
230
231 /**
232 * {@inheritDoc}
233 *
234 * @throws IndexOutOfBoundsException {@inheritDoc}
235 */
236 protected boolean useToString(int column) {
237 Comparator comparator = super.getComparator(column);
238 if (comparator != null) {
239 return false;
240 }
241 Class columnClass = getModel().getColumnClass(column);
242 if (columnClass == String.class) {
243 return false;
244 }
245 if (Comparable.class.isAssignableFrom(columnClass)) {
246 return false;
247 }
248 return true;
249 }
250
251 /**
252 * Implementation of DefaultRowSorter.ModelWrapper that delegates to a
253 * TableModel.
254 */
255 private class TableRowSorterModelWrapper extends ModelWrapper<M,Integer> {
256 public M getModel() {
257 return tableModel;
258 }
259
260 public int getColumnCount() {
261 return (tableModel == null) ? 0 : tableModel.getColumnCount();
282 }
283
284 // No converter, use getValueAt followed by toString
285 Object o = getValueAt(row, column);
286 if (o == null) {
287 return "";
288 }
289 String string = o.toString();
290 if (string == null) {
291 return "";
292 }
293 return string;
294 }
295
296 public Integer getIdentifier(int index) {
297 return index;
298 }
299 }
300
301
302 private static class ComparableComparator implements Comparator {
303 @SuppressWarnings("unchecked")
304 public int compare(Object o1, Object o2) {
305 return ((Comparable)o1).compareTo(o2);
306 }
307 }
308 }
|
114 * class of <code>Object</code>. As such all comparisons will
115 * be done using <code>toString</code>. This may be unnecessarily
116 * expensive. If the column only contains one type of value, such as
117 * an <code>Integer</code>, you should override <code>getColumnClass</code> and
118 * return the appropriate <code>Class</code>. This will dramatically
119 * increase the performance of this class.
120 *
121 * @param <M> the type of the model, which must be an implementation of
122 * <code>TableModel</code>
123 * @see javax.swing.JTable
124 * @see javax.swing.RowFilter
125 * @see javax.swing.table.DefaultTableModel
126 * @see java.text.Collator
127 * @see java.util.Comparator
128 * @since 1.6
129 */
130 public class TableRowSorter<M extends TableModel> extends DefaultRowSorter<M, Integer> {
131 /**
132 * Comparator that uses compareTo on the contents.
133 */
134 private static final Comparator<?> COMPARABLE_COMPARATOR =
135 new ComparableComparator();
136
137 /**
138 * Underlying model.
139 */
140 private M tableModel;
141
142 /**
143 * For toString conversions.
144 */
145 private TableStringConverter stringConverter;
146
147
148 /**
149 * Creates a <code>TableRowSorter</code> with an empty model.
150 */
151 public TableRowSorter() {
152 this(null);
153 }
154
197 public TableStringConverter getStringConverter() {
198 return stringConverter;
199 }
200
201 /**
202 * Returns the <code>Comparator</code> for the specified
203 * column. If a <code>Comparator</code> has not been specified using
204 * the <code>setComparator</code> method a <code>Comparator</code>
205 * will be returned based on the column class
206 * (<code>TableModel.getColumnClass</code>) of the specified column.
207 * If the column class is <code>String</code>,
208 * <code>Collator.getInstance</code> is returned. If the
209 * column class implements <code>Comparable</code> a private
210 * <code>Comparator</code> is returned that invokes the
211 * <code>compareTo</code> method. Otherwise
212 * <code>Collator.getInstance</code> is returned.
213 *
214 * @throws IndexOutOfBoundsException {@inheritDoc}
215 */
216 public Comparator<?> getComparator(int column) {
217 Comparator<?> comparator = super.getComparator(column);
218 if (comparator != null) {
219 return comparator;
220 }
221 Class<?> columnClass = getModel().getColumnClass(column);
222 if (columnClass == String.class) {
223 return Collator.getInstance();
224 }
225 if (Comparable.class.isAssignableFrom(columnClass)) {
226 return COMPARABLE_COMPARATOR;
227 }
228 return Collator.getInstance();
229 }
230
231 /**
232 * {@inheritDoc}
233 *
234 * @throws IndexOutOfBoundsException {@inheritDoc}
235 */
236 protected boolean useToString(int column) {
237 Comparator<?> comparator = super.getComparator(column);
238 if (comparator != null) {
239 return false;
240 }
241 Class<?> columnClass = getModel().getColumnClass(column);
242 if (columnClass == String.class) {
243 return false;
244 }
245 if (Comparable.class.isAssignableFrom(columnClass)) {
246 return false;
247 }
248 return true;
249 }
250
251 /**
252 * Implementation of DefaultRowSorter.ModelWrapper that delegates to a
253 * TableModel.
254 */
255 private class TableRowSorterModelWrapper extends ModelWrapper<M,Integer> {
256 public M getModel() {
257 return tableModel;
258 }
259
260 public int getColumnCount() {
261 return (tableModel == null) ? 0 : tableModel.getColumnCount();
282 }
283
284 // No converter, use getValueAt followed by toString
285 Object o = getValueAt(row, column);
286 if (o == null) {
287 return "";
288 }
289 String string = o.toString();
290 if (string == null) {
291 return "";
292 }
293 return string;
294 }
295
296 public Integer getIdentifier(int index) {
297 return index;
298 }
299 }
300
301
302 private static class ComparableComparator implements Comparator<Object> {
303 @SuppressWarnings("unchecked")
304 public int compare(Object o1, Object o2) {
305 return ((Comparable)o1).compareTo(o2);
306 }
307 }
308 }
|