Swing issue with InputMap / ActionMap

I want my JTextField to process text not only when ENTER is pressed, but also when SPACE is pressed. You can see in the code below that I have associated an action that is usually associated with ENTER in SPACE, but I am getting some unexpected behavior (see below).

import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.Action; import javax.swing.ActionMap; import javax.swing.InputMap; import javax.swing.JFrame; import javax.swing.JTextField; import javax.swing.KeyStroke; public class Test extends JFrame { private JTextField textField; public Test() { textField = new JTextField(); add(textField); InputMap inputMap = this.textField.getInputMap(); Object actionSubmit = inputMap.get(KeyStroke.getKeyStroke("ENTER")); Object actionSubmitSp = inputMap.get(KeyStroke.getKeyStroke("SPACE")); System.out.println("actionSubmit for space = " + actionSubmitSp); ActionMap actionMap = this.textField.getActionMap(); Action action = actionMap.get(actionSubmit); System.out.println("actionSubmit = " + actionSubmit); textField.getInputMap().put(KeyStroke.getKeyStroke("SPACE"), actionSubmit); textField.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent evt) { textField.setText(null); System.out.println("event received:[" + evt.getActionCommand() + "]"); } }); } public static void main(String args[]) { java.awt.EventQueue.invokeLater(new Runnable() { public void run() { Test test = new Test(); test.pack(); test.setVisible(true); } }); } } 

If I type "x SPACE", an ActionEvent is created and the JTextField is cleared. However, the updated JTextField is not a β€œnull” string as requested, but β€œ. SPACE from the previous actionβ€œ leaked ”to the updated JTextField, which is rather annoying.

I looked a little in the swing. My best guess is that an ActionEvent is generated from some KeyEvent, and KeyEvent.isConsumed () has different consequences depending on if KeyEvent was INPUT or SPACE (ENTER is swallowed, but not SPACE).

Does anyone know how to fix this? Or knows another method to achieve my goal?

+4
source share
2 answers

Several events are generated. Your code is executed in the keyPressed event. However, using a space also results in the generation of a keyTyped event. This is handled by the text component after the keyPressed code is executed, so the Document is cleared and then a space is added.

Does anyone know how to fix this?

Do not use KeyListener .

Add your code at the end of the EDT so that it runs AFTER the Document been updated with a space:

 textField.addActionListener(new ActionListener() { @Override public void actionPerformed(final ActionEvent evt) { SwingUtilities.invokeLater(new Runnable() { public void run() { textField.setText(null); System.out.println("event received:[" + evt.getActionCommand() + "]"); } }); } }); 
+4
source

I adapted your test case to use a key listener to use the space character when entering it. Just add the following and leave the rest as is.

  textField.addKeyListener(new KeyListener() { public void keyTyped(KeyEvent e) { if (e.getKeyChar() == ' ') { System.out.println("Was a space character"); e.consume(); } } public void keyPressed(KeyEvent e) { } public void keyReleased(KeyEvent e) { } }); 

I believe the problem is that ENTER is not a displayable character for a text field, while a space character. If you tried something similar in the text area, I assume that you would run into the same problem with the ENTER key.

+2
source

All Articles