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:
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.