Java 仅以编程方式进行JTable排序

Java 仅以编程方式进行JTable排序,java,swing,jtable,rowsorter,Java,Swing,Jtable,Rowsorter,我有一个JTable,它是可排序的(通过在初始化时调用setAutoCreateRowSorter(true)使其可排序)。我以编程方式对该表进行排序,并希望禁用表头上的默认事件处理,以便仅以编程方式对该表进行排序。如何实现 工作代码将是: public class SortTable extends JDialog { private JTable table; DefaultRowSorter<TableModel, String> sorter;

我有一个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表;
默认行分拣机;
公共排序表(){
JScrollPane scrollPane=新的JScrollPane();
立根(0,0,300,200);
getContentPane().setLayout(新的BorderLayout());
getContentPane().add(滚动窗格,BorderLayout.CENTER);
//-------最重要的东西-------------------
table=新的JTable();
table.setAutoCreateRowSorter(true);//启用排序
table.setModel(createModel());
sorter=(DefaultRowSorter)table.getRowSorter();//存储sorter以便稍后通过编程进行排序
//-----------------------------------------------
scrollPane.setViewportView(表);
JPanel buttonPane=新的JPanel();
buttonPane.setLayout(新的FlowLayout(FlowLayout.RIGHT));
getContentPane().add(buttonPane,BorderLayout.SOUTH);
add(新的JButton(getSortAction());
}
私有抽象操作getSortAction(){
返回新的抽象操作(“排序”){
@凌驾
已执行的公共无效操作(操作事件e){
sorter.setsortkey(Arrays.asList(新的SortKey(0,SortOrder.升序));
sorter.sort();//以编程方式进行排序
}
};
}
私有DefaultTableModel createModel(){
返回新的DefaultTableModel(
新对象[][]{
{"1", "3"},
{"5", "2"},
{“4”,null},
},
新字符串[]{
“A”、“B”
}
);
}
}
本例是一个JDialog,其中包含一个带有排序按钮的JTable。按下该按钮将使A列按升序排序。但是,该按钮并不是对表进行排序的唯一方法-我们只需单击表头即可更改排序。我的问题是如何使按钮成为对表格进行排序的唯一方法。
知道如何摆脱排序更改时出现的箭头也很好。

阅读关于类似问题的帖子(如@mKorbel建议的),并尝试自己,我已经找到了解决方案。 主要问题的答案是:使用DefaultRowSorter的
setSortable(int-index,booleanSortable)
方法。看起来很明显,但有趣的是,当使用RowSorter的
toggleSortOrder(int index)
时,此方法禁用列排序,但当使用DefaultRowSorter的
sort()
方法时,它被忽略。这是一种矛盾吗?不管怎么说,这为耍把戏打开了大门。现在我可以做:

        for (int i=0 ; i<table.getColumnCount() ; i++) {
            sorter.setSortable(i, false);
        }
更好的方法是修饰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;
            }

        });

类似的问题在这个月和上个月被问了几次,搜索bz点击rowsorter标签,或者tablerowsorter@mKorbel该死,我应该偶尔看看api文档;-)这是一种不一致吗?不,它的设计(和记录)是为了准确地解决您的需求:-)是的,您是对的,我错过了。另一方面,JTableHeader类允许此方法setReorOrderingAllowed,它可以禁用列重新排序。老实说,我认为设置RowsortingAllowed或smth更直观。这更自然地意味着头部是否正在侦听鼠标事件。实际上,我忘记了可排序属性的确切含义,建议进行修改(删除)。甚至可能在SwingX的sortController中犯了一个错误,它有用于编程排序的附加api(setSortOrder),如果列不可排序,它什么也不做。
        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;
            }

        });