我已将所有JavaFX代码放入可执行的JAR文件中。一切都在里面。
当我使用Eclipse IDE进行编译时,它可以工作,但是当我尝试执行JAR文件时,出现错误。
Caused by: javafx.fxml.LoadException:
file:/home/asus/program/JUSBPlotter/JUSBPlotter-0.0.1-SNAPSHOT-jar-with-dependencies.jar!/se/danielmartensson/fxml/front.fxml
当我有此Java代码
Parent root = FXMLLoader.load(getClass().getResource("/se/danielmartensson/fxml/front.fxml"));
FXML文件没有问题。
fx:controller="se.danielmartensson.controller.Front"
当我尝试在JavaFX中显示图片时,也会出错。
Caused by: java.io.FileNotFoundException: file:/home/asus/program/JUSBPlotter/JUSBPlotter-0.0.1-SNAPSHOT-jar-with-dependencies.jar!/se/danielmartensson/pictures/computer.png (No such file or directory)
当我有以下Java代码时:
FileInputStream picture1 = new FileInputStream(getClass().getResource("/se/danielmartensson/pictures/computer.png").getFile());
问题: 如何告诉Java JAR文件中正确的文件路径?
答案 0 :(得分:2)
要记住的一件事是,资源与文件不是同一件事,尽管它们看起来非常相似,尤其是在打包应用程序之前。打包应用程序后,这些资源文件将成为JAR文件中的条目,尽管可以将它们视为文件,但无法以与文件相同的方式进行访问。尤其是java.io.File
API无法理解如何读取这些条目。但是,您可以通过Class#getResource(String)
返回的URL
或Class#getResourceAsStream(String)
返回的InputStream
访问这些条目。请注意,后者基本上只是找到URL
,如果存在,则调用URL#openStream()
。您可以使用URL
访问JAR条目(即资源)的原因是由于JarURLConnection
和相关类;我不会详细介绍Java如何处理URL,因为这超出了此答案的范围。
现在,由于您尝试在JavaFX中显示图像,因此我假设您正在使用Image
类。基本上可以通过三种方式告诉Image
图片资源在哪里。
在参数URL没有方案的地方使用Image#<init>(String)
。在这种情况下,类会将URL视为相对于类路径根目录的路径,并尝试相应地访问图像。基本上,该参数与您为Class#getResource(String)
提供的参数相同,只是路径必须是绝对的(即,不是相对于任何类的)。 Image
类对此行为进行了记录:
URL
支持的所有URL都可以传递给构造函数。如果传递的字符串不是有效的URL,而是一个路径,则在这种情况下,将在类路径上搜索Image。
注意:如果您使用的是模块,则使用此选项时resource encapsulation会起作用。参见GitHub Issue #441。
使用与上述相同的构造函数,但传递有效的URL(即,它具有方案)。使用资源时,您可以简单地使用URL#toExternalForm()
将URL
返回的Class#getResource(Sring)
转换为String
。
Image image = new Image(getClass().getResource(...).toExternalForm());
注意:您也可以使用URL#toString()
返回相同的值。
使用Image#<init>(InputStream)
。在这里您可以使用Class#getResourceAsStream(String)
。完成操作后,别忘了关闭InputStream
。
try (InputStream is = getClass().getResourceAsStream(...)) {
Image image = new Image(is);
}
所有这些都假定在构建资源时,这些资源已正确打包在JAR文件中。如果不是这种情况,请首先遵循JoséPereda在问题评论中提供的建议。
请注意,可以使用java.util.zip.*
API,java.util.jar.*
API或Java NIO的ZipFileSystemProvider
访问ZIP / JAR文件的条目。所有这些选项,尤其是最后一个选项,都使您可以访问与实际文件类似的ZIP / JAR文件条目,因为它们是专门为这样做而设计的。但是,在应用程序中使用资源时,应坚持使用Class#getResource(String)
和相关方法。