I recently wrote about building desktop applications with Couchbase Lite and JavaFX. As demonstrated Couchbase makes an excellent solution for data storage and sync in a desktop application because of the Java SDK available. However, I realize JavaFX is not for everyone.

There is another, similar framework for building desktop applications in Java. It is called Gluon, and it offers support for Android and iOS applications as well. However, we’re strictly looking at desktop in this example.

We’re going to see how to create a Gluon desktop application using nearly the same code that was found in our previous JavaFX example.

The Requirements

There are a few requirements towards building a Gluon application that uses Couchbase.

  • JDK 1.7+
  • IntelliJ IDEA
  • Couchbase Sync Gateway

I don’t typically make this a requirement, but it is far easier to create a Gluon application with an IDE like IntelliJ, thus why it is in the list. There is a plugin for IntelliJ that will construct a Gluon project with Gradle and everything you need.

While Couchbase Sync Gateway isn’t truly a requirement, it is necessary if you want to add synchronization support between your application and Couchbase Server / other platforms and devices.

Creating a New Gluon Project

If you decide to use IntelliJ to build your project, make sure you’ve already downloaded the Gluon plugin as described here.

Using IntelliJ, create a new project, but choose to create a Gluon Desktop – Multiple View Project with FXML project as seen below.

Ultimately, it is up to you where to go from here, but to stay as close as possible to this guide, give your project a com.couchbaselabs package name and gluon main class.

Everything that follows can be left as the default as we’re only going to make a two page application with Gluon. When we’re done, hopefully we’re left with a file and directory structure that looks like the following:

You’ll notice that I did create a few extra files in there such as CouchbaseSingleton.java and Todo.java.

Essentially we have XML views and controllers to go with those views. This is very similar to what we saw in a JavaFX application. When it comes to designing those views, we have a few options. We can use raw XML, or we can use SceneBuilder. Now this SceneBuilder is not to be confused with JavaFX SceneBuilder. I made this mistake and was banging my head for quite a bit of time. The version we want will support Gluon applications.

Before we start adding application code, we should add our dependencies to the project Gradle file. If you’re unfamiliar with Gradle, it does the same job as Maven or Ant. The syntax is different, but I personally find it a little cleaner. Open the project’s build.gradle and include the following code:

What’s particularly important here are the dependencies:

This will include the Couchbase Lite library as well as the desktop application runtime for Gluon.

With the project ready to go, we can start developing the application.

Designing the Couchbase Data Layer

When working with Couchbase it is a good idea to create a singleton instance of it. This means we’re going to use the same open instance throughout the entire application, until we decide to close it.

Open the project’s src/main/java/com/couchbaselabs/CouchbaseSingleton.java file and include the following code:

If you saw the JavaFX application I built previously, you’ll notice that this singleton is the same between the two projects. You can even use a similar version for Android.

In the CouchbaseSingleton constructor method we are creating and opening a local database called fx-project. This database will be used throughout the application. We are also creating our Couchbase Lite view for querying. This todos view will emit a key-value pair of document id and document for every document in the local database.

The constructor method is private, meaning we don’t want the user to be able to instantiate an object from it. Instead we want to use a static getInstance method to get the job done.

While we won’t worry about replication until later in the guide, we do want to lay the foundation. The startReplication method will allow us to define bi-directional sync with a Sync Gateway and the stopReplication method will allow us to stop replication, maybe when the application closes.

Now we have our functions for saving and loading data.

In the save method we are accepting a custom Todo object. This object really just contains an id, a title, and a description. The class looks something like this:

The above class is found in the src/main/java/com/couchbaselabs/Todo.java file. What we’re doing is actually taking the object and adding it as properties to a Couchbase NoSQL document. After we save the document and obtain an id, we return the same document with the id included.

The query function will execute the view that we created earlier and add each of the result items to an array of Todo object, bringing our database singleton to an end.

Creating a View for Listing Data

We are going to be creating an application that uses multiple Gluon views instead of trying to slap everything into the same view. This is not to be confused with Couchbase Lite Views which are on the topic of data, not UI.

The default view will be the first view that comes up when we launch the application. This view will show a list of all our todo elements. If not using SceneBuilder, the XML markup found in src/main/resources/com/couchbaselabs/views/primary.fxml would look like the following:

 

The view that comes out of this will look like the following:

You’ll see in the image that there is a navigation bar with a button, but it doesn’t appear in the XML layout. The layout instead only contains the list view. However, the XML does reference our src/main/java/com/couchbaselabs/views/PrimaryPresenter.java file. This is the file where we not only define the navigation bar, but any logic that powers the particular view.

The src/main/java/com/couchbaselabs/views/PrimaryPresenter.java file will hold a lot of resemblence to our JavaFX project, with the differences being in the navigation component.

In the above file we have the list view property bound to the actual list view in the XML. The code that really matters, however, is the code found in the initialize method. In it we do three core things.

In the above code we define how the data will appear in the list. By default it only accepts string data, so we override it to take the title from our Todo objects.

In the above listener we set the title of our navigation bar as well as the button. When the button is pressed, the view will change to our secondary view.

Finally it leaves us with running the initial data query and populating the list, as well as listening for new data as it comes in. Should changes come in, they will be iterated over and the indicators will be reviewed on every changed document. If there was a delete indictator, the data will be removed from the list view. If there was a change, the data from the list view will be removed, then replaced. Otherwise the data will only be added. Since the listener operates on a background thread, changes to the UI must be done within the Platform.runLater.

This brings us to the second and final view.

Creating a View for Saving Data

The second view will have a form and is responsible for user input to be added to the database and displayed in the previous view. The XML markup that powers this view will look like the following:

Author

Posted by Nic Raboy, Developer Advocate, Couchbase

Nic Raboy is an advocate of modern web and mobile development technologies. He has experience in Java, JavaScript, Golang and a variety of frameworks such as Angular, NativeScript, and Apache Cordova. Nic writes about his development experiences related to making web and mobile development easier to understand.

Leave a reply