有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java 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) 个答案

  1. # 1 楼答案

    如果还不算太晚,并且对于所有正在为此而挣扎的人,我在update()方法的末尾添加了requestFocus()。这是一种变通方法,但似乎效果不错。 自动完成组合框的另一个实现是添加

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

    在构造器中,使用上下箭头键循环弹出项目,而无需更改组合框中的输入