0

In the SSCCE bellow, I have a JTextField with a registered KeyListener. The KeyRelease function, will show a JOptionPane if the key is ENTER.

The problem is: if the user validates the JOptionPane using the ENTER key, the option pane will appear again! Seems the ENTER key is not consumed and forwarded to the JTextField.

Any clue ?

import java.awt.EventQueue;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

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

public class DefaultButtonAndTextFieldKeypress {
    private static void createGUI() {
        JFrame f = new JFrame("Test");
        f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

        JTextField tf = new JTextField("Press ENTER");
        tf.addKeyListener(new KeyListener() {           
            @Override
            public void keyTyped(KeyEvent e) {}

            @Override
            public void keyReleased(KeyEvent e) {
                System.out.println("TextField::keyReleased");
                if (e.getKeyCode() == KeyEvent.VK_ENTER) {
                    JOptionPane.showMessageDialog(f, "Invalid input value, Press ENTER");
                }
            }

            @Override
            public void keyPressed(KeyEvent e) {}
        });

        f.add(tf);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                createGUI();
            }
        });
    }
}
TT.
  • 15,774
  • 6
  • 47
  • 88
Staifi78
  • 3
  • 1
  • What if you open the JOptionPane from the `keyPressed` function instead? Also, I'm not seeing you consume key events yourself. – TT. May 23 '20 at 06:31

1 Answers1

1

This happens because dialog closes when keyPressed, but you open the dialog when keyReleased. Lets see how it runs with an example:

  1. You press Enteron text field, nothing happens.
  2. You RELEASE Enter, dialog pops up.
  3. You press Enter, dialog closes and text field gains focus.
  4. You release Enter, (because u had it pressed to close dialog), and dialog pops up again.

I suggest you the following solution, when it comes to Enter press in a JTextField:

tf.addActionListener(e -> {
    JOptionPane.showMessageDialog(f, "Invalid input value, Press ENTER");
});

Check it yourself and you will see it behaves perfect.

Now, with if you want to use your key listener, it will require more effort in order to achieve it safely. Maybe a focus listener that recognizes when enter was not pressed in the text field at the first place (it was pressed on the dialog, but RELEASED on text field).

I guess there are other workarounds too, but I suggest you to use the action listener.

George Z.
  • 6,643
  • 4
  • 27
  • 47
  • Thanks very much, it's perfectly clear to me what's going on here. And i do need the keyListener because this is a simplified part of my application (to illustrate the problem), and my current JTextField is managing other keys ;( – Staifi78 May 23 '20 at 07:12
  • I moved the ENTER key management from the keyListener to an action listener as suggested, and keep the other keys, it's workig great ! So For me this answered my question and saved my day ;) – Staifi78 May 23 '20 at 07:22
  • @Staifi78 I am glad that I helped you. Since you are a new user, take a look at [What should I do when someone answers my question](https://stackoverflow.com/help/someone-answers). – George Z. May 23 '20 at 08:49