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 楼答案
如果还不算太晚,并且对于所有正在为此而挣扎的人,我在
update()
方法的末尾添加了requestFocus()
。这是一种变通方法,但似乎效果不错。 自动完成组合框的另一个实现是添加在构造器中,使用上下箭头键循环弹出项目,而无需更改组合框中的输入