Cancel the selection change to JComboBox if the condition is met (for example, checking for incoming selection)

I am trying to dynamically check an item selected by JComboBox, and I want to undo the selection change in case of incorrect validation. Is there any way to achieve this?

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

I tried to detect var storing the old value, unregister the listener and select the previous state manually, but then the problem occurs with the first change, because var is not initialized, and there is no way to save the original value.

I also tried using the ActionListener, but did not find a way to programmatically cancel the change, and I do not need a fire event, then there are no changes, but I evaluate the chance of setSelection manually, so I return to ItemListener.

+6
source share
3 answers

I can do it, I don’t know why you cannot do it. Take a look at this code example, select any value three times, then for the fourth time it will return to an empty line:

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

In the original scenario, when there is no previous selection, the default selection index is used, for example, 0.

See the sample code below:

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

The first time the textField does not contain any data, it just selects the default element, in this case its 0th element, you can have its own. If data is present, it checks and then decides whether to use the current selection or not.

+5
source

In fact, there is no way to prevent selection in JComboBox. All of the previous examples do not actually prevent the selection from being changed; instead, they simply set the selection back to the previously selected item AFTER it has been changed.

If you look at JTree, you will find TreeWillExpandListener, which will give you the opportunity to veto the extension, because you will get TreeWillExpandEvent before the extension.

If you add an ItemListener to the JComboBox, you will receive ItemEvents AFTER the selection. If stateChange is from ItemEvent DESELLECTED, then getItem () will provide you with the previously selected item. However, if you call getSelectedItem (), it will give you another element, because the selection has already been changed.

0
source

Source: https://habr.com/ru/post/916366/


All Articles