Image from relative package - java

I'm making a simple game using the java applet. I want to add buffered images to the project.
I've created a package called "resources.images.sprites" and I've put images in there.
How can I access the images?
I've tried using relative paths, but "." starts outside of the bin, so if I were to put the game on a website, I wouldn't be able to access it.
Any ideas?
Here's the main code I'm using for testing...
package resources;
import java.io.File;
import java.util.HashMap;
import entities.Sprite;
public class ImageLibrary {
private static final File sprite_path = new File(".");
private static File[] sprite_files = sprite_path.listFiles();
//private static HashMap<String,Sprite> sprite_map = new HashMap<String,Sprite>();
public static void main(String[] args){
System.out.println(sprite_files[0]); // To check the folder it's in...
}
}
Edit:
I took the accept answer, and then realized I could use the getPath method on the URL object to get what I wanted to achieve.

Use a ClassLoader.
Classloader cl = ImageLibrary.class.getClassLoader();
URL imageUrl = cl.getResource("resources/images/sprites/MyImage.png");
Once you have a URL for the image you can turn that in to an InputStream if you need to.
InputStream imageStream = imageUrl.openStream();

Related

Java Swing Icon wont show up [duplicate]

I tried this way, but it didnt changed?
ImageIcon icon = new ImageIcon("C:\\Documents and Settings\\Desktop\\favicon(1).ico");
frame.setIconImage(icon.getImage());
Better use a .png file; .ico is Windows specific. And better to not use a file, but a class resource (can be packed in the jar of the application).
URL iconURL = getClass().getResource("/some/package/favicon.png");
// iconURL is null when not found
ImageIcon icon = new ImageIcon(iconURL);
frame.setIconImage(icon.getImage());
Though you might even think of using setIconImages for the icon in several sizes.
Try putting your images in a separate folder outside of your src folder. Then, use ImageIO to load your images. It should look like this:
frame.setIconImage(ImageIO.read(new File("res/icon.png")));
Finally I found the main issue in setting the jframe icon. Here is my code. It is similar to other codes but here are few things to mind the game.
this.setIconImage(new ImageIcon(getClass().getResource("Icon.png")).getImage());
1) Put this code in jframe WindowOpened event
2) Put Image in main folder where all of your form and java files are created e.g.
src\ myproject\ myFrame.form
src\ myproject\ myFrame.java
src\ myproject\ OtherFrame.form
src\ myproject\ OtherFrame.java
src\ myproject\ Icon.png
3) And most important that name of file is case sensitive that is icon.png won't work but Icon.png.
this way your icon will be there even after finally building your project.
This works for me.
frame.setIconImage(Toolkit.getDefaultToolkit().getImage(".\\res\\icon.png"));
For the export jar file, you need to configure the build path to include the res folder and use the following codes.
URL url = Main.class.getResource("/icon.png");
frame.setIconImage(Toolkit.getDefaultToolkit().getImage(url));
Yon can try following way,
myFrame.setIconImage(Toolkit.getDefaultToolkit().getImage("Icon.png"));
Here is the code I use to set the Icon of a JFrame
import javax.imageio.ImageIO;
import java.io.File;
import java.io.IOException;
try{
setIconImage(ImageIO.read(new File("res/images/icons/appIcon_Black.png")));
}
catch (IOException e){
e.printStackTrace();
}
Just copy these few lines of code in your code and replace "imgURL" with Image(you want to set as jframe icon) location.
JFrame.setDefaultLookAndFeelDecorated(true);
//Create the frame.
JFrame frame = new JFrame("A window");
//Set the frame icon to an image loaded from a file.
frame.setIconImage(new ImageIcon(imgURL).getImage());
I'm using the following utility class to set the icon for JFrame and JDialog instances:
import java.awt.*;
import java.io.IOException;
import java.io.InputStream;
import java.net.URISyntaxException;
import java.util.Scanner;
public class WindowUtilities
{
public static void setIconImage(Window window)
{
window.setIconImage(Toolkit.getDefaultToolkit().getImage(WindowUtilities.class.getResource("/Icon.jpg")));
}
public static String resourceToString(String filePath) throws IOException, URISyntaxException
{
InputStream inputStream = WindowUtilities.class.getClassLoader().getResourceAsStream(filePath);
return toString(inputStream);
}
// http://stackoverflow.com/a/5445161/3764804
private static String toString(InputStream inputStream)
{
try (Scanner scanner = new Scanner(inputStream, "UTF-8").useDelimiter("\\A"))
{
return scanner.hasNext() ? scanner.next() : "";
}
}
}
So using this becomes as simple as calling
WindowUtilities.setIconImage(this);
somewhere inside your class extending a JFrame.
The Icon.jpg has to be located in myproject\src\main\resources when using Maven for instance.
I use Maven and have the structure of the project, which was created by entering the command:
mvn archetype:generate
The required file icon.png must be put in the src/main/resources folder of your maven project.
Then you can use the next lines inside your project:
ImageIcon img = new ImageIcon(getClass().getClassLoader().getResource("./icon.png"));
setIconImage(img.getImage());
My project code is as below:
private void setIcon() {
setIconImage(Toolkit.getDefaultToolkit().getImage(getClass().getResource("/slip/images/cage_settings.png")));
}
frame.setIconImage(new ImageIcon(URL).getImage());
/*
frame is JFrame
setIcon method, set a new icon at your frame
new ImageIcon make a new instance of class (so you can get a new icon from the url that you give)
at last getImage returns the icon you need
it is a "fast" way to make an icon, for me it is helpful because it is one line of code
*/
public FaceDetection() {
initComponents();
//Adding Frame Icon
try {
this.setIconImage(ImageIO.read(new File("WASP.png")));
} catch (IOException ex) {
Logger.getLogger(FaceDetection.class.getName()).log(Level.SEVERE, null, ex);
}
}'
this works for me.

Java Source in many Directorys above

i have a JavaFX project with many packages. i wanted to create a folder with all my icons within. the icon path is: src/icon/test.png and my class, where i try to initialize my Image, is: src/project/menus/ressources/settings/SettingWindow.java.
my problem is, that i am not able to get to the root folder, into the icon folder.
here is my source for the SettingWindow:
package project.menus.ressources.settings;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.stage.Stage;
public class SettingWindow{
#FXML private TextField nameTF;
#FXML private Button pinButton;
private Stage stage;
public void setStage(Stage stage) {
this.stage = stage;
/*-----------------Here where i try to initialize the Image -------------*/
Image icon = new Image("file: /icon/test.png", 25,25, false, false);
pinButton.setGraphic(new ImageView(icon));
}
/*-----------------------------------------------------------------------*/
public TextField getNameField() {
return this.nameTF;
}
}
"file: /icon/test.png" is not the only thing i tried. i found somewhere a solution to get the root directory with getRoot() but i couldnt use this method.
I cant use the AbsolutPath to the folder, because its planed to use this software on different PC's
In my experience, the most flexible approach for finding resources is to use an InputStream and allow the classloader to find the object. So, based upon the statement that the resource (the image) is in the src folder, and presuming that said src folder is fully added to the classpath, then something like the following might work.
Note: I am assuming the .setGraphic(new ImageView(icon)) is correct -- I'm not overly familiar with JavaFX.
private void loadAndDisplayImage(Button btn) {
final String name = "icon/test.png";
ClassLoader cl = this.getClass().getClassLoader();
//
// use the try with resources, and allow the classloader to find the resource
// on the classpath, and return the input stream
//
try (InputStream is = cl.getResourceAsStream(name)) {
// the javafx Image accepts an inputstream, with width, height, ratio, smoot
Image icon = new Image(is, 25, 25, false, false);
// should probably ensure icon is not null, but presumably if the resource
// was found, it is loaded properly, so OK to set the image
btn.setGraphic(new ImageView(icon));
}
catch (IOException e) {
e.printStackTrace();
}
}
Then call the loadAndDisplayImage(pinButton); method from the setStage(...)
I think this approach is a bit more flexible than trying to code the URL.
Do not expect the source directory to be available at runtime the same way they were before building your program.
Often the compilation results are compressed with the resources to a jar file. The contents of a jar file are not accessible via the file system. Instead you should use a Class.getResource get the url of a resource and pass it to the Image constructor. (This only works if the resources are available via classpath, but if they are available, it works whether they are packed in a jar or not):
Image icon = new Image(SettingWindow.class.getResource("/icon/test.png").toExternalForm(),
25, 25, false, false);

Accessing Images from image folder in JAVA

I'm beginner to java GUI. And want to access images from the folder but i'm getting the following error.
My Code
import java.awt.Image;
import javax.swing.ImageIcon;
public class Images {
private static String IMG_FOLDER = "C:/Users/RASHID/workspace/images/";
public static Image ICON = getImage(IMG_FOLDER + "icon.png");
private static Images instance;
private Images() {}
public static Images getInstance() {
if(instance==null)
instance = new Images();
return instance;
}
public static Image getImage(String image){
return getImageIcon(image).getImage();
}
public static ImageIcon getImageIcon(String image){
return new ImageIcon(getInstance().getClass().getClassLoader().getResource(image));
}
}
When i try to run this one in main i get the following Errors. I don't know whats happening here.
Exception in thread "main" java.lang.ExceptionInInitializerError
Caused by: java.lang.NullPointerException
at javax.swing.ImageIcon.<init>(Unknown Source)
at Images.getImageIcon(Images.java:38)
at Images.getImage(Images.java:34)
at Images.<clinit>(Images.java:9)
You don't use classloaders to fetch files from hard drive. Instead, you need to fetch them as Files and transform to Images first:
File sourceimage = new File("c:\\mypic.jpg");
Image image = ImageIO.read(sourceimage);
return new ImageIcon(image);
(taken directly from this site - take a look)
You are trying to construct ImageIcon object using a constroctur that takes URL paramter (because getResource() method returns URL object, and by the way in this case it returns null, hence NullPointerException)
You should use ImageIcon(String filename) constructor instead, which will create ImageIcon from the file specified.
Read from Local Folder
File sourceimage = new File("c:\\picture_name.jpeg");
Image image = ImageIO.read(sourceimage);

Displaying an imageicon in eclipse doesn't work

So I've just written down some simple code that just displays an image in a JButton.
What I have done is write the code:
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Main extends JFrame{
public static ImageIcon bf;
public static JPanel p;
public static JButton b;
public static void main (String args[]){
Main main = new Main();
bf = new ImageIcon("car.png");
p = new JPanel();
b = new JButton(bf);
p.add(b);
main.add(p);
main.setVisible(true);
main.setDefaultCloseOperation(main.EXIT_ON_CLOSE);
main.setSize(600,700);
}
}
And I have copied a pic named car.png in the same folder with my class, but I can't seem to get it to work in elipse.
But when I run the same exact code in BlueJ it runs it without any known issues.
Any help woul be greately apprecciated
Thanks In advance.
change
bf = new ImageIcon("car.png");
to
URL url = Main.class.getResource("car.png");
bf = new ImageIcon(url);
Check that if car.png is under the bin directory in the filesystem (it is filtered out in Eclipse, so do it in a file explorer).
Btw I would suggest using something like ImageIO.read(Main.class.getResource("/car.png")). The reason is the following: later on you will probably package your app (into a Jar file for example). Now if you do it this way, Java is able to locate the image even if it is executed as a Jar or from

Loading resources (images) contained in a .Jar file or in the classpath

So I've tried various reading various fixes for this problem on stack exchange most say to use getResourceAsStream() method, which I have done.
This is my Resource input method for the Jar .
import java.io.InputStream;
public class ResourceLoader {
public static InputStream load(String path){
InputStream input = ResourceLoader.class.getResourceAsStream(path);
if(input == null){
input = ResourceLoader.class.getResourceAsStream("/" + path);
}
return input;
}
}
This is then used in my ImageLoader class.
public class ImageLoader {
public BufferedImage load(String path){
try {
// return ImageIO.read(getClass().getResource(path));
return ImageIO.read(ResourceLoader.load(path));
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
and the images are loaded in the main program using
ImageLoader loader = new ImageLoader();
spriteSheet = loader.load("/spritesheet.png");
Now in eclipse the game runs and loads all images perfectly fine.
But what I want to do is export it to Jar, which I have done using some tutorials and
have succeeded in exporting it with the resource folder which contains my images that are used. But when I try and run the .jar file this error pops up in the cmd line.
Exception in thread "Thread-2" java,lang.IllegalArgumentException: input == null
!
at javax.imageio.ImageIO.read<Image.IO.java:1348>
at gfx.ImageLoader.load<ImageLoader.java:15>
at man.Gaim.init(Game.java:100>
at main.Game.run<Game.java:150>
at java.lang.Thread.run<Thread.java:722>
So what I'm gathering is that the image file locations are not being read properly or I inputed them wrong somehow which is returning null and none of the images are loading. When the .Jar is run the Panel appears but nothing is painted to it and that error is given.
This program does work perfectly in eclipse with no errors and all images loading.
EDIT 1:
Robermann your solution for the getClass().getClassLoader().getResourceAsStream(path)) works. The only thing is I need to have the image files in a folder with the jar.
For instance I have
Folder:
---File.Jar
---Images.png
---ImageFolder
-------More imgaes in imagefolder.png
I can load all the images when they are located like that. My actual question was when i export a .Jar the Images are also located inside is it possible to just use the images that are located inside the .jar? Or do I have to pack the imgaes in a folder alongside the jar as above, It works but i was more looking for a runnable .Jar that i could just transer to tohers without having them also need the images outside the .jar.
The question of how to load classpath resources is quite recurring, and a bit confusing for a Java newbie: some answers suggest class.getClassLoader().getResourceAsStream, others class.getResourceAsStream, although they have a slight different semantic:
class.getResourceAsStream does a path translation
class.getClassLoader().getResourceAsStream does not translate the path
For better show the difference, I'm going to propose the following test class, which in 4 different ways try to load the same resource (an image), only 2 working depending on the used path. The Jar content-tree is:
The class:
package image;
import java.io.InputStream;
public class ImageLoader {
public static void main(String[] args ){
String cmd = null;
InputStream is = null;
final String image = "save.png";
if("test1".equals(args[0])){
cmd = "ImageLoader.class.getClassLoader().getResourceAsStream(\""+image+"\")";
is = ImageLoader.class.getClassLoader().getResourceAsStream(image); //YES, FOUND
}else if("test2".equals(args[0])){
cmd = "ImageLoader.class.getResourceAsStream(\""+image+"\")";
is = ImageLoader.class.getResourceAsStream(image); //NOT FOUND
}else if("test3".equals(args[0])){
cmd = "ImageLoader.class.getResourceAsStream(\"/"+image+"\")";
is = ImageLoader.class.getResourceAsStream("/"+image); //YES, FOUND
}else if("test4".equals(args[0])){
cmd = "ImageLoader.class.getClassLoader().getResourceAsStream(\"/"+image+"\")";
is = ImageLoader.class.getClassLoader().getResourceAsStream("/"+image); //NOT FOUND
}else {
cmd = " ? ";
}
System.out.println("With "+cmd+", stream loaded: "+(is != null));
}
}
Run with:
java -cp resLoader.jar image.ImageLoader test4
Hope this class can help in understanding the different behaviour.

Categories