JTable的排序问题!   点击table各个列头, 然后table中的数据就会按所点列排序
 (用jdk1.5,不用jdk1.6)

解决方案 »

  1.   

    首先我们定义一个排序类,继承自AbstractTableModel。TableSorter 类可以自己自动处理每件事,根据按下的鼠标按钮,按照升序或降序顺序对数据进行排序,还会用箭头指示排序的方向。
    public class TableSorter extends AbstractTableModel {
        protected TableModel tableModel;    public static final int DESCENDING = -1;
        public static final int NOT_SORTED = 0;
        public static final int ASCENDING = 1;    private static Directive EMPTY_DIRECTIVE = new Directive(-1, NOT_SORTED);    public static final Comparator COMPARABLE_COMAPRATOR = new Comparator() {
            public int compare(Object o1, Object o2) {
                return ((Comparable) o1).compareTo(o2);
            }
        };
        public static final Comparator LEXICAL_COMPARATOR = new Comparator() {
            public int compare(Object o1, Object o2) {
                return o1.toString().compareTo(o2.toString());
            }
        };    private Row[] viewToModel;
        private int[] modelToView;    private JTableHeader tableHeader;
        private MouseListener mouseListener;
        private TableModelListener tableModelListener;
        private Map columnComparators = new HashMap();
        private List sortingColumns = new ArrayList();    public TableSorter() {
            this.mouseListener = new MouseHandler();
            this.tableModelListener = new TableModelHandler();
        }    public TableSorter(TableModel tableModel) {
            this();
            setTableModel(tableModel);
        }    public TableSorter(TableModel tableModel, JTableHeader tableHeader) {
            this();
            setTableHeader(tableHeader);
            setTableModel(tableModel);
        }    private void clearSortingState() {
            viewToModel = null;
            modelToView = null;
        }    public TableModel getTableModel() {
            return tableModel;
        }    public void setTableModel(TableModel tableModel) {
            if (this.tableModel != null) {
                this.tableModel.removeTableModelListener(tableModelListener);
            }        this.tableModel = tableModel;
            if (this.tableModel != null) {
                this.tableModel.addTableModelListener(tableModelListener);
            }        clearSortingState();
            fireTableStructureChanged();
        }    public JTableHeader getTableHeader() {
            return tableHeader;
        }    public void setTableHeader(JTableHeader tableHeader) {
            if (this.tableHeader != null) {
                this.tableHeader.removeMouseListener(mouseListener);
                TableCellRenderer defaultRenderer = this.tableHeader.getDefaultRenderer();
                if (defaultRenderer instanceof SortableHeaderRenderer) {
                    this.tableHeader.setDefaultRenderer(((SortableHeaderRenderer) defaultRenderer).tableCellRenderer);
                }
            }
            this.tableHeader = tableHeader;
            if (this.tableHeader != null) {
                this.tableHeader.addMouseListener(mouseListener);
                this.tableHeader.setDefaultRenderer(
                        new SortableHeaderRenderer(this.tableHeader.getDefaultRenderer()));
            }
        }    public boolean isSorting() {
            return sortingColumns.size() != 0;
        }    private Directive getDirective(int column) {
            for (int i = 0; i < sortingColumns.size(); i++) {
                Directive directive = (Directive)sortingColumns.get(i);
                if (directive.column == column) {
                    return directive;
                }
            }
            return EMPTY_DIRECTIVE;
        }    public int getSortingStatus(int column) {
            return getDirective(column).direction;
        }    private void sortingStatusChanged() {
            clearSortingState();
            fireTableDataChanged();
            if (tableHeader != null) {
                tableHeader.repaint();
            }
        }    public void setSortingStatus(int column, int status) {
            Directive directive = getDirective(column);
            if (directive != EMPTY_DIRECTIVE) {
                sortingColumns.remove(directive);
            }
            if (status != NOT_SORTED) {
                sortingColumns.add(new Directive(column, status));
            }
            sortingStatusChanged();
        }    protected Icon getHeaderRendererIcon(int column, int size) {
            Directive directive = getDirective(column);
            if (directive == EMPTY_DIRECTIVE) {
                return null;
            }
            return new Arrow(directive.direction == DESCENDING, size, sortingColumns.indexOf(directive));
        }    private void cancelSorting() {
            sortingColumns.clear();
            sortingStatusChanged();
        }    public void setColumnComparator(Class type, Comparator comparator) {
            if (comparator == null) {
                columnComparators.remove(type);
            } else {
                columnComparators.put(type, comparator);
            }
        }    protected Comparator getComparator(int column) {
            Class columnType = tableModel.getColumnClass(column);
            Comparator comparator = (Comparator) columnComparators.get(columnType);
            if (comparator != null) {
                return comparator;
            }
            if (Comparable.class.isAssignableFrom(columnType)) {
                return COMPARABLE_COMAPRATOR;
            }
            return LEXICAL_COMPARATOR;
        }    private Row[] getViewToModel() {
            if (viewToModel == null) {
                int tableModelRowCount = tableModel.getRowCount();
                viewToModel = new Row[tableModelRowCount];
                for (int row = 0; row < tableModelRowCount; row++) {
                    viewToModel[row] = new Row(row);
                }            if (isSorting()) {
                    Arrays.sort(viewToModel);
                }
            }
            return viewToModel;
        }    public int modelIndex(int viewIndex) {
            return getViewToModel()[viewIndex].modelIndex;
        }    private int[] getModelToView() {
            if (modelToView == null) {
                int n = getViewToModel().length;
                modelToView = new int[n];
                for (int i = 0; i < n; i++) {
                    modelToView[modelIndex(i)] = i;
                }
            }
            return modelToView;
        }
        public int getRowCount() {
            return (tableModel == null) ? 0 : tableModel.getRowCount();
        }    public int getColumnCount() {
            return (tableModel == null) ? 0 : tableModel.getColumnCount();
        }    public String getColumnName(int column) {
            return tableModel.getColumnName(column);
        }    public Class getColumnClass(int column) {
            return tableModel.getColumnClass(column);
        }    public boolean isCellEditable(int row, int column) {
            return tableModel.isCellEditable(modelIndex(row), column);
        }    public Object getValueAt(int row, int column) {
            return tableModel.getValueAt(modelIndex(row), column);
        }    public void setValueAt(Object aValue, int row, int column) {
            tableModel.setValueAt(aValue, modelIndex(row), column);
        }
      

  2.   

    由于内容限制,接上面:private class Row implements Comparable {
            private int modelIndex;        public Row(int index) {
                this.modelIndex = index;
            }        public int compareTo(Object o) {
                int row1 = modelIndex;
                int row2 = ((Row) o).modelIndex;            for (Iterator it = sortingColumns.iterator(); it.hasNext();) {
                    Directive directive = (Directive) it.next();
                    int column = directive.column;
                    Object o1 = tableModel.getValueAt(row1, column);
                    Object o2 = tableModel.getValueAt(row2, column);                int comparison = 0;                if (o1 == null && o2 == null) {
                        comparison = 0;
                    } else if (o1 == null) {
                        comparison = -1;
                    } else if (o2 == null) {
                        comparison = 1;
                    } else {
                        comparison = getComparator(column).compare(o1, o2);
                    }
                    if (comparison != 0) {
                        return directive.direction == DESCENDING ? -comparison : comparison;
                    }
                }
                return 0;
            }
        }    private class TableModelHandler implements TableModelListener {
            public void tableChanged(TableModelEvent e) {
               
                if (!isSorting()) {
                    clearSortingState();
                    fireTableChanged(e);
                    return;
                }
                    
                if (e.getFirstRow() == TableModelEvent.HEADER_ROW) {
                    cancelSorting();
                    fireTableChanged(e);
                    return;
                }
                int column = e.getColumn();
                if (e.getFirstRow() == e.getLastRow()
                        && column != TableModelEvent.ALL_COLUMNS
                        && getSortingStatus(column) == NOT_SORTED
                        && modelToView != null) {
                    int viewIndex = getModelToView()[e.getFirstRow()];
                    fireTableChanged(new TableModelEvent(TableSorter.this, 
                                                         viewIndex, viewIndex, 
                                                         column, e.getType()));
                    return;
                }            clearSortingState();
                fireTableDataChanged();
                return;
            }
        }    private class MouseHandler extends MouseAdapter {
            public void mouseClicked(MouseEvent e) {
                JTableHeader h = (JTableHeader) e.getSource();
                TableColumnModel columnModel = h.getColumnModel();
                int viewColumn = columnModel.getColumnIndexAtX(e.getX());
                int column = columnModel.getColumn(viewColumn).getModelIndex();
                if (column != -1) {
                    int status = getSortingStatus(column);
                    if (!e.isControlDown()) {
                        cancelSorting();
                    }
                    status = status + (e.isShiftDown() ? -1 : 1);
                    status = (status + 4) % 3 - 1; 
                    setSortingStatus(column, status);
                }
            }
        }    private static class Arrow implements Icon {
            private boolean descending;
            private int size;
            private int priority;        public Arrow(boolean descending, int size, int priority) {
                this.descending = descending;
                this.size = size;
                this.priority = priority;
            }        public void paintIcon(Component c, Graphics g, int x, int y) {
                Color color = c == null ? Color.GRAY : c.getBackground();                         int dx = (int)(size/2*Math.pow(0.8, priority));
                int dy = descending ? dx : -dx;            y = y + 5*size/6 + (descending ? -dy : 0);
                int shift = descending ? 1 : -1;
                g.translate(x, y);            g.setColor(color.darker());
                g.drawLine(dx / 2, dy, 0, 0);
                g.drawLine(dx / 2, dy + shift, 0, shift);
                
                g.setColor(color.brighter());
                g.drawLine(dx / 2, dy, dx, 0);
                g.drawLine(dx / 2, dy + shift, dx, shift);
                
                if (descending) {
                    g.setColor(color.darker().darker());
                } else {
                    g.setColor(color.brighter().brighter());
                }
                g.drawLine(dx, 0, 0, 0);            g.setColor(color);
                g.translate(-x, -y);
            }        public int getIconWidth() {
                return size;
            }        public int getIconHeight() {
                return size;
            }
        }    private class SortableHeaderRenderer implements TableCellRenderer {
            private TableCellRenderer tableCellRenderer;        public SortableHeaderRenderer(TableCellRenderer tableCellRenderer) {
                this.tableCellRenderer = tableCellRenderer;
            }        public Component getTableCellRendererComponent(JTable table, 
                                                           Object value,
                                                           boolean isSelected, 
                                                           boolean hasFocus,
                                                           int row, 
                                                           int column) {
                Component c = tableCellRenderer.getTableCellRendererComponent(table, 
                        value, isSelected, hasFocus, row, column);
                if (c instanceof JLabel) {
                    JLabel l = (JLabel) c;
                    l.setHorizontalTextPosition(JLabel.LEFT);
                    int modelColumn = table.convertColumnIndexToModel(column);
                    l.setIcon(getHeaderRendererIcon(modelColumn, l.getFont().getSize()));
                }
                return c;
            }
        }    private static class Directive {
            private int column;
            private int direction;        public Directive(int column, int direction) {
                this.column = column;
                this.direction = direction;
            }
        }
    }
      

  3.   

    最后这样使用:JTable table = new JTable();
    TableSorter sorter = new TableSorter(table.getModel, table.getTableHeader());
    table.setModel(sorter);
      

  4.   

    上面的应用方法不行 table.getModel 这错我这样用也不行 
    TableSorter sorter = new TableSorter(new MyTableModel()); //这错。。JTable table = new JTable(sorter); 
    sorter.setTableHeader(table.getTableHeader()); 
      

  5.   

    这是我的 实现类
    import javax.swing.event.ListSelectionListener;
    import javax.swing.table.AbstractTableModel;
    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.*;public class ColumnModelTest{
         
        public ColumnModelTest() {
        
        JFrame f = new JFrame();
      
       
            
            f.addWindowListener(new WindowAdapter() {
                public void windowClosing(WindowEvent e) {
                    System.exit(0);
                }
            });
        }    public static void main(String args[]) {
         JFrame f = new JFrame();
          MyTableModel tm=new MyTableModel();
          TableSorter sorter = new TableSorter(tm); 
           
            JTable table = new JTable(sorter);       
           sorter.setTableHeader(table.getTableHeader()); 
         table.setPreferredScrollableViewportSize(new Dimension(550, 100));
          JScrollPane s = new JScrollPane(table);
          f.getContentPane().add(s, BorderLayout.CENTER);
          f.setTitle("ColumnModelTest");
             f.pack();
             f.setVisible(true);
             
               
        
        }
          
    }
    还有 一个
    import javax.swing.event.TableModelListener;
    import javax.swing.table.TableModel;class MyTableModel implements TableModel{     
    Object[][] p = {
                {new Boolean(false), "人事部","12311","无名", "男", "19920103","本科","物理"},
                {new Boolean(false), "人事部","12312","无名", "男", "19920103","本科","物理"},
                {new Boolean(false), "人事部","12313","无名", "男", "19920103","本科","物理"},
                {new Boolean(false), "人事部","12314","无名", "男", "19920103","本科","物理"}};
    String[] n = {"选择","部门","教师编码","姓名","性别","生日","最终学历","研究领域"};
     
            public int getColumnCount() {
                return n.length;
            }        public int getRowCount() {
                return p.length;
            }        public String getColumnName(int col) {
                return n[col];
            }        public Object getValueAt(int row, int col) {
                return p[row][col];
            }
        public Class getColumnClass(int c) {
             return getValueAt(0, c).getClass();
         }
        public boolean isCellEditable(int rowIndex, int columnIndex) {
        return true;
         }
        public void setValueAt(Object value, int row, int col) {
             p[row][col] = value;
        fireTableCellUpdated(row, col);
         }
        private void fireTableCellUpdated(int row, int col) {
    // TODO Auto-generated method stub

    } public void addTableModelListener(TableModelListener l){
        
        }
        public void removeTableModelListener(TableModelListener l){
        
        }
    }   
      

  6.   

    这是我的 实现类
    import javax.swing.event.ListSelectionListener;
    import javax.swing.table.AbstractTableModel;
    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.*;public class ColumnModelTest{
         
        public ColumnModelTest() {
        
        JFrame f = new JFrame();
      
       
            
            f.addWindowListener(new WindowAdapter() {
                public void windowClosing(WindowEvent e) {
                    System.exit(0);
                }
            });
        }    public static void main(String args[]) {
         JFrame f = new JFrame();
          MyTableModel tm=new MyTableModel();
          TableSorter sorter = new TableSorter(tm); 
           
            JTable table = new JTable(sorter);       
           sorter.setTableHeader(table.getTableHeader()); 
         table.setPreferredScrollableViewportSize(new Dimension(550, 100));
          JScrollPane s = new JScrollPane(table);
          f.getContentPane().add(s, BorderLayout.CENTER);
          f.setTitle("ColumnModelTest");
             f.pack();
             f.setVisible(true);
             
               
        
        }
          
    }
    还有 一个
    import javax.swing.event.TableModelListener;
    import javax.swing.table.TableModel;class MyTableModel implements TableModel{     
    Object[][] p = {
                {new Boolean(false), "人事部","12311","无名", "男", "19920103","本科","物理"},
                {new Boolean(false), "人事部","12312","无名", "男", "19920103","本科","物理"},
                {new Boolean(false), "人事部","12313","无名", "男", "19920103","本科","物理"},
                {new Boolean(false), "人事部","12314","无名", "男", "19920103","本科","物理"}};
    String[] n = {"选择","部门","教师编码","姓名","性别","生日","最终学历","研究领域"};
     
            public int getColumnCount() {
                return n.length;
            }        public int getRowCount() {
                return p.length;
            }        public String getColumnName(int col) {
                return n[col];
            }        public Object getValueAt(int row, int col) {
                return p[row][col];
            }
        public Class getColumnClass(int c) {
             return getValueAt(0, c).getClass();
         }
        public boolean isCellEditable(int rowIndex, int columnIndex) {
        return true;
         }
        public void setValueAt(Object value, int row, int col) {
             p[row][col] = value;
        fireTableCellUpdated(row, col);
         }
        private void fireTableCellUpdated(int row, int col) {
    // TODO Auto-generated method stub

    } public void addTableModelListener(TableModelListener l){
        
        }
        public void removeTableModelListener(TableModelListener l){
        
        }
    }   
      

  7.   

    晕,我手误,少打了对括号:JTable table = new JTable();
    TableSorter sorter = new TableSorter(table.getModel(), table.getTableHeader());
    table.setModel(sorter);
    你应该看得出那么明显的错误吧???
      

  8.   

    把你的代码稍微改了一下,一切运行正常:
    /*
     * ColumnModelTest.java
     *
     * Created on 2008-1-11, 下午08:30:11
     */
    package com.enrising.table;import java.awt.BorderLayout;import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.JScrollPane;
    import javax.swing.JTable;
    import javax.swing.event.TableModelListener;
    import javax.swing.table.TableModel;public class ColumnModelTest extends JPanel {
    public ColumnModelTest() {
    super(new BorderLayout());
    JTable table = new JTable(new MyTableModel());
    add(new JScrollPane(table), BorderLayout.CENTER);
    TableSorter ts = new TableSorter(table.getModel(), table.getTableHeader());
    table.setModel(ts);
    } public static void createAndShowGUI() {
    JFrame f = new JFrame("ColumnModelTest");
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    f.getContentPane().add(new ColumnModelTest(), BorderLayout.CENTER);
    f.pack();
    f.setVisible(true);
    } public static void main(String args[]) {
    javax.swing.SwingUtilities.invokeLater(new Runnable() { @Override
    public void run() {
    createAndShowGUI();
    }
    }); } public static class MyTableModel implements TableModel { Object[][] p = {
    {
    new Boolean(false), "人事部", "12311", "无名", "男", "19920103", "本科", "物理"
    }, {
    new Boolean(false), "人事部", "12312", "无名", "男", "19920103", "本科", "物理"
    }, {
    new Boolean(false), "人事部", "12313", "无名", "男", "19920103", "本科", "物理"
    }, {
    new Boolean(false), "人事部", "12314", "无名", "男", "19920103", "本科", "物理"
    }
    };
    String[] n = {
    "选择", "部门", "教师编码", "姓名", "性别", "生日", "最终学历", "研究领域"
    }; public int getColumnCount() {
    return n.length;
    } public int getRowCount() {
    return p.length;
    } public String getColumnName(int col) {
    return n[col];
    } public Object getValueAt(int row, int col) {
    return p[row][col];
    } public Class getColumnClass(int c) {
    return getValueAt(0, c).getClass();
    } public boolean isCellEditable(int rowIndex, int columnIndex) {
    return true;
    } public void setValueAt(Object value, int row, int col) {
    p[row][col] = value;
    fireTableCellUpdated(row, col);
    } private void fireTableCellUpdated(int row, int col) {
    // TODO Auto-generated method stub } public void addTableModelListener(TableModelListener l) { } public void removeTableModelListener(TableModelListener l) { }
    }}
      

  9.   

    我晕,老大 我这样也不行!!import java.awt.BorderLayout;
    import java.lang.Runnable.*;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.JScrollPane;
    import javax.swing.JTable;
    import javax.swing.event.TableModelListener;
    import javax.swing.table.TableModel;public class ColumnModelTest extends JPanel {
        public ColumnModelTest() {
            super(new BorderLayout());
            JTable table = new JTable(new MyTableModel());
            add(new JScrollPane(table), BorderLayout.CENTER);
            TableSorter ts = new TableSorter(table.getModel(), table.getTableHeader());//The constructor TableSorter(TableModel,JTableHeader)is undefined        table.setModel(ts);
        }    public static void createAndShowGUI() {
            JFrame f = new JFrame("ColumnModelTest");
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            f.getContentPane().add(new ColumnModelTest(), BorderLayout.CENTER);
            f.pack();
            f.setVisible(true);
        }    public static void main(String args[]) {
            javax.swing.SwingUtilities.invokeLater(new Runnable() {           
                public void run() {
                    createAndShowGUI();
                }
            });    }    public static class MyTableModel implements TableModel {        Object[][] p = {
                    {
                            new Boolean(false), "人事部", "12311", "无名", "男", "19920103", "本科", "物理"
                    }, {
                            new Boolean(false), "人事部", "12312", "无名", "男", "19920103", "本科", "物理"
                    }, {
                            new Boolean(false), "人事部", "12313", "无名", "男", "19920103", "本科", "物理"
                    }, {
                            new Boolean(false), "人事部", "12314", "无名", "男", "19920103", "本科", "物理"
                    }
            };
            String[] n = {
                    "选择", "部门", "教师编码", "姓名", "性别", "生日", "最终学历", "研究领域"
            };        public int getColumnCount() {
                return n.length;
            }        public int getRowCount() {
                return p.length;
            }        public String getColumnName(int col) {
                return n[col];
            }        public Object getValueAt(int row, int col) {
                return p[row][col];
            }        public Class getColumnClass(int c) {
                return getValueAt(0, c).getClass();
            }        public boolean isCellEditable(int rowIndex, int columnIndex) {
                return true;
            }        public void setValueAt(Object value, int row, int col) {
                p[row][col] = value;
                fireTableCellUpdated(row, col);
            }        private void fireTableCellUpdated(int row, int col) {
                // TODO Auto-generated method stub        }        public void addTableModelListener(TableModelListener l) {        }        public void removeTableModelListener(TableModelListener l) {        }
        }}
      

  10.   

    import java.awt.BorderLayout;
    import java.lang.Runnable.*;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.JScrollPane;
    import javax.swing.JTable;
    import javax.swing.event.TableModelListener;
    import javax.swing.table.TableModel;public class ColumnModelTest extends JPanel {
        public ColumnModelTest() {
            super(new BorderLayout());
            JTable table = new JTable(new MyTableModel());
            add(new JScrollPane(table), BorderLayout.CENTER);
            TableSorter ts = new TableSorter(table.getModel(), table.getTableHeader());
    //The constructor TableSorter(TableModel,JTableHeader)is undefined
            table.setModel(ts);
        }    public static void createAndShowGUI() {
            JFrame f = new JFrame("ColumnModelTest");
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            f.getContentPane().add(new ColumnModelTest(), BorderLayout.CENTER);
            f.pack();
            f.setVisible(true);
        }    public static void main(String args[]) {
            javax.swing.SwingUtilities.invokeLater(new Runnable() {           
                public void run() {
                    createAndShowGUI();
                }
            });    }    public static class MyTableModel implements TableModel {        Object[][] p = {
                    {
                            new Boolean(false), "人事部", "12311", "无名", "男", "19920103", "本科", "物理"
                    }, {
                            new Boolean(false), "人事部", "12312", "无名", "男", "19920103", "本科", "物理"
                    }, {
                            new Boolean(false), "人事部", "12313", "无名", "男", "19920103", "本科", "物理"
                    }, {
                            new Boolean(false), "人事部", "12314", "无名", "男", "19920103", "本科", "物理"
                    }
            };
            String[] n = {
                    "选择", "部门", "教师编码", "姓名", "性别", "生日", "最终学历", "研究领域"
            };        public int getColumnCount() {
                return n.length;
            }        public int getRowCount() {
                return p.length;
            }        public String getColumnName(int col) {
                return n[col];
            }        public Object getValueAt(int row, int col) {
                return p[row][col];
            }        public Class getColumnClass(int c) {
                return getValueAt(0, c).getClass();
            }        public boolean isCellEditable(int rowIndex, int columnIndex) {
                return true;
            }        public void setValueAt(Object value, int row, int col) {
                p[row][col] = value;
                fireTableCellUpdated(row, col);
            }        private void fireTableCellUpdated(int row, int col) {
                // TODO Auto-generated method stub        }        public void addTableModelListener(TableModelListener l) {        }        public void removeTableModelListener(TableModelListener l) {        }
        }}
      

  11.   

    不一定要放入同一个包内,你只需要将TableSorter的完整类名import进你要引用的类中就可以了
      

  12.   

    (风之幽谷),看您是个java老手啦,有个问题希望指教:
    怎样给一个JXTreeTable写“ColumnSorter”呢,以至于一树表可按列排序?在网上查了很久,每发现可参考的资料。
    多谢!