2015-07-21 58 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);