1

当表格处于排序模式时(使用RowSorter),似乎大多数时候表格都是实时排序的。例如,每当我添加新行时,表格都会自动排序(编辑单元格除外)。我想知道是否有任何方法可以禁用这种实时排序行为。

我想要做的是:在对表格进行排序后,无论是升序还是降序,排序器都会保持当前的排序状态并停止实时排序。然后可以在底部添加新行,并且可以上下移动选定的行,并且表格会更新视图模型中的所有更改。

@trashgod:感谢您的回答。我实际上有点像原生行排序器方法,因为我可以在三态(升序、降序和未排序)中圈出列状态。如果使用 Collections.sort,我必须在每次排序之前创建一个变量来保存原始行顺序。

4

2 回答 2

2

您可以对TableModel独立于RowSorter使用Collections.sort()和自定义的行进行排序Comparator,例如此处显示的,可以接受指定排序方向的参数。

enum Sort { ASCENDING, DESCENDING; }
class RecordComparator implements Comparator<Record> {
    public RecordComparator(Sort sort, ...) { ... }
}
于 2012-05-31T23:27:52.223 回答
0

看起来您想要的是能够对表进行排序,然后能够添加更多行而不更改表排序顺序。即使有可能,您也必须重写DefaultRowSorterand TableRowSorter(两者都可用的源代码)。原因是当前实现旨在保持一致的排序顺序(不考虑何时添加行)。您可能无法扩展 TableRowSorter 来解决这个问题,因为它的父类有很多与我刚才描述的设计相关的私有函数。

我上面描述的是干净的方式。这是另一种方法,每次要插入新行时都这样做:

  1. 将视图的当前排序顺序保存在地图中。我使用 hashmap ( postion) 将排序列的第 i 行中的每个对象映射到它在视图中的位置。 position.put(tableModel.getValueAt(i, column), sorter.convertRowIndexToView(i));

  2. 创建一个比较器,它将使用上面创建的映射对传入数据进行排序。将 TableRowSorter 的列比较器设置为新创建的比较器。然后调用sorter.sort(),这是必要DefaultRowSorter的,因为需要缓存比较器。比较器会将现有对象放在其当前位置,并将新对象(在插入期间创建)放在最后。

  3. 将行插入到表模型中。在我的代码中,我将 3 个随机整数、布尔值和双精度值添加到表中的 3 列中。

  4. 通过将 value 设置为 null 来删除 #3 中添加的比较器,sorter.setComparator(sortKeys.get(0).getColumn(), null);这样下次在列上切换排序时,它将使用默认比较器而不是虚拟比较器。

完整代码如下。每次按下按钮时,它都会在表格中添加一行。请注意,我没有使用 sortkeys > 1 或过滤器对此进行测试(我将把它留给你)。让我知道你对这个黑客的看法。

private void insertRowButtonActionPerformed(java.awt.event.ActionEvent evt) {
    TableRowSorter<TableModel> sorter = (TableRowSorter<TableModel>)jTable1.getRowSorter();
    final HashMap<Object, Integer> position = new HashMap<Object, Integer>();
    List<? extends SortKey> sortKeys = sorter.getSortKeys();

    if(!sortKeys.isEmpty()){
        SortKey sortKey = sortKeys.get(0);
        int column = sortKey.getColumn();
        TableModel tableModel = sorter.getModel();
        int n = sorter.getModelRowCount();
        final SortOrder sortOrder = sortKey.getSortOrder();
        for(int i=0;i<n;i++){
            position.put(tableModel.getValueAt(i, column), sorter.convertRowIndexToView(i));
        }
        //add dummy comparator
        sorter.setComparator(column, new Comparator<Object>(){
            public int compare(Object o1, Object o2) {
                int obj1Position = position.containsKey(o1) ? position.get(o1):position.size();
                int obj2Position = position.containsKey(o2) ? position.get(o2):position.size();
                return sortOrder == SortOrder.DESCENDING ? obj2Position - obj1Position:obj1Position - obj2Position;
            }
        });
        sorter.sort();
    }

    /////////////insert row///////////////////
    DefaultTableModel tableModel = (DefaultTableModel)jTable1.getModel();
    tableModel.addRow(new Object[]{rand.nextInt(), rand.nextBoolean(), rand.nextDouble()});
    /////////////end insert row///////////////

    //remove dummy comparator
    if(!sortKeys.isEmpty()){
        sorter.setComparator(sortKeys.get(0).getColumn(), null);
    }
}
于 2012-06-01T08:23:55.970 回答