Lesson 5 - Birthday Reminder in Java Swing - Logic Layer
In the previous lesson, Birthday Reminder in Java Swing - Form design, we completely designed forms for our application. In today's lesson, we're going to focus on the design of the logic layer, which are the classes that contain application logic.
Date
Since working with date and time is quite uncomfortable in Java, let's add a short static class to the project to make our work easier:
public class Date { private static DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern("d'.'M'.'y"); public static String format(LocalDate date) { return date.format(dateFormat); } public static LocalDate parse(String dateText) throws ParseException { return LocalDate.parse(dateText, dateFormat); } }
The class contains a date format definition. Moreover, it has two methods to convert between a date and its text representation. The date can be extracted from a string (as entered by the user) or e.g. written as text.
Person
We'll certainly have persons in our application, so let's create a class for them.
Properties
A person will have 2 properties: name
and birthday
.
The name
will be a String
; the birthday
will be of the LocalDate
type. We'll implement both properties as
private
fields and generate getters for them:
public class Person { private String name; private LocalDate birthday; public String getName() { return name; } public LocalDate getBirthday() { return birthday; } }
Methods
A person will have several methods, but now we'll focus just on its constructor to make our application executable as soon as possible. We'll complete it later. So we'll add a parametric constructor to the class.
Constructor
Besides setting the instance properties, the constructor will be also responsible for validating these properties. Let's see its code:
public Person(String name, LocalDate birthday) throws IllegalArgumentException { if (name.length() < 3) { throw new IllegalArgumentException("The name is too short"); } if (birthday.isAfter(LocalDate.now())) { throw new IllegalArgumentException("The birth date cannot be in the future!"); } this.name = name; this.birthday = birthday; }
First, we verify that the name isn't too short, or the entered birthday isn't
in the future. If one of the situations occurs, the
IllegalArgumentException
is thrown and we pass a text message for
the user into its constructor.
If you haven't worked with exceptions yet, it doesn't matter. All you need to know is that this is how object-oriented applications handle errors, especially those caused by entering an invalid value by the user or occurred while working with files. Throwing an exception terminates the method immediately. We'll show how to respond to the exception further in the course. We'll always throw exceptions only in logic classes.
toString()
Since we want to print our persons, we'll override the
toString()
method to return the person's name:
@Override public String toString() { return name; }
This method will be later used by the JList
to print its
items.
Person manager
The last logic component of the application will be a person manager. The class will manage the persons. It'll be able to add, remove, and save their list to a file and load it back from it. Finally, it'll be able to search for a person who has the nearest birthday.
So add a new PersonManager
class to the project.
Fields
The only class field is a list of persons. The list is of the
DefaultListModel
type. We haven't encountered this collection in
this course yet. It's a special collection type that can be set as the data
source for form components. ListModel
can trigger change events
when its contents change. All components on the form that have this
ListModel
set as the data source are automatically refreshed thanks
to this mechanism. You can imagine that refreshing dozens of components on a
form manually when data changes could be very difficult. When we add a new
person in our app, it'll be immediately visible in the person list without the
need to refresh it anyhow. It'll refresh automatically. We'll generate a getter
for DefaultListModel
and rename it to getModel()
:
So far, the class looks as follows:
public class PersonManager { private DefaultListModel<Person> persons = new DefaultListModel<>(); public ListModel getModel() { return persons; } }
Methods
Again, let's put only the most important methods in the class for now.
add() and remove()
The methods for adding and removing a person are absolutely trivial:
public void add(Person person) { persons.addElement(person); } public void remove(Person person) { persons.removeElement(person); }
getPersons()
Since DefaultListModel
lacks a lot of important methods, we'll
add a getPersons()
method to the manager which returns persons as
an ordinary List
. So we can get both a model and a list. We'll
convert the model to the List
using the static
Collections
class:
public List<Person> getPersons() { return Collections.list(persons.elements()); }
We've finished the core of the logic layer. Next time, Birthday Reminder in Java Swing - Wiring the layers, we'll show you how to wire the logic to the form and get the whole application up and running.
Did you have a problem with anything? Download the sample application below and compare it with your project, you will find the error easily.
Download
By downloading the following file, you agree to the license terms
Downloaded 34x (68.64 kB)
Application includes source codes in language Java