- 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:
About the Author:
Nam Ha Minh is certified Java programmer (SCJP and SCWCD). He started programming with Java in the time of Java 1.4 and has been falling in love with Java since then. Make friend with him on
Facebook and watch
his Java videos you YouTube.