JTable 的非实时/非实时排序



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

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

@trashgod:谢谢你的回答。我实际上有点像本机行排序器方法,因为我可以在三态(升序、降序和未排序)中圈出列状态。如果使用 Collections.sort,我将不得不创建一个变量来保存原始行顺序,然后再每次对其进行排序。

您可以使用

Collections.sort()和自定义Comparator(如此处所示)对TableModel的行进行排序,而RowSorter可以接受指定排序方向的参数。

enum Sort { ASCENDING, DESCENDING; }
class RecordComparator implements Comparator<Record> {
    public RecordComparator(Sort sort, ...) { ... }
}

似乎您想要的是能够对表进行排序,但随后能够在不更改表排序顺序的情况下添加更多行。即使有可能,您也必须重写DefaultRowSorterTableRowSorter(两者的源代码都可用)。原因是当前实现旨在保持一致的排序顺序(不考虑何时添加行)。您可能无法扩展 TableRowSorter 来克服此问题,因为它的父类有很多与我刚刚描述的设计相关的私有函数。

我上面描述的是干净的方法。这是您可以执行此操作的另一种方法,每次要插入新行时都执行此操作:

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

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

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

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

完整的代码如下。它旨在每次按下按钮时向表中添加一行。请注意,我没有使用排序键> 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);
    }
}

相关内容

  • 没有找到相关文章

最新更新