在我的程序中,我有几个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
之前,我怎么能确定其他微调器触发它的更改事件?
有没有人有更简洁的方法来阻止变更事件链?
感谢您的时间。