键入一个字符后,JComboBox失去焦点

时间:2015-07-21 11:28:30

标签: java swing awt jcombobox

我扩展了JComboBox以添加自动完成功能。这是代码:

public class AutocompleteJComboBox extends JComboBox{

static final long serialVersionUID = 4321421L;

private final Searchable<String,String> searchable;

/**
 * Constructs a new object based upon the parameter searchable
 * @param s
 */

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(){
                //perform separately, as listener conflicts between the editing component
                //and JComboBox will result in an IllegalStateException due to editing 
                //the component when it is locked. 
                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);
                    }
                });
            }
        });

        //When the text component changes, focus is gained 
        //and the menu disappears. To account for this, whenever the focus
        //is gained by the JTextComponent and it has searchable values, we show the popup.

        tc.addFocusListener(new FocusListener(){
            @Override
            public void focusGained(FocusEvent arg0) {
                System.out.println("Focus gained");
                if ( tc.getText().length() > 0 ){
                    setPopupVisible(true);
                }
                tc.requestFocusInWindow();
            }

            @Override
            public void focusLost(FocusEvent arg0) {    
                System.out.println("Focus lost");

            }
        });
    }else{
        throw new IllegalStateException("Editing component is not a JTextComponent!");
    }
}

}

现在,自动完成部分工作正常。问题是,在我输入一个字符后,它会失去焦点(焦点转到我的其他UI元素,一个普通的JTextField)。我必须提一下,如果UI只包含这个组合框,它可以完美地工作,不会丢失焦点(因为我没有其他元素,我认为)。

知道我在这里做错了什么吗?感谢。

1 个答案:

答案 0 :(得分:0)

如果还不晚,并且对于每个人都在努力解决这个问题,我在requestFocus()方法的末尾添加了update()。这是一种解决方法,但似乎工作正常。 此自动完成组合框实现的另一个补充是添加

putClientProperty("JComboBox.isTableCellEditor", Boolean.TRUE);

在构造函数中,使您可以使用向上nad向下箭头键循环使用弹出项目,而无需更改组合框中的输入。