我有一个JSlider和JSpinner,它们彼此“链接”。因此,JSpinner显示了JSlider的价值。现在,当我移动JSlider时,我需要更改JSpinner的值(反之亦然)。
我现在的问题是,更改(例如,移动滑块)将更新JSpinner的值,该值将更新滑块的位置。幸运的是,这不会再次触发JSpinner的更新。但我想防止此事件被触发两次。
所以我的问题是,现在可以说事件中的更改不会再次触发该事件吗?
Fabian
您可以通过从相应组件中添加和删除侦听器的每个调用来做到这一点。因此,您需要保留共享侦听器的引用,例如以下示例代码:
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.JSpinner;
import javax.swing.SpinnerNumberModel;
import javax.swing.SwingUtilities;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class SpinnerAndSlider extends JPanel {
public static void main(final String args[]) {
SwingUtilities.invokeLater(() -> {
final JSlider slider = new JSlider();
final JSpinner spinner = new JSpinner(new SpinnerNumberModel(slider.getValue(), slider.getMinimum(), slider.getMaximum(), 1));
final ChangeListener listener = new ChangeListener() {
@Override
public void stateChanged(final ChangeEvent cevt) {
if (cevt.getSource() == spinner) {
slider.removeChangeListener(this);
slider.setValue((Integer) spinner.getValue());
slider.addChangeListener(this);
}
else if (cevt.getSource() == slider) {
spinner.removeChangeListener(this);
spinner.setValue(slider.getValue());
spinner.addChangeListener(this);
}
}
};
slider.addChangeListener(listener);
spinner.addChangeListener(listener);
final JPanel contents = new JPanel(); //FlowLayout.
contents.add(slider);
contents.add(spinner);
final JFrame f = new JFrame("Spinner with Slider");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().add(contents);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
});
}
}
当然,您也可以用两个不同的实例来实现它(每个实例都是ChangeListener
的一个单独的子类),然后在创建后,用一个setter分配例如应该链接的另一个组件。