Java JTable - 首先单击列以按降序排序

Posted

技术标签:

【中文标题】Java JTable - 首先单击列以按降序排序【英文标题】:Java JTable - First click on column to sort by descending 【发布时间】:2016-05-03 09:43:25 【问题描述】:

我有一个 Java JTable,它存储了大约 8000 行、10 列,并且一切正常。

当我点击一个列标题时,整个JTable会首先按照该列中的数据升序排序,再次点击将数据降序排序。

我想在一个特定列(双列 - 存储 %'s)上更改此行为,以便第一次单击将按降序对数据进行排序,然后第二次单击将升序 - 因为我最感兴趣在具有最高 %s 的条目中。

这不是要在表格首次呈现时更改原始排序顺序。该表最初按 ID 号(第一列)升序排序,这是我想要的。

这是关于更改基于其他列重新排序时的行为,以便第一次点击将是降序。

有人有什么想法吗?

【问题讨论】:

【参考方案1】:
    int noOfClicks = 1;
    public void arrange()

TableRowSorter<TableModel> sorter = new TableRowSorter<>(table.getModel());
table.setRowSorter(sorter);
List<RowSorter.SortKey> sortKeys = new ArrayList<>();

int columnIndexToSort = 1;
    if (noOfClicks%2==0) 
    //firstClick
    sortKeys.add(new RowSorter.SortKey(columnIndexToSort,   SortOrder.ASCENDING));

    else
   sortKeys.add(new RowSorter.SortKey(columnIndexToSort, SortOrder.DESCENDING));
    
    ++noOfClicks;


sorter.setSortKeys(sortKeys);
sorter.sort();    

    

您可以使用上述方法进行操作。如果您可以存储 noOfclicks 然后您可以检查是否应该按升序或降序排列。如果 noOfclicks 是偶数,那么您可以按 assending order 排列表格。每次点击时,点击次数将增加 +1。

【讨论】:

感谢您的帮助。那么 noOfClicks 需要按列存储吗?因为只有一列我想更改默认顺序。我在想这可能会以某种方式更改基础数据表/模型、修改和列的 asc/desc 排序 无需为每列存储noofclicks。对代码进行了一些更改,只需将columnIndexToSort 更改为您需要安排的任何列索引,这样就可以完成这项工作。注意索引从 0 开始 好的,谢谢,所以每次点击 JTable 标题时我都需要调用arrange() 方法吗?然后它将确定 asc/desc 的 noOfClicks。但这不会受到列中所有表格记录的点击总数的影响。每次单击列标题时,noOfClicks 都会增加,不是吗?因此,如果我添加一行,如果所需的列是应该工作的选定列,则只增加 noOfClicks 。但是,如果我基于另一列采取措施,那将不再可能吗?我想在所有其他列上保持默认排序功能 int index = convertColumnIndexToModel(columnAtPoint(mouseEvent.getPoint())); 我假设您已将 actionListner 添加到 jtableheader 。您可以使用上面的代码获取点击列的索引,然后借助方法内的 if 循环,您可以添加所需的函数。【参考方案2】:

我扩展了 TableRowSorter 类以获得所需的效果。就我而言,我想先对所有列进行降序排序,但第一列除外。下面的代码允许指定哪些列应该先升序排序。

/** Class sorting table descending on first click unless column is specified
 * in constructor to follow standard behaviour (ascending on first click).
 * @author Adam Jagosz */
class NormallyDescendingSorter extends TableRowSorter 

    /** columns to be sorted in a standard way, ascending on first click */
    ArrayList<Integer> ascendingColumns;

    /** Constructor
     * @param model table model to be sorted
     * @param ascendingColumns columns to follow ascending sort on first click */
    public NormallyDescendingSorter(TableModel model, int... ascendingColumns) 
        super(model);
        this.ascendingColumns = new ArrayList<>();
        for (int index = 0; index < ascendingColumns.length; index++)
        
            this.ascendingColumns.add(ascendingColumns[index]);
        
    

    /**
     * Method sorting table rows upon clicking on column header
     * @param column column to sort by */
    @Override
    public void toggleSortOrder(int column) 
        if(ascendingColumns.contains(column)) 
            super.toggleSortOrder(column);
            return;
        
        ArrayList<SortKey> sortKeys = new ArrayList<>(getSortKeys());
        if(sortKeys.isEmpty() || sortKeys.get(0).getColumn() != column) 
            sortKeys.add(0, new RowSorter.SortKey(column, SortOrder.DESCENDING));
        
        else if (sortKeys.get(0).getSortOrder() == SortOrder.ASCENDING)   
            sortKeys.removeIf(key -> key.getColumn() == column);
            sortKeys.add(0, new RowSorter.SortKey(column, SortOrder.DESCENDING));
        
        else 
            sortKeys.removeIf(key -> key.getColumn() == column);
            sortKeys.add(0, new RowSorter.SortKey(column, SortOrder.ASCENDING));
        
        setSortKeys(sortKeys);
    

你可以这样使用:

DocumentTableModel model = new DocumentTableModel(document);
JTable table = new JTable(model);
NormallyDescendingSorter sorter = new NormallyDescendingSorter(model, 0);
table.setRowSorter(sorter);

(我指定 0 为要升序排序的列索引)。

【讨论】:

这个答案应该被接受。我根据这个想法使用 DefaultRowSorter 中的 toggleSortOrder 实现了类似的东西,效果很好!

以上是关于Java JTable - 首先单击列以按降序排序的主要内容,如果未能解决你的问题,请参考以下文章

单击时按降序和升序排序

如何按降序对 ArrayList<Long> 进行排序?

Ruby - 按值按降序排序哈希值

按降序排序数组(NSArray)

按降序对数组进行排序的更好方法

如何按降序排序?