web-dev-qa-db-fra.com

Pourquoi itemStateChanged sur JComboBox est appelé deux fois lorsqu'il est modifié?

J'utilise une JComboBox avec un ItemListener dessus. Lorsque la valeur est modifiée, l'événement itemStateChanged est appelé deux fois. Le premier appel, ItemEvent affiche l'élément d'origine sélectionné. La deuxième fois, il montre l'élément qui vient d'être sélectionné par l'utilisateur. Voici un code de testeur:

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

Ainsi, lorsque j'ai changé une fois la zone de liste déroulante de "Un" à "Trois", la console affiche:

One
Three

Existe-t-il un moyen de savoir si j'utilise ItemEvent, qu'il s'agit du deuxième élément (c'est-à-dire l'élément sélectionné par l'utilisateur)? Et si quelqu'un peut expliquer pourquoi il est appelé deux fois, ce serait bien aussi!

Merci

36
Nicks

Jetez un œil à cette 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();
    }
}

Utilisez getStateChange pour déterminer si un élément est sélectionné ou désélectionné

31
kgiannakakis

Selon cela thread ,

Il est déclenché lorsque vous laissez un résultat, puis rappelé à nouveau lorsqu'il est défini sur un autre résultat.

N'écoutez pas itemStateChanged. Utilisez un ActionListener à la place, ce qui est bon pour gérer les événements du combo.
Vous avez besoin d'un ItemStateListener si vous devez gérer séparément la désélection/sélection en fonction de l'élément concerné.

La modification de l'état de l'élément dans itemStateChanged provoque le déclenchement de itemStateChanged ... cela s'appelle "réentrance".

16
VonC

Je voulais obtenir la chaîne d'index après avoir sélectionné et défini dans la zone de liste déroulante

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

Vous pouvez le faire comme ceci:

import Java.awt.event.*;

jComboBox1.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            System.out.println("Hello");
        }
    });
7
humberto mena
private void dropDown_nameItemStateChanged(Java.awt.event.ItemEvent evt) {                                                 


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

}

Bonne chance!

5
21stking

Le code est:

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);
    }
}
3
Hussain

Jetez un oeil ici,

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

Lorsque vous sélectionnez une nouvelle option, elle n'appellera qu'une seule fois le JOptionPane, indiquant que le code ne sera appelé qu'une seule fois.

1
Junaid Khan
  1. Lorsque l'item est sélectionné dans la zone de liste déroulante, il déclenche en interne le changement de sélection, c'est-à-dire qu'il appellera la fonction setSelectedItem.
  2. Si un écouteur d'événement itemStateChanged explicite est implémenté, setSelectedItem appellera itemStateChanged. Ainsi, lorsqu'un élément est sélectionné, il appelle setSelectedItem puis il appelle itemStateChanged.
  3. Lorsque la valeur de la zone de liste modifiable change, même cela déclenche également itemStateChanged et donc itemStateChanged est appelé.
  4. J'avais écrit un écouteur pour le changement d'élément pour gérer le changement de valeur de la zone de liste déroulante lorsqu'il était défini en interne à partir du code et cela a provoqué l'appel de la fonction deux fois.

Voici les 2 traces arrière, qui sont invoquées lorsqu'une valeur est sélectionnée dans la zone de liste déroulante.

1ère fois sur changement de valeur réelle:

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

2ème fois à cause de l'opération sur 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
Kuldeep Melligeri

Citation de Tutoriel Java :

"Un seul élément à la fois peut être sélectionné dans une zone de liste déroulante, donc lorsque l'utilisateur fait une nouvelle sélection, l'élément précédemment sélectionné devient non sélectionné. Ainsi, deux événements d'élément sont déclenchés chaque fois que l'utilisateur sélectionne un élément différent dans le menu . Si l'utilisateur choisit le même élément, aucun événement d'élément n'est déclenché. "

0
Alex