Search code examples
javaswingjtablekeylistenertablecelleditor

how to detect enter pressed while jtable cell is being edited?


I have a keylistener on jtable so that when someone presses enter some calculations happen. However, this only happens if the person is not editing. I would like to apply this action when a person finishes editing a cell and is pressing enter to finish and close the editing.

I cannot figure this out, anyone ever did this or know how to?

Basically, now for the action to be done, people must press enter twice, one to end the editing and another for the action that I want to happen, I would like to make it needed only once, while editing.

Thank you


Solution

  • You can override JTable.editingStopped, which is invoked when editing is finished and apply your actions in that method.

    EDIT:

    JTable.editingStopped was not designed for application extension. To avoid complications, in particular platform dependent ones, a better approach is to override model's setValueAt or register a TableModelListener. Here is an example:

    import javax.swing.*;
    import javax.swing.event.TableModelEvent;
    import javax.swing.event.TableModelListener;
    import javax.swing.table.DefaultTableModel;
    
    public class DemoTable3 {
        private static void createAndShowUI() {
            JFrame frame = new JFrame("DemoTable");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
            Object[][] rows = { { "Column 1", "Column 2" },
                    { "Column 1", "Column 2" } };
            Object[] columns = { "Column 1", "Column 2" };
    
            DefaultTableModel model = new DefaultTableModel(rows, columns);
            model.addTableModelListener(new TableModelListener() {
                @Override
                public void tableChanged(TableModelEvent e) {
                    System.out.println("apply additional action");
                }
            });
    
            JTable table = new JTable(model);
            frame.add(new JScrollPane(table));
            frame.setLocationByPlatform(true);
            frame.pack();
            frame.setVisible(true);
        }
    
        public static void main(String args[]) {
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    createAndShowUI();
                }
            });
        }
    }
    

    Another alternative is to add CellEditorListener to catch editingStopped events. For example:

    import javax.swing.*;
    import javax.swing.event.CellEditorListener;
    import javax.swing.event.ChangeEvent;
    import javax.swing.table.DefaultTableModel;
    
    public class DemoTable2 {
    
        private static void createAndShowUI() {
            JFrame frame = new JFrame("DemoTable");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
            Object[][] rows = { { "Column 1", "Column 2" },
                    { "Column 1", "Column 2" } };
            Object[] columns = { "Column 1", "Column 2" };
    
            final JTable table = new JTable(new DefaultTableModel(rows, columns));
    
            table.getDefaultEditor(String.class).addCellEditorListener(
                    new CellEditorListener() {
                        public void editingCanceled(ChangeEvent e) {
                            System.out.println("editingCanceled");
                        }
    
                        public void editingStopped(ChangeEvent e) {
                            System.out.println("editingStopped: apply additional action");
                        }
                    });
    
            frame.add(new JScrollPane(table));
            frame.setLocationByPlatform(true);
            frame.pack();
            frame.setVisible(true);
        }
    
        public static void main(String args[]) {
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    createAndShowUI();
                }
            });
        }
    }
    

    Also look at a Table Cell Listener by @camickr which offers custom processing of the edits.