Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

Why does the code enters twice in the change event of the JSpinner?

private javax.swing.JSpinner spinner = new javax.swing.JSpinner()
spinner.setModel(new javax.swing.SpinnerDateModel());
    spinner.addChangeListener(new javax.swing.event.ChangeListener() {
        @Override
        public void stateChanged(javax.swing.event.ChangeEvent evt) {
            System.out.println("Just a test");

The code above shows the message twice when u click only one time.

you are creating a model with empty values. It should not even print for once. I am certain about it. – Sage Oct 3, 2013 at 18:21

2 events are generated: one for the value being deselected and another for the new value being selected in the component. As @camickr notes in his comment this behavior occurs in SpinnerDateModel but not in the default SpinnerNumberModel

As a workaround you could use

spinner.addChangeListener(new ChangeListener() {
    Object lastValue;
    @Override
    public void stateChanged(ChangeEvent evt) {
        if (lastValue != null && !spinner.getValue().equals(lastValue)) {
           // expensive code calls here!
        lastValue = spinner.getValue();

This wont prevent the listener being called twice but will prevent any expensive code being invoked unnecessarily

Yes, I thought it was generating two events, one for the old an one for the new but I noticed that the listener only gets called twice the first time you click on the spinner. After that it only gets called once. Also, it only happens for the SpinnerDateModel and not the SpinnerNumberModel (based on my tests). – camickr Oct 3, 2013 at 18:37 I was testing the code and works fine for the first click problem. But i found the same problem when changing the position of the cursor on the spinner and then clicking again. The problem occurs again, each time u change the cursor on the spinner – Fernando Fossi Oct 3, 2013 at 22:18 What if the first state change is important? Doesn't this force the user to change state twice in order to reach "expensive code"? – Michael Starkie Oct 1, 2019 at 13:05 Perhaps this is better if (lastValue == null || !priceSpinner.getValue().equals(lastValue)) – Michael Starkie Oct 1, 2019 at 13:14

Just bumped into the same problem and found a different workaround, as the one in https://stackoverflow.com/a/19166589/5326620 caused it to miss the event when first editing the date directly on the text field.

In my case, I'm using a SpinnerDateModel for Calendar.DAY_OF_MONTH (same as Calendar.DATE). If the SpinnerDateModel is initialized with a value precisely at midnight, the event is no longer fired twice.

Calendar now = Calendar.getInstance();
now.set(Calendar.HOUR_OF_DAY, 0);
now.set(Calendar.MINUTE, 0);
now.set(Calendar.SECOND, 0);
now.set(Calendar.MILLISECOND, 0);
Date value = now.getTime();
JSpinner dateSpn = new JSpinner(new SpinnerDateModel(value, null, null, Calendar.DAY_OF_MONTH));

This is probably because the commitEdit of the JFormattedTextField tests the old and new value by equality, and Date equality is on the millisecond.

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.