使用Java 11构建和部署JavaFX应用程序

22

1
  1. 我怀疑这可能太宽泛了,我的意思是,如果您已经知道JavaFX不再与JDK捆绑在一起,那么您应该尝试使用独立的二进制文件。您可以探索新的选项,如OpenJFX,并在文档页面的JavaFX和IntelliJ部分找到构建库的指南。
  2. 那篇文章是2013年发布的,针对的是IntelliJ 12.1版本!你真的一直依赖它到现在吗?
- Naman
我搜索了很多,没有关于构建jar的指南,所有我找到的指南都只停留在运行应用程序。 - humazed
我已经阅读了您提供的文档,它帮助我运行和开发应用程序,但我无法找到任何关于如何构建它的信息。 - humazed
  1. 这篇文章仍然适用于Java 8,并且我希望它可以正常工作,所有步骤仍然有效,除了最后一步。
- humazed
1
好的,我将使用Java11创建一个Hello World JavaFX应用程序,并分享链接。 - humazed
显示剩余4条评论
6个回答

13

在Intelij中,使用JavafX JAR导出选项已经不再起作用了。你可以使用“从带依赖的模块创建Jar”将其导出为常规的jar文件。这将导出一个有效的Jar文件,但是为了运行它,您需要将您的JavaFX路径和模块添加到您的命令中。

一旦您拥有了jar文件,运行命令应该看起来像这样:

java --module-path PATH_TO_YOUR_JAVAFX_LIB_FOLDER --add-modules javafx.controls,javafx.fxml,javafx.graphics,javafx.web -jar yourJar.jar

我已经制作了一个youtube的教程: https://youtu.be/HGHu-SzL-5E


谢谢,这正是我在寻找的解决方案。 - jyoti proy
4
非常好,非常感谢。但是有没有办法直接双击运行这个JAR文件呢?在Java 8中我曾经能够做到这一点。 - SneakyShrike

10

以下方法适用于我在Windows和Ubuntu上使用IntelliJ使用OpenJDK 11和OpenJFX 11,并成功创建了一个可以在目标机器上仅通过java -jar filename.jar运行的jar,无需安装JavaFX。请记住,JavaFX jars是平台相关的。因此,Windows jar需要在Windows上编译,而Linux jar需要在Linux上编译。

我的主要方法扩展应用程序...

public class Main extends Application {

因此,首先创建一个类似于Start.java的新的Java类 - 这个类与原始的Main方法相关联。

public class Start {
    public static void main(String[] args){
        Main.main(args);
    }
}

然后创建.jar文件:

文件 > 项目结构 > 构件

点击 + > 选择JAR > 来自具有依赖项的模块

对于主类选择Start.java > 点击确定

Javafx的jar文件应该会被自动提取(如果没有,请手动添加)

点击应用和确定

构建 > 构建构件 > 构建

使用java -jar filename.jar即可在没有安装JavaFX的机器上正常运行所创建的文件。


双击并运行... 创建快捷方式。在目标框中输入... C:\Users\me\Desktop\java -jar "C:\Program Files\MyApp\myFX.jar" - Harley
在Linux上双击运行,请使用chmod +x myFX.jar - Harley

2

1
Oracle不再在其网站上提供Java 10的下载。 - humazed
2
如果有人正在寻找Java10,您可以在此处找到它:https://www.oracle.com/technetwork/java/javase/downloads/java-archive-javase10-4425482.html - humazed

1
作为Barosanu240的回答,IntelliJ目前无法导出JavaFX Jars,尽管该方面正在进行开发。此外,他在YouTube视频中的解决方案非常完美,所以感谢您发布这个。

为了使JAR文件在不使用命令行的情况下打开,应用程序基本上需要使用上述附加JVM参数重新启动自己。虽然有些混乱,但可以通过以下方式实现。

假设应用程序在其当前目录中查找名为exist.txt的临时文件。如果不存在此文件,则创建它,向CMD发送一个命令以使用附加的JVM参数启动另一个实例,然后关闭。然后新打开的实例检查exist.txt的存在性,现在它已经存在;因此,它知道UI已经打开和可见。然后删除exist.txt,应用程序继续正常运行。

尽管有些混乱,但可以通过try/catch块来实现这种方法,如下所示。

try (FileReader fileRead = new FileReader(new File(Paths.get("").toAbsolutePath().toString() + FileSystems.getDefault().getSeparator() +"exist.txt"))) {
        //If the code gets this far, the file exists. Therefore, the UI is open and visible. The file can now be deleted, for the next time the application starts.

        fileReader.close();
        File file = new File(Paths.get("").toAbsolutePath().toString() + FileSystems.getDefault().getSeparator() +"exist.txt");
        boolean result = file.delete();
        if (result) {
            System.out.println("File deleted successfully; starting update service.");
        } else {
            System.out.println("File was not deleted successfully - please delete exist.txt.");
        }

    } catch (IOException e) {
        //The file does not exist because an exception was generated. Therefore, create the file, and restart the application using CMD with the additional arguments required
        File file = new File(Paths.get("").toAbsolutePath().toString() + FileSystems.getDefault().getSeparator() +"exist.txt");
        try {
            boolean result = file.createNewFile();
            if (result) {
                //Start a new instance of this application
                final String command = "cmd /c start cmd.exe /k java --module-path PATH_TO_YOUR_JAVAFX_LIB_FOLDER --add-modules javafx.controls,javafx.fxml,javafx.graphics,javafx.web -jar yourJar.jar;
                Runtime.getRuntime().exec(command);
            } else {
                System.out.println("Unable to create exist.txt. Application will close.");
            }
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        //Now that a new file has been created and a command sent to CMD, exit this instance
        System.exit(-1);
    }

//The rest of your application's code

请注意,JavaFX lib文件夹的路径不应包含任何空格。以上代码需要放在应用程序的main方法中,在launch(args)行之前。可能有更好的方法来实现相同的行为,而不需要使用try/catch(故意调用异常不是好的实践),但这个解决方案目前可以正常工作。

0

我有同样的问题,经过大量搜索,我在YouTube上找到了解决方案,这是视频链接: https://www.youtube.com/watch?v=F8ahBtXkQzU

您需要将计算机上JavaSDKFX文件中的所有(.dill)文件添加到您要设置在Artifact中的libs中,查看链接以获取更明显的信息。


3
欢迎提供解决方案的链接,但请确保你的回答即使没有链接也是有用的:在链接周围添加一些语境,这样其他用户就可以了解它是什么以及为什么要使用它,然后如果目标页面不可用,请引用你链接页面中最相关的部分。仅仅包含链接的答案可能会被删除。 - 4b0
我明白了,以后我的回答会更加明确,谢谢。 - Ahmad Ellamey

0

构件 -> + -> JavaFX 应用程序 -> 从模块中设置应用程序类


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接