Java/Swing实现Qt中的LineEdit中的QCompleter,实现文本输入框(JTextField)的自动补全/智能提示/输入猜想。

Java/Swing实现Qt中的LineEdit中的QCompleter,实现文本输入框(JTextField)的自动补全/智能提示/输入猜想。

百度搜索的时候,在搜索框中输入一些内容,后台会智能计算出一些可能的搜索内容,方便了用户。

而在Qt搭建C端界面/上位机的时候,也有一个组件,实现了自动补齐的功能。这是根据文本匹配,通过输入的内容和库中字符串进行匹配,并在下面列出候选框中的内容。

Java的界面框架Swing并没有类似的功能。本文扩展JTextField组件,即在JTextField文本输入框中,组合QComboBox的下拉框,实现类似的功能。并提供简易的添加/删除字符串库,以及常用功能的接口。

  • 最终效果图
    在这里插入图片描述
  • 主要实现功能:
    • 点击文本框,弹出下拉框,并显示所有库中的字符串。
    • 弹出后,上下键更改选中框的选中项。
    • 回车/点击弹出框,会将选中的内容放置到输入框中。
    • 使用方法和JTextField一样(因为是继承的)
    • 输入文本后,会自动根据文本在库中筛选结果,并放到下拉框中供选择。
  • api
    • addItem(String[] str),addItem(String str),addItem(Array strings)等方法均可添加字符串库。
    • removeItem(String str)移除字符串库中的值。
  • 实现细节:
    • 将ComboBox的getPreferredSize().height设置成0,这样,就只有下拉框了。
    • ComboBox添加到JTextField的BORDER.SOUTH。
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;

public class ComboText extends JTextField {
    
    
    private JComboBox<String> comboBox;
    private Set<String> itemsSet = new HashSet<>(30);

    public ComboText() {
    
    
        setVisible(true);
        initComboBox();
        initTextField();
    }

    //当鼠标点击聚焦的时候,会弹出来。
    @Override
    public void requestFocus() {
    
    
        super.requestFocus();
        if (getText() == null || getText().equals(""))
            setText("");
        setText(getText());
    }

    public void addItem(String str) {
    
    
        //判断一下是否重复
        if (itemsSet.contains(str)) {
    
    
            return;
        }
        comboBox.addItem(str);
        itemsSet.add(str);
        setText("");//保证初始化完成后TextField中内容是空。
    }

    public void removeItem(String str) {
    
    
        if(itemsSet.contains(str)) {
    
    
            itemsSet.remove(str);
        }
    }

    

    public void addItem(String[] strings) {
    
    
        for (String str : strings) {
    
    
            addItem(str);
        }

    }

    public void addItem(ArrayList<String> strings) {
    
    
        for (String str : strings) {
    
    
            addItem(str);
        }
    }

    private void initComboBox() {
    
    
        final DefaultComboBoxModel comboBoxModel = new DefaultComboBoxModel();
        comboBox = new JComboBox(comboBoxModel) {
    
    
            @Override
            public Dimension getPreferredSize() {
    
    
                return new Dimension(super.getPreferredSize().width, 0);
            }
        };

        comboBox.addItemListener(new ItemListener() {
    
    
            @Override
            public void itemStateChanged(ItemEvent e) {
    
    
                if (e.getStateChange() == ItemEvent.SELECTED) {
    
    
                    if (comboBox.getSelectedItem() == null) {
    
    
                        return;
                    }
                    if(!isAdjusting(comboBox)) {
    
    
                        setText(comboBox.getSelectedItem().toString());
                    }
                }
            }
        });
        //comboBox.addItem("");这里可以加入默认的一些选项
        comboBox.setSelectedItem(null);
        comboBox.setEditable(true);
        comboBox.setEnabled(true);
    }

    private void initTextField() {
    
    
        setLayout(new BorderLayout());
        add(comboBox, BorderLayout.SOUTH);
        //获取文本编辑的时候的信息
        getDocument().addDocumentListener(new DocumentListener() {
    
    
            @Override
            public void insertUpdate(DocumentEvent e) {
    
    
                updateList();
            }

            @Override
            public void removeUpdate(DocumentEvent e) {
    
    
                updateList();
            }

            @Override
            public void changedUpdate(DocumentEvent e) {
    
    
                updateList();
            }

            private void updateList() {
    
    
                setAdjusting(comboBox,true);
                comboBox.removeAllItems();
                String containerStr = getText().trim();
                if (containerStr != null && containerStr != "") {
    
    
                    for (String str : itemsSet) {
    
    
                        //通过String的contains进行判断,简洁很多。否则用正则也行
                        if (str.toLowerCase().contains(containerStr.toLowerCase())) {
    
    
                            comboBox.addItem(str);
                        }
                    }
                }
                //父组件是TextField,父父组件没有说明JTextField没有设置好位置,此时弹出会抛出异常
                if(comboBox.getParent().getParent()!=null){
    
    
                    //重新弹出来一次,否则候选框的总数不知为何不会扩容只会缩容。
                    comboBox.setPopupVisible(false);
                    comboBox.setPopupVisible(true);
                    comboBox.setSelectedItem(null);
                }
                setAdjusting(comboBox,false);
            }
        });

        addMouseListener(new MouseAdapter() {
    
    
            @Override
            public void mousePressed(MouseEvent e) {
    
    
                setAdjusting(comboBox,true);
                super.mousePressed(e);
                comboBox.setPopupVisible(true);
                setAdjusting(comboBox,false);
            }
        });

        addKeyListener(new KeyAdapter() {
    
    
            @Override
            public void keyPressed(KeyEvent e) {
    
    
                setAdjusting(comboBox,true);
                super.keyPressed(e);
                if( e.getKeyCode() == KeyEvent.VK_ENTER||e.getKeyCode() == KeyEvent.VK_UP || e.getKeyCode() == KeyEvent.VK_DOWN) {
    
    
                    if(e.getKeyCode() == KeyEvent.VK_UP || e.getKeyCode() == KeyEvent.VK_DOWN) {
    
    
                        e.setSource(comboBox);
                        comboBox.dispatchEvent(e);
                    }
                    if(e.getKeyCode()==KeyEvent.VK_ENTER) {
    
    
                        if(comboBox.getSelectedItem()!=null) {
    
    
                            if(comboBox.getSelectedItem()!=null) {
    
    
                                setText(comboBox.getSelectedItem().toString());
                            }
                            comboBox.setPopupVisible(false);
                        }
                    }
                }
                setAdjusting(comboBox,false);
            }
        });
    }
    private static void setAdjusting(JComboBox jComboBox, Boolean adjusting) {
    
    
        jComboBox.putClientProperty("isAdjusting",adjusting);
    }
    private static Boolean isAdjusting(JComboBox cbInput) {
    
    
        if(cbInput.getClientProperty("isAdjusting") instanceof Boolean) {
    
    
            return (Boolean) cbInput.getClientProperty("isAdjusting");
        }
        return false;
    }
}

猜你喜欢

转载自blog.csdn.net/o_ogou/article/details/103632862