javaswingeventsjcomboboxitemlistener

Canceling selection change on a JComboBox if condition is satisfied (e.g validation on the incoming selection)


I´m trying to validate dynamically an item selected by a JComboBox, and I want to cancel the selection change in case the validation is not correct. Is there any way to achieve it?

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

I tried to define a var holding the old value, unregistering listener, and select to previous state manually, but then the problem comes with the first change, because the var is not initialized and there´s no way hold the original value.

I also tried using ActionListener, but found no way to programtically cancel the change, and I don´t need fire event then there´s no change but I am assessing the chance of setSelection manually, so I revert to ItemListener.


Solution

  • I can do that, dunno why you cannot do it. Have a look at this code example, select three times any values, then on the fourth time it will revert back to empty string :

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

    Code with Previous Value

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