更改JSpinner值而不触发更改事件

时间:2015-12-10 09:49:18

标签: java swing event-handling jspinner

在我的程序中,我有几个JSpinner和其他输入组件,它们应该显示一些值并对用户的输入作出反应。这些值彼此相关。当值A改变时,它也改变值B. 问题是,当A改变时,它会改变B并且由于B改变它会再次改变A ......依此类推。 我的问题是,如何在不触发其他组件的“值更改事件”的情况下听取用户输入并更改所有值?

这是一个带有2个微调器的简单示例:( SpinnerA将SpinnerB的值设置为A值的两倍)

public class SpinnerExample extends javax.swing.JFrame{

    private javax.swing.JSpinner spinnerA;
    private javax.swing.JSpinner spinnerB;

    public SpinnerExample(){
        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        getContentPane().setLayout(new java.awt.FlowLayout());

        // here the interesting part:
        spinnerA = new JSpinner();
        spinnerA.addChangeListener(new javax.swing.event.ChangeListener(){
            @Override
            public void stateChanged(javax.swing.event.ChangeEvent evt){
                System.out.println("Spinner A state changed to value=" + spinnerA.getValue());
               //spinnerB.setValue(spinnerA.getValue());
               spinnerB.setValue(((int) spinnerA.getValue() * 2));
            }
        });
        getContentPane().add(spinnerA);

        spinnerB = new JSpinner();
        spinnerB.addChangeListener(new javax.swing.event.ChangeListener(){
            @Override
            public void stateChanged(javax.swing.event.ChangeEvent evt){
                System.out.println("Spinner B state changed to value=" + spinnerB.getValue());
                spinnerA.setValue(spinnerB.getValue());
            }
        });
        getContentPane().add(spinnerB);

        pack();
    }

    public static void main(String args[]){
        java.awt.EventQueue.invokeLater(new Runnable(){
            @Override
            public void run(){
                new SpinnerExample().setVisible(true);
            }
        });
    }
}

在此示例中,有2个微调器: spinnerA spinnerB
当值以任何方式改变时,两者都有自己的ChangeListener 因此,当点击 spinnerA 的向上箭头时, spinnerA 的值更改为1,并且的更改侦听器的响应将由将 spinnerB 的值设置为2(A值的2倍)。 - 到目前为止很好 -
但现在B 的更改侦听器再次注册更改,并通过将 spinnerA 的值设置为2来做出反应。并再次 A 检测到值更改并将 B 设置为2xA - > 4 ......等等

我的肮脏解决方案
我使用全局boolean doUpdate变量。 true默认情况下,当其中一个微调器对更改做出反应时,它会设置为false

public void stateChanged(javax.swing.event.ChangeEvent evt){
    if(doUpdate){  // react only when set to true
        doUpdate=false; // temporarily set it to false
        System.out.println("Spinner B state changed to value=" + spinnerB.getValue());
        spinnerA.setValue(spinnerB.getValue()); // the other spinner won't react anymore since doUpdate is false
        doUpdate=true; // when finished, set it to true again.
    }
}

现在这似乎“有效”,但感觉不对。这是肮脏的方式。在doUpdate再次重置为true之前,我怎么能确定其他微调器触发它的更改事件?

有没有人有更简洁的方法来阻止变更事件链?

感谢您的时间。

0 个答案:

没有答案