MyDigitalLife

JavaFx application with Windows installer

This page describes how to create a JavaFx application as a maven project which creates a Windows installer.

Basics

We start with a simple single module example.
Although the actual project will use maven, we first use the plain tools.

Using jlink

Also read the jlink information:
Jlink – Assemble and Optimize a Set of Modules
Creating Runtime and Application Images with JLink

Note: when you run jlink, the output directory shall not exist yet.

Note: When you have a maven project, you cannot use your ‘target’ folder as module path, because then jlink will find your modules more than once. Once in the jar file and once in the generated classes.

With jlink you can generate a .bat file to execute your application. You can tell Windows to open files with a specific extension with this .bat file, but the .bat file doesn’t have an icon. You can create shortcut to your .bat file and set an icon for that shortcut, but files with the coupled extension don’t show up with that icon.
To have files with the icon of the application, you have to have a .exe file.

Using jpackage

Also read the jpackage information:
The jpackage Command
JPackage

Concepts

JavaFx Windows executable

If your main class is the subclass of javafx.application.Application, the executable doesn’t do anything. So your main class has to be a wrapper around your subclass of javafx.application.Application. See the class MarkdownWrapper in the example below.

Logging

For logging I use java.util.logging. It does what I need and it doesn’t introduce extra dependencies.
During development, when I run my application in Eclipse, I don’t log to a file, only to the console. Logging to a file causes only extra overhead. For this I have utility class goedegep.util.RunningInEclipse, which has a single static method runningInEclipse(), which returns true if the application is running in Eclipse.

A full application

The Markdown editor is used as an example.

Project/package goedegep.markdowneditor

This project is a simple Markdown editor/viewer. It shows the Markdown text on the left and the formatted text on the right.

packages
Although this is a simple application, I use the following the standard packages:

  • goedegep.markdowneditor.exe
    Contains the classes to start the application.
  • goedegep.markdowneditor.svc
    Contains only the service.
  • goedegep.markdowneditor.gui
    Contains all classes with a user interface.
  • goedegep.markdowneditor.logic
    Contains functionality.

Classes

MarkdownWrapper
The main method is in the MarkdownWrapper class. This doesn’t do anything, except calling the MarkdownApplication (that why it’s called a wrapper). The reason for having this wrapper is a problem with JavaFx in an executable. If the main class is the subclass of javafx.application.Application, the executable doesn’t do anything.

package goedegep.markdowneditor.exe;

/*
 * This class is the entyry point for the Markdown editor.
 * <p>
 * This wrapper is needed because if the main class extends from javafx.application.Application the installed executable doesn't work.
 */
public class MarkdownWrapper {
  
  public static void main(String[] args) {
    
    MarkdownApplication.main(args);
    
  }
}

MarkdownApplication
This is the class which extends goedegep.jfx.JfxApplication (which itself extends javafx.application.Application). So the main method calls Launch() and the actual work is in the start(Stage primaryStage) method.
Command line arguments
The wrapper class passes the command line arguments through to the main method of this class. I have a problem with the use of Application.getParameters(), so in the main method I store the arguments in the static field appArgs.

Resources