简体   繁体   中英

Searching a JList in Java

I am trying to create a search functionality with a JList in Java. I have a list of contacts in a ListModel that I inserted into a JList.. That displays all the contacts just fine. However, I have a search box above the list of contacts and want the contacts to be narrowed down to what the user types in the search box as they type(like Google search). However, when i try to type in search box, all contacts disappear and then Im not able to backspace either. My KeyListener code is as follows:

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);

EDIT** the original ListModel that contains all original contacts is declared before this anonymous class and is called listModel which I reused in this class to replace full contact list..

Any help solving this would be of great assistance. Let me know if I need to post other parts of my code.

It's hard to see the logic without the rest of the code. Consider posting an SSCCE . It looks like you're recreating the JList in the key listener event:

contacts = new JList(listModel);

That new list needs to be added/readded to the container. Looks like list recreation is not needed as listModel is up to date and it should notify the list to refresh the changes, unless searchResults is empty. It is just a speculation without looking at code.

It may be easier to use a single column JTable with filtering support. See Sorting and Filtering for details.

Consider using a framework which supports filtering of lists, like fi SwingX

Then the basic steps are:

  • implement a RowFilter which filters the Contacts based on the name snippets
  • install a DocumentListener to the textField
  • on change notification from the document, install a new filter on the list

Pseudo-code snippet

// 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); 

I've had a quick read and to be honest, there isn't much to go.

I'm not sure of the result of this method

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

And this to me suggests that there are no contacts available

searchResults = new ContactList();

But that's because I'm missing context.

A better solution might be to use a "Proxy" model, basically a model that wraps a model, that provides the filter functionality for you or as Max has suggested, a JTable

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM