2

我想记录“用户活动”。我正在努力记录用户触发的事件,即组合框的选定值已更改(由用户更改,而不是由应用程序调用combo.setSelectedItem()或类似内容更改)。

这是我到目前为止所做的:我注册了ItemListener一个JComboBox

comboBox.addItemListener(new ItemListener() {
    @Override
    public void itemStateChanged(ItemEvent e) {
        if (e.getStateChange() == ItemEvent.SELECTED) {
            log(USER_SELECTED_ITEM, e);
        }
    }
});

但是,itemStateChanged(...)即使组合框值由 以编程方式选择,也会调用comboBox.setSelectedItem(...)

我还发现了一个布尔字段 ,AWTEvent.isSystemGenerated我希望它true是通过显式调用comboBox.setSelectedItem(...).

    @Override
    public void itemStateChanged(ItemEvent e) {
        if (e.getStateChange() == ItemEvent.SELECTED) {
            boolean sysGen = AWTAccessor.getAWTEventAccessor().isSystemGenerated(e);
            System.out.println("system generated: " + sysGen);
        }
    }

不幸的是,true从来没有打印出来。

如何过滤掉以编程方式生成的事件?

4

2 回答 2

1

使用以下方法getItemSelectable() 它返回事件的发起者。 文档

ItemSelectable itemOrginator = e.getItemSelectable()

itemOrginator是事件的对象源。

并检查从类继承的int userOriginTypeint progOriginType使用方法的两种情况。getIDjava.awt.AWTEvent

于 2012-12-05T19:08:22.427 回答
0

这很简单。定义一个全局变量 fromSystem。

comboBox.addItemListener(new ItemListener() 
{
   @Override
   public void itemStateChanged(ItemEvent e) 
   {
      if (e.getStateChange() == ItemEvent.SELECTED) 
      {
           if(!fromSystem)
           {
               log(USER_SELECTED_ITEM, e);
           }
      }
   }

});

现在,无论您在哪里编写过 comboBox.setSelectedItem(...) ,都将这一行替换为以下 3 行。

fromSystem = true;
comboBox.setSelectedItem(...);
fromSystem = false

知道了??

于 2013-11-25T05:15:25.797 回答