Getting ENTER to work with JSpinner in the same way as with JTextField

First, to simplify my work, explain a bit, here are some of my code:

JSpinner spin = new JSpinner(); JFormattedTextField text = getTextField(spin); text.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { // Do stuff... } }); 

...

 private JFormattedTextField getTextField(JSpinner spinner) { JComponent editor = spinner.getEditor(); if (editor instanceof JSpinner.DefaultEditor) { return ((JSpinner.DefaultEditor )editor).getTextField(); } else { System.err.println( "Unexpected editor type: " + spinner.getEditor().getClass() + " isn't a descendant of DefaultEditor" ); return null; } } 

So, as you can see, I got this far. And indeed, when I enter a value into the component of the counter text field ( JFormattedTextField ), and THEN presses ENTER, it works.

Now I want the text field to respond to ENTER without having to manually enter a new value (which sorta hits the goal of creating a counter from). How to do it?

+4
source share
2 answers

I know this is not an action listener ... but maybe this might work for you?

 text.addKeyListener( new KeyAdapter() { @Override public void keyReleased( final KeyEvent e ) { if ( e.getKeyCode() == KeyEvent.VK_ENTER ) { System.out.println( "enter pressed" ); } } } ); 
+4
source

I just ran into a problem with this. In my case, I had a JSpinner with a SpinnerNumberModel setting SpinnerNumberModel that I could enter numeric identification values ​​and then retrieve them from the remote database. This worked well and well with JButton as my trigger for the query, but I wanted to be able to switch focus to the field via Tab and press enter, and also be able to change the value by entering an identifier with numeric keys, then press enter.

The one that gave me the most questions manually entered an identifier with number keys, and then hit enter. When I do this, the request will still occur, but it requests the previous identifier, not the one I just entered, so I would need to press Enter again to request a new identifier (see Code)

 ((JSpinner.DefaultEditor) minRng.getEditor()).getTextField().addKeyListener(new KeyAdapter() { @Override public void keyPressed(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_ENTER) { queryData(); } } }); 

and request method:

 private void queryData() { int minVal = Integer.parseInt(minRng.getValue().toString()); queryDataBase(minVal); } 

To fix this, all I had to do was make the request wait until the counter updated its value, which was easily done using SwingUtilities.invokeLater() to force it to the end of the EDT queue, like this:

 ((JSpinner.DefaultEditor) minRng.getEditor()).getTextField().addKeyListener(new KeyAdapter() { @Override public void keyPressed(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_ENTER) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { queryData(); } }); } } }); 

Thanks to invokeLater() request is now executed by the new value, and not by the previous one, when enter was pressed, when JSpinner then updated its value to the new input.

I assume the reason is that the entered value is not officially applied to JSpinner until you hit enter, which also calls the key listener for the request. KeyEvent for the user query listener [query] appears to be the first in the queue, so it runs its code first, and THEN the KeyEvent to apply the value to the JSpinner from the internal JFormattedTextField , so it requests the old value. SwingUtilities.invokeLater() simply puts the request itself at the end of the queue, so it allows another KeyEvent to complete its code before running the request.

Edit:

Another way to achieve this is to request the value directly from the JFormattedTextField and not JSpinner , as this should also return the newly entered value, since the JFormattedTextField contains the entered value, but it hasn’t yet been passed to JSpinner, which seems to be where the problem is .

 private void queryData() { JFormattedTextField tf = ((JSpinner.DefaultEditor) minRng.getEditor()).getTextField(); int minVal = Integer.parseInt(tf.getText()); queryDataBase(minVal); } 

The only problem with this method is that then you need to catch any NumberFormatException s when parsing the value, where the SwingUtilities.invokeLater() approach allows the spinner model to automatically remove any invalid characters and continue the request.

Anyway, I'm still a little inexperienced with Java, so if my understanding of this is wrong, let me know in the comments.

0
source

All Articles