如何从 JavaFX 中的相同代码生成 jar 和本机包(dmg、exe 等)

How to generate a jar and native bundle (dmg, exe, etc) from the same code in JavaFX

我在 IntelliJ 中设置了 JavaFX 应用程序。此应用程序可以从命令行 运行 并作为 jar 的 gui。除了 jar 中的两种模式之外,我还想发布一个本地包(在我的例子中是 mac,所以 dmg)。我想通过在 main() 中创建一个 if 语句来做到这一点,该语句接受是否启动 gui 的指令。这是我的 class.

public class Main extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception{
        Parent root = FXMLLoader.load(getClass().getResource("dummy.fxml"));
        primaryStage.setTitle("TODO");
        primaryStage.setScene(new Scene(root, 400, 400));
        primaryStage.show();
    }


    public static void main(String[] args) {
        if (args[0].equals("user_interface")) {
            //launch gui version
            launch(args);
        } else {
            //Run command line version of the app
            //TODO
        }
    }
}

我在我的 intellij 项目中创建了两个构建工件。一个用于 jar,一个用于 javafx 应用程序以生成 dmg。

罐子完美运行。它在 cli 中 运行s 并启动 javafx 应用程序,但我不知道如何在创建本机包时传递参数以便我可以传递 "user_interface"。有谁知道在创建原生包工件时如何传递参数?

有没有更好的方法呢?只有两个要求。

  1. 应该有两个神器。一个罐子和一个 dmg.
  2. jar 可以 运行 在 cli 或 gui 模式下。

您可以创建 2 个 Main 类:

  • 控制台应用程序 --> 隐藏 UI
  • UI 应用 --> 显示 UI

然后您可以创建 2 个工件:控制台工件、ui 工件。然后使用你的 main 类.

或者您可以在 JavaFx 应用程序工件的 Java FX 选项卡中定义 "Application Parameters":

这是一个带有 "key=value" 或只有 "key" 的简单属性文件。每行一个条目。 然后你可以在你的启动方法中得到这个参数:

    @Override
    public void start(Stage primaryStage) throws Exception {
        Parameters parameters = getParameters();

        List<String> unnamed = parameters.getUnnamed();
        for (String s : unnamed) {
            System.out.println(s + " (unnamed)");
            Alert al = new Alert(Alert.AlertType.INFORMATION);
            al.setContentText(s + " (unnamed)");
            al.show();
        }

        List<String> raw = parameters.getRaw();
        for (String s : raw) {
            System.out.println(s + " (raw)");
            Alert al = new Alert(Alert.AlertType.INFORMATION);
            al.setContentText(s + " (raw)");
            al.show();
        }
}

在这种情况下,我通常做的是嗅探系统属性,看看是否有任何东西可以用作代理来确定应用程序是否 运行 在应用程序包中。例如。 System.out.println(System.getProperties())

比较应用程序包中的 运行 与 CLI 中的 运行,应该会跳出一些东西。例如。启动器可能会添加一些您可以键入的系统属性。