Java Swing Example for Searching and Sorting a Collection of Objects using JList
- Details
- Written by Nam Ha Minh
- Last Updated on 05 July 2019   |   Print Email
In this Java Swing tutorial, we are going to help you integrate the search and sort functions of a collection of custom objects in a Swing application which looks something like this:
You will learn how to put theory into practice.
Theory: Search and Sort a List collection.
Practice: Build a GUI program that allows the user to add objects to a collection and perform search and sort on that collection.
Specifically, you will learn the following things throughout this tutorial:
- Building a simple graphical user interface with basic Swing components like JButton, JList, JFrame, JPanel and JOptionPane.
- Handling click event for JButton.
- Implements the methods equals(), hashCode() and compareTo() for a model class (Person class in this tutorial).
- Writing a custom list model class so we can use a collection as the underlying data for the list model. With this you can also learn how to write a generic class.
Now, let’s walk through the code in details.
1. Writing Model Class
The Swing application will manage a list collection of Person objects. Following is code of the Person class:
package net.codejava.swing; /** * Person.java * A model class represents a Person * @author www.codejava.net */ public class Person implements Comparable<Person> { protected String name; public Person() { } public Person(String name) { setName(name); } public String getName() { return this.name; } public void setName(String name) { if (name == null) { throw new IllegalArgumentException(); } this.name = name; } public String toString() { return this.name; } public int compareTo(Person another) { return this.name.compareTo(another.getName()); } public boolean equals(Object obj) { if (obj == null) return false; if (obj instanceof Person) { Person another = (Person) obj; if (this.name.equals(another.getName())) { return true; } } return false; } public int hashCode() { return this.name.hashCode(); } }
This model class has only one property ‘name’. It shows you how to implement the equals() and hashCode() method and implement the Comparable interface so Person objects can be sorted and searched in a collection.
You may consult the article Understanding equals() and hashCode() in Java and Understanding Object Ordering in Java with Comparable and Comparator.
2. Writing a Custom List Model Class
Swing uses MVC architecture which means each component has its own underlying data model. For JList component, it uses ListModel but the implementation DefaultListModel uses Vector so we cannot use DefaultListModel for our purpose.
Hence we need to create a custom list model class to support using a List collection as the underlying data. Following is the code of the CustomListModel class:
package net.codejava.swing; import javax.swing.*; import java.util.*; /** * CustomListModel.java * This is an implementation of ListModel that supports using a List * collection as the underlying data. * @author www.codejava.net */ public class CustomListModel<E> extends AbstractListModel<E> { protected List<E> list; public CustomListModel(List<E> list) { this.list = list; } public void addElement(E element) { list.add(element); int index = list.size(); fireContentsChanged(element, index, index); } public void fireDataChanged() { int index = list.size(); fireContentsChanged(list.get(index - 1), index, index); } public int getSize() { return list.size(); } public E getElementAt(int index) { return list.get(index); } }
As you can see, this model class is generified to be used with any kind of object. The underlying list collection is injected via its constructor.
Note that we should invoke the addElement() method to add an object to the collection as the method calls the fireContentsChanged() method which updates the view to reflect data changes.
And if there’s any changes to the list collection, we should call the fireDataChanged() method to notify the view (JList in this tutorial) to update its content.
3. Coding the main window (JFrame)
Following is code of the main window that displays the user interface as you see above:
package net.codejava.swing; import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.util.*; /** * MainFrame.java * This is the main user interface of the application. * @author www.codejava.net */ public class MainFrame extends JFrame { protected JButton buttonAdd = new JButton("Add New Person"); protected JButton buttonSearch = new JButton("Search Persons"); protected JButton buttonSort = new JButton("Sort Persons"); protected JList<Person> listPerson = new JList<>(); protected CustomListModel<Person> listModel; protected java.util.List<Person> persons = new ArrayList<>(); public MainFrame() { super("Swing Search & Sort Example"); initComponents(); setSize(600, 480); setLocationRelativeTo(null); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } protected void initComponents() { setLayout(new FlowLayout(FlowLayout.CENTER, 10, 10)); JPanel panelButton = new JPanel(); panelButton.setLayout(new FlowLayout(FlowLayout.CENTER)); buttonAdd.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { addPerson(); } }); buttonSort.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { sortPersons(); } }); buttonSearch.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { searchPersons(); } }); panelButton.add(buttonAdd); panelButton.add(buttonSearch); panelButton.add(buttonSort); add(panelButton); listPerson.setPreferredSize(new Dimension(400, 360)); listModel = new CustomListModel<Person>(persons); listPerson.setModel(listModel); listModel.addElement(new Person("John Doe")); add(listPerson); } private void addPerson() { String personName = JOptionPane.showInputDialog(this, "Enter person name"); if (personName != null) { listModel.addElement(new Person(personName)); } } private void sortPersons() { Collections.sort(persons); listModel.fireDataChanged(); } private void searchPersons() { String personName = JOptionPane.showInputDialog(this, "Enter person name to search for:"); if (personName == null) { return; } Collections.sort(persons); int foundIndex = Collections.binarySearch(persons, new Person(personName)); if (foundIndex >= 0) { listPerson.setSelectedIndex(foundIndex); } else { JOptionPane.showMessageDialog(this, "Could not find the person " + personName); } } }
Notice the way we use the JList component along with its model and underlying data:
protected JList<Person> listPerson = new JList<>(); protected CustomListModel<Person> listModel; protected java.util.List<Person> persons = new ArrayList<>();
And how to initialize the JList component with a single element:
listModel = new CustomListModel<Person>(persons); listPerson.setModel(listModel); listModel.addElement(new Person("John Doe"));
The main business logics are implemented in the methods addPerson(), sortPersons() and searchPersons().
4. Writing the main class
Following is code of the class which has the main() method to start the application:
package net.codejava.swing; import javax.swing.*; /** * SwingSearchSortJListExample.java * Launches the MainFrame in the Swing worker thread * @author www.codejava.net */ public class SwingSearchSortJListExample { public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { public void run() { new MainFrame().setVisible(true); } }); } }
This starts the MainFrame in the Swing worker thread which is the best practice to launch a Swing application.
5. Testing the Application
Now, it’s time to compile and run the application (run the SwingSearchSortJListExample class). Upon startup, it shows a list with only one person named John Doe:
Click button Add New Person to add a new person to the list. An input dialog appears asking for the name:
Enter the name you want and click OK. The new person will be added to the list. Repeat this step to input more persons like this:
You can notice that this list is unsorted. Click button Sort Persons to sort the list by alphabetic order:
Now click button Search Persons, an input dialog appears asking enter the person name:
Enter the person name (for example, ‘John Doe’) and click OK. If the person is found in the list (exact match), the application will select the corresponding item in the list, as shown below:
If there’s no result, the following message appears:
That’s it! We hope this tutorial is helpful for you in terms of learning Java programming with Swing and collections and generics. You can download the full source code below in the Attachments section.
Consult these tutorials to understand more about using JList component: JList basic tutorial and examples and JList custom renderer example.
Other Java Swing Tutorials:
- Java Swing Hello World Tutorial for Beginners Using Text Editor
- JFrame basic tutorial and examples
- JPanel basic tutorial and examples
- JLabel basic tutorial and examples
- JTextField basic tutorial and examples
- JComboBox basic tutorial and examples
- JButton basic tutorial and examples
Comments
You can run the main class SwingSearchSortJListExample - and download the sample project above.