使用 java11 构建和部署 javafx 应用程序
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/53450011/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Build and deploy javafx application using java11
提问by humazed
I followed the steps in https://blog.jetbrains.com/idea/2013/03/packaging-javafx-2-applications-in-intellij-idea-121/
我按照https://blog.jetbrains.com/idea/2013/03/packaging-javafx-2-applications-in-intellij-idea-121/ 中的步骤操作
but when I try to build artifacts the as in the last step I get this error
但是当我在最后一步尝试构建工件时,我收到此错误
Error:Java FX Packager: Can't build artifact - fx:deploy is not available in this JDK
错误:Java FX Packager:无法构建工件 - fx:deploy 在此 JDK 中不可用
I know JavaFX has been removed from java11 my question is what should I do to build a .jar
or .exe
我知道 JavaFX 已从 java11 中删除,我的问题是我应该怎么做才能构建.jar
或.exe
here is a hello world appfor quick testing.
这是一个用于快速测试的hello world 应用程序。
回答by Ioannis Panteleakis
Unfortunately, you won't be able to build your jar using JFX11 this way, as apparently the packager was removed from the JFX SDK. There is hope it will be implemented in a future release (maybe 12). Read here for more details:
不幸的是,您将无法以这种方式使用 JFX11 构建 jar,因为显然打包程序已从 JFX SDK 中删除。希望它会在未来的版本(可能是 12)中实现。阅读此处了解更多详情:
https://youtrack.jetbrains.com/issue/IDEA-200721containing the following 2 links:
https://youtrack.jetbrains.com/issue/IDEA-200721包含以下 2 个链接:
https://bugs.openjdk.java.net/browse/JDK-8212780
https://bugs.openjdk.java.net/browse/JDK-8212780
https://openjdk.java.net/jeps/343
https://openjdk.java.net/jeps/343
As a temporary solution, you might simply use/downgrade to version 10 which still includes the needed packager.
作为临时解决方案,您可以简单地使用/降级到仍包含所需打包程序的版本 10。
回答by Barosanu240
Using the JavafX JAR export option doesn't work anymore in Intelij. You can export it as a regular jar with "Jar-From module with dependencies". This will export a valid Jar, but in order to run it, you need to add your javaFx path and modules to your command.
在 Intelij 中不再使用 JavafX JAR 导出选项。您可以使用“具有依赖项的 Jar-From 模块”将其导出为常规 jar。这将导出一个有效的 Jar,但为了运行它,您需要将您的 javaFx 路径和模块添加到您的命令中。
After you have the jar, the run command should look something like this:
获得 jar 后,运行命令应如下所示:
java --module-path PATH_TO_YOUR_JAVAFX_LIB_FOLDER --add-modules javafx.controls,javafx.fxml,javafx.graphics,javafx.web -jar yourJar.jar
I made a youtube tutorial with this: https://youtu.be/HGHu-SzL-5E
我用这个制作了一个 youtube 教程:https: //youtu.be/HGHu-SzL-5E
回答by matt_frangakis
As Barosanu240 answered, IntelliJ cannot currently export JavaFX Jars anymore, although development on that aspect is being carried out. Further, his solution on his YouTube video works perfectly well, so thank you for posting that.
正如 Barosanu240 回答的那样,IntelliJ 目前无法再导出 JavaFX 罐子,尽管这方面的开发正在进行中。此外,他在他的 YouTube 视频上的解决方案效果很好,所以感谢您发布该内容。
In order to have a JAR file open without use of the command line, the application essentially needs to restart itself with the additional JVM argumemts listed above. Although messy, this can be accomplished in the following way.
为了在不使用命令行的情况下打开 JAR 文件,应用程序本质上需要使用上面列出的其他 JVM 参数重新启动自身。虽然很麻烦,但这可以通过以下方式完成。
Suppose the application looks for a temporary file in its current directory, named exist.txt. If this file does not exist, it creates it, sends a command to CMD to start another instance of itself with the additional JVM arguments, then closes. The newly opened instance then checks for the existence of exist.txt, and it now doesexist; therefore, it knows that the UI is open and visible. It then deletes exist.txt, and the application then continues on as normal.
假设应用程序在其当前目录中查找名为exist.txt 的临时文件。如果这个文件不存在,它会创建它,向 CMD 发送一个命令,用额外的 JVM 参数启动另一个它自己的实例,然后关闭。新打开的实例然后检查是否存在exist.txt,现在它确实存在;因此,它知道 UI 是打开和可见的。然后删除exist.txt,然后应用程序继续正常运行。
This methodology can be accomplished with a try/catch block, although admittedly messy, as follows.
这种方法可以通过一个 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
Note that the path to your JavaFX lib folder should not contain any spaces. The above code needs to be in your application's main
method, before the launch(args)
line. There are probably better ways to achieve this same behaviour without use of a try/catch (as invoking exceptions purposely is not good practice), but this solution works fine for the time being.
请注意,JavaFX lib 文件夹的路径不应包含任何空格。上面的代码需要在你的应用程序的main
方法中,launch(args)
在行之前。可能有更好的方法可以在不使用 try/catch 的情况下实现相同的行为(因为故意调用异常不是一个好习惯),但是这个解决方案暂时可以正常工作。