1 package org.objectweb.jac.aspects.gui; 2 3 import java.util.Date ; 4 import java.util.HashMap ; 5 import java.util.Vector ; 6 import javax.swing.event.TableModelEvent ; 7 import javax.swing.event.TableModelListener ; 8 import javax.swing.table.AbstractTableModel ; 9 import org.apache.log4j.Logger; 10 import org.objectweb.jac.core.Collaboration; 11 import org.objectweb.jac.core.rtti.CollectionItem; 12 import org.objectweb.jac.core.rtti.MemberItem; 13 14 15 32 33 public class TableSorter extends TableMap { 34 static Logger logger = Logger.getLogger("gui.sort"); 35 36 int indexes[]; 37 38 Vector sortingColumns = new Vector (); 39 int compares; 40 41 public TableSorter() { 42 indexes = new int[0]; } 44 45 public TableSorter(ExtendedTableModel model) { 46 setModel(model); 47 } 48 49 53 public SortCriteria getSortCriteria(int column) { 54 for (int i=0; i<sortingColumns.size(); i++) { 55 if (((SortCriteria)sortingColumns.get(i)).column==column) { 56 return (SortCriteria)sortingColumns.get(i); 57 } 58 } 59 return null; 60 } 61 62 public void setModel(ExtendedTableModel model) { 63 super.setModel(model); 64 reallocateIndexes(); 65 defaultSortOrder(); 66 } 67 68 72 public void defaultSortOrder() { 73 HashMap map = (HashMap )Collaboration.get().getAttribute(GuiAC.SORT_COLUMN); 75 if (map != null) { 76 SortCriteria criteria = (SortCriteria)map.get(getCollection()); 77 if (criteria != null) { 78 logger.debug("Using sort criteria from context: "+criteria); 79 sortByColumn(criteria.column,criteria.ascending); 80 return; 81 } 82 } 83 84 String column = GuiAC.getDefaultSortedColumn(getCollection()); 86 if (column!=null) { 87 logger.debug("Using default sort order : "+column); 88 boolean ascending = true; 89 if (column.startsWith("-")) { 90 ascending = false; 91 column = column.substring(1); 92 } else if (column.startsWith("+")) { 93 ascending = true; 94 column = column.substring(1); 95 } 96 MemberItem[] members = getMembers(); 98 for (int i=0; i<members.length; i++) { 99 if (members[i].getName().equals(column)) { 100 sortByColumn(i,ascending); 101 return; 102 } 103 } 104 } 105 } 106 107 public int compareRowsByColumn(int row1, int row2, int column) { 108 Class type = model.getColumnClass(column); 109 ExtendedTableModel data = model; 110 111 113 Object o1 = data.getValueAt(row1, column); 114 Object o2 = data.getValueAt(row2, column); 115 116 if (o1 == null && o2 == null) { 118 return 0; 119 } else if (o1 == null) { return -1; 121 } else if (o2 == null) { 122 return 1; 123 } 124 125 133 134 if (type.getSuperclass() == java.lang.Number .class) { 135 double d1 = ((Number )o1).doubleValue(); 136 double d2 = ((Number )o2).doubleValue(); 137 138 if (d1 < d2) { 139 return -1; 140 } else if (d1 > d2) { 141 return 1; 142 } else { 143 return 0; 144 } 145 } else if (type == java.util.Date .class) { 146 long n1 = ((Date )o1).getTime(); 147 long n2 = ((Date )o2).getTime(); 148 149 if (n1 < n2) { 150 return -1; 151 } else if (n1 > n2) { 152 return 1; 153 } else { 154 return 0; 155 } 156 } else if (type == String .class) { 157 return ((String )o1).compareToIgnoreCase((String )o2); 158 } else if (type == Boolean .class) { 159 boolean b1 = ((Boolean )o1).booleanValue(); 160 boolean b2 = ((Boolean )o2).booleanValue(); 161 162 if (b1 == b2) { 163 return 0; 164 } else if (b1) { return 1; 166 } else { 167 return -1; 168 } 169 } else { 170 return GuiAC.toString(data.getValueAt(row1, column)). 171 compareToIgnoreCase(GuiAC.toString(data.getValueAt(row2, column))); 172 } 173 } 174 175 public int compare(int row1, int row2) { 176 compares++; 177 for (int level=0; level<sortingColumns.size(); level++) { 178 SortCriteria criteria = (SortCriteria)sortingColumns.get(level); 179 int result = compareRowsByColumn(row1, row2, criteria.column); 180 if (result != 0) { 181 return criteria.ascending ? result : -result; 182 } 183 } 184 return 0; 185 } 186 187 190 public void reallocateIndexes() { 191 int rowCount = model.getRowCount(); 192 193 logger.debug(this+".reallocateIndexes "+rowCount); 194 195 indexes = new int[rowCount]; 198 199 for (int row = 0; row < rowCount; row++) { 201 indexes[row] = row; 202 } 203 } 204 205 public int getActualIndex(int row) { 206 return indexes[row]; 207 } 208 209 public void tableChanged(TableModelEvent e) { 210 if (e.getType()==TableModelEvent.INSERT || 211 e.getType()==TableModelEvent.DELETE) { 212 logger.debug(this+".tableChanged "+ 213 (e.getType()==TableModelEvent.DELETE?"DELETE":"INSERT")+ 214 " "+e.getFirstRow()+"-"+e.getLastRow()); 215 reallocateIndexes(); 216 sort(this); 217 super.tableChanged(e); 218 } else { 219 logger.debug(this+".tableChanged UPDATE "+ 220 e.getFirstRow()+"-"+e.getLastRow()); 221 reallocateIndexes(); 222 sort(this); 223 super.tableChanged(e); 224 } 225 } 226 227 public void checkModel() { 228 if (indexes.length != model.getRowCount()) { 229 logger.warn(this+" not informed of a change in model for collection "+ 230 getCollection().getName()+": "+indexes.length+"!="+model.getRowCount()); 231 } 232 } 233 234 public void sort(Object sender) { 235 if (sortingColumns.size()>0) { 236 logger.debug("sorting "+getCollection()+" by "+sortingColumns); 237 checkModel(); 238 239 compares = 0; 240 shuttlesort((int[])indexes.clone(), indexes, 0, indexes.length); 243 } else { 245 reallocateIndexes(); 246 } 247 } 248 249 public void n2sort() { 250 for (int i=0; i<getRowCount(); i++) { 251 for (int j=i+1; j<getRowCount(); j++) { 252 if (compare(indexes[i], indexes[j]) < 0) { 253 swap(i, j); 254 } 255 } 256 } 257 } 258 259 public void shuttlesort(int from[], int to[], int low, int high) { 267 if (high - low < 2) { 268 return; 269 } 270 int middle = (low + high)/2; 271 shuttlesort(to, from, low, middle); 272 shuttlesort(to, from, middle, high); 273 274 int p = low; 275 int q = middle; 276 277 291 292 if (high - low >= 4 && compare(from[middle-1], from[middle]) <= 0) { 293 for (int i = low; i < high; i++) { 294 to[i] = from[i]; 295 } 296 return; 297 } 298 299 301 for (int i = low; i < high; i++) { 302 if (q >= high || (p < middle && compare(from[p], from[q]) <= 0)) { 303 to[i] = from[p++]; 304 } 305 else { 306 to[i] = from[q++]; 307 } 308 } 309 } 310 311 public void swap(int i, int j) { 312 int tmp = indexes[i]; 313 indexes[i] = indexes[j]; 314 indexes[j] = tmp; 315 } 316 317 320 public Object getValueAt(int aRow, int aColumn) { 321 checkModel(); 322 if(indexes.length>aRow) { 323 logger.debug("getValueAt("+aRow+","+aColumn+") -> "+ 324 model.getValueAt(indexes[aRow], aColumn)); 325 return model.getValueAt(indexes[aRow], aColumn); 326 } else { 327 return null; 328 } 329 } 330 331 public Object getObject(int row) { 332 checkModel(); 333 return model.getObject(indexes[row]); 334 } 335 336 public int indexOf(Object object) { 337 checkModel(); 338 return indexes[model.indexOf(object)]; 339 } 340 341 public Object getObject(int row, int column) { 342 checkModel(); 343 return model.getObject(indexes[row],column); 344 } 345 346 public void setValueAt(Object aValue, int aRow, int aColumn) { 347 checkModel(); 348 model.setValueAt(aValue, indexes[aRow], aColumn); 349 } 350 351 355 public void sortByColumn(int column) { 356 sortByColumn(column, true); 357 } 358 359 364 public void toggleSortByColumn(int column) { 365 SortCriteria criteria = getSortCriteria(column); 366 SortCriteria savedCriteria; 367 if (criteria!=null) { 368 criteria.toggleAscending(); 369 savedCriteria = new SortCriteria(column,criteria.isAscending()); 370 } else { 371 sortingColumns.clear(); 372 sortingColumns.add(new SortCriteria(column,true)); 373 savedCriteria = new SortCriteria(column,true); 374 } 375 sort(this); 376 saveSortCriteria(savedCriteria); 377 super.tableChanged(new TableModelEvent (this)); 378 } 379 380 public void sortByColumn(int column, boolean ascending) { 381 logger.debug("sortByColumn "+column+ 382 "("+(ascending?"":"-")+(column>=0?getHeaders()[column]:"none")+")"); 383 sortingColumns.clear(); 384 385 if (column>=0) { 386 sortingColumns.add(new SortCriteria(column,ascending)); 387 } 388 sort(this); 389 390 saveSortCriteria(column>=0?new SortCriteria(column,ascending):null); 391 392 super.tableChanged(new TableModelEvent (this)); 393 } 394 395 399 protected void saveSortCriteria(SortCriteria criteria) { 400 HashMap map = (HashMap )Collaboration.get().getAttribute(GuiAC.SORT_COLUMN); 402 if (map == null) { 403 map = new HashMap (); 404 Collaboration.get().addAttribute(GuiAC.SORT_COLUMN, map); 405 } 406 map.put(getCollection(), criteria); 407 } 408 } 409 | Popular Tags |