Подтвердить что ты не робот

Почему itemStateChanged на JComboBox вызывается дважды при изменении?

Я использую JComboBox с ItemListener на нем. Когда значение изменяется, событие 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);
}

Итак, когда я изменил поле Combo один раз с "One" на "Three", консоль показывает:

One
Three

Есть ли способ, который я могу сказать, используя ItemEvent, возможно, что это второй элемент (т.е. выбранный пользователем элемент)? И если кто-то может объяснить, почему его дважды вызывают, это тоже было бы неплохо!

Спасибо

4b9b3361

Ответ 1

Посмотрите на этот источник:

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, чтобы определить, выбран или не выбран элемент

Ответ 2

В соответствии с этим thread,

Он сработает, когда вы оставите один результат, а затем снова вызван, когда задан другой результат

Не слушайте itemStateChanged. Вместо этого используйте ActionListener, что полезно для обработки событий комбо.
Вам нужно ItemStateListener, если вам нужно отдельно обрабатывать выбор/выбор в зависимости от объекта.

Изменение состояния элемента в itemStateChanged вызывает увольнение itemStateChanged... это называется "повторный вход".

Ответ 3

Я хотел получить индексную строку после ее выбора и установить в combobox

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

Ответ 4

Йо может сделать это вот так:

import java.awt.event.*;

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

Ответ 5

Код:

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

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


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

}

Удачи!

Ответ 7

Цитата из Учебник по Java:

"В поле со списком можно выбрать только один элемент, поэтому, когда пользователь делает новый выбор, выбранный ранее элемент становится не выбранным. Таким образом, два события элемента запускаются каждый раз, когда пользователь выбирает другой элемент из меню. Если пользователь выбирает один и тот же элемент, события элемента не запускаются."

Ответ 8

  • Когда anyitem выбран из поля со списком, он внутренне вызывает изменение выбора, т.е. вызывает функцию setSelectedItem.
  • Если используется явный элемент прослушивателя событий itemStateChanged, setSelectedItem вызывается itemStateChanged. Таким образом, когда выбран элемент, он вызывает setSelectedItem, затем вызывает itemStateChanged.
  • Когда изменяется значение поля со списком, даже это вызывает триггер itemStateChanged и, следовательно, вызывается itemStateChanged.
  • Я написал слушателя для изменения элемента, чтобы обработать изменение значения поля со списком, когда он установлен внутри кода, и это вызвало двойную функцию вызова.

Вот два обратных следа, которые вызывается, когда значение выбрано из поля со списком.

1-й раз при изменении фактической стоимости:

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-й раз из-за действия на 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)]

Ответ 9

Посмотрите здесь,

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

Когда вы выберете новую опцию, она только раз вызовет JOptionPane, указав, что код там будет вызываться только один раз.

Ответ 10

JComboBox.setFocusable(false) выполнит трюк.