2

私のコードは実際には非常に単純です。シンプルで類似したコードがこの記事からのものであることがわかりました。

最初は、1つのコンボボックスがありますitemStateChanged()というリスナーがあります。このリスナーに追加する私の目的は次のとおりです。「ユーザーがドロップボックスからアイテムをクリック(選択)したときにコードを実行する」.

Cmb_ItemCategory = new javax.swing.JComboBox();

Cmb_ItemCategory.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Loading..." }));

Cmb_ItemCategory.addItemListener(new java.awt.event.ItemListener() {
    public void itemStateChanged(java.awt.event.ItemEvent evt) {
        Cmb_ItemCategoryItemStateChanged(evt);
    }
});

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

        if(evt.getStateChange() == java.awt.event.ItemEvent.SELECTED){
        System.err.println("Sombody click or change my model content");
        }

    }

コードの背後で、いくつかのデータを取得してから、 removeAllItems() のメソッドを呼び出します。そして、(新しいデータから) 新しいモデルをそれに設定します。

-- at another line of code ---
Cmb_ItemCategory.removeAllItems();
Cmb_ItemCategory.setModel(newModel);

removeAllItem()メソッドを実行すると、itemStateChanged() が呼び出されることに気づきました。一度呼ばれた。

では、ユーザーがクリック (選択) したときにのみ呼び出され、removeAllItems() が呼び出されたときに呼び出されないようにする方法は?

この記事に似ています。しかし、removingItems ケースではありません。CMIIW。

4

5 に答える 5

5

ここでこのコードをチェックしてください。これは問題なく動作します。呼び出した場所で何か間違ったことをしている可能性がありますremoveAllItems()

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

public class ComboState 
{
    private void createAndDisplayGUI()
    {
        JFrame frame = new JFrame("Combo State Testing : ");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

        final JComboBox cbox = new JComboBox();
        cbox.addItem("One");
        cbox.addItem("Two");
        cbox.addItem("Three");
        cbox.addItem("Four");
        cbox.addItemListener(new ItemListener()
        {
            public void itemStateChanged(ItemEvent ie)
            {
                if (ie.getStateChange() == ItemEvent.SELECTED)
                {
                    System.out.println("Item Selected is : " + ie.getItem());
                }
                /*else
                {
                    System.out.println("I am called for other reasons.");
                }*/
            }
        });

        /*
         * Click me to remove JComboBox's items.
         */
        JButton removeButton = new JButton("REMOVE");
        removeButton.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent ae)
            {
                cbox.removeAllItems();
            }
        });

        frame.add(cbox, BorderLayout.CENTER);
        frame.add(removeButton, BorderLayout.PAGE_END);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    public static void main(String... args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                new ComboState().createAndDisplayGUI();
            }
        });
    }
}
于 2012-04-18T06:00:13.890 に答える
3

nIcE cOw が彼の例で既に示したように、a を使用すると確実に機能するはずですDefaultComboBoxModel(画面の後ろで発生しますが、彼のサンプル コードではそうです)。

DefaultComboBoxModelあなたのコードスニペットはあなたが1つを使用することを示唆していますが、私はあなたが非ケースで遭遇する動作を説明することができます. メソッドがインターフェースの一部ではないため、ソースコードを見るとJComboBox#removeAllItems、別のコードパスがありますremoveAllElementsMutableComboBoxModel

public void removeAllItems() {
    checkMutableComboBoxModel();
    MutableComboBoxModel<E> model = (MutableComboBoxModel<E>)dataModel;
    int size = model.getSize();

    if ( model instanceof DefaultComboBoxModel ) {
        ((DefaultComboBoxModel)model).removeAllElements();
    }
    else {
        for ( int i = 0; i < size; ++i ) {
            E element = model.getElementAt( 0 );
            model.removeElement( element );
        }
    }
    selectedItemReminder = null;
    if (isEditable()) {
        editor.setItem(null);
    }
}

したがって、 non- ではDefaultComboBoxModel、アイテムを 1 つずつ削除します。これは、特定の時点で、選択した要素を削除することを意味します。モデルの可能な実装は、その時点で選択された要素を変更する可能性があります。たとえば、 の実装を見るとDefaultComboBoxModel(このコードはトリガーされませんが)、選択が変更されていることがはっきりとわかります。

public void removeElementAt(int index) {
    if ( getElementAt( index ) == selectedObject ) {
        if ( index == 0 ) {
            setSelectedItem( getSize() == 1 ? null : getElementAt( index + 1 ) );
        }
        else {
            setSelectedItem( getElementAt( index - 1 ) );
        }
    }

    objects.removeElementAt(index);

    fireIntervalRemoved(this, index, index);
}

おそらく、モデルは同様のことを行い、イベントを説明します。DefaultComboBoxModel#removeAllElementsこの投稿を完成させるためだけに、はっきりと見える場所の背後にあるコードは、選択を に設定し、null別のオブジェクトを選択しません。そのコードの唯一の奇妙な点は、DESELECTEDイベントをリッスンすると選択が変更されたことを知っているにもかかわらず、最初にイベントを発生させないことintervalRemovedです...しかし、それは実際には問題には関係ありません

public void removeAllElements() {
    if ( objects.size() > 0 ) {
        int firstIndex = 0;
        int lastIndex = objects.size() - 1;
        objects.removeAllElements();
        selectedObject = null;
        fireIntervalRemoved(this, firstIndex, lastIndex);
    } else {
        selectedObject = null;
    }
}

結論として、あなたの問題の解決策は、投稿したコードではなく、モデルにあります。

于 2012-04-18T06:09:54.200 に答える
2

議論全体からは明らかではない、

  • すべてのアイテムを削除する前に、JComboBoxからすべてのリスナーを削除する必要があります。アイテムを削除した後、リスナーを追加し直すことができます。

  • アイテムを動的に追加および削除するか、別のJComponentに任意の値を設定できるかはまだわかりません。

  • (単純なことを複雑にすることに対して)あなたはそこが削除されるのを見ましたか、

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

public class ComboBoxTwo extends JFrame implements ActionListener, ItemListener {

    private static final long serialVersionUID = 1L;
    private JComboBox mainComboBox;
    private JComboBox subComboBox;
    private Hashtable<Object, Object> subItems = new Hashtable<Object, Object>();

    public ComboBoxTwo() {
        String[] items = {"Select Item", "Color", "Shape", "Fruit"};
        mainComboBox = new JComboBox(items);
        mainComboBox.addActionListener(this);
        mainComboBox.addItemListener(this);
        //prevent action events from being fired when the up/down arrow keys are used
        //mainComboBox.putClientProperty("JComboBox.isTableCellEditor", Boolean.TRUE);
        getContentPane().add(mainComboBox, BorderLayout.WEST);
        subComboBox = new JComboBox();//  Create sub combo box with multiple models
        subComboBox.setPrototypeDisplayValue("XXXXXXXXXX"); // JDK1.4
        subComboBox.addItemListener(this);
        getContentPane().add(subComboBox, BorderLayout.EAST);
        String[] subItems1 = {"Select Color", "Red", "Blue", "Green"};
        subItems.put(items[1], subItems1);
        String[] subItems2 = {"Select Shape", "Circle", "Square", "Triangle"};
        subItems.put(items[2], subItems2);
        String[] subItems3 = {"Select Fruit", "Apple", "Orange", "Banana"};
        subItems.put(items[3], subItems3);
//      mainComboBox.setSelectedIndex(1);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        String item = (String) mainComboBox.getSelectedItem();
        Object o = subItems.get(item);
        if (o == null) {
            subComboBox.setModel(new DefaultComboBoxModel());
        } else {
            subComboBox.setModel(new DefaultComboBoxModel((String[]) o));
        }
    }

    @Override
    public void itemStateChanged(ItemEvent e) {
        if (e.getStateChange() == ItemEvent.SELECTED) {
            if (e.getSource() == mainComboBox) {
                if (mainComboBox.getSelectedIndex() != 0) {
                    FirstDialog firstDialog = new FirstDialog(ComboBoxTwo.this,
                            mainComboBox.getSelectedItem().toString(), "Please wait,  Searching for ..... ");
                }
            } 
        }
    }

    private class FirstDialog extends JDialog {

        private static final long serialVersionUID = 1L;

        FirstDialog(final Frame parent, String winTitle, String msgString) {
            super(parent, winTitle);
            setModalityType(Dialog.ModalityType.APPLICATION_MODAL);
            JLabel myLabel = new JLabel(msgString);
            JButton bNext = new JButton("Stop Processes");
            add(myLabel, BorderLayout.CENTER);
            add(bNext, BorderLayout.SOUTH);
            bNext.addActionListener(new ActionListener() {

                @Override
                public void actionPerformed(ActionEvent evt) {
                    setVisible(false);
                }
            });
            javax.swing.Timer t = new javax.swing.Timer(1000, new ActionListener() {

                @Override
                public void actionPerformed(ActionEvent e) {
                    setVisible(false);
                }
            });
            t.setRepeats(false);
            t.start();
            setLocationRelativeTo(parent);
            setSize(new Dimension(400, 100));
            setVisible(true);
        }
    }

    public static void main(String[] args) {
        JFrame frame = new ComboBoxTwo();
        frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}
于 2012-04-18T08:16:39.767 に答える
2

簡単な方法の1つは、removeAllItem()を呼び出す前にboolをtrueに設定し、後でfalseに戻すことです。bool変数がfalseの場合にのみ、itemStateChanged()のコードを実行してください。

理想的には、removeAllItem()関数をオーバーライドできます。

于 2012-04-18T04:28:14.610 に答える