[java] Allowing the "Enter" key to press the submit button, as opposed to only using MouseClick

I'm learning Swing class now and everything about it. I've got this toy program I've been putting together that prompts for a name and then presents a JOptionPane with the message "You've entered (Your Name)". The submit button I use can only be clicked on, but I'd like to get it to work with the Enter button too. I've tried adding a KeyListener, as is recommended in the Java book I'm using (Eventful Java, Bruce Danyluk and Murtagh).

NamePrompt enter image description here

This is my code:

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;


public class NamePrompt extends JFrame{


    private static final long serialVersionUID = 1L;

    String name;

    public NamePrompt(){

        setLayout(new BorderLayout());

        JLabel enterYourName = new JLabel("Enter Your Name Here:");
        JTextField textBoxToEnterName = new JTextField(21);
        JPanel panelTop = new JPanel();
        panelTop.add(enterYourName);
        panelTop.add(textBoxToEnterName);

        JButton submit = new JButton("Submit");
        submit.addActionListener(new SubmitButton(textBoxToEnterName));
        submit.addKeyListener(new SubmitButton(textBoxToEnterName));
        JPanel panelBottom = new JPanel();
        panelBottom.add(submit);

        //Add panelTop to JFrame
        add(panelTop, BorderLayout.NORTH);
        add(panelBottom, BorderLayout.SOUTH);

        //JFrame set-up
        setTitle("Name Prompt Program");
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        pack();
        setLocationRelativeTo(null);


    }



    public static void main(String[] args) {
        NamePrompt promptForName = new NamePrompt();
        promptForName.setVisible(true); 
    }


}

And this is the actionListener, keyListener class:

import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JTextField;


public class SubmitButton implements ActionListener, KeyListener {

    JTextField nameInput;


    public SubmitButton(JTextField textfield){
        nameInput = textfield;
    }

    @Override
    public void actionPerformed(ActionEvent submitClicked) {

        Component frame = new JFrame();
        JOptionPane.showMessageDialog(frame , "You've Submitted the name " + nameInput.getText());
    }

    @Override
    public void keyPressed(KeyEvent e) {
        if (e.getKeyCode()==KeyEvent.VK_ENTER){
            System.out.println("Hello");
        }
        Component frame = new JFrame();
        JOptionPane.showMessageDialog(frame , "You've Submitted the name " + nameInput.getText());

    }

    @Override
    public void keyReleased(KeyEvent arg0) {
        // TODO Auto-generated method stub

    }

    @Override
    public void keyTyped(KeyEvent arg0) {

    }
}

This question is related to java swing keylistener

The answer is


You can use the top level containers root pane to set a default button, which will allow it to respond to the enter.

SwingUtilities.getRootPane(submitButton).setDefaultButton(submitButton);

This, of course, assumes you've added the button to a valid container ;)

UPDATED

This is a basic example using the JRootPane#setDefaultButton and key bindings API

public class DefaultButton {

    public static void main(String[] args) {
        new DefaultButton();
    }

    public DefaultButton() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Test");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }

        });
    }

    public class TestPane extends JPanel {

        private JButton button;
        private JLabel label;
        private int count;

        public TestPane() {

            label = new JLabel("Press the button");
            button = new JButton("Press me");

            setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridy = 0;
            add(label, gbc);
            gbc.gridy++;
            add(button, gbc);
            gbc.gridy++;
            add(new JButton("No Action Here"), gbc);

            button.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    doButtonPressed(e);
                }

            });

            InputMap im = button.getInputMap(WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
            ActionMap am = button.getActionMap();

            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0), "spaced");
            am.put("spaced", new AbstractAction() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    doButtonPressed(e);
                }

            });

        }

        @Override
        public void addNotify() {
            super.addNotify();
            SwingUtilities.getRootPane(button).setDefaultButton(button);
        }

        protected void doButtonPressed(ActionEvent evt) {
            count++;
            label.setText("Pressed " + count + " times");
        }

    }

}

This of course, assumes that the component with focus does not consume the key event in question (like the second button consuming the space or enter keys


Without a frame this works for me:

JTextField tf = new JTextField(20);
tf.addKeyListener(new KeyAdapter() {

  public void keyPressed(KeyEvent e) {
    if (e.getKeyCode()==KeyEvent.VK_ENTER){
       SwingUtilities.getWindowAncestor(e.getComponent()).dispose();
    }
  }
});
String[] options = {"Ok", "Cancel"};
int result = JOptionPane.showOptionDialog(
    null, tf, "Enter your message", 
    JOptionPane.OK_CANCEL_OPTION,
    JOptionPane.QUESTION_MESSAGE,
    null,
    options,0);

message = tf.getText();

textField_in = new JTextField();
textField_in.addKeyListener(new KeyAdapter() {

    @Override
    public void keyPressed(KeyEvent arg0) {
        System.out.println(arg0.getExtendedKeyCode());
        if (arg0.getKeyCode()==10) {
            String name = textField_in.getText();
            textField_out.setText(name);
        }

    }

});
textField_in.setBounds(173, 40, 86, 20);
frame.getContentPane().add(textField_in);
textField_in.setColumns(10);

In the ActionListener Class you can simply add

public void actionPerformed(ActionEvent event) {
    if (event.getSource()==textField){
        textButton.doClick();
    }
    else if (event.getSource()==textButton) {
        //do something
    }
}

 switch(KEYEVENT.getKeyCode()){
      case KeyEvent.VK_ENTER:
           // I was trying to use case 13 from the ascii table.
           //Krewn Generated method stub... 
           break;
 }

I know this isn't the best way to do it, but right click the button in question, events, key, key typed. This is a simple way to do it, but reacts to any key