?? JComboBox是Java的Swing开发中比较常用的组件,但是默认的功能比较简单,在开发一个自己的小工具的时候,就希望能够通过上下方向键控制下拉框里Item的选中与否,并且希望能通过按Delete键对选中的Item进行删除,但是JComboBox从设计上就禁掉了对下来框里Item的各种事件的操作,所以实现起来就要换个思路,不能对下拉框里的Item进行绑定事件,因为他无法获取焦点,而焦点一直在JCombox的文本框里(我设置的是可编辑的JCombox),所以应该把事件加到JCombox的编辑框中,通过编辑框的KeyListener事件进行监听,代码如下:
?
class="java">package javax.swing; import java.awt.Color; import java.awt.Component; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; /** * * 带键盘事件的渲染器 * * @author 倪庆洋 <niqy@qq.com> * * @date 2015-1-17 下午05:34:02 * */ public class LabelCellRenderer extends JLabel implements ListCellRenderer, KeyListener { private static final long serialVersionUID = 1L; private 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){ // 为防止误删除,只有在下来选项可视的情况下才可以执行caozuo.html" target="_blank">删除操作 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) { } }
?
?
通过此渲染器对Item进行重新渲染,在渲染的过程中记录所选择的索引并进行键盘事件的监听。
?? 调用如下:?
package com.cntrust.file.test; import javax.swing.JComboBox; import javax.swing.JFrame; //自定义 import javax.swing.LabelCellRenderer; public class TestMain { /** * @param args * @throws Exception */ public static void main(String[] args) throws Exception { JComboBox comboBox = new JComboBox(); //只有为true的时候才能进行删除 comboBox.setEditable(true); comboBox.setRenderer(new LabelCellRenderer(comboBox)); JFrame jFrame = new JFrame(); jFrame.add(comboBox); comboBox.addItem("张三"); comboBox.addItem("李四"); comboBox.addItem("王五"); comboBox.addItem("赵六"); jFrame.setSize(280, 60); jFrame.setVisible(true); } }
?? 效果如下图:
?
删除前:
?删除后:
?
?
?
?