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,但找不到以编程方式取消更改的方法,而且我不需要触发事件然后没有更改,但我正在手动评估 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

我能做到,不知道为什么你不能做到。看看这个代码示例,选择任何值三次,然后在第四次它将恢复为空字符串:

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,您会发现 TreeWillExpandListener,它可以让您否决扩展,因为您将在 TreeWillExpandEvent 扩展之前收到它。

如果您将 ItemListener 添加到 JComboBox,您将在选择更改后收到 ItemEvents。如果 ItemEvent 的 stateChange 为 DESELECTED,则 getItem() 将为您提供先前选择的项目。但是,如果您调用 getSelectedItem() 它会给您另一个项目,因为选择已经更改。

于 2016-06-19T14:09:48.303 回答