0

My jSpinner does not reflect the value to JLabel when I change the value using keyboard.

When I use up down arrows works fine !

enter image description here

When I use keyboard JLabel remains with previous value

enter image description here

Here is the code below

private void jSpinner1StateChanged(javax.swing.event.ChangeEvent evt) {                                       

    value = (Integer)jSpinner1.getValue();
    jLabel1.setText(value.toString());
 }                                      

  private void jSpinner1KeyTyped(java.awt.event.KeyEvent evt) {                                   

   value = (Integer)jSpinner1.getValue();
   jLabel1.setText(value.toString());

}    
mKorbel
  • 109,525
  • 20
  • 134
  • 319
user3498019
  • 95
  • 1
  • 2
  • 10
  • I'm not surprised, the `JSpinner` isn't an editor in of itself, it's a container for several other classes. – MadProgrammer May 06 '14 at 08:51
  • so what to do ? why they put in right click on jspinner and add events like keyreleased keytyped etc... in Netbeans ? – user3498019 May 06 '14 at 08:53
  • From memory, you need to hit `Enter` to make the new value be written to the model. Forget the `KeyListener`, it is a dead end here. For better help sooner, post an [MCVE](http://stackoverflow.com/help/mcve) (Minimal Complete and Verifiable Example). – Andrew Thompson May 06 '14 at 10:53

4 Answers4

3

My jSpinner does not reflect the value to JLabel when I change the value using keyboard.

  • don't to use KeyListener for Swing JComponents, KeyListener doesn't react correctly to BackSpace, nor for inserted array of chars from ClipBoard (copy -> paste)

  • use DocumentListener added to derived editor JTextField/JFormattedTextField from JSpinner,

mKorbel
  • 109,525
  • 20
  • 134
  • 319
  • how to add document listener to jlabel , is there auto add option on netbeans – user3498019 May 06 '14 at 08:56
  • JLabel isn't focusable, by default never to receiving a KeyEvent, with plain JLabel this idea isn't possible, isn't designated for users input, you have to use JTextField/JFormattedTextField – mKorbel May 06 '14 at 08:58
2

First, don't use KeyListeners, they are just horrible little creatures...

Second, JSpinner itself is not the editor, but a container for other components, as such, you need to ask the JSpinner for the editor, for example, from the JavaDocs

JComponent editor = spinner.getEditor()
if (editor instanceof DefaultEditor) {
    //...
}

Now, DefaultEditor is still a compound class, you need to ask for the JTextField that is acutally been used by the editor...

JFormattedTextField field = ((DefaultEditor)editor).getTextField();

From here, you can simply attach a DocumentListener to the field.

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • I am just trying to understand what you are talking about please simplify your answer , i am using jlabel not textfields ! – user3498019 May 06 '14 at 10:25
  • You're trying to make the changes in a `JSpinner` reflected by a `JLabel` as those changes occur. In order to do that, you need to monitor the changes of the editor within the spinner... – MadProgrammer May 06 '14 at 10:53
  • ok I solved the issue so the spinner has the editor component which is separated from those arrows thanks I will post the answer ! – user3498019 May 06 '14 at 10:58
  • @user3498019 Just so you know, this is not the best approach. Until the user commits the value, they can type what ever they like – MadProgrammer May 06 '14 at 11:57
  • how to fix that I mean type whatever you like – user3498019 May 06 '14 at 11:59
  • @user3498019 The approach of using a `DocumentListener` will work, but the user is capable of typing what ever they want. If you only want to update the label when the value is committed, you will need to use a `PropertyChangeListener` and monitor for the editors committed state – MadProgrammer May 06 '14 at 21:49
2

The user needs to hit Enter to make the new value be noticed by the model/listener etc.. Either that or the or keys. If the value is outside the allowable range or otherwise invalid, no action occurs. See below for the source used to confirm that in the default Metal PLAF.

Forget the KeyListener, it is a dead end here.

import java.awt.*;
import javax.swing.*;
import javax.swing.event.*;

class TimeBeforeClass {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                JPanel gui = new JPanel(new FlowLayout(FlowLayout.LEFT, 3,3));
                gui.add(new JLabel("Show"));
                final JLabel output = new JLabel("Output..");
                final JSpinner sp = new JSpinner(
                        new SpinnerNumberModel(15,0,20,1));
                sp.addChangeListener(new ChangeListener() {

                    @Override
                    public void stateChanged(ChangeEvent e) {
                        output.setText(sp.getValue() + " minutes.");
                    }
                });
                gui.add(sp);
                gui.add(new JLabel("minutes before class"));

                JPanel mainUI = new JPanel(new BorderLayout(5, 5));
                mainUI.add(output, BorderLayout.PAGE_END);
                mainUI.add(gui);

                JOptionPane.showMessageDialog(null, mainUI);
            }
        });
    }
}
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
1

I did in this way , I right click on jSpinner in design view and customize the code add this code below now it works fine , jSpinner1 is only allowing the numbers so no any other character.

 jSpinner1 = new javax.swing.JSpinner();
 jSpinner1.setFont(new java.awt.Font("Calibri", 0, 14)); 
 jSpinner1.setModel(new javax.swing.SpinnerNumberModel(1, 1, 1000, 1));
 JFormattedTextField field1 = ((JSpinner.NumberEditor)        
 jSpinner1.getEditor()).getTextField();
 ((NumberFormatter) field1.getFormatter()).setAllowsInvalid(false);
 DefaultFormatter formatter1 = (DefaultFormatter) field1.getFormatter();
 formatter1.setCommitsOnValidEdit(true);

And this the state change event

    private void jSpinner1StateChanged(javax.swing.event.ChangeEvent evt) 
    {                                       
           value = (Integer)jSpinner1.getValue();
           jLabel1.setText(value.toString());
    } 
user3498019
  • 95
  • 1
  • 2
  • 10