我有一个 JSlider 和 JSpinner,它们彼此“链接”。所以 JSpinner 显示了 JSlider 的值。现在,当我移动 JSlider 时,我需要更改 JSpinner 的值(反之亦然)。
我现在的问题是改变(例如你移动滑块)它将更新 JSpinner 的值,这将更新滑块的位置。幸运的是,这不会再次触发 JSpinner 的更新。但是我想防止这个事件被触发两次。
所以我现在的问题是,是否有可能以某种方式说事件中的更改不会再次触发事件?
费边
我有一个 JSlider 和 JSpinner,它们彼此“链接”。所以 JSpinner 显示了 JSlider 的值。现在,当我移动 JSlider 时,我需要更改 JSpinner 的值(反之亦然)。
我现在的问题是改变(例如你移动滑块)它将更新 JSpinner 的值,这将更新滑块的位置。幸运的是,这不会再次触发 JSpinner 的更新。但是我想防止这个事件被触发两次。
所以我现在的问题是,是否有可能以某种方式说事件中的更改不会再次触发事件?
费边
好吧,您可以通过从相应组件中为每个调用添加和删除侦听器来做到这一点。因此,您需要保留共享侦听器的引用,如以下示例代码:
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 分配例如应该链接的另一个组件。
或者,您可以在 的实例中使用布尔标志ChangeListener
(以便一个知道何时被另一个调用),而不必在每次侦听器到组件时删除然后再次添加回来。