|
@@ -15,24 +15,22 @@ |
15 |
15 |
|
*/ |
16 |
16 |
|
package com.google.gwt.gen2.table.client; |
17 |
17 |
|
|
18 |
|
- |
import java.util.*; |
19 |
|
- |
|
20 |
18 |
|
import com.google.gwt.gen2.event.shared.*; |
21 |
19 |
|
import com.google.gwt.gen2.table.client.TableModelHelper.*; |
22 |
20 |
|
import com.google.gwt.gen2.table.event.client.*; |
23 |
21 |
|
import com.google.gwt.user.client.*; |
24 |
22 |
|
|
|
23 |
+ |
import java.util.*; |
|
24 |
+ |
|
25 |
25 |
|
/** |
26 |
26 |
|
* A variation of the {@link Grid} |
27 |
27 |
|
* that supports sorting and row movement. |
28 |
28 |
|
*/ |
29 |
|
- |
public class SortableGrid extends SelectionGrid implements HasColumnSortHandlers |
30 |
|
- |
{ |
|
29 |
+ |
public class SortableGrid extends SelectionGrid implements HasColumnSortHandlers { |
31 |
30 |
|
/** |
32 |
31 |
|
* The column sorter defines an algorithm to sort columns. |
33 |
32 |
|
*/ |
34 |
|
- |
public abstract static class ColumnSorter |
35 |
|
- |
{ |
|
33 |
+ |
public abstract static class ColumnSorter { |
36 |
34 |
|
/** |
37 |
35 |
|
* Override this method to implement a custom column sorting algorithm. |
38 |
36 |
|
* |
|
@@ -47,11 +45,9 @@ |
47 |
45 |
|
* The default {@link ColumnSorter} used if no other {@link ColumnSorter} is |
48 |
46 |
|
* specified. This column sorted uses a quicksort algorithm to sort columns. |
49 |
47 |
|
*/ |
50 |
|
- |
private static class DefaultColumnSorter extends ColumnSorter |
51 |
|
- |
{ |
|
48 |
+ |
private static class DefaultColumnSorter extends ColumnSorter { |
52 |
49 |
|
@Override |
53 |
|
- |
public void onSortColumn( SortableGrid grid, ColumnSortList sortList, SortableGrid.ColumnSorterCallback callback ) |
54 |
|
- |
{ |
|
50 |
+ |
public void onSortColumn( SortableGrid grid, ColumnSortList sortList, SortableGrid.ColumnSorterCallback callback ) { |
55 |
51 |
|
// Get the primary column and sort order |
56 |
52 |
|
int column = sortList.getPrimaryColumn(); |
57 |
53 |
|
boolean ascending = sortList.isPrimaryAscending(); |
|
@@ -60,30 +56,22 @@ |
60 |
56 |
|
SelectionGridCellFormatter formatter = grid.getSelectionGridCellFormatter(); |
61 |
57 |
|
int rowCount = grid.getRowCount(); |
62 |
58 |
|
List<Element> tdElems = new ArrayList<Element>( rowCount ); |
63 |
|
- |
for ( int i = 0; i < rowCount; i++ ) |
64 |
|
- |
{ |
|
59 |
+ |
for ( int i = 0; i < rowCount; i++ ) { |
65 |
60 |
|
tdElems.add( formatter.getRawElement( i, column ) ); |
66 |
61 |
|
} |
67 |
62 |
|
|
68 |
63 |
|
// Sort the cell elements |
69 |
|
- |
if ( ascending ) |
70 |
|
- |
{ |
71 |
|
- |
Collections.sort( tdElems, new Comparator<Element>() |
72 |
|
- |
{ |
|
64 |
+ |
if ( ascending ) { |
|
65 |
+ |
Collections.sort( tdElems, new Comparator<Element>() { |
73 |
66 |
|
@Override |
74 |
|
- |
public int compare( Element o1, Element o2 ) |
75 |
|
- |
{ |
|
67 |
+ |
public int compare( Element o1, Element o2 ) { |
76 |
68 |
|
return o1.getInnerText().compareTo( o2.getInnerText() ); |
77 |
69 |
|
} |
78 |
70 |
|
} ); |
79 |
|
- |
} |
80 |
|
- |
else |
81 |
|
- |
{ |
82 |
|
- |
Collections.sort( tdElems, new Comparator<Element>() |
83 |
|
- |
{ |
|
71 |
+ |
} else { |
|
72 |
+ |
Collections.sort( tdElems, new Comparator<Element>() { |
84 |
73 |
|
@Override |
85 |
|
- |
public int compare( Element o1, Element o2 ) |
86 |
|
- |
{ |
|
74 |
+ |
public int compare( Element o1, Element o2 ) { |
87 |
75 |
|
return o2.getInnerText().compareTo( o1.getInnerText() ); |
88 |
76 |
|
} |
89 |
77 |
|
} ); |
|
@@ -91,8 +79,7 @@ |
91 |
79 |
|
|
92 |
80 |
|
// Convert tdElems to trElems, reversing if needed |
93 |
81 |
|
Element[] trElems = new Element[rowCount]; |
94 |
|
- |
for ( int i = 0; i < rowCount; i++ ) |
95 |
|
- |
{ |
|
82 |
+ |
for ( int i = 0; i < rowCount; i++ ) { |
96 |
83 |
|
trElems[i] = DOM.getParent( tdElems.get( i ) ); |
97 |
84 |
|
} |
98 |
85 |
|
|
|
@@ -104,8 +91,7 @@ |
104 |
91 |
|
/** |
105 |
92 |
|
* Callback that is called when the row sorting is complete. |
106 |
93 |
|
*/ |
107 |
|
- |
public class ColumnSorterCallback |
108 |
|
- |
{ |
|
94 |
+ |
public class ColumnSorterCallback { |
109 |
95 |
|
/** |
110 |
96 |
|
* An array of the tr elements that should be reselected. |
111 |
97 |
|
*/ |
|
@@ -114,8 +100,7 @@ |
114 |
100 |
|
/** |
115 |
101 |
|
* Construct a new {@link ColumnSorterCallback}. |
116 |
102 |
|
*/ |
117 |
|
- |
protected ColumnSorterCallback( Element[] selectedRows ) |
118 |
|
- |
{ |
|
103 |
+ |
protected ColumnSorterCallback( Element[] selectedRows ) { |
119 |
104 |
|
this.selectedRows = selectedRows; |
120 |
105 |
|
} |
121 |
106 |
|
|
|
@@ -127,13 +112,11 @@ |
127 |
112 |
|
* |
128 |
113 |
|
* @param trIndexes the row index in their new order |
129 |
114 |
|
*/ |
130 |
|
- |
public void onSortingComplete( int[] trIndexes ) |
131 |
|
- |
{ |
|
115 |
+ |
public void onSortingComplete( int[] trIndexes ) { |
132 |
116 |
|
// Convert indexes to row elements |
133 |
117 |
|
SelectionGridRowFormatter formatter = getSelectionGridRowFormatter(); |
134 |
118 |
|
Element[] trElems = new Element[trIndexes.length]; |
135 |
|
- |
for ( int i = 0; i < trElems.length; i++ ) |
136 |
|
- |
{ |
|
119 |
+ |
for ( int i = 0; i < trElems.length; i++ ) { |
137 |
120 |
|
trElems[i] = formatter.getRawElement( trIndexes[i] ); |
138 |
121 |
|
} |
139 |
122 |
|
|
|
@@ -149,8 +132,7 @@ |
149 |
132 |
|
* |
150 |
133 |
|
* @param trElems the row elements in their new order |
151 |
134 |
|
*/ |
152 |
|
- |
public void onSortingComplete( Element[] trElems ) |
153 |
|
- |
{ |
|
135 |
+ |
public void onSortingComplete( Element[] trElems ) { |
154 |
136 |
|
// Move the rows to their new positions |
155 |
137 |
|
applySort( trElems ); |
156 |
138 |
|
|
|
@@ -164,14 +146,11 @@ |
164 |
146 |
|
* Use this method if your {@link ColumnSorter} rearranges the columns |
165 |
147 |
|
* manually. |
166 |
148 |
|
*/ |
167 |
|
- |
public void onSortingComplete() |
168 |
|
- |
{ |
|
149 |
+ |
public void onSortingComplete() { |
169 |
150 |
|
// Reselect things that need reselecting |
170 |
|
- |
for ( int i = 0; i < selectedRows.length; i++ ) |
171 |
|
- |
{ |
|
151 |
+ |
for ( int i = 0; i < selectedRows.length; i++ ) { |
172 |
152 |
|
int rowIndex = getRowIndex( selectedRows[i] ); |
173 |
|
- |
if ( rowIndex >= 0 ) |
174 |
|
- |
{ |
|
153 |
+ |
if ( rowIndex >= 0 ) { |
175 |
154 |
|
selectRow( rowIndex, false ); |
176 |
155 |
|
} |
177 |
156 |
|
} |
|
@@ -193,8 +172,7 @@ |
193 |
172 |
|
/** |
194 |
173 |
|
* Constructor. |
195 |
174 |
|
*/ |
196 |
|
- |
public SortableGrid() |
197 |
|
- |
{ |
|
175 |
+ |
public SortableGrid() { |
198 |
176 |
|
super(); |
199 |
177 |
|
} |
200 |
178 |
|
|
|
@@ -206,31 +184,27 @@ |
206 |
184 |
|
* |
207 |
185 |
|
* @throws IndexOutOfBoundsException |
208 |
186 |
|
*/ |
209 |
|
- |
public SortableGrid( int rows, int columns ) |
210 |
|
- |
{ |
|
187 |
+ |
public SortableGrid( int rows, int columns ) { |
211 |
188 |
|
this(); |
212 |
189 |
|
resize( rows, columns ); |
213 |
190 |
|
} |
214 |
191 |
|
|
215 |
192 |
|
@Override |
216 |
|
- |
public HandlerRegistration addColumnSortHandler( ColumnSortHandler handler ) |
217 |
|
- |
{ |
|
193 |
+ |
public HandlerRegistration addColumnSortHandler( ColumnSortHandler handler ) { |
218 |
194 |
|
return addHandler( ColumnSortEvent.TYPE, handler ); |
219 |
195 |
|
} |
220 |
196 |
|
|
221 |
197 |
|
/** |
222 |
198 |
|
* @return the column sorter used to sort columns |
223 |
199 |
|
*/ |
224 |
|
- |
public ColumnSorter getColumnSorter() |
225 |
|
- |
{ |
|
200 |
+ |
public ColumnSorter getColumnSorter() { |
226 |
201 |
|
return getColumnSorter( false ); |
227 |
202 |
|
} |
228 |
203 |
|
|
229 |
204 |
|
/** |
230 |
205 |
|
* @return the {@link ColumnSortList} of previously sorted columns |
231 |
206 |
|
*/ |
232 |
|
- |
public ColumnSortList getColumnSortList() |
233 |
|
- |
{ |
|
207 |
+ |
public ColumnSortList getColumnSortList() { |
234 |
208 |
|
return columnSortList; |
235 |
209 |
|
} |
236 |
210 |
|
|
|
@@ -241,8 +215,7 @@ |
241 |
215 |
|
* |
242 |
216 |
|
* @throws IndexOutOfBoundsException |
243 |
217 |
|
*/ |
244 |
|
- |
public void moveRowDown( int row ) |
245 |
|
- |
{ |
|
218 |
+ |
public void moveRowDown( int row ) { |
246 |
219 |
|
swapRows( row, row + 1 ); |
247 |
220 |
|
} |
248 |
221 |
|
|
|
@@ -253,26 +226,22 @@ |
253 |
226 |
|
* |
254 |
227 |
|
* @throws IndexOutOfBoundsException |
255 |
228 |
|
*/ |
256 |
|
- |
public void moveRowUp( int row ) |
257 |
|
- |
{ |
|
229 |
+ |
public void moveRowUp( int row ) { |
258 |
230 |
|
swapRows( row, row - 1 ); |
259 |
231 |
|
} |
260 |
232 |
|
|
261 |
233 |
|
/** |
262 |
234 |
|
* Completely reverse the order of all rows in the table. |
263 |
235 |
|
*/ |
264 |
|
- |
public void reverseRows() |
265 |
|
- |
{ |
|
236 |
+ |
public void reverseRows() { |
266 |
237 |
|
int lastRow = numRows - 1; |
267 |
|
- |
for ( int i = 0; i < numRows / 2; i++ ) |
268 |
|
- |
{ |
|
238 |
+ |
for ( int i = 0; i < numRows / 2; i++ ) { |
269 |
239 |
|
swapRowsRaw( i, lastRow ); |
270 |
240 |
|
lastRow--; |
271 |
241 |
|
} |
272 |
242 |
|
|
273 |
243 |
|
// Set the column sorting as reversed |
274 |
|
- |
for ( ColumnSortInfo sortInfo : columnSortList ) |
275 |
|
- |
{ |
|
244 |
+ |
for ( ColumnSortInfo sortInfo : columnSortList ) { |
276 |
245 |
|
sortInfo.setAscending( !sortInfo.isAscending() ); |
277 |
246 |
|
} |
278 |
247 |
|
fireColumnSorted(); |
|
@@ -283,8 +252,7 @@ |
283 |
252 |
|
* |
284 |
253 |
|
* @param sorter the new {@link ColumnSorter} |
285 |
254 |
|
*/ |
286 |
|
- |
public void setColumnSorter( ColumnSorter sorter ) |
287 |
|
- |
{ |
|
255 |
+ |
public void setColumnSorter( ColumnSorter sorter ) { |
288 |
256 |
|
this.columnSorter = sorter; |
289 |
257 |
|
} |
290 |
258 |
|
|
|
@@ -293,8 +261,7 @@ |
293 |
261 |
|
* |
294 |
262 |
|
* @param columnSortList the new {@link ColumnSortList} |
295 |
263 |
|
*/ |
296 |
|
- |
public void setColumnSortList( ColumnSortList columnSortList ) |
297 |
|
- |
{ |
|
264 |
+ |
public void setColumnSortList( ColumnSortList columnSortList ) { |
298 |
265 |
|
setColumnSortList( columnSortList, true ); |
299 |
266 |
|
} |
300 |
267 |
|
|
|
@@ -304,12 +271,10 @@ |
304 |
271 |
|
* @param columnSortList the new {@link ColumnSortList} |
305 |
272 |
|
* @param fireEvents true to trigger the onSort event |
306 |
273 |
|
*/ |
307 |
|
- |
public void setColumnSortList( ColumnSortList columnSortList, boolean fireEvents ) |
308 |
|
- |
{ |
|
274 |
+ |
public void setColumnSortList( ColumnSortList columnSortList, boolean fireEvents ) { |
309 |
275 |
|
assert columnSortList != null : "columnSortList cannot be null"; |
310 |
276 |
|
this.columnSortList = columnSortList; |
311 |
|
- |
if ( fireEvents ) |
312 |
|
- |
{ |
|
277 |
+ |
if ( fireEvents ) { |
313 |
278 |
|
fireColumnSorted(); |
314 |
279 |
|
} |
315 |
280 |
|
} |
|
@@ -322,14 +287,10 @@ |
322 |
287 |
|
* |
323 |
288 |
|
* @throws IndexOutOfBoundsException |
324 |
289 |
|
*/ |
325 |
|
- |
public void sortColumn( int column ) |
326 |
|
- |
{ |
327 |
|
- |
if ( column == columnSortList.getPrimaryColumn() ) |
328 |
|
- |
{ |
|
290 |
+ |
public void sortColumn( int column ) { |
|
291 |
+ |
if ( column == columnSortList.getPrimaryColumn() ) { |
329 |
292 |
|
sortColumn( column, !columnSortList.isPrimaryAscending() ); |
330 |
|
- |
} |
331 |
|
- |
else |
332 |
|
- |
{ |
|
293 |
+ |
} else { |
333 |
294 |
|
sortColumn( column, true ); |
334 |
295 |
|
} |
335 |
296 |
|
} |
|
@@ -342,15 +303,11 @@ |
342 |
303 |
|
* |
343 |
304 |
|
* @throws IndexOutOfBoundsException |
344 |
305 |
|
*/ |
345 |
|
- |
public void sortColumn( int column, boolean ascending ) |
346 |
|
- |
{ |
|
306 |
+ |
public void sortColumn( int column, boolean ascending ) { |
347 |
307 |
|
// Verify the column bounds |
348 |
|
- |
if ( column < 0 ) |
349 |
|
- |
{ |
|
308 |
+ |
if ( column < 0 ) { |
350 |
309 |
|
throw new IndexOutOfBoundsException( "Cannot access a column with a negative index: " + column ); |
351 |
|
- |
} |
352 |
|
- |
else if ( column >= numColumns ) |
353 |
|
- |
{ |
|
310 |
+ |
} else if ( column >= numColumns ) { |
354 |
311 |
|
throw new IndexOutOfBoundsException( "Column index: " + column + ", Column size: " + numColumns ); |
355 |
312 |
|
} |
356 |
313 |
|
|
|
@@ -371,8 +328,7 @@ |
371 |
328 |
|
* |
372 |
329 |
|
* @throws IndexOutOfBoundsException |
373 |
330 |
|
*/ |
374 |
|
- |
public void swapRows( int row1, int row2 ) |
375 |
|
- |
{ |
|
331 |
+ |
public void swapRows( int row1, int row2 ) { |
376 |
332 |
|
checkRowBounds( row1 ); |
377 |
333 |
|
checkRowBounds( row2 ); |
378 |
334 |
|
swapRowsRaw( row1, row2 ); |
|
@@ -381,8 +337,7 @@ |
381 |
337 |
|
/** |
382 |
338 |
|
* Fire column sorted event to listeners. |
383 |
339 |
|
*/ |
384 |
|
- |
protected void fireColumnSorted() |
385 |
|
- |
{ |
|
340 |
+ |
protected void fireColumnSorted() { |
386 |
341 |
|
fireEvent( new ColumnSortEvent( columnSortList ) ); |
387 |
342 |
|
} |
388 |
343 |
|
|
|
@@ -394,10 +349,8 @@ |
394 |
349 |
|
* |
395 |
350 |
|
* @return the column sorter |
396 |
351 |
|
*/ |
397 |
|
- |
protected ColumnSorter getColumnSorter( boolean createAsNeeded ) |
398 |
|
- |
{ |
399 |
|
- |
if ( (columnSorter == null) && createAsNeeded ) |
400 |
|
- |
{ |
|
352 |
+ |
protected ColumnSorter getColumnSorter( boolean createAsNeeded ) { |
|
353 |
+ |
if ( (columnSorter == null) && createAsNeeded ) { |
401 |
354 |
|
columnSorter = new DefaultColumnSorter(); |
402 |
355 |
|
} |
403 |
356 |
|
return columnSorter; |
|
@@ -409,32 +362,24 @@ |
409 |
362 |
|
* @param row1 the first row to swap |
410 |
363 |
|
* @param row2 the second row to swap |
411 |
364 |
|
*/ |
412 |
|
- |
protected void swapRowsRaw( int row1, int row2 ) |
413 |
|
- |
{ |
|
365 |
+ |
protected void swapRowsRaw( int row1, int row2 ) { |
414 |
366 |
|
Element tbody = getBodyElement(); |
415 |
|
- |
if ( row1 == row2 + 1 ) |
416 |
|
- |
{ |
|
367 |
+ |
if ( row1 == row2 + 1 ) { |
417 |
368 |
|
// Just move row1 up one |
418 |
369 |
|
Element tr = getSelectionGridRowFormatter().getRawElement( row1 ); |
419 |
370 |
|
int index = OverrideDOM.getRowIndex( tr ); |
420 |
371 |
|
DOM.removeChild( tbody, tr ); |
421 |
372 |
|
DOM.insertChild( tbody, tr, index - 1 ); |
422 |
|
- |
} |
423 |
|
- |
else if ( row2 == row1 + 1 ) |
424 |
|
- |
{ |
|
373 |
+ |
} else if ( row2 == row1 + 1 ) { |
425 |
374 |
|
// Just move row2 up one |
426 |
375 |
|
Element tr = getSelectionGridRowFormatter().getRawElement( row2 ); |
427 |
376 |
|
int index = OverrideDOM.getRowIndex( tr ); |
428 |
377 |
|
DOM.removeChild( tbody, tr ); |
429 |
378 |
|
DOM.insertChild( tbody, tr, index - 1 ); |
430 |
|
- |
} |
431 |
|
- |
else if ( row1 == row2 ) |
432 |
|
- |
{ |
|
379 |
+ |
} else if ( row1 == row2 ) { |
433 |
380 |
|
// Do nothing if rows are the same |
434 |
381 |
|
return; |
435 |
|
- |
} |
436 |
|
- |
else |
437 |
|
- |
{ |
|
382 |
+ |
} else { |
438 |
383 |
|
// Remove both rows |
439 |
384 |
|
Element tr1 = getSelectionGridRowFormatter().getRawElement( row1 ); |
440 |
385 |
|
Element tr2 = getSelectionGridRowFormatter().getRawElement( row2 ); |
|
@@ -444,13 +389,10 @@ |
444 |
389 |
|
DOM.removeChild( tbody, tr2 ); |
445 |
390 |
|
|
446 |
391 |
|
// Reinsert them into the table |
447 |
|
- |
if ( row1 > row2 ) |
448 |
|
- |
{ |
|
392 |
+ |
if ( row1 > row2 ) { |
449 |
393 |
|
DOM.insertChild( tbody, tr1, index2 ); |
450 |
394 |
|
DOM.insertChild( tbody, tr2, index1 ); |
451 |
|
- |
} |
452 |
|
- |
else if ( row1 < row2 ) |
453 |
|
- |
{ |
|
395 |
+ |
} else if ( row1 < row2 ) { |
454 |
396 |
|
DOM.insertChild( tbody, tr2, index1 ); |
455 |
397 |
|
DOM.insertChild( tbody, tr1, index2 ); |
456 |
398 |
|
} |
|
@@ -460,12 +402,10 @@ |
460 |
402 |
|
Map<Integer, Element> selectedRows = getSelectedRowsMap(); |
461 |
403 |
|
Element tr1 = selectedRows.remove( new Integer( row1 ) ); |
462 |
404 |
|
Element tr2 = selectedRows.remove( new Integer( row2 ) ); |
463 |
|
- |
if ( tr1 != null ) |
464 |
|
- |
{ |
|
405 |
+ |
if ( tr1 != null ) { |
465 |
406 |
|
selectedRows.put( new Integer( row2 ), tr1 ); |
466 |
407 |
|
} |
467 |
|
- |
if ( tr2 != null ) |
468 |
|
- |
{ |
|
408 |
+ |
if ( tr2 != null ) { |
469 |
409 |
|
selectedRows.put( new Integer( row1 ), tr2 ); |
470 |
410 |
|
} |
471 |
411 |
|
} |
|
@@ -478,14 +418,11 @@ |
478 |
418 |
|
* |
479 |
419 |
|
* @param trElems the row elements in their new order |
480 |
420 |
|
*/ |
481 |
|
- |
void applySort( Element[] trElems ) |
482 |
|
- |
{ |
|
421 |
+ |
void applySort( Element[] trElems ) { |
483 |
422 |
|
// Move the rows to their new positions |
484 |
423 |
|
Element bodyElem = getBodyElement(); |
485 |
|
- |
for ( int i = trElems.length - 1; i >= 0; i-- ) |
486 |
|
- |
{ |
487 |
|
- |
if ( trElems[i] != null ) |
488 |
|
- |
{ |
|
424 |
+ |
for ( int i = trElems.length - 1; i >= 0; i-- ) { |
|
425 |
+ |
if ( trElems[i] != null ) { |
489 |
426 |
|
DOM.removeChild( bodyElem, trElems[i] ); |
490 |
427 |
|
DOM.insertChild( bodyElem, trElems[i], 0 ); |
491 |
428 |
|
} |