| 1 20 21 22 package edu.umd.cs.findbugs.gui; 23 24 import java.awt.Component ; 25 import java.awt.event.MouseAdapter ; 26 import java.awt.event.MouseEvent ; 27 import java.util.ArrayList ; 28 import java.util.Collections ; 29 import java.util.Comparator ; 30 import java.util.List ; 31 32 import javax.swing.ImageIcon ; 33 import javax.swing.JLabel ; 34 import javax.swing.JTable ; 35 import javax.swing.SwingConstants ; 36 import javax.swing.event.TableModelEvent ; 37 import javax.swing.event.TableModelListener ; 38 import javax.swing.table.AbstractTableModel ; 39 import javax.swing.table.DefaultTableCellRenderer ; 40 import javax.swing.table.JTableHeader ; 41 import javax.swing.table.TableCellRenderer ; 42 import javax.swing.table.TableModel ; 43 44 48 public class DefaultSortedTableModel extends AbstractTableModel  49 { 50 53 private static final long serialVersionUID = 1L; 54 public static final int SORT_NO_ORDER = 0; 55 public static final int SORT_ASCENDING_ORDER = 1; 56 public static final int SORT_DESCENDING_ORDER = 2; 57 public static final int NUM_SORT_DIREECTIONS = 3; 58 59 private AbstractTableModel baseModel; 60 private List <Integer > viewToModelMapping; 61 private int sortDirection = SORT_ASCENDING_ORDER; 62 private int sortColumn = 0; 63 private ImageIcon upIcon, downIcon; 64 65 66 public DefaultSortedTableModel( AbstractTableModel model, JTableHeader header ) { 67 baseModel = model; 68 model.addTableModelListener(new BaseTableModelListener()); 69 70 final JTableHeader baseHeader = header; 71 baseHeader.addMouseListener(new HeaderListener()); 72 final TableCellRenderer baseRenderer = baseHeader.getDefaultRenderer(); 73 baseHeader.setDefaultRenderer( new DefaultTableCellRenderer () { 74 @Override  75 public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { 76 JLabel label = (JLabel )baseRenderer.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); 77 if (baseHeader.getTable().convertColumnIndexToModel(column) == sortColumn) { 78 if (sortDirection != SORT_NO_ORDER) { 79 label.setHorizontalTextPosition(SwingConstants.LEFT); 80 label.setIcon( sortDirection == SORT_ASCENDING_ORDER ? downIcon : upIcon ); 81 } else { 82 label.setIcon(null); 83 } 84 } else { 85 label.setIcon(null); 86 } 87 return label; 88 } 89 }); 90 91 setupMapping(); 92 ClassLoader classLoader = this.getClass().getClassLoader(); 93 upIcon = new ImageIcon (classLoader.getResource("edu/umd/cs/findbugs/gui/up.png")); 94 downIcon = new ImageIcon (classLoader.getResource("edu/umd/cs/findbugs/gui/down.png")); 95 } 96 97 99 public TableModel getBaseTableModel() { 100 return baseModel; 101 } 102 103 public int getBaseModelIndex( int viewIndex ) { 104 return viewToModelMapping.get(viewIndex).intValue(); 105 } 106 107 109 @Override  110 public void fireTableCellUpdated( int row, int col ) { 111 if (baseModel != null) 112 setupMapping(); 113 super.fireTableCellUpdated(row, col); 114 } 115 116 @Override  117 public void fireTableChanged( TableModelEvent e ) { 118 if (baseModel != null) 119 setupMapping(); 120 super.fireTableChanged(e); 121 } 122 123 @Override  124 public void fireTableDataChanged() { 125 if (baseModel != null) 126 setupMapping(); 127 super.fireTableDataChanged(); 128 } 129 130 @Override  131 public void fireTableRowsDeleted( int first, int last ) { 132 if (baseModel != null) 133 setupMapping(); 134 super.fireTableRowsDeleted(first,last); 135 } 136 137 @Override  138 public void fireTableRowsInserted( int first, int last ) { 139 if (baseModel != null) 140 setupMapping(); 141 super.fireTableRowsInserted(first, last); 142 } 143 144 @Override  145 public void fireTableRowsUpdated( int first, int last ) { 146 if (baseModel != null) 147 setupMapping(); 148 super.fireTableRowsUpdated(first, last); 149 } 150 151 @Override  152 public void fireTableStructureChanged() { 153 if (baseModel != null) 154 setupMapping(); 155 super.fireTableStructureChanged(); 156 } 157 158 160 @Override  161 public int findColumn( String columnName ) { 162 if (baseModel == null) 163 return -1; 164 165 return baseModel.findColumn(columnName); 166 } 167 168 public int getColumnCount() { 169 if (baseModel == null) 170 return 0; 171 172 return baseModel.getColumnCount(); 173 } 174 175 public int getRowCount() { 176 if (baseModel == null) 177 return 0; 178 179 return baseModel.getRowCount(); 180 } 181 182 @Override  183 public Class <?> getColumnClass( int column ) { 184 if (baseModel == null) 185 return null; 186 187 return baseModel.getColumnClass(column); 188 } 189 190 @Override  191 public String getColumnName( int column ) { 192 if (baseModel == null) 193 return null; 194 195 return baseModel.getColumnName(column); 196 } 197 198 @Override  199 public boolean isCellEditable( int row, int col ) { 200 if (baseModel == null) 201 return false; 202 203 return baseModel.isCellEditable( row, col ); 204 } 205 206 public Object getValueAt( int row, int col ) { 207 if (baseModel == null) 208 return null; 209 210 return baseModel.getValueAt(viewToModelMapping.get(row).intValue(), col); 211 } 212 213 @Override  214 public void setValueAt( Object value, int row, int col ) { 215 if (baseModel == null) 216 return; 217 218 baseModel.setValueAt( value, viewToModelMapping.get(row).intValue(), col ); 219 fireTableDataChanged(); 220 } 221 222 private void setupMapping() { 223 int numRows = baseModel.getRowCount(); 224 viewToModelMapping = new ArrayList <Integer >(numRows); 225 for (int i = 0; i < numRows; i++) 226 viewToModelMapping.add((Integer )(i)); 227 228 Collections.sort( viewToModelMapping, new Comparator <Integer >() { 229 @SuppressWarnings ("unchecked") 230 public int compare( Integer a, Integer b ) { 231 if ((sortDirection == SORT_NO_ORDER) || (sortColumn == -1)) 232 return a.compareTo(b); 233 234 Comparable <Object > first = (Comparable <Object >)baseModel.getValueAt( a.intValue(), sortColumn ); 235 Comparable <Object > second = (Comparable <Object >)baseModel.getValueAt( b.intValue(), sortColumn ); 236 237 if (sortDirection == SORT_ASCENDING_ORDER) 238 return first.compareTo(second); 239 else 240 return second.compareTo(first); 241 } 242 }); 243 244 } 245 246 private class BaseTableModelListener implements TableModelListener  247 { 248 public void tableChanged( TableModelEvent e ) { 249 DefaultSortedTableModel.this.fireTableChanged(e); 250 } 251 } 252 253 private class HeaderListener extends MouseAdapter  254 { 255 @Override  256 public void mouseClicked(MouseEvent e) { 257 JTableHeader header = (JTableHeader )e.getSource(); 258 int column = header.columnAtPoint(e.getPoint()); 259 column = header.getTable().convertColumnIndexToModel(column); 260 if (column != sortColumn) { 261 sortColumn = column; 262 sortDirection = SORT_ASCENDING_ORDER; 263 } else { 264 sortDirection = (sortDirection + 1) % NUM_SORT_DIREECTIONS; 265 } 266 super.mouseClicked(e); 267 DefaultSortedTableModel.this.fireTableDataChanged(); 268 } 269 } 270 } | Popular Tags |