001/* 002 * $Id$ 003 * 004 * Copyright 2009 Sun Microsystems, Inc., 4150 Network Circle, 005 * Santa Clara, California 95054, U.S.A. All rights reserved. 006 * 007 * This library is free software; you can redistribute it and/or 008 * modify it under the terms of the GNU Lesser General Public 009 * License as published by the Free Software Foundation; either 010 * version 2.1 of the License, or (at your option) any later version. 011 * 012 * This library is distributed in the hope that it will be useful, 013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 015 * Lesser General Public License for more details. 016 * 017 * You should have received a copy of the GNU Lesser General Public 018 * License along with this library; if not, write to the Free Software 019 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 020 * 021 */ 022package org.jdesktop.swingx.sort; 023 024import java.text.Collator; 025import java.util.Comparator; 026 027import javax.swing.table.TableModel; 028 029/** 030 * A SortController to use for a JXTable.<p> 031 * 032 * @author Jeanette Winzenburg 033 */ 034public class TableSortController<M extends TableModel> extends DefaultSortController<M> { 035 /** 036 * Underlying model. 037 */ 038 private M tableModel; 039 040 public TableSortController() { 041 this(null); 042 } 043 044 /** 045 * @param model 046 */ 047 public TableSortController(M model) { 048 super(); 049 setModel(model); 050 } 051 052 /** 053 * Sets the <code>TableModel</code> to use as the underlying model 054 * for this <code>TableRowSorter</code>. A value of <code>null</code> 055 * can be used to set an empty model. 056 * 057 * @param model the underlying model to use, or <code>null</code> 058 */ 059 public void setModel(M model) { 060 tableModel = model; 061 if (model != null) 062 cachedModelRowCount = model.getRowCount(); 063 setModelWrapper(new TableRowSorterModelWrapper()); 064 } 065 066 067 /** 068 * Returns the <code>Comparator</code> for the specified 069 * column. If a <code>Comparator</code> has not been specified using 070 * the <code>setComparator</code> method a <code>Comparator</code> 071 * will be returned based on the column class 072 * (<code>TableModel.getColumnClass</code>) of the specified column. 073 * If the column class is <code>String</code>, 074 * <code>Collator.getInstance</code> is returned. If the 075 * column class implements <code>Comparable</code> a private 076 * <code>Comparator</code> is returned that invokes the 077 * <code>compareTo</code> method. Otherwise 078 * <code>Collator.getInstance</code> is returned.<p> 079 * 080 * PENDING JW: think about implications to string value lookup! 081 * 082 * @throws IndexOutOfBoundsException {@inheritDoc} 083 */ 084 @Override 085 public Comparator<?> getComparator(int column) { 086 Comparator<?> comparator = super.getComparator(column); 087 if (comparator != null) { 088 return comparator; 089 } 090 Class<?> columnClass = getModel().getColumnClass(column); 091 if (columnClass == String.class) { 092 return Collator.getInstance(); 093 } 094 if (Comparable.class.isAssignableFrom(columnClass)) { 095 return COMPARABLE_COMPARATOR; 096 } 097 return Collator.getInstance(); 098 } 099 100 /** 101 * {@inheritDoc}<p> 102 * Note: must implement same logic as the overridden comparator 103 * lookup, otherwise will throw ClassCastException because 104 * here the comparator is never null. <p> 105 * 106 * PENDING JW: think about implications to string value lookup! 107 * 108 * @throws IndexOutOfBoundsException {@inheritDoc} 109 */ 110 @Override 111 protected boolean useToString(int column) { 112 Comparator<?> comparator = super.getComparator(column); 113 if (comparator != null) { 114 return false; 115 } 116 Class<?> columnClass = getModel().getColumnClass(column); 117 if (columnClass == String.class) { 118 return false; 119 } 120 if (Comparable.class.isAssignableFrom(columnClass)) { 121 return false; 122 } 123 return true; 124 } 125 126 127 /** 128 * Implementation of DefaultRowSorter.ModelWrapper that delegates to a 129 * TableModel. 130 */ 131 private class TableRowSorterModelWrapper extends ModelWrapper<M,Integer> { 132 @Override 133 public M getModel() { 134 return tableModel; 135 } 136 137 @Override 138 public int getColumnCount() { 139 return (tableModel == null) ? 0 : tableModel.getColumnCount(); 140 } 141 142 @Override 143 public int getRowCount() { 144 return (tableModel == null) ? 0 : tableModel.getRowCount(); 145 } 146 147 @Override 148 public Object getValueAt(int row, int column) { 149 return tableModel.getValueAt(row, column); 150 } 151 152 @Override 153 public String getStringValueAt(int row, int column) { 154 return getStringValueProvider().getStringValue(row, column) 155 .getString(getValueAt(row, column)); 156 } 157 158 @Override 159 public Integer getIdentifier(int index) { 160 return index; 161 } 162 } 163 164 165}