参考文章:可编辑的组合框JComboBox实现可删除下拉选项效果
LabelCellRender类
package org.fiend.swing.test.demo.jcombobox;
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
/**
* 带键盘事件的渲染器
* 事件加到JCombox的编辑框中,通过编辑框的KeyListener事件进行监听
* @author pelang 2021-09-03 14:43:23
*/
public class LabelCellRender extends JLabel implements ListCellRenderer, KeyListener {
private static final long serialVersionUID = 1L;
private final JComboBox comboBox;
private int selectedIndex = -1;
/**
* 构造函数
* @param comboBox 当前渲染器所属的JComboBox
*/
public LabelCellRenderer(final JComboBox comboBox) {
setOpaque(true);
this.comboBox = comboBox;
this.comboBox.getEditor().getEditorComponent().addKeyListener(this);
}
public Component getListCellRendererComponent(JList list,
Object value,
int index,
boolean isSelected,
boolean cellHasFocus) {
this.setText(value.toString());
this.setFont(this.comboBox.getFont());
Color background;
Color foreground;
if (isSelected) {
background = Color.decode("#3399FE");
foreground = Color.WHITE;
this.selectedIndex = index;
} else {
background = Color.WHITE;
foreground = Color.BLACK;
}
setBackground(background);
setForeground(foreground);
return this;
}
@Override
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();
if (keyCode == 38) {// 按向上的方向键则索引减一
int index = this.comboBox.getSelectedIndex();
if (index == 0) {
return;
}
index--;
this.comboBox.setSelectedIndex(index);
} else if (keyCode == 40) {// 按向下的方向键则索引加一
int index = this.comboBox.getSelectedIndex();
if (index == this.comboBox.getItemCount() - 1) {
return;
}
index++;
this.comboBox.setSelectedIndex(index);
} else if (keyCode == 127) {
// 为防止误删除,只有在下来选项可视的情况下才可以执行删除操作
if (this.comboBox.isPopupVisible()) {
// 下来选框可见的情况下,设置Delete对文本框内文字操作无效
JTextField textField = ((JTextField) this.comboBox.getEditor().getEditorComponent());
String text = textField.getText();
int position = ((JTextField) this.comboBox.getEditor().getEditorComponent()).getCaretPosition();
// 如果是按Delete键则移除当前选中的Item
if (this.selectedIndex >= 0 && this.selectedIndex < this.comboBox.getItemCount()) {
this.comboBox.removeItemAt(this.selectedIndex);
textField.setText(text);
textField.setCaretPosition(position);
}
//此处代码在JDK1.6起作用,在JDK1.7失效,请注意
e.setKeyCode(-1);
}
}
}
@Override
public void keyReleased(KeyEvent e) {
}
@Override
public void keyTyped(KeyEvent e) {
}
}
LabelCellRenderTest类
package org.fiend.swing.test.demo.jcombobox;
import javax.swing.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
/**
* JCombobox添加和删除item功能
* @author pelang 2021-09-03 14:45:14
*/
public class LabelCellRenderTest {
public static void main(String[] args) {
JFrame jFrame = new JFrame("可删除下拉列表测试");
jFrame.setSize(280, 60);
jFrame.setLocationRelativeTo(null);
jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JComboBox<String> comboBox = new JComboBox<>();
//只有为true的时候才能进行删除
comboBox.setEditable(true);
comboBox.setRenderer(new LabelCellRender(comboBox));
comboBox.addItem("张三");
comboBox.addItem("李四");
comboBox.addItem("王五");
comboBox.addItem("赵六");
// 添加监听事件
comboBox.getEditor().getEditorComponent().addKeyListener(new KeyAdapter(){
@Override
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();
// 回车键添加新的item到下拉列表
if(keyCode == KeyEvent.VK_ENTER){
String s = (String)comboBox.getEditor().getItem();
System.out.println(s);
// 添加新的item到jCombobox列表
comboBox.addItem(s);
comboBox.setSelectedIndex(comboBox.getItemCount() -1);
}
// 添加删除功能, 该删除功能与LabelCellRender类无关
if (keyCode == 127) {
// 为防止误删除,只有在下来选项可视的情况下才可以执行删除操作
if (comboBox.isPopupVisible()) {
// 如果是按Delete键则移除当前选中的Item, index==0时不能删除
int selectedIndex = comboBox.getSelectedIndex();
if (selectedIndex > 0 && selectedIndex < comboBox.getItemCount()) {
comboBox.removeItemAt(selectedIndex);
comboBox.hidePopup();
// comboBox.setSelectedIndex(comboBox.getItemCount() - 1);
comboBox.showPopup();
}
//此处代码在JDK1.6起作用,在JDK1.7失效,请注意
e.setKeyCode(-1);
}
}
}
});
jFrame.add(comboBox);
jFrame.setVisible(true);
}
}