Question

So I created a Java application that uses a JSpinner and a ChangeEventListener to run some code when certain values are reached. When those certain values are reached, a JOptionPane appears. But then the JSpinner keeps spinning. So if the JSpinner allowed values 1-50 and I had increased the JSpinner from 20 to 21, it goes all the way to 50 while the JOptionPane is open.

The strange thing is, this was a known bug in Java 1.4.2, but was supposedly fixed in 5.0 (Bug ID: 4840869). I'm running Java 6u37. In fact, the source code provided in the bug issue (shown below) has the exact same effect for me that it did for the original poster of the bug. It most certainly has not been fixed for me.

The only thing that I can think of about why this might be is that I am running Mac OS 10.7.5 and maybe the bug fix didn't make it in to my version somehow. Is there anything I can do to prevent this behavior from happening?

Source code demonstrating this (originally from the bug report):

import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JSpinner;
import javax.swing.SpinnerNumberModel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

public class SpinnerFrame extends JFrame implements ChangeListener {

    private JSpinner spinner;

    private boolean changing;

    private SpinnerFrame() {
        super();
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        getContentPane().add(getSpinner());
        setSize(80,60);
        setLocation(200, 300);
        setVisible(true);
        changing = false;
    }

    private JSpinner getSpinner() {
        if (spinner == null) {
            spinner = new JSpinner();
            spinner.setModel(new SpinnerNumberModel(10, 1, 50, 1));
            spinner.addChangeListener(this);
        }
        return spinner;
    }

    public void stateChanged(ChangeEvent e) {
        JSpinner spinner = (JSpinner) e.getSource();
        int value = ((Integer) spinner.getValue()).intValue();
        System.out.println("Changed to " + value);
        if (changing) {
            return;
        }
        changing = true;
        if (value > 20) {
            JOptionPane.showMessageDialog(this, "20 exceeded");
            //While this is up, the JSpinner continues to 50
        }
        changing = false;
    }

    public static void main(String[] args) {
        new SpinnerFrame();
    }
}
Was it helpful?

Solution

I think if you show the message dialog in an EventQueue#invokeLater() it should not have this problem. If you want to cancel the spin to 21 after showing, just reset the value back to 20 after.

OTHER TIPS

I can reproduce a similar effect using either JDK 5 and 6 on an earlier version of Mac OS X. The effect occurs when using the mouse, but not the keyboard.

  1. While the mouse remains pressed on the spinner's up-arrow, the dialog appears at 21.

  2. When the mouse is later released and the first dialog is dismissed, a second dialog appears.

  3. The longer the mouse is held, the higher is the reported value, up to the maximum.

For reference in checking your version, the relevant code mentioned in the bug report is four calls to autoRepeatTimer.stop() in the private static class ArrowButtonHandler found in BasicSpinnerUI. The effect varies by JDK version and may be an artifact of how often the arrow can repeat within the chosen initial delay.

autoRepeatTimer.setInitialDelay(300);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top