【问题标题】:How to identify the source of an event..?如何识别事件的来源..?
【发布时间】:2011-01-12 13:27:12
【问题描述】:

JComboBox.removeAllItems() 方法是否会触发 ItemStateChanged 事件..?
如果是这样,我如何确定由于用户操作或调用方法 removeAllItems()..而生成事件的天气?
我在组合框的 itemStateChanged() 方法中有一些代码,当用户更改组合框中的选择时,它可以正常工作,但是根据代码的性质,它在调用时会引发空指针异常在该组合框上调用 removeAllItems()。如果我可以确定事件的原因是 removeAllItems() 方法并返回控件,那么我的问题将得到解决。我该怎么做..?
更新
在你们提出答案后,我使用了以下代码...

 @Override
        public void itemStateChanged(ItemEvent e) {
            if(e.getSource()==branch_list)
            {
                if(!UserConstants.FID.contains("hod"))
                {
                    ignoreEvents=true;//static boolean variable not used by any other methods
                    year_list.removeAllItems();
                    year_list.addItem(" ");
                    sem_list.removeAllItems();
                    sem_list.addItem(" ");
                    branch_list.removeAllItems();
                    branch_list.addItem(" ");
                    if(branch_list.getSelectedItem().equals(" "))
                        return;
                    Iterator year_it=DatabaseConnector.map.get(branch_list.getSelectedItem().toString()).keySet().iterator();
                    while(year_it.hasNext())
                    {
                        year_list.addItem(year_it.next());

                    }
                    ignoreEvents=false;
                }
                return;
            }
            else if(e.getSource()==year_list)
            {
                if((branch_list.getSelectedItem()==null)||branch_list.getSelectedItem().toString().equals(" ")||ignoreEvents)
                return;
                sem_list.removeAllItems();
                section_list.removeAllItems();
                sem_list.addItem(" ");
                section_list.addItem(" ");
                Iterator i=DatabaseConnector.map.get(branch_list.getSelectedItem().toString()).get(year_list.getSelectedItem().toString()).iterator();
                int first=0;
                while(i.hasNext())
                {
                    String cur=i.next().toString();
                    if(first==0)
                    {
                        sem_list.addItem(cur.charAt(0));
                        section_list.addItem(cur.charAt(1));
                        first++;
                    }
                    else
                    {
                        section_list.addItem(cur.charAt(1));
                    }

                }


            }

        }
I am getting the following error:-  
Exception in thread "AWT-EventQueue-0" java.lang.StackOverflowError
    at sun.nio.cs.SingleByteEncoder.encodeArrayLoop(SingleByteEncoder.java:91)
    at sun.nio.cs.SingleByteEncoder.encodeLoop(SingleByteEncoder.java:130)
    at java.nio.charset.CharsetEncoder.encode(CharsetEncoder.java:544)
    at sun.nio.cs.StreamEncoder.implWrite(StreamEncoder.java:252)
    at sun.nio.cs.StreamEncoder.write(StreamEncoder.java:106)
    at java.io.OutputStreamWriter.write(OutputStreamWriter.java:190)
    at java.io.BufferedWriter.flushBuffer(BufferedWriter.java:111)
    at java.io.PrintStream.write(PrintStream.java:476)
    at java.io.PrintStream.print(PrintStream.java:619)
    at java.io.PrintStream.println(PrintStream.java:756)
    at attendence.Home.itemStateChanged(Home.java:427)

等等…………

【问题讨论】:

    标签: java events swing awt jcombobox


    【解决方案1】:

    我相信你最好的选择是要么

    1. 当你对事件不感兴趣时​​移除监听器,即使它是临时的

      cb.removeItemListener(listener);
      cb.removeAllItems();
      cb.addItemListener(listener);
      

      或者,

    2. 引入一个名为 ignoreEvents 的布尔变量并执行

      ignoreEvents = true;
      cb.removeAllItems();
      ignoreEvents = false;
      

      并让处理程序方法尊重ignoreEvents 值。


    关于您的更新:

    你需要有

    if (ignoreEvents == true)
        return;
    

    在您的处理程序的顶部。另外,在你的

    if(branch_list.getSelectedItem().equals(" "))
        return;
    

    您没有将 ignoreEvents 设置回 false。您可以使用 try / finally 确保在从方法返回时始终将 ignoreEvents 设置回 false。

    【讨论】:

    • 是的,以上两个是有效的选项,谢谢。但是有没有办法知道是什么导致了这些事件?我预计会有这样的事情存在。?
    • 您不会找到任何包含 CAUSED_BY_REMOVE_ALL 值或任何内容的标志。除了 ItemEvent 类和 getStateChange 方法中的常量之外,您必须自己跟踪。
    【解决方案2】:

    你试过event.getSource() 吗?

    【讨论】:

    • 在任何一种情况下都应该给出组合框实例,不是吗?
    • aioobe 是正确的使用 getSource() 返回组合框的实例,但这不会解决问题...
    【解决方案3】:

    这是 JComboBox.removeAllItem() 的代码。

    public void removeAllItems() {
            checkMutableComboBoxModel();
            MutableComboBoxModel model = (MutableComboBoxModel)dataModel;
            int size = model.getSize();
    
            if ( model instanceof DefaultComboBoxModel ) {
                ((DefaultComboBoxModel)model).removeAllElements();
            }
            else {
                for ( int i = 0; i < size; ++i ) {
                    Object element = model.getElementAt( 0 );
                    model.removeElement( element );
                }
            }
        selectedItemReminder = null;
        if (isEditable()) {
            editor.setItem(null);
        }
        }
    

    我认为您需要添加删除项目侦听器。

    【讨论】:

    • @sasidhar,这是 removeAllItems() 的上述代码。我有几个建议:1.请确保 removeAllItems() 方法在触发时生成事件。2.如果没有,覆盖removeAllItems()方法,调用JComboBox.3中的removeAllItem()方法。然后在这个方法本身中发起一个事件。动态生成事件可以查看这个链接:java.sun.com/products/jfc/tsc/articles/generic-listener/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-08-04
    • 1970-01-01
    • 2013-09-21
    • 1970-01-01
    • 1970-01-01
    • 2019-02-25
    • 1970-01-01
    相关资源
    最近更新 更多