1 package edu.psu.geovista.app.spreadsheet.table;
2
3 /*
4 * Description: A toolkit for sorting table based on columns
5 * Date: Mar 20, 2003
6 * Time: 3:38:43 PM
7 * @author Jin Chen
8 */
9
10 import edu.psu.geovista.app.spreadsheet.formula.Cell;
11
12 import javax.swing.*;
13 import javax.swing.table.TableModel;
14 import javax.swing.table.TableColumnModel;
15 import java.util.Vector;
16 import java.util.HashSet;
17 import java.awt.*;
18 import java.awt.event.MouseEvent;
19 import java.awt.event.MouseAdapter;
20
21 import edu.psu.geovista.app.spreadsheet.util.Debug;
22
23 public class TableColumnSort {
24 //private JTable table;
25 private boolean tableSort;
26 private SSTableModel tm;
27 /***
28 * Contain vectors, each of which is for sorting a individual column
29 * nth vector map to nth Column in Model
30 * Except vector(0), which is for sorting whole table
31 */
32 private Vector sorts;
33
34 private SortRange sortRange; //The range to be sorted
35 private Vector baseRange;//the range based on which sorting is done. For now only allow one range(col/row)
36
37 public TableColumnSort(SSTableModel tm) {
38 //this.table = table;
39 this.tm =tm;
40 this.createSort() ;
41
42 }
43 private void createSort() {
44 sorts=new Vector();
45 this.sortRange =new SortRange();
46 int numOfColumn=this.tm.getColumnCount() ;
47 for (int i=0;i<numOfColumn;i++){ //??? Need add more if adding column
48 sorts.add(null);
49 }
50 Debug.println("sorts' size:"+sorts.size() );
51
52 }
53
54
55 public SortRange getSortRange() {
56 return sortRange;
57 }
58
59 /***
60 * Do different sorting for table selection and a given column:
61 * - if select a column: do the individual column sort
62 * - if select a entire table: do entire table sort based on a selected column
63 * - if select serveral rows(contigent or not: do sort only for those rows based on a selected column
64 * - if select a range: do sort only for the range based on a selected column
65 * sort whole table based on a column
66 * @param col the index of the column based on which the table is sorted
67 */
68
69 /*** !!!
70 * create a vector in sorts(Vector).
71 * It is a map in between Model index and View index
72 * @param column in View
73 */
74 private void createSortMap (int col){
75 this.setTableSort(true);
76 int rowCount = tm.getRowCount();
77 if (col==0){//creat sort map for entire table
78 //tablesort, store map between sort index to row index for all columns
79 Vector ts=this.createSortVector(rowCount) ;
80 //System.out.println("ts"+ts.elementAt(2));
81 if (sorts.size() ==0) {
82 sorts.add(ts);
83 } else {
84 sorts.setElementAt(ts, 0);//default vector for sorting whole table
85 }
86 }
87 else {
88 /*
89 Vector colsort;
90 int size=sorts.size();
91 colsort=this.getColumnSort(col);
92 if (colsort==null){
93 colsort=this.createSortVector(rowCount) ;
94 }
95 sorts.setElementAt(colsort,col); */
96
97 //* replaced by above on 04032003
98 Vector colsort=this.createSortVector(rowCount) ;
99 int size=sorts.size();
100
101 //int mcol=edu.psu.geovista.app.spreadsheet.formula.Cell.transColViewToModel(col);//Model index
102 int mcol=col;
103 if (mcol<size){//Vector.setElementAt(colsort,mcol); won't throw edu.psu.geovista.app.spreadsheet.exception
104 sorts.setElementAt(colsort,mcol);
105 }
106 else{//Vector.setElementAt(colsort,mcol); will throw edu.psu.geovista.app.spreadsheet.exception, MUST fill with null element
107 int needCol=mcol-size+1;
108 for (int i=0;i<needCol;i++){
109 sorts.add(null);//For those columns no need sort, just maintain a null for them
110 }
111 sorts.setElementAt(colsort,mcol);
112 }
113 }//else
114 }
115 /**
116 * Return the sort vector for the column with given index(in model)
117 * if not vector exist for the index, set null for that index in sorts
118 * it means that column is not sorted(thus no corresponding vector in sorts)
119 */
120 public Vector getColumnSort(int col){
121 int size=sorts.size();
122 if (col>=size){
123 //Vector.setElementAt(colsort,mcol); will throw edu.psu.geovista.app.spreadsheet.exception,
124 //MUST fill with null element
125 int needCol=col-size+1;
126 for (int i=0;i<needCol;i++){
127 sorts.add(null);//For those columns no need sort, just maintain a null for them
128 }
129
130 }
131 return (Vector)sorts.elementAt(col);
132 }
133
134 public void sortRows(int col, int[] rows, boolean ascending){
135 this.sortRange.setType(SortRange.ROWS );
136 for (int i=0;i<rows.length ;i++){
137 int row=rows[i];
138 this.sortRange.setRow(row);
139 }
140 this.createSortMap(0);//use table sort
141 this.sortRows(col,false);
142 }
143 //sort entire table
144 public void sortTable(int col, boolean ascending){
145 this.sortRange.setType(SortRange.ENTIRE_TABLE );
146 this.sortRows(col,ascending);
147 }
148 //sort rows
149 private void sortRows(int col, boolean ascending){
150
151 System.out.println("********* edu.psu.geovista.app.spreadsheet.tools.Sort ->");
152 this.createSortMap(0);
153
154 int rowCount = tm.getRowCount();
155 int sortType=this.sortRange.getType() ;
156 if(sortType==SortRange.ENTIRE_TABLE
157 || sortType==SortRange.ROWS ){
158 Vector sortMap=(Vector)this.sorts.get(0);
159 this.showVector(sortMap);
160 for(int i=0; i < rowCount; i++) {
161 //ith is the current element
162 for(int j = i+1; j < rowCount; j++) {
163 //(i+1)th is the next elements
164 int indexi=((Integer)(sortMap.elementAt(i))).intValue() ;
165 int indexj=((Integer)(sortMap.elementAt(j))).intValue() ;
166 if(compare(indexi, indexj, col, ascending) < 0) {
167 /*if (this.sortRange.containRow(i)&&
168 this.sortRange.containRow(j)){ */
169 swap(i,j,sortMap);
170
171 System.out.println("Swap "+i+" and "+j);
172 // } //if2
173 }//if 1
174
175 } //for2
176 }//for
177 this.showVector(sortMap);
178
179 }
180 else{
181 assert false:"sortRows() can sort it";
182 }
183 }
184 /*** sort column
185 * @param col based on which sorting is done
186 * @param cols sorting apply only to those columns
187 *
188 */
189 public void sortColumns(int col, int[] cols,boolean ascending){
190 System.out.println("********* edu.psu.geovista.app.spreadsheet.tools.Sort ->");
191 for (int i=0;i<cols.length ;i++){
192 int scol=cols[i];//selected column in table view
193 this.sortRange.setColumn(scol);
194 this.createSortMap(scol);
195 }
196 this.sortRange.setType(SortRange.COLUMNS);
197
198 int rowCount = tm.getRowCount();
199 int sortType=this.sortRange.getType() ;
200 if (sortType==SortRange.COLUMNS ){
201 for (int k=0;k<cols.length ;k++){//do sort for each column
202 //int mcol=edu.psu.geovista.app.spreadsheet.formula.Cell.transColViewToModel(cols[k]);
203 int mcol=cols[k];
204 Vector sortMap=(Vector)this.sorts.get(mcol);
205 for(int i=0; i < rowCount; i++) {
206 //ith is the current element
207 for(int j = i+1; j < rowCount; j++) {
208 //(i+1)th is the next elements
209 //if (SortRange.
210 int indexi=((Integer)(sortMap.elementAt(i))).intValue() ;
211 int indexj=((Integer)(sortMap.elementAt(j))).intValue() ;
212 if(compare(indexi, indexj, col, ascending) < 0) {
213
214 swap(i,j,sortMap);
215
216 System.out.println("Swap "+i+" and "+j);
217
218 }//if 1
219 } //for2
220 }//for1
221 Debug.showVector(sortMap, "Show SortMap "+mcol) ;
222 }//for0
223
224 }
225 else if (sortType==SortRange.RANGE ){
226 }
227 else{
228 assert false:"sortColumns() can sort it";
229 }
230
231 System.out.println("******************************************* edu.psu.geovista.app.spreadsheet.tools.Sort <-");
232 }//sortTable
233
234 /*** sort Range
235 * @param col based on which sorting is done
236 * @param cols sorting apply only to those columns
237 *
238 */
239 public void sortRange(int col,int[] rows,int[] cols,boolean ascending){
240 System.out.println("********* edu.psu.geovista.app.spreadsheet.tools.Sort ->");
241 for (int i=0;i<cols.length ;i++){
242 int scol=cols[i];//selected column in table view
243 if (!sortRange.contains(scol)){
244 this.sortRange.setColumn(scol);
245 this.createSortMap(scol);
246 }
247 }
248 this.sortRange.setType(SortRange.RANGE );
249
250 int rowCount = tm.getRowCount();
251 int sortType=this.sortRange.getType() ;
252 if (sortType==SortRange.RANGE ){
253 for (int k=0;k<cols.length ;k++){//do sort for each column
254 //int mcol=edu.psu.geovista.app.spreadsheet.formula.Cell.transColViewToModel(cols[k]);
255 int mcol=cols[k];
256
257 Vector sortMap=(Vector)this.sorts.get(mcol);
258 for(int i=0; i < rowCount; i++) {
259 //ith is the current element
260 for(int j = i+1; j < rowCount; j++) {
261 //(i+1)th is the next elements
262 //if (SortRange.
263 int indexi=((Integer)(sortMap.elementAt(i))).intValue() ;
264 int indexj=((Integer)(sortMap.elementAt(j))).intValue() ;
265 if (rows[0]<=indexi&& indexi<=rows[rows.length -1]&&
266 rows[0]<=indexj&& indexj<=rows[rows.length -1]){
267 if(compare(indexi, indexj, col, ascending) < 0) {
268 swap(i,j,sortMap);
269 System.out.println("Swap "+i+" and "+j);
270 }//if 1
271 }
272 } //for2
273 }//for1
274 Debug.showVector(sortMap, "Show SortMap "+mcol) ;
275 }//for0
276
277 }
278 else if (sortType==SortRange.RANGE ){
279 }
280 else{
281 assert false:"sortColumns() can sort it";
282 }
283
284 System.out.println("******************************************* edu.psu.geovista.app.spreadsheet.tools.Sort <-");
285 }//sortTable
286
287 /***
288 * create a Vector contain same number of element as the row count
289 */
290 private Vector createSortVector(int numOfRow){
291
292
293 Vector ts=new Vector(numOfRow);
294 for (int i=0;i<numOfRow;i++){
295 Integer index=new Integer(i);
296 ts.add(index);
297 }
298 return ts;
299
300 }
301 /***
302 * swap ith and jth element in column
303 */
304 private void swap(int i, int j, Vector ts) {
305 //Vector ts=(Vector)this.sorts.elementAt(0);//tablesort
306
307 int indexi=((Integer)(ts.elementAt(i))).intValue() ;
308 int indexj=((Integer)(ts.elementAt(j))).intValue() ;
309
310 ts.setElementAt(new Integer(indexj), i);
311 ts.setElementAt(new Integer(indexi),j);
312 /*int tmp = indexes[i];
313 indexes[i] = indexes[j];
314 indexes[j] = tmp; */
315 }
316 /***
317 * compare ith element and jth element of tableModel's column
318 * @param column column index in table edu.psu.geovista.app.spreadsheet.model
319 */
320 private int compare(int i, int j, int column, boolean ascending) {
321 //int modelCol=table.convertColumnIndexToModel(column);
322 int modelCol=column;
323 SSTableModel realModel =tm;
324 Cell ic =(Cell) realModel.getRealModelValueAt(i,modelCol);
325 Cell jc =(Cell) realModel.getRealModelValueAt(j,modelCol);
326
327 int c = jc.compareTo(ic,ascending);//ascending
328 if (ic!=null&&jc!=null){
329 if(ic.getValue() !=null&&jc.getValue()!=null )
330 System.out.println("Compare "+j+"th("+jc.getValue() +") to"+i+"th("+ic.getValue() +") ="+c);
331 //Descend if A>B => c<0; A<B => c>0
332 //ascend if A>B => c>0; A<B => c<0
333 }
334
335 return c;
336 //return (c < 0) ? -1 : ((c > 0) ? 1 : 0);
337 }
338 /***
339 * Given a cell point in sortModel, return it position in real Model
340 * @param vx sortModel 's x . For table view, it is just Model x
341 */
342 public Point getCellPointAt(int vx, int vy){
343 int mx,my;//edu.psu.geovista.app.spreadsheet.model x, edu.psu.geovista.app.spreadsheet.model y
344 my=vy;
345 int sortSize=this.sorts.size() ;
346 Vector columnIndex;
347 if(sortSize==0 ){//The table is not sort
348 mx=vx;
349 return new Point(mx,my);
350
351 }
352 else if ( this.sorts.elementAt(0)!=null){// entire table is sort also may have individual column sorts
353 if (my>=sorts.size() ){//the column is not individually sort
354 columnIndex=(Vector)this.sorts.elementAt(0); // table sort index
355 mx=((Integer)columnIndex.elementAt(vx)).intValue(); //only apply table sort
356 }
357 else{// the column may be individually sort
358 columnIndex=(Vector)this.sorts.elementAt(my);
359 if (columnIndex==null){ //the column is not individually sort
360 columnIndex=(Vector)this.sorts.elementAt(0); //use table sort index
361 mx=((Integer)columnIndex.elementAt(vx)).intValue();
362
363 }
364 else {//The individual column is sort
365 int colsortx=((Integer)columnIndex.elementAt(vx)).intValue() ;//x based on individual column's sort
366 Vector tableSort=(Vector)this.sorts.elementAt(0); //table sort index
367 mx=((Integer)tableSort.elementAt(vx)).intValue(); //apply table sort
368 }
369 }
370
371
372
373 }
374 else{ //no entire-table sort, may have individual column sort
375 if (my<sorts.size() &&(columnIndex=(Vector)this.sorts.elementAt(my))!=null ){
376 //only individual sort apply
377 mx=((Integer)columnIndex.elementAt(vx)).intValue();
378 }
379 else{//the column is not individually sort
380 //Not any sort at all
381 mx=vx;
382 //return new Point(mx,my);
383 }
384
385 }
386 return new Point(mx,my);
387 /*
388 else if (my>this.sorts.size()){ //The column is not selected for sorting
389 }
390 Vector columnIndex=(Vector)this.sorts.elementAt(my);
391 if (columnIndex!=null){//The individual column is indexed
392 mx=((Integer)columnIndex.elementAt(vx)).intValue() ;
393 }
394 else{
395 columnIndex=(Vector)this.sorts.elementAt(0); //use table sort index
396 if (columnIndex!=null){
397 mx=((Integer)columnIndex.elementAt(vx)).intValue() ;
398 }
399 else{ // no table sort index
400 mx=vx;
401 }
402 }
403 return new Point(mx,my); */
404
405 }
406
407
408
409
410
411
412 /***
413 * Select a column
414 */
415
416
417 public static void showVector(Vector v) {
418 System.out.println("Show Vector -->");
419 for (int i=0;i<v.size() ;i++){
420 System.out.println(v.elementAt(i).toString() );
421 }
422 System.out.println("Show Vector <--");
423 }
424
425 public Vector getSorts() {
426 return sorts;
427 }
428
429
430 /***
431 * return true if sort apply to any range of the table
432 */
433 public boolean isTableSort(){
434 return tableSort;
435 }
436
437 public void setTableSort(boolean tableSort) {
438 this.tableSort = tableSort;
439 }
440 /***
441 * clear all sort of the table
442 */
443 public void clearSort() {
444 this.setTableSort(false);
445 this.createSort() ;
446 }
447 }
448
This page was automatically generated by Maven