【问题标题】:non-live/non realtime sorting of JTableJTable的非实时/非实时排序
【发布时间】:2012-05-31 22:46:29
【问题描述】:

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

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

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

【问题讨论】:

    标签: java swing jtable live tablerowsorter


    【解决方案1】:

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

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

    【讨论】:

    • 感谢您的回答。我实际上有点像原生行排序器方法,因为我可以在三态(升序、降序和未排序)中圈出列状态。如果使用 Collections.sort,我必须在每次排序之前创建一个变量来保存原始行顺序。
    • 使用setSortKeys(null) 表示视图应该是未排序的;这与模型的顺序无关。
    • 这就是我用来圈出订单状态的方法。但是,当处于升序和降序模式时(未排序很好),重新排列的行将被排序器覆盖。正如我所提到的,使用 Collection.sort() 将重新排序真实的表模型,然后如果我想循环到原始顺序,我首先需要一些东西来存储它。不知道是否有更好的解决方案。
    • 可以在底部添加新行的要求意味着一些顺序取决于您的TableModel的实现方式。
    【解决方案2】:

    看起来您想要的是能够对表格进行排序,然后能够在不更改表格排序顺序的情况下添加更多行。即使有可能,您也必须重写 DefaultRowSorterTableRowSorter(两者都可用的源代码)。原因是当前实现旨在保持一致的排序顺序(不考虑何时添加行)。您可能无法扩展 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 或过滤器对此进行测试(我将把它留给你)。让我知道你对这个 hack 的看法。

    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);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-01-07
      • 1970-01-01
      • 1970-01-01
      • 2015-03-24
      • 2011-03-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多