Reputation: 13
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.
Upvotes: 1
Views: 3385
Reputation: 33
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.
Upvotes: 0
Reputation: 159764
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
Upvotes: 3