java - 按 JTable 中未包含的值对 JTable 进行排序

标签 java swing jtable tablerowsorter

我有一个JTable,它显示了该类型的数据数组

String [] data = {"String1", "String2", "String3", "String4"};

但在 JTable 中,我只显示前 3 项,第四项对用户隐藏。但即使在 JTable 中未显示的 String4 的基础上,我也会对表进行排序。我阅读了 JTable 教程,我发现了如何使用 TableRowSorter 并设置一个 Comparator 但是方法 setComparator 希望将要排序的列作为其参数,但这我不可用。

谁能帮我解决这个任务?谢谢你

最佳答案

诀窍是,将列包含在 TableModel 中,但将其从 TableColumnModel 中移除

Sorted

“A”列实际上是随机生成的,所以它会以不可预知的方式排序

您可以使用类似 sorter.setSortable(1, false); 的方式禁止列进行排序,这可用于防止用户单击列标题并破坏您的“隐藏”排序.

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.RowSorter;
import javax.swing.SortOrder;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableRowSorter;

public class MagicSort {

    public static void main(String[] args) {
        new MagicSort();
    }

    public MagicSort() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private SortOrder order = SortOrder.ASCENDING;

        public TestPane() {
            RowDataTableModel model = new RowDataTableModel();
            TableRowSorter<RowDataTableModel> sorter = new TableRowSorter<>(model);
            sorter.setComparator(0, new Comparator<String>() {
                @Override
                public int compare(String o1, String o2) {
                    return o1.compareTo(o2);
                }
            });

            JTable table = new JTable(model);
            table.setRowSorter(sorter);
            table.getColumnModel().removeColumn(table.getColumn("A"));

            setLayout(new BorderLayout());
            add(new JScrollPane(table));

            JButton change = new JButton("Change");
            add(change, BorderLayout.SOUTH);

            change.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    sort(sorter);
                }
            });

            sort(sorter);
        }

        protected void sort(TableRowSorter<RowDataTableModel> sorter) {

            List<RowSorter.SortKey> keys = new ArrayList<>(1);
            keys.add(new RowSorter.SortKey(0, order));

            sorter.setSortKeys(keys);

            switch (order) {
                case ASCENDING:
                    order = SortOrder.DESCENDING;
                    break;
                case DESCENDING:
                    order = SortOrder.UNSORTED;
                    break;
                case UNSORTED:
                    order = SortOrder.ASCENDING;
                    break;
            }

        }

    }

    public class RowDataTableModel extends AbstractTableModel {

        private List<RowData> data = new ArrayList<>(25);

        public RowDataTableModel() {
            for (int index = 0; index < 10; index++) {
                data.add(new RowData(index));
            }
        }

        public String getKeyColumnValue(int row) {
            return data.get(row).get(0);
        }

        @Override
        public int getRowCount() {
            return data.size();
        }

        @Override
        public int getColumnCount() {
            return 5;
        }

        @Override
        public Object getValueAt(int rowIndex, int columnIndex) {
            return data.get(rowIndex).get(columnIndex);
        }

    }

    public class RowData {

        private List<String> values = new ArrayList<>();

        public RowData(int offset) {
            offset *= 5;
            for (int index = 1; index < 5; index++) {
                values.add(Character.toString((char) ('A' + (offset + index))));
            }

            values.add(0, Character.toString((char) ('A' + Math.random() * 26)));
        }

        public String get(int col) {
            return values.get(col);
        }

    }

}

注意:但是,从视觉上看,这可能会让用户感到困惑,所以我会谨慎使用它。

关于java - 按 JTable 中未包含的值对 JTable 进行排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32863249/

相关文章:

java - 如何修复闪烁

java - JNA char** 参数

java - 使用注释验证值对象

java - JTable焦点查询?

java - 以编程方式启用通过击键编辑 JTable 单元格

Java JTable - 只使一列可编辑

Java循环异常

java - 如何解决错误? Swing 按钮重画

java - 打印 JComponent

java - 在 JFileChooser 中选择文件后关闭 Jframe