Сортировать JTable по значению, не включенному в JTable

У меня есть JTable который показывает массив данных типа

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

но в JTable я показываю только первые 3 элемента, а четвертый скрыт для пользователя. Но я бы отсортировал таблицу даже в базе String4это не показано в JTable. Я прочитал учебник JTable, и я узнал, как использовать TableRowSorterи установить Comparator но метод setComparator хочет в качестве аргумента столбец для заказа, но это не доступно для меня.

Может ли кто-нибудь помочь мне решить эту задачу? благодарю вас

1 ответ

Хитрость заключается в том, включить столбец в TableModel, но удалите его из TableColumnModel

Столбец "А" фактически генерируется случайным образом, поэтому он будет сортироваться непредсказуемым образом

Вы можете отключить сортировку столбцов, используя что-то вроде 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);
        }

    }

}

Примечание. Однако визуально это может сбить пользователя с толку, поэтому я бы использовал его с осторожностью.

Другие вопросы по тегам