简体   繁体   English

如何使用JTable的行分类器恢复原始行顺序?

[英]How to restore the original row order with JTable's row sorter?

I've enabled sorting in JTable with setAutoCreateRowSorter method. 我已经使用setAutoCreateRowSorter方法在JTable中启用了排序。 Mouse clicks on the column headers will switch between ascending and descending order, but I would like to switch it between ascending, descending and the original (unsorted) row order. 鼠标单击列标题将在升序和降序之间切换,但我想在升序,降序和原始(未排序)行顺序之间切换。 Any hints how to achieve this? 任何提示如何实现这一目标?

The mapping of a mouse click to changing the sort state is implemented in BasicTableHeaderUI and happens exclusively via the RowSorter's toggleSortOrder(columnIndex). 鼠标单击到更改排序状态的映射在BasicTableHeaderUI中实现,并且仅通过RowSorter的toggleSortOrder(columnIndex)进行。 It's default behaviour is to switch 它的默认行为是切换

UNSORTED --> ASCENDING --> DESCENDING --> ASCENDING -- UNSORTED - > ASCENDING - > DESCENDING - > ASCENDING -

that is, no way back into the UNSORTED. 也就是说,没有办法回到UNSORTED。 If the requirement is to simply widen the circle into: 如果要求只是将圆圈扩展为:

UNSORTED --> ASCENDING --> DESCENDING -- UNSORTED --> ASCENDING -- UNSORTED - > ASCENDING - > DESCENDING - UNSORTED - > ASCENDING -

the way to go is to subclass TableRowSorter and override its toggleSortOrder accordingly 要走的路是子类TableRowSorter并相应地覆盖它的toggleSortOrder

    /** 
     * @inherited <p>
     */
    @Override
    public void toggleSortOrder(int column) {
        List<? extends SortKey> sortKeys = getSortKeys();
        if (sortKeys.size() > 0) {
            if (sortKeys.get(0).getSortOrder() == SortOrder.DESCENDING) {
                setSortKeys(null);
                return;
            }
        }
        super.toggleSortOrder(column);
    }

Note: this is a bit simplified as it doesn't account for n-ary sorted columns, see SwingX DefaultSortController for a full version. 注意:这有点简化,因为它没有考虑n-ary排序列,请参阅SwingX DefaultSortController获取完整版本。 Or use SwingX to start with, its JXTable has api to configure the sorting cycle like 或者使用SwingX开始,它的JXTable有api来配置排序周期

 table.setSortOrderCycle(ASCENDING, DESCENDING, UNSORTED);

Cheers Jeanette 干杯珍妮特

This code implements cycle ASCENDING->DESCENDING->UNSORTED->... without overriding TableRowSorter: 此代码实现循环ASCENDING-> DESCENDING-> UNSORTED - > ...而不覆盖TableRowSorter:

TableRowSorter sorter = new TableRowSorter(getModel());
setRowSorter(sorter);
// Remove default sort MouseListener
for (MouseListener mouseListener : getTableHeader().getMouseListeners()) {
    if (mouseListener instanceof javax.swing.plaf.basic.BasicTableHeaderUI.MouseInputHandler) {
        getTableHeader().removeMouseListener(mouseListener);
    }
}
// Add MouseListener for onClick event
getTableHeader().addMouseListener(new MouseAdapter() {
    private SortOrder currentOrder = SortOrder.UNSORTED;

    @Override
    public void mouseClicked(MouseEvent e) {
        int column = getTableHeader().columnAtPoint(e.getPoint());
        RowSorter sorter = getRowSorter();
        List sortKeys = new ArrayList();
        switch (currentOrder) {
            case UNSORTED:
                sortKeys.add(new RowSorter.SortKey(column, currentOrder = SortOrder.ASCENDING));
                break;
            case ASCENDING:
                sortKeys.add(new RowSorter.SortKey(column, currentOrder = SortOrder.DESCENDING));
                break;
            case DESCENDING:
                sortKeys.add(new RowSorter.SortKey(column, currentOrder = SortOrder.UNSORTED));
                break;
        }
        sorter.setSortKeys(sortKeys);
    }
});

If you're using the DefaultRowSorter : "An empty sortKeys list indicates that the view should [be] unsorted, the same as the model." 如果你正在使用DefaultRowSorter :“一个空的sortKeys列表表明视图应该[未],与模型相同。”

RowSorter rs = table.getRowSorter();
rs.setSortKeys(null);

Addendum: Note that " null is a shorthand for specifying an empty list" in setSortKeys() . 附录:请注意, setSortKeys()中的“ null是指定空列表的简写”。

Kornell's answer is working great for me (thanks!) Kornell的回答对我很有用(谢谢!)

I made these changes which others may find helpful: 我做了这些改变,其他人可能会觉得有帮助:

  1. Convert column from view to model coordinates. 将列从视图转换为模型坐标。 This is a bug in the original. 这是原版中的一个错误。
  2. Omit removing the other mouse listeners, because doing this disables column dragging and resizing. 省略删除其他鼠标侦听器,因为这样做会禁用列拖动和调整大小。
  3. Filter out anything but left clicks 过滤除了点击之外的任何内容
  4. Whenever column changes, reinitialize sort order. 每当列更改时,重新初始化排序顺序。 User experience is significantly more intuitive this way, as you can successively click different columns and get ascending order each time. 用户体验通过这种方式更加直观,因为您可以连续单击不同的列并每次都按升序排列。

     TableRowSorter sorter = new TableRowSorter(getModel()); setRowSorter(sorter); getTableHeader().addMouseListener(new MouseAdapter() { private SortOrder currentOrder = SortOrder.UNSORTED; private int lastCol = -1; @Override public void mouseClicked(MouseEvent e) { int column = getTableHeader().columnAtPoint(e.getPoint()); column = convertColumnIndexToModel(column); if (column != lastCol) { currentOrder = SortOrder.UNSORTED; lastCol = column; } RowSorter<?> sorter = getRowSorter(); List<SortKey> sortKeys = new ArrayList<SortKey>(); if (e.getButton() == MouseEvent.BUTTON1) { switch (currentOrder) { case UNSORTED: sortKeys.add(new RowSorter.SortKey(column, currentOrder = SortOrder.ASCENDING)); break; case ASCENDING: sortKeys.add(new RowSorter.SortKey(column, currentOrder = SortOrder.DESCENDING)); break; case DESCENDING: sortKeys.add(new RowSorter.SortKey(column, currentOrder = SortOrder.UNSORTED)); break; } sorter.setSortKeys(sortKeys); } } }); 

由于内置排序机制仅为您提供升序或降序,如果您在JTable附近提供外部重载JButton,您可以返回到原始状态,只需将相同的模型设置回您显示的模型在任何排序活动发生之前,表格是第一次。

If you looking for UI way of doing it - shift-click on column header will do it. 如果您正在寻找用户界面的方式 - 按住列标题的Shift键点击就可以了。 This is built-in JTable functionality 这是内置的JTable功能

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM