3

我正在尝试使用 Java 中的 JList 创建搜索功能。我在插入到 JList 的 ListModel 中有一个联系人列表。它显示所有联系人都很好。但是,我在联系人列表上方有一个搜索框,并希望将联系人缩小到用户在输入时在搜索框中输入的内容(如 Google 搜索)。但是,当我尝试在搜索框中输入时,所有联系人都会消失,然后我也无法退格。我的 KeyListener 代码如下:

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,我在此类中重用它来替换完整的联系人列表..

解决这个问题的任何帮助都会有很大帮助。让我知道是否需要发布我的代码的其他部分。

4

3 回答 3

5

没有其余代码,很难看到逻辑。考虑发布SSCCE。看起来您正在重新创建JList关键侦听器事件:

contacts = new JList(listModel);

需要将该新列表添加/读取到容器中。看起来不需要重新创建列表,因为listModel它是最新的,它应该通知列表刷新更改,除非searchResults为空。不看代码,只是猜测。

JTable使用带有过滤支持的单列可能更容易。有关详细信息,请参阅排序和过滤

于 2012-08-16T03:15:16.963 回答
5

考虑使用支持列表过滤的框架,例如 fi SwingX

然后基本步骤是:

  • 实现一个 RowFilter,它根据名称片段过滤联系人
  • 将 DocumentListener 安装到 textField
  • 在文档的更改通知中,在列表中安装一个新的过滤器

伪代码片段

// 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); 
于 2012-08-16T08:36:29.383 回答
3

我已经快速阅读了,老实说,没有什么可去的。

我不确定这种方法的结果

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

这对我来说表明没有可用的联系人

searchResults = new ContactList();

但那是因为我缺少上下文。

更好的解决方案可能是使用“代理”模型,基本上是一个包装模型的模型,它为您提供过滤器功能,或者正如 Max 所建议的那样,JTable

于 2012-08-16T03:18:43.757 回答