Keep the original unfiltered data in a structure (e.g an ArrayList) and add a DocumentListener
to the search textfield in order to know whether the search text has been changed. Then, filter the original data and removeAllElements()
from JList
's model. Finally add the the filtered data to the model of JList
.
Example:
public class SearchInJList extends JFrame implements DocumentListener {
private static final long serialVersionUID = -1662279563193298340L;
private JList<String> list;
private List<String> data;
private DefaultListModel<String> model;
private JTextField searchField;
public SearchInJList() {
super("test");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLayout(new BorderLayout());
searchField = new JTextField();
searchField.getDocument().addDocumentListener(this);
add(searchField, BorderLayout.PAGE_START);
createData();
list = new JList<>(model = new DefaultListModel<>());
data.forEach(model::addElement);
add(new JScrollPane(list), BorderLayout.CENTER);
setSize(500, 500);
setLocationByPlatform(true);
}
private void createData() {
data = new ArrayList<String>();
for (int i = 0; i < 1000; i++) {
String s = "String: " + i + ".";
data.add(s);
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
SearchInJList example = new SearchInJList();
example.setVisible(true);
});
}
@Override
public void insertUpdate(DocumentEvent e) {
search();
}
@Override
public void removeUpdate(DocumentEvent e) {
search();
}
@Override
public void changedUpdate(DocumentEvent e) {
search();
}
private void search() {
List<String> filtered = data.stream().filter(s -> s.toLowerCase().contains(searchField.getText().toLowerCase()))
.collect(Collectors.toList());
model.removeAllElements();
filtered.forEach(model::addElement);
}
}
It does not work with a button, but I guess this is something you can do. I mean add the search()
method into button's action listener.