Search code examples
javaswingjdialog

Can I keep a JDialog from closing on escape/enter press?


I created a dialog to take user keystrokes to change key bindings for menu items. I'd like enter and escape to be keys the user can bind, but they both close the dialog. How can those presses be intercepted?

Edit: dialog is created with JOptionPane and a custom component

GetKeyComponent comp = new GetKeyComponent(accels, menuItem);
Object[] array = { comp };
JOptionPane optionPane = new JOptionPane(array, 
    JOptionPane.PLAIN_MESSAGE, JOptionPane.OK_CANCEL_OPTION);

Solution

  • Edit: dialog is created with JOptionPane and a custom component

    One solution: don't do this. Create your own modal JDialog, set its KeyBindings, and use it. e.g.,

    import java.awt.event.ActionEvent;
    import java.awt.event.KeyEvent;    
    import javax.swing.*;
    
    public class JDialogTest {
       private static void createAndShowGUI() {
          final JFrame frame = new JFrame("JDialogTest");
    
          JPanel panel = new JPanel();
          panel.add(new JButton(new AbstractAction("Push Me") {
    
             @Override
             public void actionPerformed(ActionEvent arg0) {
                final JTextArea textArea = new JTextArea(15, 30);
                textArea.setFocusable(false);
                JDialog dialog = new JDialog(frame, "Dialog", true);
    
                int condition = JComponent.WHEN_IN_FOCUSED_WINDOW;
                JPanel contentPane = (JPanel) dialog.getContentPane();
                InputMap inputMap = contentPane.getInputMap(condition);
                ActionMap actionMap = contentPane.getActionMap();
    
                KeyStroke enterKs = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0);
                inputMap.put(enterKs, enterKs.toString());
                actionMap.put(enterKs.toString(), new AbstractAction() {
    
                   @Override
                   public void actionPerformed(ActionEvent arg0) {
                      textArea.append("Enter pushed\n");
                   }
                });
    
                KeyStroke escKs = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0);
                inputMap.put(escKs, escKs.toString());
                actionMap.put(escKs.toString(), new AbstractAction() {
    
                   @Override
                   public void actionPerformed(ActionEvent arg0) {
                      textArea.append("Escape pushed\n");
                   }
                });
    
    
                dialog.add(new JScrollPane(textArea));
                dialog.pack();
                dialog.setVisible(true);
             }
          }));
    
          frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          frame.getContentPane().add(panel);
          frame.pack();
          frame.setLocationRelativeTo(null);
          frame.setVisible(true);
       }
    
       public static void main(String[] args) {
          SwingUtilities.invokeLater(new Runnable() {
             public void run() {
                createAndShowGUI();
             }
          });
       }
    }