0

The GUI has a search bar that when the user types a book and click search, it pops up on the JList. But I don't know how to write the code for it.

public void actionPerformed(ActionEvent e) {
   if (e.getSource() == searchButton) {
       // Action for the SEARCH button
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
Wietlol
  • 69
  • 1
  • 10

2 Answers2

1

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.

George Z.
  • 6,643
  • 4
  • 27
  • 47
  • 1
    *"It does not work with a button, but.."* But nothing! Searching on typing is the better solution for 99%(1) of situations. 1) I wrote a similar thing for the Unicode charset with over a million entries. It was so many entries it was necessary to make a `SwingWorker` for it. But it did not make much sense to create the worker for every event, so the code started a timer to schedule it. (Or .. a more complicated implementation of what you did.) I **could** have gotten around the problem by adding an action listener instead. Search being done one when the user presses 'enter' in text field .. – Andrew Thompson Dec 27 '19 at 03:14
  • .. but that **still** would not have required a button as the OP was originally using! – Andrew Thompson Dec 27 '19 at 03:17
0

So for every button press you can:

  1. Fill a DefaultListModel with the strings that match the search criteria.
  2. Create a new JList with the model of the previous step.
  3. Pop a JOptionPane with the list of the previous step as its message.

Example code:

import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class Main {
    public static void main(final String[] args) {

        final String[] data = new String[]{"abcdef", "ABCdEF", "defGhi", "DEFghi"};

        final JTextField textField = new JTextField(20);

        final JButton searchButton = new JButton("Search");
        searchButton.addActionListener(e -> {
            final String searchText = textField.getText().toLowerCase();
            final DefaultListModel<String> model = new DefaultListModel<>();
            for (final String str: data)
                if (str.toLowerCase().contains(searchText))
                    model.addElement(str);
            final JList<String> list = new JList<>(model);
            JOptionPane.showMessageDialog(searchButton, list);
        });

        final JPanel panel = new JPanel();
        panel.add(textField);
        panel.add(searchButton);

        final JFrame frame = new JFrame("Search form");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(panel);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}
gthanop
  • 3,035
  • 2
  • 10
  • 27