我不知道我在尝试将 JavaFx 导出为 Jar/Exe

I have no clue what I'm doing trying to export JavaFx as a Jar/Exe

我尽最大努力导出我的 javafx(11) 项目,但似乎没有任何效果。我在使用 IntelliJ IDE,例如让我们使用这个项目:https://github.com/EveningSt3r/JFX-hotel-project。 (我用了 30 分钟写了这篇文章,但它很简单并且满足了这个问题的目的)

当我使用 IntelliJ 的 Build Artifacts 功能时:“fx:deploy 不可用” 我不知道如何使用 jlink,所有在线教程都难倒我。 大多数 javafx 教程都是从它属于 JDK 的时候开始的,所以这没有帮助。 我不知道如何使用 Maven 和 Gradle.

这来自一个对 Java 实际工作原理没有很好理解,只知道如何制作东西的家伙。

我花了数周的时间试图解决这个问题,所以有人可以帮我把它简化到婴儿级别,关于如何将它变成可运行的东西或 exe 吗?我知道我听起来很蠢,但我只是累了

它与 jlink 无关,只与您创建工件的方式有关。

每当您在 IntelliJ 中创建 .jar 文件时,在创建工件之前,您必须将 java bin 文件中的文件输入到工件中。

要做到这一点,您必须前往 File-Project Structure-Artifacts。

然后单击加号“+”,将鼠标悬停在 JAR 和 select 来自具有依赖项的模块上。

在那之后 select 弹出显示中的“主要 Class”栏并输入您的主要 class(可能标题为“主要”)并单击确定。

之后您会看到一个新框。在该框中单击其中的加号,然后单击“文件”。

然后转到程序文件中的 jre 文件夹,该文件夹位于“Java”文件夹中。进入它然后双击“bin”。突出显示所有属于文件而非文件夹的内容,然后将其放入您的工件中。

之后在您的工件上单击“确定”window,它将关闭。

现在您已准备好单击“构建工件”按钮!

单击按钮并select“构建”

点击按钮后,.jar 文件将出现在“out”下的项目文件夹和“artifacts”中!

祝你有愉快的一天! :)

一种选择是使用 jpackage 工具。该工具是 Java 14-15 中的一项孵化功能,并在 Java 16 中进行了标准化。它创建了一个独立的应用程序。换句话说,生成的应用程序不仅包含您自己的代码和任何依赖项,还包含嵌入式 Java 运行时环境 (JRE)。这样您的最终用户就不必担心安装 Java 或 JavaFX。相反,他们最终得到了原生 installer/executable.

有个user guide for jpackage. There's also a script another user on this site (along with others, if I'm not mistaken) has created that may make things simpler for you: JPackageScriptFX.


这是创建 JavaFX 应用程序的最小示例,其中应用程序与 jpackage 一起打包,完全从命令行。该示例假设一个模块化应用程序(即您的代码和所有依赖项都有一个 module-info 文件),但 jpackage 也能够打包基于 class 路径的应用程序(即非模块化应用程序) .

项目结构

├───out
│   ├───classes
│   └───package
└───src
    └───com.example
        │   module-info.java
        │
        └───com
            └───example
                └───app
                        Main.java

请注意,源代码位于名为 com.example 的目录下。这与模块同名,使手动使用 javac 更容易(编译模块时)。但是,您不需要这样做。事实上,如果您使用的是 IDE,那么您的源代码可能直接位于 src 下(如果使用 Maven/Gradle,则可能是 src/main/java)。

因为您可能会让 IDE 编译代码,所以我 建议创建一个名称与模块名称匹配的目录。

源文件

这是 module-info.java 文件:

module com.example {
  requires javafx.controls;

  exports com.example.app to javafx.graphics;
}

这是 Main.java 文件:

package com.example.app;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class Main extends Application {

  public void start(Stage primaryStage) {
    StackPane root = new StackPane(new Label("Hello, World!"));
    Scene scene = new Scene(root, 500, 300);
    primaryStage.setScene(scene);
    primaryStage.setTitle("JPackage Example");
    primaryStage.show();
  }
}

编译

这是编译上述代码的命令。注意工作目录是项目目录。

javac --module-source-path src --module com.example -d out\classes

我有一个 JDK,其中包括 JavaFX。如果不这样做,则需要确保将 JavaFX 放在模块路径上。例如:

javac --module-path <path-to-fx> --module-source-path src --module com.example -d out\classes

但同样,您可能会让 IDE 处理编译。

包装

这是打包现在编译的应用程序的命令。

jpackage --type app-image --name JPackageExample --module-path out/classes --module com.example/com.example.app.Main --dest out/package

--type 决定了申请类型。在 Windows 上有三个选项:app-image(我相信所有平台都通用)、exemsi。第一个将简单地创建一个展开的目录(在 Windows 上包含一个 exe 文件)。后两者将为您的应用程序创建 Windows 个安装程序。请注意,您必须在 Windows 上才能创建 Windows 包(MacOS 和 Linux 相同)。

--module 参数告诉工具主模块和 class 是什么(即应用程序的入口点)。它的格式是<main-module>[/<main-class>]。如果合适,可以省略主要 class(例如,您将代码打包到指定了 --main-class 的 JAR 文件中)。

同样,我有一个 JDK,其中包括 JavaFX。如果不这样做,请确保在 --module-path 参数中包含 JavaFX 以及您自己的代码。 重要提示: 与编译期间不同,如果您将 JavaFX 与 JDK 分开,请确保将 JavaFX JMOD 文件放在模块上-路径,不是普通的JAR文件;您可以从 Gluon 获取 JMOD 文件(可能是您获取 JavaFX SDK 的同一个地方)。请记住,JavaFX 是特定于平台的。


以上示例完全来自命令行。您可能使用的是 IDE,因此某些步骤可能会有所不同。例如,您可以依靠 IDE 来编译您的代码,如果需要,还可以将其打包到 JAR 文件中。您甚至可以让 IDE 处理调用 jpackage,但我不确定。