【问题标题】:Don't trigger event when another component would trigger it当另一个组件触发它时不要触发事件
【发布时间】:2012-09-22 05:49:19
【问题描述】:

我有一个 JSlider 和 JSpinner,它们相互“链接”。所以 JSpinner 显示了 JSlider 的值。现在,当我移动 JSlider 时,我需要更改 JSpinner 的值(反之亦然)。

我现在的问题是更改(例如,您移动滑块)它将更新 JSpinner 的值,这将更新滑块的位置。幸运的是,这不会再次触发 JSpinner 的更新。但是我想防止这个事件被触发两次。

所以我现在的问题是,是否有可能以某种方式说事件中的更改不会再次触发事件?

法比安

【问题讨论】:

  • 为了更好的帮助尽快发布和SSCCE,否则有一些关于BoundedRangeModel和(Property)ChangeListener的代码
  • SpinSlider 可能是一个有用的例子。
  • SpinSlider 准确地显示了我的问题:当您调试看到的代码时,当您只更改一件事时,这两个事件都会被触发。例如,我在两个事件中添加了一个 System.out.println(...),当我更改微调器的值时,两个 println() 都会被触发。

标签: java swing jslider jspinner changelistener


【解决方案1】:

您可以通过从相应组件中为每个调用添加和删除侦听器来做到这一点。因此,您需要保留共享侦听器的引用,如以下示例代码:

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 的实例中使用布尔标志(让一个知道何时被另一个调用),而不必在每次侦听器到组件时删除然后再次添加回来。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多