2015-07-21 70 views
0

我扩展了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只包含这个组合框,它完美的工作,没有焦点丢失(因为没有其他元素,我假设)。

任何想法我可能在这里做错了吗?谢谢。

+0

将空方法更改为此时会发生什么? '@Override public void changedUpdate(DocumentEvent arg0){update();}' – Juvanis

+1

为了更好地帮助您,请发布[MCVE](http://stackoverflow.com/help/mcve)(最小完整可验证示例)或[ SSCCE](http://www.sscce.org/)(简短,独立,正确的例子)。 –

+0

@Juvanis没有什么变化 – Florina

回答

0

如果还不算太晚,并且每个人都为此苦苦挣扎,我在update()方法的末尾添加了requestFocus()。这是一种解决方法,但似乎工作正常。 另外除了这个实现自动完成组合框的是在它使您能够循环槽弹出项目使用了NAD下来,而不在组合框中改变输入方向键构造函数添加

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