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