KDComboBox/JComboBox选择事件执行2次有关问题
在监听KDComboBox的时候,代码总是执行2次,这个原因一直没找到,当时也懒的深究,以为是控件的Bug。
comboBox.addItemListener(new ItemListener() { public void itemStateChanged(ItemEvent e) { comboBox_itemStateChanged(e); } }); protected void comboBox_itemStateChanged(ItemEvent e) { System.out.println("comboBox"); }
执行结果:
comboBox
comboBox
可以通过调试,明显知道执行了2次逻辑。
以前的解决方案:
ItemListener listener;//定义类变量 //监听 listener = new ItemListener() { public void itemStateChanged(ItemEvent e) { comboBox_itemStateChanged(e); } }; comboBox.addItemListener(listener); //方法: comboBox_itemStateChanged(ItemEvent e){ System.out.println("comboBox"); comboBox.removeItemListener(listener); comboBox.addItemListener(listener); }
以上方法并不科学,执行了一次之后将listener remove,然后再添加listener,当时并不了解comboBox_itemStateChanged的逻辑,导致很多代码都这样写了。今天看到一篇文章,才知道这样写是错误的。
在JComboBox的监听事件时总是执行两次,原因如下:
ItemListener类中的方法itemStateChanged()事件的itemState有关,itemState在这里的状态有两个,Selected 和 deSelected(即选中和未被选中)
所以,当改变下拉列表中被选中的项的时候,其实是触发了两次事件:
第一次是上次被选中的项的 State 由 Selected 变为 deSelected ,即取消选择
第二次是本次被选中的项的 State 由 deSelected 变为 Selected ,即新选中,所以,必然的 ItemStateChanged 事件中的代码要被执行两次了。加上最外面的if语句,就可以解决这个问题。
简单理解,当下拉框从item1下拉选择item2的时候,相当于 item1从Selected->deSelected ,item2从deSelected-Selected,使用才执行了2次,知道了原因之后,发现以前的代码写的多么不规范了,害死人啊。
ComboBox后台的实现可能是item1、item2都是CheckBox,下拉事件item1状态从选中变成取消执行一次,item2由取消状态变成选中状态执行一次导致的。
解决方法如下
protected void comboBox_itemStateChanged(ItemEvent e) { if (e.getStateChange() == ItemEvent.SELECTED && e.getSource() == comboBox) { System.out.println("comboBox"); } }
e.getSource() == comboBox//这个判断也能省略的,如果没有多个comboBox公用一个监听
protected void comboBox_itemStateChanged(ItemEvent e) { if (e.getStateChange() == ItemEvent.SELECTED) { System.out.println("comboBox"); } }