可编辑的组合框JComboBox实现可删除,可添加下拉选项效果

参考文章:可编辑的组合框JComboBox实现可删除下拉选项效果

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

风情客家__

原创不易,觉得好的话给个打赏哈

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值