将 JSlider 值更改为 JSpinner 值,反之亦然

Changing JSlider value to JSpinner value and vice versa on change

我有一个名为 quantitySl 的 JSlider 对象和一个名为 quantitySp 的 JSpinner 对象。当有人更改微调器时,我想将滑块更改为相同的值,反之亦然。

对象初始化如下:

SpinnerNumberModel quantityLimiter = new SpinnerNumberModel(1, 0, 20, 1); 
JSpinner quantitySp = new JSpinner(quantityLimiter);
JSlider quantitySl = new JSlider(0,20,1);
quantitySl.addChangeListener(this);
quantitySp.addChangeListener(this);

这是我尝试更改值的代码:

@Override
public void stateChanged(ChangeEvent ce) {
        if(ce.getSource()==quantitySp){
            quantitySp.setValue(quantitySl.getValue());
        }
        else if(ce.getSource()==quantitySl){
            quantitySl.setValue((int) quantitySp.getValue());
        }
}

问题在于,更改微调器的值会触发其 statechanged 事件,从而导致锁定这两个输入字段。我该如何解决这个问题?

尝试像这样为每个组件添加单独的侦听器:

import java.awt.BorderLayout;
import javax.swing.JFrame;
import javax.swing.JSlider;
import javax.swing.JSpinner;
import javax.swing.SpinnerNumberModel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

@SuppressWarnings("serial")
public class Main extends JFrame
{
    private JSlider slider;
    private JSpinner spinner;
    private int min, max;

    public Main()
    {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 400, 200);
        initializeComponents();
        setVisible(true);
    }

    public void initializeComponents()
    {
        min = 0;
        max = 100;
        slider = new JSlider(JSlider.HORIZONTAL, min, max, min);
        slider.setMajorTickSpacing(10);
        slider.setMinorTickSpacing(1);
        slider.setPaintTicks(true);
        slider.setPaintLabels(true);
        spinner = new JSpinner(new SpinnerNumberModel(min, min, max, 1));

        slider.addChangeListener(new ChangeListener()
        {
            @Override
            public void stateChanged(ChangeEvent e)
            {
                spinner.setValue(slider.getValue());
            }
        });

        spinner.addChangeListener(new ChangeListener()
        {
            @Override
            public void stateChanged(ChangeEvent e)
            {
                slider.setValue((int) spinner.getValue());
            }
        });

        add(slider, BorderLayout.NORTH);
        add(spinner, BorderLayout.SOUTH);
    }

    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {

                try
                {
                    UIManager.setLookAndFeel("javax.swing.plaf.nimbus.NimbusLookAndFeel");
                }
                catch (ClassNotFoundException | InstantiationException
                        | IllegalAccessException
                        | UnsupportedLookAndFeelException e)
                {
                }
                new Main();
            }
        });
    }
}