web-dev-qa-db-ja.com

JComboBoxのitemStateChangedが変更されると2回呼び出されるのはなぜですか?

ItemListenerを含むJComboBoxを使用しています。値が変更されると、itemStateChangedイベントが2回呼び出されます。最初の呼び出しであるItemEventは、選択された元のアイテムを表示しています。 2回目は、ユーザーが選択したばかりのアイテムを表示しています。テスターコードは次のとおりです。

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

したがって、コンボボックスを「1」から「3」に一度変更すると、コンソールに次のように表示されます。

One
Three

多分ItemEventを使用して、それが2番目のアイテム(つまり、ユーザーが選択したアイテム)であることを伝える方法はありますか?そして、誰かがなぜそれが二度呼ばれるのかを説明できれば、それもいいでしょう!

ありがとう

36
Nicks

このソースを見てください:

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を使用して、アイテムが選択または選択解除されているかどうかを判断します

31
kgiannakakis

これによると thread

ある結果を残すとトリップし、別の結果に設定すると再び呼び出されます

ItemStateChangedをリッスンしないでください。代わりに、ActionListenerを使用してください。これは、コンボのイベントを処理するのに適しています。
関連するアイテムに応じて選択解除/選択を個別に処理する必要がある場合は、ItemStateListenerが必要です。

ItemStateChanged内のアイテムの状態を変更すると、itemStateChangedが発生します。これは「リエントラント」と呼ばれます。

16
VonC

コンボボックスで選択して設定した後にインデックス文字列を取得したかった

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

Yoは次のようにできます:

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

}

幸運を!

5
21stking

コードは次のとおりです。

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

こちらをご覧ください

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が1回だけ呼び出され、そこにあるコードが1回だけ呼び出されることを示します。

1
Junaid Khan
  1. Anyitemがコンボボックスから選択されると、内部で選択の変更がトリガーされます。つまり、関数setSelectedItemが呼び出されます。
  2. 明示的なitemStateChangedイベントリスナーが実装されている場合、setSelectedItemはitemStateChangedを呼び出します。そのため、アイテムが選択されると、setSelectedItemが呼び出され、itemStateChangedが呼び出されます。
  3. コンボボックスの値が変更されると、それでもitemStateChangedがトリガーされ、itemStateChangedが呼び出されます。
  4. コードから内部的に設定されたときにコンボボックスの値の変更を処理するアイテム変更のリスナーを作成したため、関数が2回呼び出されました。

以下は、コンボボックスから値が選択されたときに呼び出される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)]

コンボボックスの操作による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: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

Javaチュートリアル からの引用:

「コンボボックスで選択できるのは一度に1つのアイテムのみであるため、ユーザーが新しい選択を行うと、以前に選択されたアイテムは選択解除されます。メニューとは異なるアイテム。ユーザーが同じアイテムを選択した場合、アイテムイベントは発生しません。」

0
Alex