4

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

工作代码将是:

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,其中包含一个带有排序按钮的 JTable。按下该按钮将导致 A 列升序排序。但是,按钮并不是对表格进行排序的唯一方法——我们可以简单地单击表格标题来更改排序。我的问题是如何使按钮成为对表格进行排序的唯一方法。知道如何摆脱排序更改时出现的箭头也很好。

4

1 回答 1

4

阅读有关类似问题的帖子(如@mKorbel 建议的)并尝试自己,我设法找到了解决方案。主要问题的答案是:使用setSortable(int index, boolean sortable)DefaultRowSorter 的方法。看起来很明显,但有趣的是,此方法在使用toggleSortOrder(int index)RowSorter 时禁用列排序,但在使用sort()DefaultRowSorter 方法时会被忽略。这是一种矛盾吗?无论如何,这让门打开了一个诡计。现在我可以这样做:

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

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

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

更好的方法是装饰 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;
            }

        });
于 2013-11-15T08:53:55.537 回答