001/* 002 * $Id: SortController.java 3498 2009-09-10 09:35:40Z kleopatra $ 003 * 004 * Copyright 2004 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.util.Comparator; 025 026import javax.swing.RowFilter; 027import javax.swing.SortOrder; 028 029/** 030 * Defines the interactive sort control for sortable collection components (like 031 * JXList, JXTable). All sort gesture requests from their sort api 032 * are routed through the SortController. 033 * <p> 034 * 035 * This is very-much work-in-progress: while moving from ol' SwingX sorting to 036 * core jdk6 sorting we need a hook for sorting api on the view. So in terms of 037 * jdk6 classes, this is something like:<p> 038 * 039 * <code><pre> 040 * SortController == DefaultRowSorter - RowSorter + XX 041 * </pre></code> 042 * All methods which change sort state must respect per-controller and per-column 043 * sortable property, as follows 044 * <ol> 045 * <li> if per-controller sortable is false, do nothing 046 * <li> if per-controller sortable is true, if per-column sortable is false, do nothing 047 * <li> if both are true toggle the SortOrder of the given column 048 * </ol> 049 * 050 * 051 * @author <a href="mailto:jesse@swank.ca">Jesse Wilson</a> 052 * @author Jeanette Winzenburg 053 * 054 */ 055public interface SortController<M> { 056 057//----------------- configuration 058 059 /** 060 * Sets whether or not this controller is sortable.<p> 061 * 062 * The default is true.<p> 063 * 064 * PENDING JW: define behaviour if sortable is disabled while has sortOrders. 065 * In this case JXTable resets all sorts. 066 * 067 * @param sortable whether or not this controller is sortable 068 * @see #isSortable() 069 */ 070 void setSortable(boolean sortable); 071 072 /** 073 * Returns true if this controller is sortable; otherwise, false. 074 * 075 * @return true if this controller is sortable 076 * 077 * @see #isSortable() 078 */ 079 boolean isSortable(); 080 081 /** 082 * Sets whether or not the specified column is sortable.<p> 083 * 084 * The default is true.<p> 085 * 086 * PENDING JW: define behaviour if sortable is disabled while has sortOrders. 087 * In this case JXTable removes the sort of the column.<p> 088 * 089 * PENDING JW: decide whether or not this method should trigger a resort 090 * DefaultRowSorter explicitly doesn't, JXTable does. 091 * 092 * @param column the column to enable or disable sorting on, in terms 093 * of the underlying model 094 * @param sortable whether or not the specified column is sortable 095 * @throws IndexOutOfBoundsException if <code>column</code> is outside 096 * the range of the model 097 * @see #isSortable(int) 098 * @see #toggleSortOrder(int) 099 * @see #setSortOrder(int, SortOrder) 100 */ 101 void setSortable(int column, boolean sortable); 102 103 /** 104 * Returns true if the specified column is sortable. <p> 105 * This returns true if both the controller's sortable property and 106 * the column's sortable property is true. Returns false if any of 107 * them is false. 108 * 109 * @param column the column to check sorting for, in terms of the 110 * underlying model 111 * @return true if the column is sortable 112 * @throws IndexOutOfBoundsException if column is outside 113 * the range of the underlying model 114 * 115 * @see #isSortable(int) 116 */ 117 boolean isSortable(int column); 118 119 /** 120 * Sets the <code>Comparator</code> to use when sorting the specified 121 * column. This does not trigger a sort. If you want to sort after 122 * setting the comparator you need to explicitly invoke <code>sort</code>. 123 * 124 * @param column the index of the column the <code>Comparator</code> is 125 * to be used for, in terms of the underlying model 126 * @param comparator the <code>Comparator</code> to use 127 * @throws IndexOutOfBoundsException if <code>column</code> is outside 128 * the range of the underlying model 129 */ 130 public void setComparator(int column, Comparator<?> comparator); 131 132 /** 133 * Returns the <code>Comparator</code> for the specified 134 * column. This will return <code>null</code> if a <code>Comparator</code> 135 * has not been specified for the column. 136 * 137 * @param column the column to fetch the <code>Comparator</code> for, in 138 * terms of the underlying model 139 * @return the <code>Comparator</code> for the specified column 140 * @throws IndexOutOfBoundsException if column is outside 141 * the range of the underlying model 142 */ 143 public Comparator<?> getComparator(int column); 144 145 /** 146 * Sets the cycle of sort ordes to toggle through. Zero or more SortOrders which 147 * must not be null. 148 * 149 * @param cycle the SortOrders to cycle through, may be empty 150 * @throws NullPointerException if the array or any of its elements is null 151 */ 152 void setSortOrderCycle(SortOrder... cycle); 153 154 /** 155 * Returns the cycle of sort orders to cycle through. 156 * 157 * @return 158 */ 159 SortOrder[] getSortOrderCycle(); 160 161 /** 162 * If true, specifies that a sort should happen when the underlying 163 * model is updated (<code>rowsUpdated</code> is invoked). For 164 * example, if this is true and the user edits an entry the 165 * location of that item in the view may change. The default is 166 * true. 167 * 168 * @param sortsOnUpdates whether or not to sort on update events 169 */ 170 void setSortsOnUpdates(boolean sortsOnUpdates); 171 172 /** 173 * Returns true if a sort should happen when the underlying 174 * model is updated; otherwise, returns false. 175 * 176 * @return whether or not to sort when the model is updated 177 */ 178 boolean getSortsOnUpdates(); 179 180 /** 181 * Sets the StringValueProvider to look up the StringValues. If the value 182 * is not-null, it guarantees to use it exclusively for string conversion. <p> 183 * 184 * PENDING JW: this is more or less parallel to TableStringConverter. Need to think 185 * about merging somehow. 186 * 187 * @param provider the look up for StringValues, may be null. 188 */ 189 void setStringValueProvider(StringValueProvider provider); 190 191 /** 192 * Returns the StringValueProvider used to look up StringValues. 193 * 194 * @return StringValueProvider used to look up StringValues, guaranteed to 195 * be not null. 196 */ 197 StringValueProvider getStringValueProvider(); 198 199//------------------------ sort 200 201 /** 202 * Reverses the sort order of the specified column. The exact behaviour is 203 * up to implementations.<p> 204 * 205 * Implementations must respect the per-controller and per-column-sortable 206 * property. 207 * 208 * @param column the model index of the column to toggle 209 * @see #isSortable(int) 210 * @see #isSortable() 211 */ 212 void toggleSortOrder(int column); 213 214 /** 215 * Sets the sort order of the specified column. <p> 216 * 217 * Implementations must respect the per-controller and per-column-sortable 218 * property. 219 * 220 * @param column the model index of the column to set 221 * @param sortOrder the SortOrder to set for the column 222 * 223 * @see #isSortable(int) 224 * @see #isSortable() 225 */ 226 void setSortOrder(int column, SortOrder sortOrder); 227 228 /** 229 * Returns the sort order of the specified column. 230 * 231 * 232 * @return one of {@link SortOrder#ASCENDING}, 233 * {@link SortOrder#DESCENDING} or {@link SortOrder#UNSORTED}. 234 */ 235 SortOrder getSortOrder(int column); 236 237 238 /** 239 * Resets all interactive sorting. <p> 240 * 241 * Implementations must respect the per-controller and per-column-sortable 242 * property. 243 * 244 */ 245 void resetSortOrders(); 246 247//-------------------- filter 248 249 /** 250 * Sets the filter that determines which rows, if any, should be 251 * hidden from the view. The filter is applied before sorting. A value 252 * of <code>null</code> indicates all values from the model should be 253 * included. 254 * <p> 255 * <code>RowFilter</code>'s <code>include</code> method is passed an 256 * <code>Entry</code> that wraps the underlying model. The number 257 * of columns in the <code>Entry</code> corresponds to the 258 * number of columns in the underlying model. The identifier 259 * comes from the underlying model as well. 260 * <p> 261 * This method triggers a sort. 262 * 263 * PENDING JW: the "underlying model" is the ModelWrapper ... want to 264 * expose here as well? Otherwise, the second paramter doesn't make much sense. 265 * 266 * @param filter the filter used to determine what entries should be 267 * included 268 */ 269 void setRowFilter(RowFilter<? super M, ? super Integer> filter); 270 271 /** 272 * Returns the filter that determines which rows, if any, should 273 * be hidden from view. 274 * 275 * @return the filter 276 */ 277 RowFilter<? super M,? super Integer> getRowFilter(); 278 279 280 281}