JTable仅以编程方式排序 [英] JTable sorting programmatically only

查看:85
本文介绍了JTable仅以编程方式排序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个可排序的JTable(通过在初始化时调用setAutoCreateRowSorter(true)使其可排序).我以编程方式对该表进行排序,并且希望禁用表头的默认事件处理,以便可以以编程方式对表进行排序.如何实现?

I have a JTable, that is sortable (made it sortable by calling setAutoCreateRowSorter(true) at initialization). I sort this table programmatically and I would like to disable the default event handling on table header, so that the table can be sorted programmatically only. How to achieve it?

有效的代码段将是:

public class SortTable extends JDialog {

    private JTable table;

    DefaultRowSorter<TableModel, String> sorter;

    public SortTable() {
        JScrollPane scrollPane = new JScrollPane();
        setBounds(0, 0, 300, 200);
        getContentPane().setLayout(new BorderLayout());
        getContentPane().add(scrollPane, BorderLayout.CENTER);

        //-------most important stuff-------------------
        table = new JTable();
        table.setAutoCreateRowSorter(true); //enabling sorting
        table.setModel(createModel());
        sorter = (DefaultRowSorter<TableModel, String>)table.getRowSorter(); //store sorter to sort programatically later on
        //-----------------------------------------------

        scrollPane.setViewportView(table);
        JPanel buttonPane = new JPanel();
        buttonPane.setLayout(new FlowLayout(FlowLayout.RIGHT));
        getContentPane().add(buttonPane, BorderLayout.SOUTH);
        buttonPane.add(new JButton(getSortAction()));
    }

    private AbstractAction getSortAction() {
        return new AbstractAction("Sort") {

            @Override
            public void actionPerformed(ActionEvent e) {
                sorter.setSortKeys(Arrays.asList(new SortKey(0,SortOrder.ASCENDING)));
                sorter.sort(); //sorting programatically

            }
        };
    }

    private DefaultTableModel createModel() {
        return new DefaultTableModel(
            new Object[][] {
                {"1", "3"},
                {"5", "2"},
                {"4", null},
            },
            new String[] {
                "A", "B"
            }
        );
    }
}

此示例是一个JDialog,其中包含带有 Sort 按钮的JTable.按下该按钮将导致A列升序排列.但是,按钮不是对表格进行排序的唯一方法-我们只需单击表格标题即可更改排序.我的问题是如何使按钮成为对表格进行排序的唯一方法. 知道如何摆脱排序更改时出现的箭头也很高兴.

This example is a JDialog containing a JTable with Sort button. Pressing that button will cause column A to be sorted ascending. However, the button is not the only way to sort the table - we can simply click the table header to change sorting. My question is how to make the button the only way to sort the table. It would be also nice to know how to get rid of the arrow that appears when sorting is changed.

推荐答案

阅读有关类似问题的帖子(例如@mKorbel建议)并进行实验,我设法找到了解决方案. 主要问题的答案将是:使用DefaultRowSorter的setSortable(int index, boolean sortable)方法.似乎显而易见,但有趣的是,此方法在使用RowSorter的toggleSortOrder(int index)时禁用对列的排序,但是在使用DefaultRowSorter的sort()方法时将被忽略.这是一种矛盾吗?无论如何,这让门开了个花招.现在我可以了:

Reading posts on similar questions (like @mKorbel suggested) and experimenting myself I've managed to find a solution. The answer for the main question would be: Use setSortable(int index, boolean sortable) method of DefaultRowSorter. Seems obvious but what is interesting, is that this method disables sorting of a column when using toggleSortOrder(int index) of RowSorter but it's ignored when using sort() method of DefaultRowSorter. Is that a kind of inconsistency? Anyway this leaves the door open for a trick. Now I can do:

        for (int i=0 ; i<table.getColumnCount() ; i++) {
            sorter.setSortable(i, false);
        }

...并且瞧-无法再通过单击表头对表进行排序,但是可以通过编程方式对表进行排序. 如果有人面临像我一样隐藏那些排序指示符图标的怪异要求,那就有办法了.首先会产生全局效果,但我不喜欢它-将相应的属性设置为UIManager.

...and voila - the table cannot be sorted by clicking table headers anymore, but it can be sorted programatically. If anyone faces a weird requirement of hiding those sort order indicator icons like I have, there are to ways. First will take a global effect and I don't like it - set the corresponding properties to UIManager.

        UIManager.put("Table.ascendingSortIcon", new EmptyIcon());
        UIManager.put("Table.descendingSortIcon", new EmptyIcon());

更好的方法是装饰TableHeader的默认渲染器:

The better one is to decorate default renderer of the TableHeader:

        final TableCellRenderer defaultRenderer = table.getTableHeader().getDefaultRenderer();
        table.getTableHeader().setDefaultRenderer(new TableCellRenderer() {

            @Override
            public Component getTableCellRendererComponent(JTable table,
                    Object value, boolean isSelected, boolean hasFocus,
                    int row, int column) {
                JLabel label = (JLabel)defaultRenderer.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
                label.setIcon(null);
                return label;
            }

        });

这篇关于JTable仅以编程方式排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆