6

JComboBox によって選択された項目を動的に検証しようとしていますが、検証が正しくない場合に選択の変更をキャンセルしたいと考えています。それを達成する方法はありますか?

private ItemListener itemListener = new ItemListener() {
    @Override                                            
    public void itemStateChanged(ItemEvent e) {
        if (e.getStateChange() == ItemEvent.SELECTED) {
            if (true) CANCEL_CHANGE;
        }
    }
};

古い値を保持する var を定義し、リスナーを登録解除し、以前の状態を手動で選択しようとしましたが、var が初期化されておらず、元の値を保持する方法がないため、最初の変更で問題が発生します。

ActionListener も使用してみましたが、変更をプログラムでキャンセルする方法が見つかりませんでした。また、fire イベントは必要なく、変更はありませんが、setSelection の可能性を手動で評価しているため、ItemListener に戻ります。

4

3 に答える 3

5

前の選択が存在しない場合の初期シナリオでは、0 などのデフォルトの選択インデックスにデフォルト設定します。

以下のサンプル コードを参照してください。

import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;


import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class TestChangeListener {

    final JTextField jTextField = new JTextField(20);
    Object list[] = { "ItemA", "ItemB" };
    int oldSelectionIndex = -1;
    final JComboBox jComboBox = new JComboBox(list);

    void init() {
        JFrame jFrame = new JFrame("Test");
        JPanel jPanel = new JPanel();
        new TestChangeListener();
        jPanel.add(jTextField);
        jPanel.add(jComboBox);
        jFrame.add(jPanel);
        jComboBox.addItemListener(new ItemListener() {
            @Override
            public void itemStateChanged(ItemEvent event) {
                if (event.getStateChange() == ItemEvent.SELECTED) {
                    if (!"Okay".equalsIgnoreCase(jTextField.getText())) {
                        if (oldSelectionIndex < 0) {
                            jComboBox.setSelectedIndex(0);
                        } else {
                            jComboBox.setSelectedIndex(oldSelectionIndex);
                        }
                    } else {
                        oldSelectionIndex = jComboBox.getSelectedIndex();
                    }
                }
            }
        });
        jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jFrame.pack();
        jFrame.setVisible(true);
    }

    public static void main(String args[]) {
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new TestChangeListener().init();
            }
        });
    }
}

初めて textField にデータが含まれていない場合は、デフォルトのアイテム (この場合はその 0 番目の要素) を選択するだけで、独自のアイテムを持つことができます。データが存在する場合は、現在の選択を使用するかどうかを確認して決定します。

于 2012-05-22T16:05:12.340 に答える
4

私はそれができますが、なぜあなたがそれをできないのかわかりません。このコード例を見て、任意の値を 3 回選択すると、4 回目で空の文字列に戻ります。

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

public class ComboTest {

    private JLabel imageLabel;
    private JComboBox comboImage;

    private String[] names = {"", "ukIcon","caIcon","unknwon"};
    private boolean flag;
    private int counter;

    public ComboTest(){
        flag = false;
        counter = 0;
        initComponents();
    }

    public void initComponents(){
        JFrame frame = new JFrame("Test Combo");        
        frame.setSize(320, 160);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLayout(new FlowLayout());

        comboImage = new JComboBox(names);
        comboImage.addItemListener(new ItemListener(){
            public void itemStateChanged(ItemEvent event){
                if(event.getStateChange() == ItemEvent.SELECTED){
                    if (flag)
                        comboImage.setSelectedItem("");
                    else
                    {
                        counter++;
                        if (counter == 3)
                            flag = true;
                        System.out.println((String) comboImage.getSelectedItem());
                    }   
                }
            }
        });

        frame.add(comboImage);
        frame.setVisible(true);
    }

    public static void main(String... args)
    {
        javax.swing.SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                new ComboTest();
            }
        });
    }
}

前の値を持つコード

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

public class ComboTest {

    private JLabel imageLabel;
    private JComboBox comboImage;

    private String[] names = {"", "ukIcon","caIcon","unknwon"};
    private boolean flag;
    private int counter;
    private String previousValue;

    public ComboTest(){
        flag = false;
        counter = 0;
        previousValue = "";
        initComponents();
    }

    public void initComponents(){
        JFrame frame = new JFrame("Test Combo");        
        frame.setSize(320, 160);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLayout(new FlowLayout());

        comboImage = new JComboBox(names);
        comboImage.addItemListener(new ItemListener(){
            public void itemStateChanged(ItemEvent event){
                if(event.getStateChange() == ItemEvent.SELECTED){
                    if (flag)
                        comboImage.setSelectedItem(previousValue);
                    else
                    {
                        counter++;
                        if (counter == 3)
                            flag = true;
                        previousValue = (String) comboImage.getSelectedItem();  
                        System.out.println((String) comboImage.getSelectedItem());
                    }   
                }
            }
        });

        frame.add(comboImage);
        frame.setVisible(true);
    }

    public static void main(String... args)
    {
        javax.swing.SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                new ComboTest();
            }
        });
    }
}
于 2012-05-22T15:58:38.817 に答える
0

実際、JComboBox で選択が変更されるのを防ぐ方法はありません。前の例はすべて、実際には選択の変更を妨げているわけではなく、変更後に以前に選択されていたアイテムに選択を戻すだけです。

JTree を見ると、展開する前に TreeWillExpandEvent を受け取るため、展開を拒否できる TreeWillExpandListener が見つかります。

JComboBox に ItemListener を追加すると、選択が変更された後に ItemEvents を受け取ります。ItemEvent の stateChange が DESELECTED の場合、getItem() は以前に選択された項目を返します。ただし、 getSelectedItem() を呼び出すと、選択が既に変更されているため、別のアイテムが返されます。

于 2016-06-19T14:09:48.303 に答える