2012-08-16 63 views
1

我正嘗試在Java中使用JList創建搜索功能。我有一個ListModel中的聯繫人列表,我插入到一個JList中。這顯示所有聯繫人都很好。不過,我在聯繫人列表上方有一個搜索框,並希望將聯繫人縮小到用戶鍵入搜索框時鍵入的內容(如Google搜索)。但是,當我嘗試在搜索框中鍵入時,所有聯繫人消失,然後我無法退格。我的KeyListener代碼如下:在Java中搜索JList

KeyListener klisten = new KeyListener() 
    { 
     public void keyPressed(KeyEvent evt) 
     { 
      searchResults = new ContactList(); 
      listModel.removeAllElements(); 
      searchResults.addContact(contactList.getContact(evt.getKeyChar())); 
      for (int i = 0; i < searchResults.getContacts().size(); i++) 
      { 
       listModel.addElement(searchResults.getContact(i).getFname() + " " + searchResults.getContact(i).getLname()); 
      } 
      contacts = new JList(listModel); 
      contacts.validate(); 
     } 
     public void keyReleased(KeyEvent evt) {} 
     public void keyTyped(KeyEvent evt) {} 
    }; 
    searchField.addKeyListener(klisten); 

編輯**包含所有原始聯繫人原來的ListModel是這個匿名類之前聲明,被稱爲ListModel的,我在這個類重用替換整個聯繫人列表..

任何幫助解決這個問題都會有很大的幫助。讓我知道是否需要發佈我的代碼的其他部分。

+3

首先,你真的不應該使用'KeyListener'爲此,試試在文本字段上使用'DocumentListener'而不是 – MadProgrammer 2012-08-16 03:13:12

回答

5

考慮使用它支持的框架過濾列表,如fiSwingX

隨後的基本步驟是:

  • 實現其過濾基於名稱網頁摘要
  • 上更改通知從文檔中安裝的DocumentListener到文本框
  • 聯繫人一個RowFilter,安裝名單上新的過濾器

僞代碼片段

// the custom RowFilter 
public class ContactRowFilter extends RowFilter { 
    private String compare; 

    public ContactRowFilter(String compare) { 
     this.compare = compare; 
    } 

    public boolean include(Entry entry) { 
     Contact contact = (Contact) entry.getValue(0); 
     return contact.getName().contains(compare); 
    } 
} 

// custom documentListener 
public class SearchFieldListener implements DocumentListener { 
    private JXList list; 

    public SearchFieldListener(JXList list) { 
     this.list = list; 
    } 

    @Override 
    public void insertUpdate(...) { 
     updateFilter(evt.getDocument()); 
    } 
    .... 
    protected void updateFilter(Document doc) { 
     String text = doc.getText(0, doc.getLength()); 
     list.setRowFilter(text.length > 0 ? 
      new ContactRowFilter(text) : null); 
    } 

} 

// usage 
JXList list = new JXList(myModel); 
list.setAutoCreateRowSorter(true); 
DocumentListener listener = new SearchFieldListener(list); 
JTextField searchField = new JTextField(20); 
searchField.getDocument().addDocumentListener(listener); 
+0

@Behe good catch , 謝謝 :-) – kleopatra 2013-03-26 11:43:25

5

沒有剩下的代碼就很難看到邏輯。考慮發佈SSCCE。它看起來像你在關鍵的偵聽器事件重現JList

contacts = new JList(listModel); 

那新名單需要添加/重新加入到容器中。看起來像列表娛樂是不需要的,因爲listModel是最新的,它應該通知列表刷新更改,除非searchResults爲空。這只是一個猜測而沒有看代碼。

使用具有過濾支持的單列JTable可能更容易。詳情請參閱Sorting and Filtering

+0

+1用於發現'new JList' nice;) – MadProgrammer 2012-08-16 03:35:01

3

我有一個快速閱讀,說實話,沒有太多要去。

我不知道這種方法

searchResults.addContact(contactList.getContact(evt.getKeyChar())); 

的結果,這對我來說意味着沒有可用的

searchResults = new ContactList(); 

接觸但那是因爲我缺少上下文。

更好的解決辦法可能是使用「代理」的模式,基本上是一個包裝了模型的模型,它提供了你或最多曾建議過濾功能,一個JTable