Whimusical Whimusical - 5 months ago 10
Java Question

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.

Answer

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