Mega Code Archive

 
Categories / Java Tutorial / Swing
 

Sorting JTable Elements

import java.awt.BorderLayout; import java.awt.Container; import java.awt.event.InputEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.Date; import java.util.Enumeration; import java.util.Vector; import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.UIDefaults; import javax.swing.UIManager; import javax.swing.event.TableModelEvent; import javax.swing.event.TableModelListener; import javax.swing.table.AbstractTableModel; import javax.swing.table.JTableHeader; import javax.swing.table.TableColumnModel; import javax.swing.table.TableModel; public class ListProperties {   static class CustomTableModel extends AbstractTableModel {     Vector keys = new Vector();     Vector values = new Vector();     private static final String columnNames[] = { "Property String", "Value" };     public int getColumnCount() {       return columnNames.length;     }     public String getColumnName(int column) {       return columnNames[column];     }     public int getRowCount() {       return keys.size();     }     public Object getValueAt(int row, int column) {       Object returnValue = null;       if (column == 0) {         returnValue = keys.elementAt(row);       } else if (column == 1) {         returnValue = values.elementAt(row);       }       return returnValue;     }     public synchronized void uiDefaultsUpdate(UIDefaults defaults) {       Enumeration newKeys = defaults.keys();       keys.removeAllElements();       while (newKeys.hasMoreElements()) {         keys.addElement(newKeys.nextElement());       }       Enumeration newValues = defaults.elements();       values.removeAllElements();       while (newValues.hasMoreElements()) {         values.addElement(newValues.nextElement());       }       fireTableDataChanged();     }   }   public static void main(String args[]) {     final JFrame frame = new JFrame("List Properties");     final CustomTableModel model = new CustomTableModel();     model.uiDefaultsUpdate(UIManager.getDefaults());     TableSorter sorter = new TableSorter(model);     JTable table = new JTable(sorter);     TableHeaderSorter.install(sorter, table);     table.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);     Container content = frame.getContentPane();     JScrollPane scrollPane = new JScrollPane(table);     content.add(scrollPane, BorderLayout.CENTER);     frame.setSize(400, 400);     frame.setVisible(true);   } } class TableSorter extends TableMap implements TableModelListener {   int indexes[] = new int[0];   Vector sortingColumns = new Vector();   boolean ascending = true;   public TableSorter() {   }   public TableSorter(TableModel model) {     setModel(model);   }   public void setModel(TableModel model) {     super.setModel(model);     reallocateIndexes();     sortByColumn(0);     fireTableDataChanged();   }   public int compareRowsByColumn(int row1, int row2, int column) {     Class type = model.getColumnClass(column);     TableModel data = model;     // Check for nulls     Object o1 = data.getValueAt(row1, column);     Object o2 = data.getValueAt(row2, column);     // If both values are null return 0     if (o1 == null && o2 == null) {       return 0;     } else if (o1 == null) { // Define null less than everything.       return -1;     } else if (o2 == null) {       return 1;     }     if (type.getSuperclass() == Number.class) {       Number n1 = (Number) data.getValueAt(row1, column);       double d1 = n1.doubleValue();       Number n2 = (Number) data.getValueAt(row2, column);       double d2 = n2.doubleValue();       if (d1 < d2)         return -1;       else if (d1 > d2)         return 1;       else         return 0;     } else if (type == String.class) {       String s1 = (String) data.getValueAt(row1, column);       String s2 = (String) data.getValueAt(row2, column);       int result = s1.compareTo(s2);       if (result < 0)         return -1;       else if (result > 0)         return 1;       else         return 0;     } else if (type == java.util.Date.class) {       Date d1 = (Date) data.getValueAt(row1, column);       long n1 = d1.getTime();       Date d2 = (Date) data.getValueAt(row2, column);       long n2 = d2.getTime();       if (n1 < n2)         return -1;       else if (n1 > n2)         return 1;       else         return 0;     } else if (type == Boolean.class) {       Boolean bool1 = (Boolean) data.getValueAt(row1, column);       boolean b1 = bool1.booleanValue();       Boolean bool2 = (Boolean) data.getValueAt(row2, column);       boolean b2 = bool2.booleanValue();       if (b1 == b2)         return 0;       else if (b1) // Define false < true         return 1;       else         return -1;     } else {       Object v1 = data.getValueAt(row1, column);       String s1 = v1.toString();       Object v2 = data.getValueAt(row2, column);       String s2 = v2.toString();       int result = s1.compareTo(s2);       if (result < 0)         return -1;       else if (result > 0)         return 1;       else         return 0;     }   }   public int compare(int row1, int row2) {     for (int level = 0, n = sortingColumns.size(); level < n; level++) {       Integer column = (Integer) sortingColumns.elementAt(level);       int result = compareRowsByColumn(row1, row2, column.intValue());       if (result != 0) {         return (ascending ? result : -result);       }     }     return 0;   }   public void reallocateIndexes() {     int rowCount = model.getRowCount();     indexes = new int[rowCount];     for (int row = 0; row < rowCount; row++) {       indexes[row] = row;     }   }   public void tableChanged(TableModelEvent tableModelEvent) {     super.tableChanged(tableModelEvent);     reallocateIndexes();     sortByColumn(0);     fireTableStructureChanged();   }   public void checkModel() {     if (indexes.length != model.getRowCount()) {       System.err.println("Sorter not informed of a change in model.");     }   }   public void sort() {     checkModel();     shuttlesort((int[]) indexes.clone(), indexes, 0, indexes.length);     fireTableDataChanged();   }   public void shuttlesort(int from[], int to[], int low, int high) {     if (high - low < 2) {       return;     }     int middle = (low + high) / 2;     shuttlesort(to, from, low, middle);     shuttlesort(to, from, middle, high);     int p = low;     int q = middle;     for (int i = low; i < high; i++) {       if (q >= high || (p < middle && compare(from[p], from[q]) <= 0)) {         to[i] = from[p++];       } else {         to[i] = from[q++];       }     }   }   private void swap(int first, int second) {     int temp = indexes[first];     indexes[first] = indexes[second];     indexes[second] = temp;   }   public Object getValueAt(int row, int column) {     checkModel();     return model.getValueAt(indexes[row], column);   }   public void setValueAt(Object aValue, int row, int column) {     checkModel();     model.setValueAt(aValue, indexes[row], column);   }   public void sortByColumn(int column) {     sortByColumn(column, true);   }   public void sortByColumn(int column, boolean ascending) {     this.ascending = ascending;     sortingColumns.removeAllElements();     sortingColumns.addElement(new Integer(column));     sort();     super.tableChanged(new TableModelEvent(this));   } } class TableHeaderSorter extends MouseAdapter {   private TableSorter sorter;   private JTable table;   private TableHeaderSorter() {   }   public static void install(TableSorter sorter, JTable table) {     TableHeaderSorter tableHeaderSorter = new TableHeaderSorter();     tableHeaderSorter.sorter = sorter;     tableHeaderSorter.table = table;     JTableHeader tableHeader = table.getTableHeader();     tableHeader.addMouseListener(tableHeaderSorter);   }   public void mouseClicked(MouseEvent mouseEvent) {     TableColumnModel columnModel = table.getColumnModel();     int viewColumn = columnModel.getColumnIndexAtX(mouseEvent.getX());     int column = table.convertColumnIndexToModel(viewColumn);     if (mouseEvent.getClickCount() == 1 && column != -1) {       System.out.println("Sorting ...");       int shiftPressed = (mouseEvent.getModifiers() & InputEvent.SHIFT_MASK);       boolean ascending = (shiftPressed == 0);       sorter.sortByColumn(column, ascending);     }   } } class TableMap extends AbstractTableModel implements TableModelListener {   TableModel model;   public TableModel getModel() {     return model;   }   public void setModel(TableModel model) {     if (this.model != null) {       this.model.removeTableModelListener(this);     }     this.model = model;     if (this.model != null) {       this.model.addTableModelListener(this);     }   }   public Class getColumnClass(int column) {     return model.getColumnClass(column);   }   public int getColumnCount() {     return ((model == null) ? 0 : model.getColumnCount());   }   public String getColumnName(int column) {     return model.getColumnName(column);   }   public int getRowCount() {     return ((model == null) ? 0 : model.getRowCount());   }   public Object getValueAt(int row, int column) {     return model.getValueAt(row, column);   }   public void setValueAt(Object value, int row, int column) {     model.setValueAt(value, row, column);   }   public boolean isCellEditable(int row, int column) {     return model.isCellEditable(row, column);   }   public void tableChanged(TableModelEvent tableModelEvent) {     fireTableChanged(tableModelEvent);   } }