Skip to content

JavaFX

If you want to experiment with a simple auto-generated JavaFX project, or if you're new to Conveyor, start by following the tutorial. This page is for people who already have a basic understanding of Conveyor and want to package an existing JavaFX project.

Apps that use Gradle

  1. Add the Conveyor Gradle plugin.
  2. Write a conveyor.conf file.

To add the Gradle plugin add these snippets to your settings.gradle[.kts] and build.gradle[.kts] files:

settings.gradle.kts
1
2
3
4
5
6
pluginManagement {
    repositories {
        gradlePluginPortal()
        maven("https://maven.hq.hydraulic.software")
    }
}
settings.gradle
1
2
3
4
5
6
  pluginManagement {
      repositories {
          gradlePluginPortal()
          maven { uri = "https://maven.hq.hydraulic.software" }
      }
}
  • Open build.gradle{.kts} file. It should apply the Conveyor plugin at the top:
build.gradle.kts
1
2
3
plugins {
    id("dev.hydraulic.conveyor") version "1.0.1"
}
build.gradle
1
2
3
plugins {
    id 'dev.hydraulic.conveyor' version '1.0.1'
}

Get the latest version number and plugins code snippet here.

Then write a conveyor.conf that packages your app like this:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
include required("/stdlib/jdk/17/openjdk.conf")
include required("/stdlib/jvm/enhancements/client/v1.conf")
include "#!./gradlew -q printConveyorConfig"

app {
  display-name = "YourApp Name!"
  fsname = your-app-name
  site.base-url = your-site.com/downloads

  // We include the PNGs in the Windows and Linux app packages so they can be set as the window icon.
  windows.icons   = "icons/icon-square-*.png"
  windows.inputs += ${app.windows.icons}
  linux.icons     = "icons/icon-rounded-*.png"
  linux.inputs   += ${app.linux.icons}
  mac.icons       = "icons/icon-rounded-*.png"
}

This will define the names of your app both for the user and on disk, define where the packages will look for online updates, and import PNGs to act as icon files (you must supply these). The rest of the config will be generated by the gradlew -q printConveyorConfig command, which you can run to check that everything is working. In particular, check that the JARs for each platform are being calculated correctly with your setup.

Apps that use other build systems

The idea is straightforward - get all the JARs your app needs into a single directory. Below is a config that packages the gallery demo for the modern AtlantaFX skin. Here's the commit that added the packaging. The Maven POM in this project collects all the app JARs into the sampler/target/dependencies directory when the commands at the top of the file are run by hand. Conveyor can then just pick them up and package them.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
// Before packaging do the build like this:
//
// mvn install -pl styles
// mvn install -pl base
// mvn prepare-package jar:jar -pl sampler

// Use a vanilla Java 17 build, latest as of packaging.
include required("/stdlib/jdk/17/openjdk.conf")

// Import JavaFX JMODs.
include required("/stdlib/jvm/javafx/from-jmods.conf")

// Small tweaks e.g. enabling proxy detection (https://conveyor.hydraulic.dev/2/stdlib/jvm-clients/)
include required("/stdlib/jvm/enhancements/client/v1.conf")

javafx.version = 18.0.2

app {
  display-name = AtlantaFX Sampler
  fsname = atlantafx-sampler

  // Not allowed to have versions ending in -SNAPSHOT
  version = 0.1

  // Open source projects use Conveyor for free.
  vcs-url = github.com/mkpaz/atlantafx

  // Import the JARs.
  inputs += sampler/target/dependencies

  // Linux/macOS want rounded icons, Windows wants square.
  icons = "sampler/icons/icon-rounded-*.png"
  windows.icons = "sampler/icons/icon-square-*.png"

  jvm {
    gui.main-class = atlantafx.sampler.Launcher
    modules = [ java.logging, jdk.localedata, java.desktop, javafx.controls, javafx.swing, javafx.web ]
  }

  site.base-url = downloads.hydraulic.dev/atlantafx/sampler
}

There are several tasks accomplished by this config:

  1. Import a JDK of the right version from your preferred vendor.
  2. Import the JavaFX JMODs so the JVM will have it linked in.
  3. Add the client enhancements config (this line is optional).
  4. Set the names, versions and get a free license by pointing to the GitHub URL.
  5. Supply Conveyor with the directory where the app JARs can be found.
  6. Import icons for macOS and Windows. Icons must be PNG files. You don't have to supply all the sizes.
  7. Define the main class and the JDK modules (including the javafx modules) that you want to use.
  8. Define the URL where the packages will look for online updates.

Use package icons

We can use the same icons as what the package is using with code like this:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
private static void loadIconsForStage(Stage stage) throws IOException {
  String appDir = System.getProperty("app.dir");
  if (appDir == null)
    return;
  Path iconsDir = Paths.get(appDir);
  try (var dirEntries = Files.newDirectoryStream(iconsDir, "icon-*.png")) {
    for (Path iconFile : dirEntries) {
      try (var icon = Files.newInputStream(iconFile)) {
        stage.getIcons().add(new Image(icon));
      }
    }
  }
}

The above code assumes you've imported the icons as inputs so the raw PNGs are included in the package, not just put them in the app.icons keys. If you just supply PNGs for package icons then they'll be converted to platform native formats, but JavaFX wants PNGs when setting images on a Stage.