用键盘对JTable进行排序?

问题描述 投票:0回答:1

我可以通过单击任何列对 JTable 进行排序,但我还需要使用键盘对 JTable 进行排序。

是否有内置方法可以通过键盘以相同的方式进行排序,或者我是否必须添加某种侦听器?

java swing jtable
1个回答
0
投票

我创建了一个示例 GUI,允许用户使用键盘对

JTable
进行排序。
JTable
必须具有
table.setColumnSelectionAllowed(true);
table.setRowSelectionAllowed(false);
才能使此应用程序正常工作。

这是 GUI 的样子。

Example

您可以通过左键单击列标题对列进行排序。 您还可以使用以下键盘按键对列进行排序。 (感谢@Just 另一位 Java 程序员的评论。)

  • CTRL + 向右键 - 选择下一列。
  • CTRL + 向左键 - 选择上一列。
  • CTRL + 向上键 - 按升序对所选列进行排序。
  • CTRL + 向下键 - 按降序对所选列进行排序。
  • CTRL + SPACE - 对所选列取消排序,恢复原始顺序。

不按 CTRL 的左右箭头也会选择一列。 为了保持一致性,我决定使用 CTRL +。 默认左右箭头不会选择排序列。

这是完整的可运行代码。 我制作了所有附加类的内部类,这样我就可以将代码作为一个块发布。

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.List;

import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.BorderFactory;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.KeyStroke;
import javax.swing.RowSorter;
import javax.swing.SortOrder;
import javax.swing.SwingUtilities;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;

public class SortJTable implements Runnable {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new SortJTable());
    }

    private int columnIndexToSort;

    private final Company company;

    private JTable table;

    public SortJTable() {
        this.company = new Company();
        this.columnIndexToSort = -1;
    }

    @Override
    public void run() {
        JFrame frame = new JFrame("Sort JTable");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.add(createTablePanel(), BorderLayout.CENTER);

        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    private JPanel createTablePanel() {
        JPanel panel = new JPanel(new BorderLayout());
        panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));

        EmployeeTableModel tableModel = new EmployeeTableModel();
        Employee[] employees = company.getEmployees();
        for (Employee employee : employees) {
            tableModel.addRow(employee);
        }

        table = new JTable(tableModel);
        table.getColumnModel().getColumn(2)
                .setCellRenderer(new SalaryCellRenderer());
        table.setAutoCreateRowSorter(true);
        table.setColumnSelectionAllowed(true);
        table.setRowSelectionAllowed(false);
        setKeyBindings(table);
        JScrollPane scrollPane = new JScrollPane(table);
        panel.add(scrollPane, BorderLayout.CENTER);

        return panel;
    }

    private void setKeyBindings(JTable table) {
        InputMap inputMap = table.getInputMap();
        ActionMap actionMap = table.getActionMap();

        inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP,
                InputEvent.CTRL_DOWN_MASK), "ctrl up");
        inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN,
                InputEvent.CTRL_DOWN_MASK), "ctrl down");
        inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT,
                InputEvent.CTRL_DOWN_MASK), "ctrl left");
        inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT,
                InputEvent.CTRL_DOWN_MASK), "ctrl right");
        inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE,
                InputEvent.CTRL_DOWN_MASK), "ctrl space");

        actionMap.put("ctrl up",
                new SortColumnAction(this, SortOrder.ASCENDING));
        actionMap.put("ctrl down",
                new SortColumnAction(this, SortOrder.DESCENDING));
        actionMap.put("ctrl left", new SelectColumnAction(this, -1));
        actionMap.put("ctrl right", new SelectColumnAction(this, +1));
        actionMap.put("ctrl space",
                new SortColumnAction(this, SortOrder.UNSORTED));
    }

    public JTable getTable() {
        return table;
    }

    public int getColumnIndexToSort() {
        return columnIndexToSort;
    }

    public void setColumnIndexToSort(int columnIndexToSort) {
        this.columnIndexToSort = columnIndexToSort;
    }

    public class SelectColumnAction extends AbstractAction {

        private static final long serialVersionUID = 1L;

        private final int columnCount, increment;

        private final SortJTable view;

        public SelectColumnAction(SortJTable view, int increment) {
            this.view = view;
            this.increment = increment;
            this.columnCount = view.getTable().getColumnCount();
        }

        @Override
        public void actionPerformed(ActionEvent event) {
            int columnIndexToSort = view.getColumnIndexToSort();
            columnIndexToSort += increment;
            columnIndexToSort %= columnCount;
            columnIndexToSort = (columnIndexToSort < 0)
                    ? columnIndexToSort + columnCount
                    : columnIndexToSort;

            JTable table = view.getTable();
            table.removeColumnSelectionInterval(0, table.getColumnCount() - 1);
            table.addColumnSelectionInterval(columnIndexToSort,
                    columnIndexToSort);
            view.setColumnIndexToSort(columnIndexToSort);
        }

    }

    public class SortColumnAction extends AbstractAction {

        private static final long serialVersionUID = 1L;

        private final SortJTable view;

        private final SortOrder sortOrder;

        public SortColumnAction(SortJTable view, SortOrder sortOrder) {
            this.view = view;
            this.sortOrder = sortOrder;
        }

        @Override
        public void actionPerformed(ActionEvent event) {
            int columnIndexToSort = view.getColumnIndexToSort();
            columnIndexToSort = Math.max(0, columnIndexToSort);
            JTable table = view.getTable();
            TableRowSorter<TableModel> sorter = new TableRowSorter<>(
                    table.getModel());
            table.setRowSorter(sorter);

            List<RowSorter.SortKey> sortKeys = new ArrayList<>();
            sortKeys.add(new RowSorter.SortKey(columnIndexToSort, sortOrder));

            sorter.setSortKeys(sortKeys);
            sorter.sort();

//          table.addColumnSelectionInterval(columnIndexToSort, columnIndexToSort);
        }

    }

    public class SalaryCellRenderer extends DefaultTableCellRenderer {

        private static final long serialVersionUID = 1L;

        @Override
        public Component getTableCellRendererComponent(JTable table,
                Object value, boolean isSelected, boolean hasFocus, int row,
                int column) {
            JLabel label = (JLabel) super.getTableCellRendererComponent(table,
                    value, isSelected, hasFocus, row, column);
            int salary = (Integer) value;
            label.setText("$" + String.format("%,d", salary) + " ");
            label.setHorizontalAlignment(JLabel.TRAILING);
            return label;
        }

    }

    public class EmployeeTableModel extends DefaultTableModel {

        private static final long serialVersionUID = 1L;

        public EmployeeTableModel() {
            super();
            String[] columns = { "Name", "Title", "Salary" };
            this.setColumnIdentifiers(columns);
        }

        public void addRow(Employee employee) {
            Object[] newRow = new Object[3];
            newRow[0] = employee.getName();
            newRow[1] = employee.getTitle();
            newRow[2] = employee.getSalary();
            this.addRow(newRow);
        }

        @Override
        public Class<?> getColumnClass(int column) {
            if (column == 2) {
                return Integer.class;
            } else {
                return String.class;
            }
        }

    }

    public class Company {

        private final Employee[] employees;

        public Company() {
            this.employees = new Employee[10];
            this.employees[0] = new Employee("Smith, John", "Senior Analyst",
                    75_000);
            this.employees[1] = new Employee("White, Susan", "Junior Analyst",
                    35_200);
            this.employees[2] = new Employee("Baker, Nancy", "Senior Analyst",
                    75_600);
            this.employees[3] = new Employee("Potter, Harry", "Junior Analyst",
                    36_100);
            this.employees[4] = new Employee("Smythe, Frank", "Analyst",
                    52_700);
            this.employees[5] = new Employee("Accosta, Sue", "Senior Analyst",
                    75_000);
            this.employees[6] = new Employee("Baker, Veronica", "Analyst",
                    50_500);
            this.employees[7] = new Employee("Green, Maggie", "Analyst",
                    52_700);
            this.employees[8] = new Employee("Wesson, James", "Analyst",
                    52_700);
            this.employees[9] = new Employee("Ericson, Leif", "Analyst",
                    51_400);
        }

        public Employee[] getEmployees() {
            return employees;
        }

    }

    public class Employee {

        private int salary;

        private String name, title;

        public Employee(String name, String title, int salary) {
            this.name = name;
            this.title = title;
            this.salary = salary;
        }

        public int getSalary() {
            return salary;
        }

        public void setSalary(int salary) {
            this.salary = salary;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getTitle() {
            return title;
        }

        public void setTitle(String title) {
            this.title = title;
        }

    }

}
© www.soinside.com 2019 - 2024. All rights reserved.