ImageIcon lost after creating a runnable JAR file - java

The project runs fine when I click play in Eclipse but after I created the runnable JAR file, The ImageIcon for the button is gone.
The images are stored within the src folder, uder a subfolder images.
I created the image icon as
Icon playIcon = (Icon) new ImageIcon("src/images/play.png");
Although I am using a relative path, the button does not display images, How do I get the images even in the JAR file?
Update after Nikolay Kuznetsov's answer
I ended up creating a very unstructured monolithic code for screen recorder and now it is slightly difficult to implement what he said.
I was wondering if there is a way like creating a class or interface that will contain all these resources.
For example:
public class embeddedResources {
public static Icon blackCursor;
public static Icon whiteCursor;
...
...
}
Then all I have to do is import these statics and in my main ScreenRecorder class,
this.blackCursor = embeddedResources.blackCorsor;

I am using this method to read image into BufferedImage where IconManager is class where it is defined.
private static BufferedImage readBufferedImage (String imagePath) {
try {
InputStream is = IconManager.class.getClassLoader().getResourceAsStream(imagePath);
BufferedImage bimage = ImageIO.read(is);
is.close();
return bimage;
} catch (Exception e) {
return null;
}
}

I had the same problem.
Try to make you JAR file and add your images to an extern folder.
So you have a folder "Game" in this folder are the folder for your images called "images" or so and your jar file.
If you now edit you folder path to "../images/play.png" it should work.

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.

How to export my code correctly in Eclipse

I right-click on my project, then select Export, then select Runnable Jar File And then Export, but when I launch it, it just has a clear screen, but in Eclipse it shows my image.
How would I fix this?
I've tried numerous posts and did everything they said to do, but when I try to put the .jar file in the images folder and then launch the jar it still launches with no background image.
I had the same issue. It took me a bit to actually find an answer. Here is the answer I found. Save your images in a seperate folder somewhere in your src folder and add to build path. Then, since the images are static you can just access it like this: blueSprite = ImageLoader.blueSprite; Don't forget to call ImageLoader.loadImages() too.
final public class ImageLoader {
public static BufferedImage blueSprite;
public static InputStream load(String path) {
InputStream input = ImageLoader.class.getResourceAsStream(path);
if (input==null) {
input=ImageLoader.class.getResourceAsStream("/"+path);
}
return input;
}
public static void loadImages() {
try {
blueSprite= ImageIO.read(ImageLoader.load("explosionSheetBlueShort.png"));
} catch (Exception e) {
JOptionPane.showMessageDialog(null, "ERROR LOADING IMAGES. CONTACT ADMIN FOR SUPPORT");
e.printStackTrace();
}
}
}

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.

JLabel doesn't show image

I'm not sure where the problem is. Is it in the path? The image doesn't show although there are no errors at all in the code syntax. Should I provide the whole path or just place the image in the directory and call its name? Thank you.
public class NetworkingGame {
private JFrame jfrm;
NetworkingGame(){
jfrm = new JFrame("Angry Painters");
jfrm.setSize(800, 480);
jfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jfrm.setVisible(true);
}// end of constructor
public void ImageLoading(){
ImageIcon i = new ImageIcon("C:/Users/TOSHIBA/Documents/NetBeansProjects/NetworkingGame/build/classes/angry-painters.jpeg");
JLabel jl = new JLabel(i);
jfrm.add(jl);
}
public static void main(String[] args) throws Exception{
SwingUtilities.invokeLater(new Runnable(){
#Override
public void run(){
NetworkingGame ng = new NetworkingGame();
ng.ImageLoading();
} // end of run method
}); // end of Runnable
}//end of main method
}//end of class NetworkingGame
Do not use the file path as icon location as this will only work on your computer. You really cannot expect all machines in the world to have C:/Users/TOSHIBA ...angry-painters.jpeg in the right place!
Copy the file next to the source code (.java) class you use and then call
new ImageIcon(getClass().getResource("angry-painters.jpeg"));
The builder should copy the image resource to the class folder itself.
Try to use path something like this :
jLabel1.setIcon(new ImageIcon("c:\\Users\\xyz\\Documents\\NetBeansProjects\\game\\src\\images.jpg"));
Update
If dis also does not work, then
jLabel.setIcon(new ImageIcon(getClass().getResource("/image.jpg")));
jLabel.setText("jLabel");
should.The image.jpg should be inside your project folder.
I think your code doesn't like the way your binding the image.
assumes that your put the images/icons in the source folder
ImageIcon i=new javax.swing.ImageIcon(getClass().getResource("myimage.jpeg"))
or if you create a folder in the source folder
InputStream stream = this.getClass().getClassLoader().getResourceAsStream("/images/image.jpg");
BufferedImage bufferedImage=ImageIO.read(stream);
ImageIcon icon= new ImageIcon(bufferedImage);
in IntellijIdea. 2021
In my case it just didn't read image files.
To fix that:
1. make res folder in project root('src's folder sibling)
2. Handle artifact in File->Project Structure->artifacts by + , -
3. File->Project Structure->artifacts->output layout tab make structure of final jar as 'res' folder , app root package folder(say 'com'), and 'META-INF' folder. Fill out them with content from yourapp/output folder and 'res's content from mentioned in 1. step 'res'.
4. After that in 'project structure' 'Modules' rightclick on 'res' and mark it as resources.
5. Declare images like this:
ImageIcon loadingLcl = new ImageIcon(this.getClass().getResource("/res/32.gif"));
before putting into JLabel.
Also it s preferable to read image once when initializing the app. Otherwise sometimes it can throw IOException. So if possible handle that at start. Like they do in gamemaking.

Java: When a program is .jar 'ed, it no longer reads the images in the jar file?

I need it to run without having the files exported to the computer.
At the moment, my code for storing the images is:
ImageIcon icon = new ImageIcon("images\\images2.gif");
It can't just be an image since I'm adding it to a JLabel.
When I jar the entire program, it stores the image files in the jar.
When I go to run the actual problem, there are no images.
Again, I can't just leave the .jar in a folder with the images already. It has to work on a separate computer, by itself.
You'll want to get the image via the system class loader:
URL url = ClassLoader.getSystemClassLoader().getResource("images/images2.gif");
Icon icon = new ImageIcon(url)
images is at the root of the classpath.
Note that the Java runtime will translate the separator (/) to the OS specific separator (\ for Windows).
You need to access those files through class-loader... Something like this:
InputStream is = this.getClass().getClassloader().getResourceAsStream("images/image.ico");
HTH
UPD: note, that this will work both with JARed package and with plain directory structure.
The basic issue is that the File class only knows how to work with what the underlying operating system consider a file, and a whole one.
A jar file is essentially a zip file with some extra information so you cannot use File's with that. Instead Java provides the "resource" concept which roughly translates to "a chunk of bytes or characters which we don't care where is, as long as we have them when we need them". You can ask the class loader for any resource in the class path - which is what you want here - or access it through an URL.
Try this:
ImageIcon icon = new ImageIcon(this.getClass().getClassloader().getResource("images/images2.gif"));
if that doesn't work, replace this.getClass().getClassloader() with MyClass.class where MyClass is the name of your class.
I remember having to edit this slightly to make it work in Eclipse, but when you deploy it, it works like a charm.
Edit: To make it work in Eclipse, you may need to change it to:
ImageIcon icon = new ImageIcon(this.getClass().getClassloader().getResource("bin/images/images2.gif"));
If that doesn't work, do the standard, replace this.getClass().getClassloader() with MyClass.class. If it still doesn't work, try replacing "bin" with "src". Try jar'ing it with the first way and see what happens.
Here is a convenient utility class that can be used for loading image resources. The log4j logger can be removed of changed to whatever is more appropriate.
public class ResourceLoader {
private static final Logger logger = Logger.getLogger(ResourceLoader.class);
public static Image getImage(final String pathAndFileName) {
try {
return Toolkit.getDefaultToolkit().getImage(getURL(pathAndFileName));
} catch (final Exception e) {
logger.error(e.getMessage());
return null;
}
}
public static ImageIcon getIcon(final String pathAndFileName) {
try {
return new ImageIcon(getImage(pathAndFileName));
} catch (final Exception e) {
logger.error(e.getMessage());
return null;
}
}
public static URL getURL(final String pathAndFileName) {
return Thread.currentThread().getContextClassLoader().getResource(pathAndFileName);
}
}
I suppose images2.gif is inside the package images
URL imageurl = getClass().getResource("/images/images2.gif");
Image myPicture = Toolkit.getDefaultToolkit().getImage(imageurl);
JLabel piclabel = new JLabel(new ImageIcon( myPicture ));
piclabel.setBounds(0,0,myPicture.getWidth(null),myPicture.getHeight(null));
If your images are located this way.
Then this should do the job.
private String imageLocation "/images/images2.png";
private ImageIcon getImageIconFromJar(String imageLocation)
{
try
{
BufferedImage bi = ImageIO.read(this.getClass().getResource(imageLocation));
ImageIcon ic = new ImageIcon(bi);
return ic;
} catch (IOException e)
{
System.out.println("Error: "+e);
}
return null;
}

Categories