可编辑的JCombobox,用于过滤列表并仅显示包含我编写的文本的文本

时间:2015-04-15 08:22:08

标签: java netbeans jcombobox

我需要一个包含元素的可编辑JCombobox:例如:

element 1
element 2
item one
item one two
element item

当我写例如"一个"时,它必须只显示我

item one
item one two

之前我发现的所有内容都是AutocompleteJCombobox,它会将我滚动到以"一个"开头的项目。

提前谢谢

2 个答案:

答案 0 :(得分:1)

使用例如algosome.com/articles/java-jcombobox-autocomplete.html用s.indexOf(value) == 0替换s.indexOf(value) >=0

答案 1 :(得分:0)

与同一Window中的其他组件一起使用时,StanislavL的AutocompleteJComboBox在键入时会失去焦点(至少在我的情况下如此)。
不过有一个简单的解决方法-添加requestFocus();在运行功能的末尾。

附加代码:

public class AutocompleteJComboBox extends JComboBox{
static final long serialVersionUID = 4321421L;
private final Searchable<String,String> searchable;

public AutocompleteJComboBox(Searchable<String,String> s){
    super();
    this.searchable = s;
    setEditable(true);
    Component c = getEditor().getEditorComponent();

    if ( c instanceof JTextComponent ){
        final JTextComponent tc = (JTextComponent)c;
        tc.getDocument().addDocumentListener(new DocumentListener(){

            @Override
            public void changedUpdate(DocumentEvent arg0) {}

            @Override
            public void insertUpdate(DocumentEvent arg0) {
                update();
            }

            @Override
            public void removeUpdate(DocumentEvent arg0) {
                update();
            }

            public void update(){
                SwingUtilities.invokeLater(new Runnable(){

                    @Override
                    public void run() {
                        List<String> founds = new ArrayList<String>(searchable.search(tc.getText()));
                        Set<String> foundSet = new HashSet<String>();
                        for ( String s : founds ){
                            foundSet.add(s.toLowerCase());
                        }
                        Collections.sort(founds);//sort alphabetically
                        setEditable(false);
                        removeAllItems();
                        //if founds contains the search text, then only add once.

                        if ( !foundSet.contains( tc.getText().toLowerCase()) ){
                            addItem( tc.getText() );
                        }                           

                        for (String s : founds) {
                            addItem(s);
                        }
                        setEditable(true);
                        setPopupVisible(true);
                        requestFocus();
                    }
                });
            }
        });

        tc.addFocusListener(new FocusListener(){

            @Override
            public void focusGained(FocusEvent arg0) {
                if ( tc.getText().length() > 0 ){
                    setPopupVisible(true);
                }
            }

            @Override
            public void focusLost(FocusEvent arg0) {                        
            }
        });
    }else{
        throw new IllegalStateException("Editing component is not a JTextComponent!");
    }
}
}