import java.awt.event.*;
import java.util.*;

import javax.swing.*;
import javax.swing.table.*;

/**
 * @author Remi Forax
 *
 */
public class SortTableExample {

  static public class SortedTableModel extends AbstractTableModel {
    public SortedTableModel(TableModel model) {
      this.model=model;
      
      Integer[] table=new Integer[model.getRowCount()];
      for(int i=0;i<table.length;i++)
        table[i]=new Integer(i);
      this.table=table;
    }
    
    public int getColumnCount() {
      return model.getColumnCount();
    }

    public int getRowCount() {
      return model.getRowCount();
    }

    public Object getValueAt(int row, int column) {
      return model.getValueAt(getSortedRow(row),column);
    }

    public Class getColumnClass(int column) {
      return model.getColumnClass(column);
    }

    public String getColumnName(int column) {
      return model.getColumnName(column);
    }

    public boolean isCellEditable(int row, int column) {
      return model.isCellEditable(getSortedRow(row), column);
    }

    public void setValueAt(Object aValue, int row, int column) {
      model.setValueAt(aValue,getSortedRow(row),column);
    }

    private int getSortedRow(int row) {
      return table[row].intValue();
    }
    
    public void sort(final int column) {
      Arrays.sort(table,new Comparator() {
        public int compare(Object o1, Object o2) {
          int i1=((Integer)o1).intValue();
          int i2=((Integer)o2).intValue();
        
          Comparable c1=(Comparable)model.getValueAt(i1,column);
          Comparable c2=(Comparable)model.getValueAt(i2,column);
          
          return c1.compareTo(c2);
        }
      });
      
      fireTableDataChanged();
    }
    
    private final Integer[] table;
    final TableModel model;
  }

  public static void main(String[] args) {
    TableModel model=new AbstractTableModel() {
      public int getColumnCount() {
        return 3;
      }
      public int getRowCount() {
        return 50;
      }
      public Object getValueAt(int row, int column) {
        Random random=new Random(row);
        int v1=random.nextInt(100);
        int v2=random.nextInt(100);
        return new Integer(new int[] {v1,v2,v1+v2}[column]);
      }
    };
    
    final SortedTableModel sortedModel=new SortedTableModel(model);
    final JTable table=new JTable(sortedModel);
    table.getTableHeader().addMouseListener(new MouseAdapter() {
      public void mouseClicked(MouseEvent event) {
        if (event.getClickCount()<2)
          return;
        int tableColumn = table.columnAtPoint(event.getPoint());
        int modelColumn = table.convertColumnIndexToModel(tableColumn);
        sortedModel.sort(modelColumn);
      }
    });
    
    JFrame frame=new JFrame("SortTableExample");
    frame.setContentPane(new JScrollPane(table));
    frame.pack();
    frame.show();
  }
}
