我正在尝试动态验证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。
答案 0 :(得分: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个元素,你可以拥有它自己的。如果存在数据,则检查然后确定是否应该使用当前选择。
答案 1 :(得分: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();
}
});
}
}
答案 2 :(得分:0)
实际上,没有办法阻止选择在JComboBox中进行更改。 之前的所有示例都没有真正阻止选择更改,而只是在选择更改后将其设置回先前选择的项目。
如果你看一下JTree,你会发现TreeWillExpandListener,它会让你有可能否决扩展,因为你会在它扩展之前收到TreeWillExpandEvent。
如果将ItemListener添加到JComboBox,您将在选择更改后收到ItemEvents。如果ItemEvent的stateChange是DESELECTED,那么getItem()将为您提供先前选择的项目。但是,如果你调用getSelectedItem(),它会给你另一个项目,因为选择已经改变了。