【问题标题】:JTabe selecting / highlighting row(s) by pressing a key on keyboardJTabe 通过按键盘上的键来选择/突出显示行
【发布时间】:2015-09-01 12:32:06
【问题描述】:

我有一个实际上有 4 列和很多行的 JTable。现在我想通过按下键盘上的一个键来选择一行或多行。但我不知道该怎么做。

这是我想要的示例:

  • 如果我在键盘上按“F”,我的应用程序应该选择或突出显示表格中的第一行,该行有一个以字符“F”开头的条目(或我按下的另一个)
  • 如果我再次按下同一个键(此处为“F”),则应选择或突出显示以字符“F”开头的条目的下一行
  • 如果选择了最后一行并且我再次按下相同的键,它应该再次选择或突出显示第一行(循环)
  • 当我按下另一个键时,例如“U”,它应该对上面以“U”开头的行执行相同的操作。

【问题讨论】:

    标签: java select keyboard jtable highlight


    【解决方案1】:

    这听起来是个有趣的问题。所以我破解了一些可以作为你解决方案的基础的东西。注意:您可以通过适当的封装和泛型进一步改进这一点。 警告:仅当您的表数据模型很小时才使用它。如果它很大,您应该考虑一些更好的搜索方法以及并发/UI 反馈,以避免冻结您的 UI。 无论如何,解决方案将与以下类似。关键是向表中添加一个键侦听器,然后根据行/列值检查按键字符。高温

    package example;
    
    import javax.swing.*;
    import javax.swing.table.DefaultTableModel;
    import javax.swing.table.TableModel;
    import java.awt.*;
    import java.awt.event.KeyAdapter;
    import java.awt.event.KeyEvent;
    
    /** Extend default model to make cells non-editable */
    class MyTableModel extends DefaultTableModel {
        public MyTableModel(Object[][] data, Object[] headers) {
            super(data, headers);
        }
    
        @Override
        public boolean isCellEditable(int row, int column) {
            return false;
        }
    }
    
    /** Key listener that controls row highlighting */
    class SearchingKeyAdapter extends KeyAdapter {
        private final JTable table;
        private int selectedRow = -1;//before start
    
        public SearchingKeyAdapter(JTable table) {
            this.table = table;
        }
    
        @Override
        public void keyReleased(KeyEvent e) {
            String keyChar = String.valueOf(e.getKeyChar());
            TableModel model = table.getModel();
            int startRow = selectedRow;
            if (selectedRow == model.getRowCount() - 1) {
                startRow = -1;//Go before start
            }
            //Check each cell to see if it starts with typed char.
            //if so set corresponding row selected and return.
            for (int row = startRow+1; row < model.getRowCount(); row++) {
                for (int col = 0; col < model.getColumnCount(); col++) {
                    String value = (String) model.getValueAt(row, col);
                    if (value != null && value.startsWith(keyChar)) {
                        table.getSelectionModel().clearSelection();
                        table.getColumnModel().getSelectionModel().clearSelection();
                        table.setRowSelectionInterval(row, row);
                        selectedRow = row;
                        return;
                    }
                }
            }
    
        }
    }
    
    public class App {
        JFrame frame;
        JTable table;
        String[][] data = {
                {"for", "util", "synchronized", "final"}, {"finally", "throw", "throws", "try"}, {"import", "class", "interface", "if"}, {"public", "private", "protected", "volatile"}
        };
        String[] headers = {"Keyword1", "Keyword2", "Keyword3", "Keyword3"};
    
        public App() {
            table = new JTable();
            table.setModel(new MyTableModel(data, headers));
            //Add special key listener that will move highlight based on typed char
            table.addKeyListener(new SearchingKeyAdapter(table));
            //We need to have only single selection
            table.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
            frame = new JFrame();
            frame.setLayout(new BorderLayout());
            JScrollPane scrollPane = new JScrollPane();
            scrollPane.getViewport().add(table);
            frame.getContentPane().add(scrollPane);
            frame.pack();
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setVisible(true);
        }
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    App app = new App();
                }
            });
        }
    }
    

    【讨论】:

    • 感谢您的帮助。我用你的代码试过了,对于我的实际表格,它几乎可以工作,我想要它。但是一个问题是:当我通过单击其中一个 tableHeader 列对表格进行排序时,您的代码将停止工作。我注意到的另一个问题是:当我不选择任何行并对表格进行排序时,它会选择行,但会选择错误的行,所以 tableDataModel 或它所做的选择不正确:(你能添加这块吗我需要的代码,当我对我的表进行排序时它也可以工作?再次感谢!:)
    • 您好,请注意,当您进行排序时,您正在干预模型本身。因此很可能 selectedRow 变量值在该上下文中变得无效。代码的目的是展示如何实现这一点,它并未涵盖所有用例。值得您尝试解决这个问题。
    猜你喜欢
    • 2012-12-01
    • 1970-01-01
    • 2012-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多