获取图像的URL的问题

时间:2016-04-29 23:39:34

标签: java swing user-interface

我正在尝试设置JButton的图标,但我似乎无法获取我的图像的url,继续给我一个空指针。我正在使用图像的绝对位置,但由于我计划将其导出为可运行的JAR,我需要它在源文件中。

这是我的构建路径: Build Path

这是代码的一部分,它给了我一个空指针:

public void loadLogo() {
    logo = new JLabel();

    // ---- This line ---- //
    ImageIcon icon = new ImageIcon(getClass().getResource("/res/Back.png"));


    Image img = icon.getImage();
    BufferedImage bi = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_ARGB);
    Graphics g = bi.createGraphics();
    g.drawImage(img, 0, 0, 200, 200, null);
    icon = new ImageIcon(bi);
    logo.setIcon(icon);
    logo.setBounds(220, -20, 400, 800);
    add(logo);
}

// getClass().getResource("/res/Back.png") <-- is a null URL object

提前致谢!

1 个答案:

答案 0 :(得分:1)

资源加载总是有点棘手(包括我糟糕的初始答案)。要记住的关键事项是资源是相对于类路径加载的,而Class上的方法相对于当前包。此外,Class支持从/开始表示“来自类路径根”的路径,而ClassLoader则不支持。{/ p>

以下是一些例子。考虑以下项目:

$ find *
java
java/a
java/demo
java/demo/a
java/demo/Demo.java
java/res
java/res/a
res
res/a
res/b

$ cat java/demo/Demo.java
package demo;

public class Demo {
  public static void main(String[] args) {
    System.out.println("System CL:\t"  + ClassLoader.getSystemResource(args[0]));
    System.out.println("Demo CL:\t"    + Demo.class.getClassLoader().getResource(args[0]));
    System.out.println("Demo Class:\t" + Demo.class.getResource(args[0]));
  }
}

请注意,全部有a个资源。如果我们尝试加载a,我们会得到不同的结果,具体取决于我们获取资源的方式。

$ java -cp 'java;res' demo.Demo a
System CL:      file:/tmp/java/a
Demo CL:        file:/tmp/java/a
Demo Class:     file:/tmp/java/demo/a

$ java -cp 'java;res' demo.Demo /a
System CL:      null
Demo CL:        null
Demo Class:     file:/tmp/java/a

因此ClassLoader查看类路径,而Class查看包。使用/ ClassLoader doesn't find anything while thelooks at the top of the classpath. Neither found res / a`。

另一方面,b资源只存在于res中,因此ClassLoaderClass都会找到它,但在不同的地方:

$ java -cp 'java;res' demo.Demo b
System CL:      file:/tmp/res/b
Demo CL:        file:/tmp/res/b
Demo Class:     null

$ java -cp 'java;res' demo.Demo /b
System CL:      null
Demo CL:        null
Demo Class:     file:/tmp/res/b

您的确切结果在很大程度上取决于您的项目设置以及您的类路径中的内容。您的res目录位于src方向内(Eclipse通常将其复制到bin),因此它应位于类路径上,因此Class.getResource("/res/Black.png")应该有效。您是否在bin中看到了自己的资源?如果你不这样做,那就是你的问题。

如果您确实在bin中看到了资源,请尝试打印System.getProperty("java.class.path")以验证其中包含您期望的目录。

如果这些都没有证明问题,请尝试在项目中运行Demo并传入不同的路径,看看是否找到了任何内容。

作为一般的最佳做法,我建议将res移出src并进入类路径中自己的目录;这会将您的资源与代码分离。我还建议使用ClassLoader的方法而不是Class,因为包相对或类路径相对的行为可能更容易出错。