Java Quiz Player

A Notes App using Java Swing, H2 Database and JPA

February 27, 2017

1. Overview

This article shows how to build a simple Notes desktop application. The app has functions to create Notes, edit and save them in a database. The GUI is built with the Java Swing API. The Notes data are stored in a H2 relational database (http://www.h2database.com/) which is accessed using EclipseLink Java Persistence API (http://www.eclipse.org/eclipselink/).

The following text is the description or requirement of the app:

The app is a simple Notes management application.

A Note is a document with some useful information. A Note has a mandatory name and optional text. In this app create a new Note, edit and save. The Note is stored in a database and is displayed in the Notes list.

The Note name has 5 to 25 characters (alphabets, numbers, space and an underscore "_"). The name must be unique.

Select a Note in the Notes list and double-click to edit it and save. While a Note is being newly entered or updated, cancel by clicking the Cancel (Undo) button or by selecting another Note.

The finished app's GUI is shown in the following screenshot:

GUI image

The app is built in three stages. In the first step build the GUI, in the second make the GUI working without the database, and in the third step finish with connecting to a Notes database.

There is source code from each step with instructions to compile and run the code. The Java source code for the finished application can be downloaded from the Download section below.

2. Build the GUI

The following is the screenshot of the finished GUI.

GUI image

The app has a main window in which all the components (widgets) are placed. The Swing components used are the JFrame for the main window, the JList for the Notes list, a JTextField for the Note name text, a JTextArea for the Note description or text, JButtons in a JToolBar for the New, Save, Delete, Cancel and Help buttons. The messages are displayed in a JLabel or in a JOptionPane popup message dialog. Finally, the help text is shown in JTextArea within a JDialog. All the widget classes used in this app are defined in the javax.swing package.

All the widgets (except the JOptionPane and JDialog) are placed within the JFrame using the layout type called GridBag Layout. The java.awt.GridBagLayout class is a flexible layout manager that aligns components vertically, horizontally or along their baseline without requiring that the components be of the same size.

In this app, the widgets are laid out in the JFrame as shown below. The values (0,0, 0,1, etc.,) indicate the grid positions along the x-axis and the y-axis; a 0,0 specifies first x and first y position. A 1,0 specifies second x and first y position. The gridheight=2 specifies that the JList occupies two y positions. See the layout in the following picture:

GUI image

The widgets are created with various attributes like the size, borders, margins, fonts, etc. Note that the JList and the JButtons are not wired to their respective listener classes in this step; no action can be performed on these widgets. Only the Help button opens the help dialog with the help text. Note that the help text is same as that of the requirement defined at the beginning of this article.

2.1. JButtons with Icons

Note that the buttons are created with icons rather than the text. These are standard icons used in Java desktop apps with Java look and feel. The following link at Oracle Corporation's web site has a Java Look and Feel Graphics Repository: http://www.oracle.com/technetwork/java/index-138612.html

The icon JAR file jlfgr-1_0.jar has all the icons and the required ones are accessed from the app (for instructions see the source code and also the link in the previous paragraph). This JAR file is required to be in the classpath to run the app.

2.2. Java Source Code

The following is the project directory structure:

project
    |- srce
    |- classes
    |- resources

The directory srce has the source code with package structure sub-directories and the source Java files. The classes has the compiled classes. The resources has utility files used within the app, for example the help text file.

Java classes: Resources:

Download the Java source code for the example: notes-app-1.zip

2.3. Compile and Run

From the operating system command prompt navigate to the project directory; compile and run the app. Note that Java SE 1.8.0_72 or above is required to compile and run this app.

javac -d classes srce/com/javaquizplayer/examples/notesapp/*.java
java -cp resources/jlfgr-1_0.jar;classes com.javaquizplayer.examples.notesapp.ApplicationStarter

3. Note and its Functions

In this step the GUI is not changed, but code is added to make the GUI usable with the function actions.

The functions of the Note are - create, update, delete, cancel and save. There are buttons for all the functions except the update. Create code to map these functions to the respective button (New, Save, Delete, Cancel) actions. Create listener classes of type java.awt.event.ActionListener and add them to the buttons.

The created Notes are listed in the JList. Two listeners are added to the Note list. (1) A javax.swing.event.ListSelectionListener type listener gets notifications when a Note item in the list is selected. When a Note item is selected in the list its name and text values are shown in the text field and the text area respectively. (2) A listener of type java.awt.event.MouseAdapter to receive mouse events from the list; to access an existing Note for update through a mouse double-click action on a selected Note.

Newly created and edited Notes when saved are added to the Note list. The Note name and text are in read-only mode when saved. To update the Note, select it in the list and double-click it; edit the changes and save. During editing a new or updating an existing one cancel the action by clicking the Cancel or Undo button or by selecting another Note. To delete a Note select it from the list and click the delete button.

3.1. List Data Model

The JList requires a data model to maintain its contents, the Notes. The abstract class javax.swing.AbstractListModel is extended to create a list model class NoteListModel.java for the Notes list. The list model is supplied to the JList through a setter method.

Note has a name and text as attributes. So, create a class Note.java with the attributes. The Notes in the list are maintained in an ascending sorted order of Note names. The Note class implements the java.lang.Comparable interface so that the Notes in the list are sorted.

In this step the Note data is stored in the list data model for an application session; it is not persisted to a database.

3.2. Note Validation

A Note is entered in the app. The name is entered in the text field; this is mandatory. The name is of 5 to 25 characters long (with A-Z a-z 0-9 space and underscore characters) and must be unique. The Note text is optional.

The validation of the Note name is done in a class NoteValidator.java which has validate() method that accepts the Note details and throws an exception InvalidNoteException in case of a not valid Note. The InvalidNoteException.java class's constructor accepts a string message describing the validation message which is displayed in the message JLabel; for example, "Name must be 5 to 25 characters long!".

3.3. Java Source Code

The following is the project directory structure:

project
    |- srce
    |- classes
    |- resources

The directory srce has the source code with package structure sub-directories and the source Java files. The classes has the compiled classes. The resources has data files used within the app, for example the help text file.

Java classes: Resources:

Download the Java source code for the example: notes-app-2.zip

3.4. Compile and Run

From the operating system command prompt navigate to the project directory; compile and run the app. Note that Java SE 1.8.0_72 or above is required to compile and run this app.

javac -d classes srce/com/javaquizplayer/examples/notesapp/*.java
java -cp resources/jlfgr-1_0.jar;classes com.javaquizplayer.examples.notesapp.ApplicationStarter

4. Persist Notes to Database

In this step the Notes are stored in a database and are accessed using the Java Persistence API (JPA). The database software is the H2 database and the persistence framework is the EclipseLink.

4.1. H2 Database

H2 is a Java relational database. This is an open source database with a small footprint and supports JDBC (Java Database Connectivity). The database can be used with embedded, server or in-memory modes.

The H2 software can be downloaded and installed from http://www.h2database.com/.

In the install directory: (i) The docs directory has the user manuals and the API javadocs. (ii) The bin directory has the h2-1.4.189.jar file (the 1.4.189 of the JAR file is the software version). This JAR file includes the JDBC driver software. This JAR file is required to be in classpath to run the Java code using H2 database.

4.1.1. Notes Database

In this app the embedded version of the H2 database is used. The CreateNotesDatabase.java utility class creates a new Notes database and the tables. The database has only one table, NOTE. Runing this class creates a new Notes database in the specified directory and a new NOTE table. In case the database and the table already exist, uses the existing database, drops the table and creates a new table.

In this app the database is named as notesDB and is created in a directory db. The project directory has two new sub-directories: utility and db. The utility directory has the class CreateNotesDatabase.java.

Compile and run the utility class from the project directory:

javac utility/CreateNotesDatabase.java
java -cp utility;lib/h2-1.4.189.jar CreateNotesDatabase

NOTE: The H2 database and the tables can be accessed interactively from H2 Console. Double-click the h2-1.4.189.jar file to open the console in the browser.

GUI image

4.2. EclipseLink JPA

EclipseLink is an open source mapping and persistence framework for use in Java SE and EE environments. This is used to read and write objects to a data source like a relational databases using Java Persistence API (JPA). JPA is the Java API for object/relational mapping (ORM), where Java objects are mapped to database artifacts, for managing relational data in Java applications.

In this app the EclipseLink version 2.6 is used. This software and documentation can be downloaded from the EclipseLink website: http://www.eclipse.org/eclipselink/

The downloaded software contains the javadocs for the EclipseLink JPA and the JAR files for using the JPA. The jlib directory has the eclipselink.jar and in the jlib/jpa directory there is the javax.persistence_2.1.1.v201509150925.jar. These two JAR files are required to be in the classpath to compile and run this app.

Here is an article on Using the Java Persistence API in Desktop Applications at the Oracle Corporation's website: http://www.oracle.com/technetwork/articles/java/persistenceapi-135534.html

4.3. Object Relational Mapping

The NOTE table of the Notes database is mapped to the Note entity. The existing Note class is annotated with the @Entity annotation to specify that the Note class is mapped to the NOTE table.

The Note class is also modified so that a Note is identified using a unique id, a primary key in the relational database. This is specified using the @Id annotation. The id is an integer which is generated and is specified with the annotation @GeneratedValue.

The annotations mentioned above are defined in the javax.persistence package of Java EE API.

The Note class's overridden equals() method and the NoteListModel class's containsName() method are changed to reflect the introduction of the id property in the Note class.

4.4. Notes Persistence

The class NotesPersistence.java has the methods to access the Notes database using the JPA. There are methods to get all the Notes getAll(), insert a Note create(), update a Note update() and delete a Note delete(). The class NotesPersistence.java uses the Persistence, EntityManagerFactory and EntityManager of the javax.persistence package of Java EE API.

The NotesPersistence class's methods catch the JPA exception (javax.persistence.PersisenceException a runtime exception) and throws a custom checked exception AppPersistenceException. The AppPersistenceException is caught in the app (NotesAppGUI.java) and an appropriate user friendly message is displayed in a javax.swing.JOptionPane message box. In case of any persistence exceptions, after the message is shown, the app is closed.

4.5. persistence.xml

The set of entities in an application is called a persistence unit. The application's persistence unit is defined in a configuration file persistence.xml. This file should exist for the application in a META-INF directory.

The persistence.xml file has many functions. The important ones are used in this app and are defined in the following elements: persistence-unit, provider, class and properties.

A property called eclipselink.logging.level provides a logging utility. A specific logging level (for example, INFO) can be specified. The log output is shown on the console. There are other logging property options to log to a file or use a different logger etc.

In this app, META-INF subdirectory with the persistence.xml is within the classes sub-directory of the project directory.

4.6. Java Source Code

The following is the project directory structure:

project
    |- srce
    |- classes
        |- META-INF
    |- resources
    |- utility
    |- db
    |- lib

The directory srce has the source code with package structure sub-directories and the source Java files. The classes has the compiled classes and the META-INF sub-directory has the persistence.xml. The resources has data files used within the app, for example the help text file. The directory utility has the Java source code to create the Notes database and its table. The database is created in the directory db. The lib directory has the database driver and EclipseLink library JAR files.

Java classes: Resources: Configuration file in META-INF: Utility class: JAR files to be in the classpath to use H2 database and EclipseLink JPA:

4.7. Compile and Run

Download the Java source code for the example from the following section: Download

From the operating system command prompt navigate to the project directory; compile and run the app. Note that Java SE 1.8.0_72 or above is required to compile and run this app.

javac -cp 
  lib/h2-1.4.189.jar;lib/eclipselink.jar;lib/javax.persistence_2.1.1.v201509150925.jar
  -d classes srce/com/javaquizplayer/examples/notesapp/*.java
java -cp 
  resources/jlfgr-1_0.jar;lib/h2-1.4.189.jar;lib/eclipselink.jar;
  lib/javax.persistence_2.1.1.v201509150925.jar;classes;resources
  com.javaquizplayer.examples.notesapp.ApplicationStarter

4.8. Unit Tests

There are unit test classes included with the download in the test directory for couple of classes: NoteListModelTest and NoteValidatorTest. The tests run with JUnit 4.12 (junit.org).

5. Download

Download the Java source code for the example: notes-app.zip

6. Useful Links

7. What's Next

Some ideas to enhance the Notes application with various features and functions:

Return to top