解决JComboBox组合框中出现重复选项及输出两次已添加项的问题
- 起初的问题代码(主要部分)
- 问题描述:单击已有选项,可以在JTextArea输出,修改后按了enter键,在组合框与面板中都添加了两次
//【**添加事件监听**】
ActionListener a1 = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
JComboBox jcb = (JComboBox) e.getSource();
String c;
if (jcb == jcb1) {
// 将选项插入jcb2的第一个位置
// jcb2.insertItemAt(jcb1.getSelectedItem(),0);
ta.append("\nItem" + jcb1.getSelectedItem());
}else if(jcb == jcb2){
jcb2.addItem(jcb2.getSelectedItem());//将当前输入的字符串添加到选项中
ta.append("\nYou SELECTED ITEM :" + jcb2.getSelectedItem()); //ta是一个JTextArea的实例
}
}
};
运行结果:
- 对组合框中的内容进行了判断,选项中没有与已经输入的值一样的选项时输出并添加至选项
- 问题描述:只有回车才能够构成一次输出,也只能是新的值,对鼠标的点击不再响应
//【**添加事件监听**】
ActionListener a1 = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
JComboBox jcb = (JComboBox) e.getSource();
String c;
if (jcb == jcb1) {
// 将选项插入jcb2的第一个位置
// jcb2.insertItemAt(jcb1.getSelectedItem(),0);
ta.append("\nItem" + jcb1.getSelectedItem());
}
else if(jcb == jcb2){
String tmp = (String) jcb2.getSelectedItem();
boolean flag = true;
for (int i = 0; i < jcb2.getItemCount(); i++) {
if (jcb2.getItemAt(i).equals(tmp)) {
flag = false;
break;
}
}
if(flag){
jcb2.addItem(jcb2.getSelectedItem());
ta.append("\nYou SELECTED ITEM :" + jcb2.getSelectedItem());
}
}
}
};
运行结果:
修改完成的主要代码块:
//【**添加事件监听**】
ActionListener a1 = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
JComboBox jcb = (JComboBox) e.getSource();
String c;
if (jcb == jcb1) {
// 将选项插入jcb2的第一个位置
// jcb2.**insertItemAt(jcb1.getSelectedItem(),0);
ta.append("\nItem" + jcb1.getSelectedItem());
}
else if(jcb == jcb2){
//【**存放用户输入完成的字符串**】
String tmp = (String) jcb2.getSelectedItem();
boolean flag = true;
//【**将用户输入的值与已有选项一一比较**】
for (int i = 0; i < jcb2.getItemCount(); i++) {
//【**如果有与用户输入的值相同的值,仅添加到面板不添加到选项**】
if (jcb2.getItemAt(i).equals(tmp)) {
flag = false;
ta.append("\nYou SELECTED ITEM :" + jcb2.getSelectedItem());
break;
}
}
//【**如果输入的值选项中没有,则添加到选项,事件会持续监听,再次执行到for循环时,检测到有相同值,仅输出】
if(flag){
jcb2.addItem(jcb2.getSelectedItem());
}
}
}
};
执行结果:
本案例为清华大学出版社Java程序设计(第三版)程序8-5
欢迎高手评论指正
笔者全部代码块如下:
package experiment_eight; import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Scanner;import javax.swing.BorderFactory;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.border.Border;public class JComboBoxDemo {
// 【**新建一个窗口**】
JFrame frame = new JFrame("jJComboBox Demo");
// 【**定义两个组合框的变量**】
JComboBox jcb1, jcb2;
// 【**设定文本框的列数,即显示的行的长度**】
JTextArea ta = new JTextArea(0, 30); public static void main(String[] args) {
JComboBoxDemo cbd = new JComboBoxDemo();
cbd.go();
} public void go() {
// 【**创建4个画板**】
JPanel p1 = new JPanel();
JPanel p2 = new JPanel();
JPanel p3 = new JPanel();
JPanel p4 = new JPanel();
// 【**创建组合框具有的选项**】
String[] itemList = { "One", "Two", "Three", "Four", "Five" };
// 【**将选项内容加入到组合框中**】
jcb1 = new JComboBox(itemList);
// 【**设置当前的选项,一下为设置当前的可选项目是第一个项**】
jcb1.setSelectedIndex(0);
// 【**将组合框添加到panel1中去**】
p1.add(jcb1); /*
* BorderFactory提供了很多边框的方法:下面etched、border分别是创建了一个 凹凸的边框和一个标题边框
*/
Border etched = BorderFactory.createEtchedBorder();
Border border = BorderFactory.createTitledBorder(etched, "Uneditable JComboBox");
p1.setBorder(border);
// 【**新建一个组合框实例**】
jcb2 = new JComboBox(); // 【**添加四个可选项给jcb2**】
jcb2.addItem("Six");
jcb2.addItem("Seven");
jcb2.addItem("Eight");
jcb2.addItem("nine"); // 【**将jcb2设置为可编辑的**】
jcb2.setEditable(true);
p2.add(jcb2);
// 【**设置同样的边框**】
border = BorderFactory.createTitledBorder(etched, "Editable JComboBox");
p2.setBorder(border); JScrollPane jp = new JScrollPane(ta);
p3.setLayout(new BorderLayout());
// 【**p3放着的是带有滚动条的文本框**】
p3.add(jp);
// 【**设置边框**】
border = BorderFactory.createTitledBorder(etched, "Results");
p3.setBorder(border);
//【**添加事件监听**】
ActionListener a1 = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
JComboBox jcb = (JComboBox) e.getSource();
String c;
if (jcb == jcb1) {
// 将选项插入jcb2的第一个位置
// jcb2.**insertItemAt(jcb1.getSelectedItem(),0);
ta.append("\nItem" + jcb1.getSelectedItem());
}
else if(jcb == jcb2){
//【**存放用户输入完成的字符串**】
String tmp = (String) jcb2.getSelectedItem();
boolean flag = true;
//【**将用户输入的值与已有选项一一比较**】
for (int i = 0; i < jcb2.getItemCount(); i++) {
//【**如果有与用户输入的值相同的值,仅添加到面板不添加到选项**】
if (jcb2.getItemAt(i).equals(tmp)) {
flag = false;
ta.append("\nYou SELECTED ITEM :" + jcb2.getSelectedItem());
break;
}
}
//【**如果输入的值选项中没有,则添加到选项,事件会持续监听,再次执行到for循环时,检测到有相同值,仅输出】
if(flag){
jcb2.addItem(jcb2.getSelectedItem());
}
}
}
};
/*//【**添加事件监听jcb2**】
ActionListener a2 = new ActionListener() {
int i = 0;
@Override
public void actionPerformed(ActionEvent e) {
String tmp = (String) jcb2.getSelectedItem();
boolean flag = true;
for (int i = 0; i < jcb2.getItemCount(); i++) {
if (jcb2.getItemAt(i).equals(tmp)) {
flag = false;
break;
}
}
if(flag){
jcb2.addItem(jcb2.getSelectedItem());
ta.append("\nYou SELECTED ITEM :" + jcb2.getSelectedItem());
} }
};*/ jcb1.addActionListener(a1);
jcb2.addActionListener(a1); p4.setLayout(new GridLayout(0, 1));
p4.add(p1);
p4.add(p2); Container cp = frame.getContentPane();
cp.setLayout(new GridLayout(0, 1));
cp.add(p4);
cp.add(p3); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}}
小结:查找了很久并没有找到针对于这个问题的解释,后在一个例子中找到了解决的方法,所以特别将这个错误写出来供大家查看,希望可以帮到你。之前疑惑当判断用户输入的数据与已有选项中数据不一样后,应该不只是添加到已有选项,还应该将值输出到JTextArea的实例中去,这样一来,一个新事件的for循环又判断到输入框中的值与已有选项相同,又输出了一遍。因此,我们只需在判断到是一个新值时添加到选项,让这个不停监听着组合框动态的事件知道输入框的数与已有选项相同,然后仅输出。