我一直在尝试将图像资源显示在我正在开发的GUI上,但是很难让它们显示出来。我遇到过有关加载资源的其他问题,例如java-swing-displaying-images-from-within-a-jar和images-will-not-work-in-a-jar-file,但它们对我不起作用。
我的问题似乎与第一个链接相同,其中图像在从Eclipse运行时出现,并且在使用Jars从命令行运行时不显示。但是,这些问题的解决方案不会使图像出现。
我检索资源的代码是:
public class R {
public static final String resourcePackage = "path/to/image/package";
/**
* Returns the resource string that refers to the <code>resource</code> file
* in the <code>path.to.image.package.png</code> package.
*
* @param resource
* the file in the <code>png</code> package
* @return the full resource string
*/
public static String png(String resource) {
return String.format("%s/png/%s", resourcePackage, resource);
}
public static ResizableIcon resizableIcon(String resource) {
return ImageWrapperResizableIcon.getIcon(R.class.getClassLoader()
.getResourceAsStream(resource), new Dimension(48, 48));
}
}
我在生成GUI时调用它
JCommandButton connect = new JCommandButton(i18ln.getString("ports"),
R.resizableIcon(R.png("serial-port-32x32.png")));
print语句表示找到了资源,因为R.class.getClassLoader().getResourceAsStream
返回sun.net.www.protocol.jar.JarURLConnection$JarURLInputStream
的实例。
我很难过。我花了好几个小时试图解决这个问题,但可以使用一些帮助。有什么想法吗?
仅供参考:我认为这不重要,但我使用Flamingo作为我的GUI。
根据Stefan的要求编辑:
src/ main/ java/ com.company.project (packages) R.java MyGui.java resources/ com.company.project (packages) .png (package) serial-port-32x32.png (more images) .i18ln (package) MyGui.properties
至于更多代码,我不知道我能提供什么,这对这个问题有很大好处。上面提供了用于检索资源的所有代码以及我如何使用该代码。你有什么具体的东西吗?
更新:
当我使用Eclipse创建Jar并从命令行运行它时,图像资源正确显示。当我使用Gradle创建Jar时,不会显示图像。因此,在生成Jars时会有不同的做法,允许通过Eclipse Jar正确访问图像资源,而不是Gradle Jar。我打开了a question on the Gradle forums with respect to this issue。
答案 0 :(得分:3)
取决于您的应用程序所在的环境(独立, ApplicationServer ),您需要使用相应的< / strong> ClassLoader
。
如果你有一个实用工具类Utils
,你可以试试这样的东西:
/* Returns a instance of InputStream for the resource */
public static InputStream getResourceAsStream(String resource)
throws FileNotFoundException {
String stripped = resource.startsWith("/")?resource.substring(1):resource;
InputStream stream = null;
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
if (classLoader != null) {
stream = classLoader.getResourceAsStream(stripped);
}
if (stream == null) {
stream = Utils.class.getResourceAsStream(resource);
}
if (stream == null) {
stream = Utils.class.getClassLoader().getResourceAsStream(stripped);
}
if (stream == null) {
throw new FileNotFoundException("Resource not found: " + resource);
}
return stream;
}
使用:
Utils.getResourceAsStream("com/company/project/png/serial-port-32x32.png");
答案 1 :(得分:2)
在此尝试此示例HOW TO LOAD IMAGES TO YOUR ECLIPSE PROJECT。希望这能为您解释一些事情,More STEPS HERE
不要使用ClassLoader,尽管如此,如Java Doc所述,它的引用声明“所有类加载器将首先搜索资源作为系统资源,类似于为类文件搜索。“
答案 2 :(得分:2)
忘记类加载器,检查路径。如果可行,请使用getResource i.o. getResourceAsStream(样式问题:更直接,未找到时传递null)。
由于getResource(AsStream)是基于类的,路径是相对的,所以试试这个:
R.class.getResource("/" + resource)
答案 3 :(得分:1)
创建资源包并将此类和图像放入其中:
public final class Resources {
public static ImageIcon getImage(String filename) {
URL resourceUrl = Resources.class.getResource(filename);
return new ImageIcon(resourceUrl);
}
}
修改强>
我用maven和flamingo(使用你的R类)重建了你的结构,它可以使用这些新增功能:
变化:
R.class.getClassLoader().getResourceAsStream(resource);
为:
R.class.getResource("png/"+resource);
我已经使用maven-assemble-plugin来构建jar,如here所述。
答案 4 :(得分:0)
URL imageurl = getClass().getResource("/images/serial-port-32x32.png");//relative path of the image as argument
Image myPicture = Toolkit.getDefaultToolkit().getImage(imageurl);
使用此图像'myPicture'作为ImageWrapperResizableIcon.getIcon方法的第一个参数