为什么JComboBox上的itemStateChanged在更改时被调用两次?

时间:2008-12-01 11:40:30

标签: java swing jcombobox itemlistener

我正在使用带有ItemListener的JComboBox。更改值时,将调用itemStateChanged事件两次。第一个调用,ItemEvent显示所选的原始项目。第二次,它显示用户刚刚选择的项目。这是一些测试人员代码:

public Tester(){

    JComboBox box = new JComboBox();
    box.addItem("One");
    box.addItem("Two");
    box.addItem("Three");
    box.addItem("Four");

    box.addItemListener(new ItemListener(){
        public void itemStateChanged(ItemEvent e){
            System.out.println(e.getItem());
        }
    });

    JFrame frame = new JFrame();
    frame.getContentPane().add(box);
    frame.pack();
    frame.setVisible(true);
}

因此,当我将组合框从“一”改为“三”时,控制台显示:

One
Three

有没有一种方法我可以告诉使用ItemEvent,它是第二项(即用户选择的项目)?如果有人可以解释为什么它会被调用两次,那也会很好!

由于

10 个答案:

答案 0 :(得分:31)

看一下这个来源:

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class Tester {

    public Tester(){

        JComboBox box = new JComboBox();
        box.addItem("One");
        box.addItem("Two");
        box.addItem("Three");
        box.addItem("Four");

        box.addItemListener(new ItemListener(){
            public void itemStateChanged(ItemEvent e){
                System.out.println(e.getItem() + " " + e.getStateChange() );
            }
        });

        JFrame frame = new JFrame();
        frame.getContentPane().add(box);
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String [] args) {
        Tester tester = new Tester();
    }
}

使用getStateChange确定是选择还是取消选择项目

答案 1 :(得分:16)

根据此thread

  

当你留下一个结果时它会被触发,然后在设置为另一个结果时再次被调用

     

不要听itemStateChanged。请改用ActionListener,这对于处理组合事件很有用   如果需要根据所涉及的项目单独处理取消选择/选择,则需要ItemStateListener。

     

更改itemStateChanged中项目的状态会导致触发itemStateChanged ...这称为“reentrance”。

答案 2 :(得分:13)

我想在选择后获取索引字符串并在组合框中设置

        comboBox1.addItemListener(new ItemListener() {
            @Override
            public void itemStateChanged(ItemEvent e) {
                if(e.getStateChange() == ItemEvent.SELECTED) {
                    comboBox1ItemStateChanged();
                }
            }
        });

答案 3 :(得分:7)

哟可以这样做:

import java.awt.event.*;

jComboBox1.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            System.out.println("Hello");
        }
    });

答案 4 :(得分:5)

private void dropDown_nameItemStateChanged(java.awt.event.ItemEvent evt) {                                                 


    if(evt.getStateChange() == ItemEvent.SELECTED)
    {
        String item = (String) evt.getItem();
        System.out.println(item);
    }

}
祝你好运!

答案 5 :(得分:3)

代码是:

public class Tester {

    private JComboBox box;

    public Tester() {

        box = new JComboBox();
        box.addItem("One");
        box.addItem("Two");
        box.addItem("Three");
        box.addItem("Four");

        box.addItemListener(new ItemListener() {

            public void itemStateChanged(ItemEvent e) {
                if (e.getStateChange() == 1) {

                    JOptionPane.showMessageDialog(box, e.getItem());
                    System.out.println(e.getItem());
                }
            }
        });

        JFrame frame = new JFrame();
        frame.getContentPane().add(box);
        frame.pack();
        frame.setVisible(true);
    }
}

答案 6 :(得分:1)

看看这里,

box.addItemListener(new ItemListener(){
    public void itemStateChanged(ItemEvent e){
        if(e.getStateChange()== ItemEvent.SELECTED) {
            //this will trigger once only when actually the state is changed
            JOptionPane.showMessageDialog(null, "Changed");
        }
    }
});

当你选择一个新选项时,它只会调用一次JOptionPane,表示那里的代码只会调用一次。

答案 7 :(得分:0)

引自Java Tutorial

“在组合框中一次只能选择一个项目,因此当用户进行新选择时,先前选择的项目将被取消选择。因此,每次用户选择不同的项目时,都会触发两个项目事件从菜单。如果用户选择相同的项目,则不会触发任何项目事件。“

答案 8 :(得分:0)

  1. 当从组合框中选择anyitem时,它会在内部触发选择更改,即它将调用函数setSelectedItem。
  2. 如果实现了显式的itemStateChanged事件侦听器,则setSelectedItem将调用itemStateChanged。因此,当选择一个项目时,它会调用setSelectedItem,然后调用itemStateChanged。
  3. 当组合框的值发生变化时,即使这也会触发itemStateChanged,因此会调用itemStateChanged。
  4. 我已经为项目更改编写了监听器,以便在代码内部设置时处理组合框值的更改,并导致函数被调用两次。
  5. 以下是2个返回跟踪,当从组合框中选择一个值时会调用它。

    实际价值变化的第一次:

    dataMgr.MainInterface.jComboBoxPaymentStatusValueChangeHandle(MainInterface.java:1431), 
    dataMgr.MainInterface.jComboBoxPaymentStatusItemStateChanged(MainInterface.java:1676), 
    dataMgr.MainInterface.access$600(MainInterface.java:28), 
    dataMgr.MainInterface$7.itemStateChanged(MainInterface.java:437), 
    javax.swing.JComboBox.fireItemStateChanged(JComboBox.java:1223), 
    javax.swing.JComboBox.selectedItemChanged(JComboBox.java:1271), 
    javax.swing.JComboBox.contentsChanged(JComboBox.java:1330), 
    javax.swing.AbstractListModel.fireContentsChanged(AbstractListModel.java:118), 
    javax.swing.DefaultComboBoxModel.setSelectedItem(DefaultComboBoxModel.java:93), 
    javax.swing.JComboBox.setSelectedItem(JComboBox.java:576), javax.swing.JComboBox.setSelectedIndex(JComboBox.java:622), javax.swing.plaf.basic.BasicComboPopup$Handler.mouseReleased(BasicComboPopup.java:852), java.awt.AWTEventMulticaster.mouseReleased(AWTEventMulticaster.java:290), java.awt.Component.processMouseEvent(Component.java:6533), javax.swing.JComponent.processMouseEvent(JComponent.java:3324), javax.swing.plaf.basic.BasicComboPopup$1.processMouseEvent(BasicComboPopup.java:501), java.awt.Component.processEvent(Component.java:6298), java.awt.Container.processEvent(Container.java:2236), java.awt.Component.dispatchEventImpl(Component.java:4889), java.awt.Container.dispatchEventImpl(Container.java:2294), java.awt.Component.dispatchEvent(Component.java:4711), java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4888), java.awt.LightweightDispatcher.processMouseEvent(Container.java:4525), java.awt.LightweightDispatcher.dispatchEvent(Container.java:4466), java.awt.Container.dispatchEventImpl(Container.java:2280), java.awt.Window.dispatchEventImpl(Window.java:2746), java.awt.Component.dispatchEvent(Component.java:4711), java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758), java.awt.EventQueue.access$500(EventQueue.java:97), java.awt.EventQueue$3.run(EventQueue.java:709), java.awt.EventQueue$3.run(EventQueue.java:703), java.security.AccessController.doPrivileged(Native Method), java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76), java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86), java.awt.EventQueue$4.run(EventQueue.java:731), java.awt.EventQueue$4.run(EventQueue.java:729), java.security.AccessController.doPrivileged(Native Method), java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76), java.awt.EventQueue.dispatchEvent(EventQueue.java:728), java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201), java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116), java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105), java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101), java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93), java.awt.EventDispatchThread.run(EventDispatchThread.java:82)]
    

    第二次从组合框操作开始

    dataMgr.MainInterface.jComboBoxPaymentStatusValueChangeHandle(MainInterface.java:1431), 
    dataMgr.MainInterface.jComboBoxPaymentStatusItemStateChanged(MainInterface.java:1676), 
    dataMgr.MainInterface.access$600(MainInterface.java:28), 
    dataMgr.MainInterface$7.itemStateChanged(MainInterface.java:437), 
    javax.swing.JComboBox.fireItemStateChanged(JComboBox.java:1223), 
    javax.swing.JComboBox.selectedItemChanged(JComboBox.java:1280), 
    javax.swing.JComboBox.contentsChanged(JComboBox.java:1330), 
    javax.swing.AbstractListModel.fireContentsChanged(AbstractListModel.java:118), 
    javax.swing.DefaultComboBoxModel.setSelectedItem(DefaultComboBoxModel.java:93), 
    javax.swing.JComboBox.setSelectedItem(JComboBox.java:576), 
    javax.swing.JComboBox.setSelectedIndex(JComboBox.java:622), 
    javax.swing.plaf.basic.BasicComboPopup$Handler.mouseReleased(BasicComboPopup.java:852), 
    java.awt.AWTEventMulticaster.mouseReleased(AWTEventMulticaster.java:290), 
    java.awt.Component.processMouseEvent(Component.java:6533), 
    javax.swing.JComponent.processMouseEvent(JComponent.java:3324), 
    javax.swing.plaf.basic.BasicComboPopup$1.processMouseEvent(BasicComboPopup.java:501), 
    java.awt.Component.processEvent(Component.java:6298), java.awt.Container.processEvent(Container.java:2236), 
    java.awt.Component.dispatchEventImpl(Component.java:4889), java.awt.Container.dispatchEventImpl(Container.java:2294), 
    java.awt.Component.dispatchEvent(Component.java:4711), java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4888), 
    java.awt.LightweightDispatcher.processMouseEvent(Container.java:4525), java.awt.LightweightDispatcher.dispatchEvent(Container.java:4466), 
    java.awt.Container.dispatchEventImpl(Container.java:2280), java.awt.Window.dispatchEventImpl(Window.java:2746), 
    java.awt.Component.dispatchEvent(Component.java:4711), java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758),
    java.awt.EventQueue.access$500(EventQueue.java:97), java.awt.EventQueue$3.run(EventQueue.java:709), 
    java.awt.EventQueue$3.run(EventQueue.java:703), java.security.AccessController.doPrivileged(Native Method),
    java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76), 
    java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86), 
    java.awt.EventQueue$4.run(EventQueue.java:731), java.awt.EventQueue$4.run(EventQueue.java:729), 
    java.security.AccessController.doPrivileged(Native Method), java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76), java.awt.EventQueue.dispatchEvent(EventQueue.java:728), java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201), java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116), java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105), java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101), java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93), java.awt.EventDispatchThread.run(EventDispatchThread.java:82)]
    

答案 9 :(得分:-4)

JComboBox.setFocusable(false)可以解决问题。