JTable edit on keypress

前端 未结 1 940
自闭症患者
自闭症患者 2021-01-23 20:12

I am trying to programatically start editing third column of current row in a JTable on a keypress.

I\'ve implemented a KeyListener which in keyReleas

相关标签:
1条回答
  • 2021-01-23 20:59

    Avoid KeyListener, it is unreliable when it comes to focus and the order in which the events are dispatched (it's possible to have they key consumed BEFORE your listener, so you would never be notified).

    Use key bindings instead

    InputMap im = table.getInputMap(JTable.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
    ActionMap am = table.getActionMap();
    
    KeyStroke enterKey = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0);
    
    im.put(enterKey, "Action.enter");
    am.put("Action.enter", new AbstractAction() {
        public void actionPerformed(ActionEvent evt) {
            table.changeSelection(table.getSelectedRow(), 2, false, false);
            if (!table.editCellAt(table.getSelectedRow(), 2)) {
                JOptionPane.showMessageDialog(table, "Failed to start cell editing");
            }
        }
    });
    

    I'm also suspicious of this myTab.changeSelection(myTab.getSelectedRow(), 2, true, false); call. The JavaDocs basically say...

    toggle: true, extend: false. If the specified cell is selected, deselect it. If it is not selected, select it.

    Which suggest to me, if the cell is currently selected, it will be made unselected.

    Updated with working example

    public class TestTableEditor {
    
        public static void main(String[] args) {
            new TestTableEditor();
        }
    
        private JTable table;
    
        public TestTableEditor() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    }
    
                    table = new JTable(new MyTableModel());
                    InputMap im = table.getInputMap(JTable.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
                    ActionMap am = table.getActionMap();
    
                    KeyStroke enterKey = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0);
    
                    im.put(enterKey, "Action.enter");
                    am.put("Action.enter", new AbstractAction() {
                        public void actionPerformed(ActionEvent evt) {
                            table.changeSelection(table.getSelectedRow(), 1, false, false);
                            if (!table.editCellAt(table.getSelectedRow(), 1)) {
                                JOptionPane.showMessageDialog(table, "Failed to start cell editing");
                            }
                        }
                    });
    
                    JFrame frame = new JFrame();
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.setLayout(new BorderLayout());
                    frame.add(new JScrollPane(table));
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    
        public class MyTableModel extends AbstractTableModel {
    
            @Override
            public int getRowCount() {
                return 1;
            }
    
            @Override
            public int getColumnCount() {
                return 3;
            }
    
            @Override
            public Object getValueAt(int rowIndex, int columnIndex) {
                Object value = null;
                switch (columnIndex) {
                    case 0:
                        value = "Can't edit";
                        break;
                    case 1:
                        value = "Edit me";
                        break;
                    case 2:
                        value = "Can't edit";
                        break;
                }
                return value;
            }
    
            @Override
            public boolean isCellEditable(int rowIndex, int columnIndex) {
                return columnIndex == 1;
            }
        }
    }
    

    Updated

    Of all the stupid, painful, hard to find ...

    Add table.setSurrendersFocusOnKeystroke(true); to your code...

    Sets whether editors in this JTable get the keyboard focus when an editor is activated as a result of the JTable forwarding keyboard events for a cell. By default, this property is false, and the JTable retains the focus unless the cell is clicked.

    0 讨论(0)
提交回复
热议问题