Java 使用与已编译Jar相同文件夹中的图像不起作用

Java 使用与已编译Jar相同文件夹中的图像不起作用,java,swing,Java,Swing,我所要做的就是使用与.jar位于同一目录中的图像创建一个JLabel,如果它不存在,它将加载位于.jar内部的默认照片。图片存在于文件夹中,但它始终默认为.jar中的图片 String path = this.getClass().getProtectionDomain().getCodeSource().getLocation().getPath(); File logo = new File(path + "logo.png"); JLabel lblNewLabel_1; if (lo

我所要做的就是使用与.jar位于同一目录中的图像创建一个JLabel,如果它不存在,它将加载位于.jar内部的默认照片。图片存在于文件夹中,但它始终默认为.jar中的图片

String path = this.getClass().getProtectionDomain().getCodeSource().getLocation().getPath();

File logo = new File(path + "logo.png");

JLabel lblNewLabel_1;
if (logo.exists()){
    lblNewLabel_1 = new JLabel(new ImageIcon(logo.getPath()));
} else {
    lblNewLabel_1 = new JLabel(new ImageIcon(Main.class.getResource("/com/daniel/Coffee.png")));    
}

frame.getContentPane().add(lblNewLabel_1, BorderLayout.WEST);

final JLabel lblStatus = new JLabel(new ImageIcon(Main.class.getResource("/com/daniel/status1.png")));
frame.getContentPane().add(lblStatus, BorderLayout.EAST);

诊断此问题最简单的方法是应用简单的System.out.println,如下所示

String path = this.getClass().getProtectionDomain().getCodeSource().getLocation().getPath(;
System.our.println("Jar path is "+path); <- you will see the actual path content here
File logo = new File(path + "logo.png");

检查结果并根据需要调整连接路径。我猜该路径要么指向与您想象的不同的目录,要么就是在末尾缺少File.separator。尝试并分享结果

看起来您在路径的末尾缺少了一个“/”。这样做:

String path = this.getClass().getProtectionDomain().getCodeSource().getLocation().getPath();
File logo = new File(new File(path).getParentFile(), "logo.png");
...
关键是首先为包含目录创建一个文件,然后使用构造函数FileFile dir,String name代替字符串连接

此外,您应该提前检查文件夹和文件权限,为错误诊断提供适当的日志输出。为此,使用canRead而不是exists,假设日志作为某种日志记录工具可用-替换为您选择的日志记录机制:

String path = this.getClass().getProtectionDomain().getCodeSource().getLocation().getPath();
File sourceLocation = new File(path);

// go up in the hierarchy until there is a directory
while (sourceLocation != null && !sourceLocation.isDirectory()) {
    sourceLocation = sourceLocation.getParentFile();
    if (sourceLocation == null) {
        log.warn(path + " is not a directory but has no parent");
    }
}

if (sourceLocation != null && sourceLocation.canRead()) {
    File logo = new File(sourceLocation, "logo.png");
    if (logo.canRead()) {
        log.info("Using logo " + logo.getAbsolutePath());
        lblNewLabel_1 = new JLabel(new ImageIcon(logo.getPath()));
    } else {
        log.warn("can not read " + logo.getAbsolutePath());
    }
}

if (lblNewLabel_1 == null) {
    log.warn("logo location not accessible, using default logo: " + sourceLocation);
    lblNewLabel_1 = new JLabel(new ImageIcon(Main.class.getResource("/com/daniel/Coffee.png")));
}

// ...

检查getResource是否返回null。不应使用字符串path=this.getClass.getProtectionDomain.getCodeSource.getLocation.getPath;。要获取外部文件,应使用Path类:Path Path=FileSystems.getDefault.getPathlogo.png;如果getResource返回null,我想我们会在这里得到NPE,不是吗?新的Filelogo.png有什么问题?假设执行上下文与jar是同一个目录…查看logo的文件路径在何处,它似乎正在执行…\logo.jar\logo.pngOkay,我添加了一个对getParentFile的调用,以从路径中删除logo.jar。我这样做了,同样,路径是“…\logo.jar”,实际的图像本身是“\logo.jar\logo.png”,如何在该字符串路径中查找目录?如果getLocation返回File,则返回getParentFile。您可以始终使用/。/来提升一个级别。您确实不应该自己连接文件名,而应该依赖API方法。