user3750671
user3750671

Reputation: 33

Inconsistent behavior when editing JTable

I want to create a JTable that has the following properties:

I tried to implement this last item by adding an item to the ActionMap of the text field of a DefaultCellEditor. This works under the following sequence:

But if I navigate to any other cell via tab, edit that cell, then click enter, this does not work. The Action is only fired if I hit enter in the cell that I started editing via a click. If I got to that cell by tabbing or using the arrow keys, it does not work.

I think maybe the focus is still on the cell where I started editing? I noticed that if I click/edit/tab a few times, then click in the currently edited cell before pressing enter, that seems to work.

Does tabbing take the user to the next cell without transferring focus? Any help would be appreciated.

package jtabletest;

import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;

import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.DefaultCellEditor;
import javax.swing.InputMap;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;

public class JTableKeyMap {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(JTableKeyMap::createAndDisplayGui);
    }


    public static void createAndDisplayGui() {
        final JTable table = new JTable(4, 4);
        final JTextField cell = new JTextField();
        final DefaultCellEditor cellEditor = new DefaultCellEditor(cell);
        cellEditor.setClickCountToStart(1);

        table.setDefaultEditor(Object.class, cellEditor);

        KeyStroke enterKeyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0);
        String enterText = "enterKeyPressed";

        final InputMap iMap = cell.getInputMap(JComponent.WHEN_FOCUSED);
        iMap.put(enterKeyStroke, enterText);

        AbstractAction action = new AbstractAction() {
            @Override
            public void actionPerformed(final ActionEvent e) {
                System.out.println("Callback for key event");
                cellEditor.stopCellEditing();
            }
        };

        ActionMap aMap = cell.getActionMap();
        aMap.put(enterText, action);

        aMap.put(KeyEvent.getKeyText(KeyEvent.VK_ENTER), new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                System.out.println("Callback for key event");

                cellEditor.stopCellEditing();
            }
        });

        JScrollPane scrollPane = new JScrollPane(table);


        final JFrame frame = new JFrame("Table Test");
        frame.setContentPane(scrollPane);
        frame.setPreferredSize(scrollPane.getPreferredSize());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
    }
}

Upvotes: 0

Views: 40

Answers (1)

camickr
camickr

Reputation: 324098

Add the following when you create you JTable:

table.setSurrendersFocusOnKeystroke(true);

This will give the editor focus if you just start typing when a cell has focus. Then the editor will respond to your key bindings.

Upvotes: 2

Related Questions