I'm trying to setup a JSpinner using a SpinnerNumberModel with value = 0.0005, min = 0.0, max = 1.0, and step size = 0.0005. However, when I create a spinner with these parameters I observe very strange behavior. Rather than starting at 0.0005 and increasing by 0.0005 with each click of the up arrow, the value seems to stick at 0.
To make sure this isn't just a formatting issue, I printed out the value of the spinner after each change event. Surely enough, for each click of the up arrow, the console shows the value as 0 and then 0.0005, regardless how many times the spinner has been clicked.
Below is the code I've used to test this, including a spinner with slightly different values that works just fine for comparison purposes.
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;
public class Main {
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setSize(200, 80);
JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());
final JSpinner spinner1 = new JSpinner(new SpinnerNumberModel(0.0005, 0.0, 1.0, 0.0005));
final JSpinner spinner2 = new JSpinner(new SpinnerNumberModel(0.05, 0.0, 1.0, 0.05));
panel.add(spinner1, BorderLayout.NORTH);
panel.add(spinner2, BorderLayout.SOUTH);
frame.add(panel);
spinner1.addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e) {
System.out.println("spinner1: " + ((Number) spinner1.getValue()).doubleValue());
}
});
spinner2.addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e) {
System.out.println("spinner2: " + ((Number) spinner2.getValue()).doubleValue());
}
});
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
Can anyone explain to me why spinner2 works as intended, but spinner1 does not?
Thanks.
Edit: Thanks to Peter for pointing out that the formatting of the spinner's text field actually has an effect on the stored value. To get the first spinner to work as intended, I added the line: spinner1.setEditor(new JSpinner.NumberEditor(spinner1, "0.0000"));
.
the problem is this in the JFormattedTextField used by the spinner. In that editor you can find:
public void commitEdit() throws ParseException {
AbstractFormatter format = getFormatter();
if (format != null) {
setValue(format.stringToValue(getText()), false, true);
}
}
your spinner display 0.0005 as 0.0, if you increment it first put 0.0 in your model and then increments to 0.0005, you event actually captures it but your textfield only sees 0.0
so solution will be to change the formatting of the spinner textfield.
you can overide the editor
final JSpinner spinner1 = new JSpinner(new SpinnerNumberModel(0.0005, 0.0, 1.0, 0.0005)) {
@Override
protected JComponent createEditor( SpinnerModel model )
{
return new NumberEditor(this, "0.0000");//needed decimal format
}
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With