正如 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 的情况下实现相同的行为(因为故意调用异常不是好的做法),但这个解决方案暂时可以正常工作。