将 JavaFX 应用程序打包为平台特定可执行文件

JavaFX 是一个运行在 JDK 之上的软件平台,它使您能够开发桌面应用程序以及运行在各种设备上的富 Web 应用程序。当您的 JavaFX 应用程序准备就绪后,您可以将其打包到一个自执行 jar 文件中并发布给您的用户。但这意味着您的用户应该安装了与您打包应用程序时使用的相同 JDK 版本。为了避免这种情况,您可以创建一个自定义运行时映像,其中只包含应用程序所需的平台模块。

使用 jmod 编译 JavaFX 应用程序

让我们考虑以下 HelloWorldFX.java 应用程序,它会在每次单击时更改圆圈的颜色

package helloworld;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

import javafx.scene.Group;
import javafx.scene.input.MouseEvent;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;

import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
import javafx.scene.text.Text;

public class HelloWorldFX extends Application {

	@Override
	public void start(Stage stage) {
		String javaVersion = System.getProperty("java.version");
		String javafxVersion = System.getProperty("javafx.version");
		
		Circle circle = new Circle(300.0f, 200.0f, 50.0f);
		circle.setFill(Color.BLUE);
		circle.setStrokeWidth(20);

		//Set text
		Text text = new Text("Click on the circle to change its color");
		text.setFont(Font.font(null, FontWeight.BOLD, 20));
		text.setFill(Color.WHITE);
		text.setX(150);
		text.setY(50);

		//Setup the mouse event handler 
		EventHandler<MouseEvent> eventHandler = new EventHandler<MouseEvent>() {
			@Override
			public void handle(MouseEvent e) {
				System.out.println(String.format("Hello World running on JavaFX %s on top of Java %s", javafxVersion, javaVersion));
				if (circle.getFill().equals(Color.BLUE)) 
					circle.setFill(Color.RED);
				else
					circle.setFill(Color.BLUE);
			}
		};
		//Register the event filter 
		circle.addEventFilter(MouseEvent.MOUSE_CLICKED, eventHandler);

		//Add circle and text to a group
		Group root = new Group(circle, text);
		
		Scene scene = new Scene(root, 640, 480);
		scene.setFill(Color.WHITE);

		stage.setTitle("Color shifter");
		stage.setScene(scene);
		stage.show();
	}

	public static void main(String[] args) {
		launch();
	}

}

以下 module-info.java 文件定义了 helloworldfx 模块

module helloworldfx {
    requires javafx.controls;
    exports helloworld;
}

您可以使用 JavaFX 发布页面 中提供的 jmod 文件集运行您的 JavaFX 应用程序。下载适合您操作系统的存档

  • Linux/x64
  • macOS/x64
  • macOS/AArch64
  • Windows/x64

您可以尝试使用 JavaFX 21 或更高版本使用示例应用程序。如果您的操作系统是 Linux/x64 或 macOS,请解压缩下载的存档并添加指向结果 jmods 目录的环境变量

export PATH_TO_FX_JMODS=path/to/javafx-jmods-21.0.1

如果您是 Windows 操作系统用户,请解压缩下载的存档并添加指向结果 jmods 目录的环境变量

set PATH_TO_FX_JMODS="path\to\javafx-jmods-21.0.1"

让我们使用 JavaFX jmod 编译应用程序

  • 对于 Linux/x64、macOS/x64、macOS/AArch64
javac --module-path $PATH_TO_FX_JMODS -d mods/helloworldfx $(find . -name "*.java")
  • 对于 Windows
dir /s /b *.java > sources.txt & javac --module-path %PATH_TO_FX_JMODS% -d mods/helloworldfx @sources.txt & del sources.txt

将自包含的 JavaFX 应用程序作为平台特定可执行文件发布

因为 helloworldfx 是一个模块化应用程序,所以您可以使用 jpackage 自动生成运行时映像。如果您的本地操作系统是 macOS,您可以运行以下命令以在 dmg 格式中构建本机软件包

jpackage \
 --dest output \
 --name ShiftingCircle \
 --type dmg \
 --module-path $PATH_TO_FX_JMODS:mods \
 --add-modules helloworldfx \
 --module helloworldfx/helloworld.HelloWorldFX \
 --mac-package-name ShiftingCircle \
 --mac-package-identifier helloworld.HelloWorldFX \
 --java-options -Xmx2048m

jpackage 将自动运行 jlink 并生成包含所需模块的运行时。

前面的命令在 output 文件夹 (--dest output) 中构建了一个本机 macOS 应用程序 (--type dmg),其名称为 ShiftingCircle。要创建此运行时映像,您应该指定 JavaFX jmod 的路径 (--module-path $PATH_TO_FX_JMODS:mods),但也添加包含 HelloWorldFX.java (--add-modules helloworldfx) 的模块。

选项 --module helloworldfx/helloworld.HelloWorldFX 指示应用程序启动器在哪里找到应用程序的主类。由于生成的执行文件是本机 macOS 映像,因此您可以添加一些特定于 Mac 的选项

  • 定义应用程序在菜单栏中显示的名称 (--mac-package-name ShiftingCircle)
  • 在签署应用程序包时,没有现有包标识符的组件将以 --mac-package-identifier 选项的值为前缀。

如果您在 Windows 操作系统上运行,则可以将前面的应用程序作为 Microsoft 安装程序 (msi) 文件发布。在运行 jpackage 命令之前,请确保您已安装 WiX 工具。然后在 命令提示符 窗口中使用以下命令

jpackage 
 --dest output 
 --name ShiftingCircle 
 --type msi 
 --module-path "%PATH_TO_FX_JMODS%;mods" 
 --add-modules helloworldfx 
 --module helloworldfx/helloworld.HelloWorldFX 
 --win-shortcut --win-menu 
 --java-options -Xmx2048m

运行前面的命令将创建一个 ShiftingCircle-1.0.msi Microsoft 安装程序文件。运行 ShiftingCircle-1.0.msi 将要求添加应用程序的 开始菜单 快捷方式,并创建一个与之关联的桌面快捷方式。

Shifting Circle Color Application

总之,如果您想发布 Java/JavaFX 应用程序而无需用户安装 JDK,请考虑使用 jpackage 创建本机 macOS、Windows 或 Linux 软件。