ImageIcon with external images in a jar - java

I'm doing my university project, and it runs on my IDE, but when i try to run it directly from a jar, it doesn't load any images at all. So i created a resources folder in my proyect, but apparently, it's not working, because i'm not sure of how to call them. I already read a lot of posts using the "getClass().getResource()" method, but it's giving me a null pointer exception. Any help guys? I'm leaving my code:
(Btw, it's a megaman game):
public GameObject(int x,int y, int velX,int velY,String archivo){
this.x = x;
this.y = y;
this.velX = velX;
this.velY = velY;
principal = new ArrayList<ImageIcon>();
ImageIcon imagen = new ImageIcon(archivo);
principal.add(imagen);
mono = new JLabel(principal.get(0));
mono.setBounds(this.x,this.y,mono.getIcon().getIconWidth(),mono.getIcon().getIconHeight());
}
This is my main "Sprite" code, i just create other sprites which extends from this class. The "Archivo" variable, it's a string where the .png file is, here i'm putting an example of how i'm calling it:
public MegamanSprite(int x, int y) {
super(x, y, 1, 1, "src/Resources/megamanpd.png");
}
and here it's an image of how i have my folders in my Eclipse project:
I already tried using this:
public GameObject(int x,int y, int velX,int velY,String archivo){
this.x = x;
this.y = y;
this.velX = velX;
this.velY = velY;
principal = new ArrayList<ImageIcon>();
ImageIcon imagen = new ImageIcon(getClass().getResource(archivo));
principal.add(imagen);
mono = new JLabel(principal.get(0));
mono.setBounds(this.x,this.y,mono.getIcon().getIconWidth(),mono.getIcon().getIconHeight());
}
but this is giving me a null pointer exception, and without it it's not. Any help will be really apreciated. Thanks in advance!

You need to get your resource as stream. This will get you an InputStream which you can use to load your image from a jar.
Get the class of your object as a Class using the getClass()
Use the getResourceAsStream() to get an InputStream. Remember, your src folder will disappear in a jar. JB Nizet pointed that out.
Then use ImageIO.read() and pass the InputStream to get back a BufferedImage
BufferedImage is an Image and hence you can cast it to a variable of type Image. So, do that.
ImageIcon has a constructor that has a constructor which accepts an Image.
You are done !

It’s hard to guess when the only thing we have is a screenshot but by looking at your icons I have the suspicion that you Resources folder is excluded from the build path. In this case it is not copied to the bin folder and therefore not accessible by getResource invocations.
Try right-clicking on the Resources folder and choosing “Build Path”→“Include” from the popup menu. The icon should change from a generic folder to a package-like icon (it will look different from packages containing classes though). Then a GameObject.class.getResourceAsStream( "Resources/megamanpd.png"); should work from within Eclipse.
If the build path is set up correctly, generating a jar should get the right default setup but it seems that including the src/Resources/ folder additionally to the bin contents has been added manually. So you might have to fix the setup manually. Regenerating the jar with the default setup should now work to get a jar in which getResource works correctly.

Related

Why are images in my IntelliJ IDEA project accessible to some Java classes but aren't to others in JavaFX?

I'm working on a simple 2D game in JavaFX, and I loaded some of my assets (just a bunch of folders and images) into my project into their own directory, and went to make another Java class for all the stuff the player needs (movement, keypress, loading player assets), and none of the images are loading. Does anyone know why? I have the code I know is causing the problem below.
class Player
{
public Player() throws FileNotFoundException
{
System.exit(-1);
}
Image leftSide = new Image(new FileInputStream("resources/player/leftNO.png");
ImageView leftSideView = new ImageView(leftSide);
}
My directory is listed below:
.idea
out
resources
player
leftNO.png
rightNO.png
src
sample
Main.java
Player.java
Anyone know why this is happening? Thanks in advance, even if you don't have an answer.
EDIT: Also, I forgot to mention that when I try to open the image in the Main.java class, it loads fine.
When you say not loading, do you mean that it throws an exception or is blank?
Depending on which, this could work:
Mark your resources directory as a source folder and try
class Player
{
public Player() throws FileNotFoundException
{
System.exit(-1);
}
Image leftSide = new Image(getClass().getResourceAsStream("/player/leftNO.png");
ImageView leftSideView = new ImageView(leftSide);
}
This will also allow you app to work from within a jar

After buiding java app, some GUI components does not work properly, but during IDE tests everything is fine. Why?

I am working on GUI java project which contains FileChooser(combined with JLabel it becomes ImageChooser) and JTextArea (inside of JScrollPane). Both of these components are inside of JPanel.
When ever I ran it inside of IntelliJ Idea (version 2017.2.4)everything works fine:
UI when executed from IDE
But if I build Artifacts and create .jar file, then image inside of JLabel is not initialized and the size(height) of JTextArea becomes minimal(though minimal value is set to 200):
IU when executed from .jar file
I suspect that ImageIcon cannot be initialized due to relative path I provide:
...
imagePath = "src/main/resources/" + item.getImageName();
//item.getImageName() returns a proper image name, tested with
//System.out.println() and there is a proper image in that folder.
ImageIcon img = new ImageIcon(imagePath);
img = ImageManager.resize(img);
...
//Resize function in ImageManager class
public static ImageIcon resize(ImageIcon imageIcon, int size){
return resize(imageIcon, size, size);
}
public static ImageIcon resize(ImageIcon icon){
return resize(icon, defaultSize);
}
However, I've tried options with relative path like main/resources/ and /main/resources/ , but none of them worked both in IDE and .jar executable.
Is it a problem with a path?
If yes, why does it affect JTextArea's size?
P.S.
JTextArea's size becomes normal if there is an image in JLabel.
You are right, the way you fetch resources is problematic in a jar.
The way you should access them:
ImageIcon img = new ImageIcon(this.getClass().getClassLoader().getResource(item.getImageName()));
This method supports relative paths. Just make sure your src/main/resources directory is properly marked as a 'Resource Root' in IntelliJ IDEA.

Java applet AccessControlException issue

I am having problems with my new Java applet.
public Speler() {
this.x = 10;
this.y = 470;
hitBox = new Rectangle( x, y, 52, 10 );
spaceShip = new ImageIcon( "images/spaceship.png" );
}
In my project's src folder, I have some .png images which need to be loaded in. In Eclipse AppletViewer this works just fine, however in my browser it does not.
I have already searched the internet and tried signing it, however this didn't help.
Any help would be appreciated, however I just started programming in Java, so I don't know an awful lot!
new ImageIcon( "images/spaceship.png" );
That constructor presumes the String represents a File path. It cannot work for an applet from a web site since a File can only ever point to a resource on the client computer where the applet is running.
For an applet, instead access resources by URL. The URL might be constructed relative to the code base or document base of the applet, or from a Jar on the run-time class-path of the applet. If an applet is digitally signed and declares all-permissions, it can even reach across sites to fetch images, as long as the external site allows hot-linking.

getResourceAsStream() returning null in jar but fine in eclipse

I have a program in Java using LWJGL. It runs fine in Eclipse, but when I try to compile it as a jar file it crashes, giving me a NullPointerException. It's been asked before, I know, but I don't seem to get an answer that works. Any help here? Thanks in advance!
The thing that seems to be having the problem is the class TextureHelper:
public class TextureHelper {
public static Texture LoadTexture(String texture)
{
try {
return TextureLoader.getTexture("PNG", ResPlaceholder.class.getResourceAsStream(texture));
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
}
Some notes:
I've also tried "/res/" + texture, as well as many other things like it.
ResPlaceholder is a class that sits in the res folder where I store all my images. It's a blank empty class.
This works perfectly in Eclipse.
My jar has these folders (just as an example):
foo.jar
----core
--------TextureLoader
----res
-------- Assorted Image Files
-------- ResPlaceholder
This is the same as the packages in eclipse.
Any help you have would be appreciated, I've been stuck on this for days with no progress.
EDIT:
META-INF/MANIFEST.MF
Main.class config/
config/Images.class
core/
core/LevelLoader.class
core/TextureHelper.class
core/TileSet.class
-Skipping some other stuff that has nothing to do with this-
res/
res/ResPlaceholder.class
res/BlankImg.png
res/test.txt
res/testImg.png
res/testTiles.png
If the path String is something like: /res/testImg.png it should work.
i.e.,
String resourcePath = "/res/testImg.png";
InputStream inStream = ResPlaceholder.class.getResourceAsStream(resourcePath );
BufferedImage img = ImageIO.read(inStream);
// use the img BufferedImage here
// for example:
ImageIcon icon = new ImageIcon(img);
JOptionPane.showMessageDialog(null, icon);
As an aside, it's always good to test problems and check new concepts in small test programs. In your case, I would create a small simple program with just a main method that attempts to extract a jar's image resource and display it in an option pane much like my small code above does. I'd try to avoid long lines and instead separate each step on its own line, again similar to my post above. This way if an exception is thrown, the code on the line will be much more informative as to what is causing the error.

Images in Applet not showing in web page

I am trying to display a JPEG image and a moving dot on a Java applet which I am using on a web based application. However, when I run the applet it works fine, but when I display the applet from the JSP page, I get the moving dot but not the JPEG image.
Is there a specific folder where the JPEG needs to be?
These are the 2 methods i use for drawing the picture and the moving dot on the screen.
public class mapplet extends Applet implements Runnable {
int x_pos = 10;
int y_pos = 100;
int radius = 20;
Image img, img2;
Graphics gr;
URL base;
MediaTracker m;
#Override
public void init() {
mt = new MediaTracker(this);
try {
//getDocumentbase gets the applet path.
base = getCodeBase();
img = getImage(base, "picture.jpg");
m.addImage(img, 1);
m.waitForAll();
} catch (InterruptedException ex) {
Logger.getLogger(movement.class.getName()).log(Level.SEVERE, null, ex);
}
public void paint (Graphics g) {
g.drawImage(img, 0, 0, this);
// set color
g.setColor (Color.red);
// paint a filled colored circle
g.fillOval (x_pos - radius, y_pos - radius, 2 * radius, 2 * radius);
}
The code one below is the call from the jsp page
<applet archive="mapplet.jar" code="myapplets/mapplet.class" width=350 height=200>
</applet>
The jar file and the picture are in the same folder as the jsp page, and there is also a folder containing the contents of the class and image of the applet in the web section of the application. The applet loads fine however the picture doesn't display. I think it's not the code but the location of the picture that is causing a problem.
Thanks
Yes, the image should be in the same folder as the source code. I would recommend to do a folder called images and inside it put all your images and just change "picture.jpg" to "\images\picture.jpg". Check your website directory to see if the image is in the same folder as the source code.
Some comments that might make it more clear for you.
//getDocumentbase gets the applet path.
No. getDocumentBase() provides the path to the web page. But that is neither here, nor there, since this applet actually calls..
base = getCodeBase();
..which provides the codebase. The codebase defaults to the directory of the web page, unless a codebase parameter is specified in the applet element. Since the applet element declares no codebase, the base will be the same URL as the document base.
BTW: In the applet element
code="myapplets/mapplet.class"
..should be..
code="myapplets.mapplet"
And since common nomenclature for Java class names is EachWordUpperCase, the class name should be changed.
Doe the applet declare?
package myapplets;
BTW (2):
there is also a folder containing the contents of the class and image of the applet in the web section of the application.
What does that mean? Please provide complete paths from the root of the server to all resources (e.g. the HTML/JSP, Jar file & image) used.
please check your path ..or to resolve it please put your files inside a folder and pack it with JAR file.and provide the relative path of image files inside your jar.
Like:
let your applet name is myapp.class in package demoapp
then put your files in dir "images" inside demoapp and provide path relative to this path in all your java code.
dont forget to include image files in jar build.

Categories

Resources