我在程序中调用了TableSorter  
    
  TableSorter  sorter  =  new  TableSorter(new  MyTableModel());  //ADDED  THIS  
  JTable  table  =  new  JTable(sorter);                          //NEW  
  sorter.setTableHeader(table.getTableHeader());  //ADDED  THIS  
    
  但是点击Header只会引出升或降的箭头图标改变,数据并没有重新排序。 把TableSorter用在指南TableSorterDemo里,就可以排序。但我这个表就不行。 不知道有没有人遇到过这个问题?应该怎样解决? 谢谢!

解决方案 »

  1.   

    public class TestSortedTable {
    public static void main(String args[]) {
    JFrame frame = new JFrame("JTable的排序测试");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    // 表格中显示的数据
    Object rows[][] = { { "王明", "中国", 44 }, { "姚明", "中国", 25 },
    { "赵子龙", "西蜀", 1234 }, { "曹操", "北魏", 2112 },
    { "Bill Gates", "美国", 45 }, { "Mike", "英国", 33 } };
    String columns[] = { "姓名", "国籍", "年龄" };
    TableModel model = new DefaultTableModel(rows, columns);
    JTable table = new JTable(model);
    RowSorter<TableModel> sorter = new TableRowSorter<TableModel>(model);
    table.setRowSorter(sorter);
    JScrollPane pane = new JScrollPane(table);
    frame.add(pane, BorderLayout.CENTER);
    frame.setSize(300, 150);
    frame.setVisible(true);
    }
    }
      

  2.   


    哦,这种方法我会的。我想调用java手册里给出的TableSorter这个类,
    并且我修改了手册里TableSorterDemo,用以调用这个类,能够实现
    排序。但是作用于我现在项目中的表,就只能显示排序的△、▽,但对
    行没有任何操作。
      

  3.   

    通知模型刷新了吗?fireTableDataChanged();
      

  4.   


    恩,是的。这步在TableSorter里已经做了。补充一下:我的表模型里只设置了表头和各行的显示格式,
    数据都是从数据库里读出来的。
      

  5.   

    你用的是1.5之前的一个表格排序的例子吧?表格排序,需要模型维护数据,在模型中调用sort方法,实际上就是将表格模型Vector/Object[][]的行号进行变化,最后通知模型刷新
      

  6.   

    数据排序的事件估计没触发吧 要不然就是没有重新render数据
      

  7.   

    刷新模型的步骤是在TableSorter里做的。
      

  8.   


    不是1.5之前的版本。TableSorter的源码如下:一次贴不完,分两次贴了。package cn.ac.ia.hitic.MyClient;import java.awt.*;
    import java.awt.event.*;
    import java.util.*;
    import java.util.List;import javax.swing.*;
    import javax.swing.event.TableModelEvent;
    import javax.swing.event.TableModelListener;
    import javax.swing.table.*;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;
    }
      

  9.   

    // TableModel interface methods  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);
    } // Helper classes 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;
    // Define null less than everything, except null.
    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 we're not sorting by anything, just pass the event along.             
    if (!isSorting())
    {
    clearSortingState();
    fireTableChanged(e);
    return;
    } // If the table structure has changed, cancel the sorting; the             
    // sorting columns may have been either moved or deleted from             
    // the model. 
    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;
    } // Something has happened to the data that may have invalidated the row order. 
    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();
    }
    // Cycle the sorting states through {NOT_SORTED, ASCENDING, DESCENDING} or 
    // {NOT_SORTED, DESCENDING, ASCENDING} depending on whether shift is pressed. 
    status = status + (e.isShiftDown() ? -1 : 1);
    status = (status + 4) % 3 - 1; // signed mod, returning {-1, 0, 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();
    // In a compound sort, make each succesive triangle 20% 
    // smaller than the previous one. 
    int dx = (int) (size / 2 * Math.pow(0.8, priority));
    int dy = descending ? dx : -dx;
    // Align icon (roughly) with font baseline. 
    y = y + 5 * size / 6 + (descending ? -dy : 0);
    int shift = descending ? 1 : -1;
    g.translate(x, y); // Right diagonal. 
    g.setColor(color.darker());
    g.drawLine(dx / 2, dy, 0, 0);
    g.drawLine(dx / 2, dy + shift, 0, shift); // Left diagonal. 
    g.setColor(color.brighter());
    g.drawLine(dx / 2, dy, dx, 0);
    g.drawLine(dx / 2, dy + shift, dx, shift); // Horizontal line. 
    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;
    }
    }
    }
      

  10.   


    import java.awt.BorderLayout;import javax.swing.JFrame;
    import javax.swing.JScrollPane;
    import javax.swing.JTable;
    import javax.swing.table.DefaultTableModel;
    import javax.swing.table.TableModel;public class TestSortedTable {
    public static void main(String args[]) {
    JFrame frame = new JFrame("JTable的排序测试");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    // 表格中显示的数据
    Object rows[][] = { { "王明", "中国", 44 }, { "姚明", "中国", 25 },
    { "赵子龙", "西蜀", 1234 }, { "曹操", "北魏", 2112 },
    { "Bill Gates", "美国", 45 }, { "Mike", "英国", 33 } };
    String columns[] = { "姓名", "国籍", "年龄" };
    TableModel model = new DefaultTableModel(rows, columns);
    JTable table = new JTable(model);
    TableSorter sorter = new TableSorter();
    sorter.setTableHeader(table.getTableHeader());
    sorter.setTableModel(model);
    table.setModel(sorter);
    JScrollPane pane = new JScrollPane(table);
    frame.add(pane, BorderLayout.CENTER);
    frame.setSize(300, 150);
    frame.setVisible(true);
    }
    }看我的调用代码,是可以进行排序的,你是不是没有TableSorter.setTableModel(model);
      

  11.   


    谢谢你的回复。你给的这个示例程序我知道能正确运行。因为之前我在自己的示例程序中也能正确运行,但是用在现在这个表中就出现问题了。
    TableSorter调用现在一时处理不好,我打算使用Table.setRowSorter(new TableRowSorter(Model));
    但是出现了一个问题,和之前你回复别人的一模一样。
    “用TableRowSorter后点击某列标题可以排序,但有一列全数字还是按字符来排序的,比如:1,10,11,2,3,4  我想让它按数字大小排序 怎么办啊??”
    我和这人一样,表头统一是用vector<String>做的,如:Vector<String> data,所以调用data.add(),括号中只能是String,排序也只能依据
    String来排了,怎么解决呢?
      

  12.   

    一样的实现:你可以添加一个 setColumnClasses(Class[])的方法,对表格中的每一列设置其返回类型,如果需要是数值的,是使用 Number.class重写 
    public CLass getColumnClass(int column){
    return classes[i]; //这里根据你的实际情况实现
    }修改  protected Comparator getComparator(int column) ;
    添加 NumberComparetor进行数值类型的比较,Object o1、o2实际上就是Number类型了,转化成数值就可以了。Best Regards!