有两个JComboBox和一个JTextArea,姑且叫 boxList1和boxList2和areaTest,两个JComboBox都注册了addItemListener, boxList1选择有变化,就改变boxList2的item,boxList2有变化就改变areaTest的值。现在的问题是程序的原因,在boxList1变化时,先移除boxList2所有的项boxList2.removeAllItems(),然后再根据条件加一些项到boxList2中,最后JTextArea的变化是由boxList2刚开始选中的值,和移除又增加值后选中的值是否变化来判断,如果boxList2的值有变化,就把JTextArea的值设为空,如果没有就保留原来的(像变化之前手工填一数到JTextArea中)?怎么样实现? 因为boxList2要remove和add时,它的itemStateChanged事件要产生,所以就不好判断了,后来想到,先把boxList2的东西保存起来,到最后再跟选中的比较,但是也不行,因为中途有事件发生,把JTextArea的值改变了。 不知道说清楚了没有,反正就是boxList2要一个事件,这个事件只判断开始和最终的所选值有变化就产生事件,不管中间的移除和增加,如果没有就不产生,大家有什么良策没?

解决方案 »

  1.   

    在remove boxList2的组件之前 先remove他的监听
    public void removeItemListener(ItemListener aListener)
      

  2.   

    听楼主一步步描述那么流畅,还以为那些都实现了,居然后面弄个“怎么样实现?” 眼球一下闪了。设个状态标记变量呗。
    在第一个CB变化要改写第二个CB之前将FLAG(标记,旗帜)变量设一个初值。(每次一改二时都执行)
    第一个CB改写第二个完成后将它设为另一个值(比如,就可以存储第二个CB里那个最初的选中值)。
    在第二个CB的变化事件中,检测到这个变量为初值就不管。否则,就代表是存了第二个初始选中值,拿它和现在的值比较一下。就可以决定那个文本框的值了。
      

  3.   


    移除监听后,如果boxList2有变化就不能改变JTextArea的值了,而且又没有好时机再加上了.
      

  4.   


    事件发生并不是你说的这个顺序,第一个CB改写第二个的时候,第二个CB有变化,就产生事件,已经把JTextArea里面的改变了,后面就不好弄了.
      

  5.   

    先删除Listener,然后再根据条件有变化再加上,试试!
      

  6.   

    在更新ComboBox的选项时,通过setModel更新,就可以了。当有新数据时,生成新的模型
    DefaultComboBoxModel model=new DefaultComboBoxModel(Object[] data);
    DefaultComboBoxModel model=new DefaultComboBoxModel(Vector data);
    然后调用ComboBox.setModel(model);就可以了
      

  7.   

    你为什么要用itemlistener?
    这个监听并不常用。我不知道,你用这个监听实现了什么样的操作。
    但是,我想说,如果你只需点击鼠标或者用键盘操作才触发的动作,不要用这个。
    而且,这个itemlistener一旦触发,就必然是两个。你不差之下很容易动作执行两遍。或许无所谓,但或许,某些情形下就与你的预期完全不同。
      

  8.   

    再问一下就结贴了: 一个JComboBox注册了事件addItemListener,它变化的话会变化JTextArea的值;
      有个一个函数首先会触发JComboBox的事件,然后也会set值到JTextArea中去,到底是先触发事件,改变值以后,再接着执行函数,还是他们是同时进行的?为什么?
      

  9.   


     /** 
         * Sets the selected item in the combo box display area to the object in 
         * the argument.
         * If <code>anObject</code> is in the list, the display area shows 
         * <code>anObject</code> selected.
         * <p>
         * If <code>anObject</code> is <i>not</i> in the list and the combo box is
         * uneditable, it will not change the current selection. For editable 
         * combo boxes, the selection will change to <code>anObject</code>.
         * <p>
         * If this constitutes a change in the selected item, 
         * <code>ItemListener</code>s added to the combo box will be notified with
         * one or two <code>ItemEvent</code>s.
         * If there is a current selected item, an <code>ItemEvent</code> will be
         * fired and the state change will be <code>ItemEvent.DESELECTED</code>. 
         * If <code>anObject</code> is in the list and is not currently selected
         * then an <code>ItemEvent</code> will be fired and the state change will 
         * be <code>ItemEvent.SELECTED</code>.
         * <p>
         * <code>ActionListener</code>s added to the combo box will be notified
         * with an <code>ActionEvent</code> when this method is called.
         *
         * @param anObject  the list object to select; use <code>null</code> to
                            clear the selection
         * @beaninfo
         *    preferred:   true
         *    description: Sets the selected item in the JComboBox.
         */
        public void setSelectedItem(Object anObject) {
    Object oldSelection = selectedItemReminder;
            Object objectToSelect = anObject;
    if (oldSelection == null || !oldSelection.equals(anObject)) {     if (anObject != null && !isEditable()) {
    // For non editable combo boxes, an invalid selection
    // will be rejected.
    boolean found = false;
    for (int i = 0; i < dataModel.getSize(); i++) {
                        Object element = dataModel.getElementAt(i);
        if (anObject.equals(element)) {
    found = true;
                            objectToSelect = element;
    break;
        }
    }
    if (!found) {
        return;
    }
        }
        
        // Must toggle the state of this flag since this method
        // call may result in ListDataEvents being fired.
        selectingItem = true;
        dataModel.setSelectedItem(objectToSelect);
        selectingItem = false;     if (selectedItemReminder != dataModel.getSelectedItem()) {
    // in case a users implementation of ComboBoxModel
    // doesn't fire a ListDataEvent when the selection
    // changes.
    selectedItemChanged();
        }
    }
    fireActionEvent();
        }
      

  10.   

    请看以上部分程序。这是JComboBox的源码,一个很重要的方法。这个我不必多说,文档已然描述得很清晰它是做什么用的。
    特别是注释部分也已经描述的非常清晰:
    Sets the selected item in the combo box display area to the object in 
         the argument.
    而后对一些不同的情形,可能产生的情况说了一下。
    如果你关心itemListener:
    If this constitutes a change in the selected item, 
         * <code>ItemListener</code>s added to the combo box will be notified with
         * one or two <code>ItemEvent</code>s.
         * If there is a current selected item, an <code>ItemEvent</code> will be
         * fired and the state change will be <code>ItemEvent.DESELECTED</code>. 
         * If <code>anObject</code> is in the list and is not currently selected
         * then an <code>ItemEvent</code> will be fired and the state change will 
         * be <code>ItemEvent.SELECTED</code>.
    如果是actionListener:
     <code>ActionListener</code>s added to the combo box will be notified
          with an <code>ActionEvent</code> when this method is called.
    告诉你,会调用注册的监听。
    其实,所有的监听都会走。至于先后,我是说,监听执行的先后,逆序,更多请参考文档及源程序。
      

  11.   

    而你所说的area,如果是要在是另一个单独的组件,那你要去赋值,肯定有一个先后的顺序。给自己,是赋值,然后触发监听器。而监听器中可以给你想要的东西区赋值,操作等等。
    还是没有明白你的意思,如果说的不是你想要的,请再详细些描述。
      

  12.   

    感谢gentalguo,我把代码拿出来应该更直接一点:请看.
    JTextArea text1 =new JTextArea(15,20);
    JComboBox list =new JComboBox();
    list.addItemListener(this);  
    public void itemStateChanged(ItemEvent arg0) {   //监听就只把text1的内容设为空
    // TODO Auto-generated method stub
    text1.setText(null);
    }  下面有个函数:
      list.removeAllItems();     //第一行
            list.addItem("aaaaaaaaa"); //第二行
            text1.setText("值值");     //第三行我的意思是这样的:就是说上面代码的第一行或第二行因为要改变list的值,会调用事件,会text1.setText(null);  而第三行又 text1.setText("值值"); text1最后的值一定是值值吗? list的事件执行一定在第三行之前执行吗? 因为如果是多线程的话,有可能第三行先执行,再执行事件.不知道说清楚了没有?