Why is itemStateChanged on JComboBox is called twice when changed?

后端 未结 10 1861
忘掉有多难
忘掉有多难 2020-12-03 09:32

I\'m using a JComboBox with an ItemListener on it. When the value is changed, the itemStateChanged event is called twice. The first call, the ItemEvent is showing the origin

相关标签:
10条回答
  • 2020-12-03 10:08
    1. When the anyitem is selected from the combo box, it internally triggers selection change, i.e. it will call the function setSelectedItem.
    2. If an explicit itemStateChanged event listener is implemented, the setSelectedItem will call itemStateChanged. So, when an item is selected it calls setSelectedItem then it calls itemStateChanged.
    3. As the value of the combo box changes, even that too triggers itemStateChanged and hence itemStateChanged gets called.
    4. I had written listener for item change to handle change in value of combo box when set internally from the code and that caused the function getting called twice.

    Here are the 2 back traces, which gets invoked when a value is selected from combo box.

    1st time on actual value change:

    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)]
    

    2nd time from the due to operation on combobox

    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)]
    
    0 讨论(0)
  • 2020-12-03 10:09

    I wanted to get the index string after selected and set in combobox

            comboBox1.addItemListener(new ItemListener() {
                @Override
                public void itemStateChanged(ItemEvent e) {
                    if(e.getStateChange() == ItemEvent.SELECTED) {
                        comboBox1ItemStateChanged();
                    }
                }
            });
    
    0 讨论(0)
  • 2020-12-03 10:11

    According to this thread,

    It gets tripped when you leave one result and then called again when set to another result

    Don't listen for itemStateChanged. Use an ActionListener instead, which is good for handling events of the combo.
    You need a ItemStateListener if you need to separately handle deselection / selection depending on the item involved.

    Changing the state of the item within itemStateChanged causes itemStateChanged to be fired... this called "reentrance".

    0 讨论(0)
  • 2020-12-03 10:11

    Yo can do it like this:

    import java.awt.event.*;
    
    jComboBox1.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                System.out.println("Hello");
            }
        });
    
    0 讨论(0)
  • 2020-12-03 10:15

    JComboBox.setFocusable(false) will do the trick.

    0 讨论(0)
  • 2020-12-03 10:16

    Have a look at this source:

    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();
        }
    }
    

    Use the getStateChange to determine if an item is selected or deselected

    0 讨论(0)
提交回复
热议问题