Setting imageIcon without full path - java

I'm trying to st the icon on a Jlabel but I get "NullPointerException" every time I run it. It does run while I put in the full path but I don't want to do that because I want to move the java programme around the environment.
jLabel1.setIcon(new ImageIcon(this.getClass().getResource("/data/images/image.jpg")));
I believe the problem is in the path I'm trying to use.
My rough project environment is:
projectfolder/src
projectfolder/data/images/image.jpg
I've tried using:
/image.jpg
/data/images/image.jpg
data/images/image.jpg
.\\data\\images\\image.jpg
What am I doing wrong?

Class#getResource() returns the resource relative to your class' location. Use ClassLoader#getResource() instead. If using the default class loader, it returns the resource relative to the classpath of your program.
this.getClass().getClassLoader().getResource("data/images/image.jpg")
You should place your data folder inside the src folder. Otherwise the data folder is not contained in the program's .jar.

Related

Java file path f.exists() always returns false

I'm trying to create a basic Java program that allows the user create files and folders.
I want all this to happen in a folder inside my project (image attached) so I've got some doubts...
This would be my proyect tree
Is the folder "Test" correctly placed? if not how do i access to it? As you see, it's inside com.company, should I move it to src?
When I try to check if exists, it says false.
This is my code:
public class Main {
Scanner input = new Scanner(System.in);
public static void main(String[] args) {
Main main = new Main();
main.init();
}
public void init(){
File f = new File("Test"); //Here i've tried "com"+File.separator+"company"+File.separator+"Test"
System.out.println(f.exists()); //output is false here
}
}
f.getParent() says null.
But when I try: System.out.println(f.getAbsolutePath()); it shows correctly the whole path.
The point of using relative path is because i'd like this code to work on ANY computer.
Thanks in advice, hope someone could help me a bit.
If you use relative pathnames in Java, they will be resolved relative to the running application's working directory. So you need to know what the working directory is going to be.
When you are launching an application in an IDE, the working directory depends on the IDE and the launcher configs. But it is typically the file system directory that corresponds to the top of the project.
Another thing to note is that the src folder you see is special. The entries in it are typically not files and directories. The are typically Java packages and classes. So in the file system, "src" > "com.company" > "Main" is actually represented as a file with the path "src/com/company/Main.java".
This means that it is kind of wrong to put arbitrary folders and files into the "src" folder. It will work ... but it is conceptually wrong. Data files don't belong in the source tree, and certainly not data files written by your application. (And when you start using a source control system, you will find that writing data files into your source tree is going to give you a headache. I won't go into details ... but I am pretty sure that you would regret it.)
The other thing that is conceptually wrong about what you are doing is that Java programs are normally written to be free standing things. The user of your program should not need to download and install Intellij or some other IDE and load your project into it. They will want to just run it from a JAR file. In that world, the project directory and the "src" folder won't exist, and hardwiring relative paths like "src/Test" will be problematic.
So lets ignore that for now and look at what your code is currently doing
Is the folder "Test" correctly placed? if not how do i access to it? As you see, it's inside com.company, should I move it to src?
According to the image, the Test folder (actually package) >>is<< in the src Folder.
When I try to check if exists, it says false.
Your code is using the wrong path. With the "Test" folder places where you have it (according to the picture!), the relative path should be "src/Test", not "Test" or "com/company/Test".
Note that Windows accepts either "/" or "\" will work as a file separator, even though "\" is what is used conventionally.
f.getParent() says null.
That is correct. The relative path "Test" does not have a parent part. It is a simple file / directory name.
Think of it this way. Until a File with a relative path is resolved, it is not determined what directory it is relative to.
But when I try: System.out.println(f.getAbsolutePath()); it shows correctly the whole path.
Again, correct.
When you call f.getAbsolutePath() on a relative File, the runtime system prepends the path of the application's working directory, and then gives you the result.
The point of using relative path is because I'd like this code to work on ANY computer.
That relative path will NOT work on ANY computer. You are using a path that is within your project's src tree, and your project typically won't exist on an end-user's computer. (See above.)
So what should you do?
There is no single correct answer.
You could put the file / directory into the user's current / working directory.
You could put the file / directory into the user's home directory, or a hidden subdirectory in the home directory. (This is a common approach on Linux.)
You could make the pathname for the directory a command line argument
You could get the pathname from an environment variable
You could get the pathname from an application specific config file.
The best answer will depend on the context.
According to your picture the path is wrong, you should check inside the src directory:
File f = new File("src/Test");
System.out.println(f.exists());

What path to put inside .getResource()

[Java]
I am having trouble figuring which String to put inside variable s below.
return new ImageIcon(getClass().getResource(s));
I do know that I need to put the path here, but I don't know the format.
This is the full path of the image I am trying to import (which didn't work):
Users/Kevin1031/eclipse-workspace/B-Tring/bin/textures/Center_Ring_0.png
I am using Mac OS, and B-Tring is the project folder, textures is the package, and Center_Ring_0.png is the image I want to import and use.
So, can someone tell me what path to put in?
first try the full absolute path with / at the beginning
/Users/Kevin1031/eclipse-workspace/B-Tring/bin/textures/Center_Ring_0.png
I don't know about Eclipse, I work in IntelliJ, where if you cofigure a folder as "resources" in the module settings, you can reference from there. f.e. if you would set bin/ as resourcer the path would be /textures/Center_Ring_0.png.
Third option is to use a relative path. f.e. if you call the method from B-Tring/src/foo.java try something like ../textures/Center_Ring_0.png. Notice not starting with the slash

Relative path does not work

I'm trying to reconstruct Tetris in JavaFX.
My project is called TetrisProject (C:\Users\Matthias\IdeaProjects\OOPROG\TetrisProject)
Inside Main there is a problem with getting resources. (C:\Users\Matthias\IdeaProjects\OOPROG\TetrisProject\tetris\src\be\kdg\tetris\Main.java)
public class Main extends Application {
primaryStage.getIcons().add(new Image("tetris\\resources\\images\\icon.png")
}
icon.png is the icon I want to set for my windows. (C:\Users\Matthias\IdeaProjects\OOPROG\TetrisProject\tetris\resources\images\icon.png)
tetris\\resources\\images\\icon.png should be the relative path since
File f = new File(".");
System.out.println(f.getAbsolutePath());
run inside Main.java outputs C:\Users\Matthias\IdeaProjects\OOPROG\TetrisProject\.
The relative path I wrote for icon.png is correct, right?
The path is not a file path, it's a URL for the resource.
The documentation says "If the passed string is not a valid URL, but a path instead, the Image is searched on the classpath in that case." Presumably resources is a source folder, so the path would need to be simply images/icon.png:
primaryStage.getIcons().add(new Image("images/icon.png"));
You can check by looking at what is in the output/build/bin folder (whatever your IDE calls it). Depending on how your IDE is configured to handle the resources directory, the image should be copied there, and that is where the Image constructor will be looking at runtime. (Your source folders, obviously, at generally not accessible at runtime.)

How can I find my resource image

I am trying to load an image into a JLabel using:
java.net.URL imgURL =Thread.currentThread().getContextClassLoader().getResource("MyLogo.png");
However, I always get a null pointer. I have tried every combination of my folder structure I could think of.
This is where file is on my c: drive, but I want to run as webapp.
C:\Users\JoJo\Eclipse\workspace1\proj1\src\main\resources\Images\MyLogo.png
I have tried things like:
src/main/resources/Images/MyLogo.png
java.net.URL imgURL =Thread.currentThread().getContextClassLoader().getResource("/main/resources/Images/MyLogo.png");
That should do it.
As far as I know, The first / in the path indicates it should search inside the .jar file.
you need to add the directory to the class path
my advice is to add another folder in proj1 called resources and copy the image into it like so:
C:\Users\JoJo\Eclipse\workspace1\proj1\resources\Images\MyLogo.png
then you go in the project settings and set the classpath to include the C:\Users\JoJo\Eclipse\workspace1\proj1\resources\ folder, then you can use /Images/MyLogo.png

Why is my BufferedImage receiving a null value from ImageIO.read()

BufferedImage = ImageIO.read(getClass().getResourceAsStream("/Images/player.gif"));
First of all, yes I did add the image folder to my classpath.
For this I receive the error java.lang.IllegalArgumentException: input == null!
I don't understand why the above code doesn't work. From everything I read, I don't see why it wouldn't. I've been told I should be using FileInputStream instead of GetResourceAsStream, but, as I just said, I don't see why. I've read documentation on the methods and various guides and this seems like it would work.
Edit: Okay, trying to clear some things up with regards to what I have in the classpath.
This is a project created in Eclipse. Everything is in the project folder DreamGame, including the "Images" folder. DreamGame is, of course, in the classpath. I know this works because I'm reading a text file in /Images with info on the gif earlier on in the code.
So I have: /DreamGame/Images/player.gif
Edit 2: The line that's currently in the original post is all that's being passed; no /DreamGame/Images/player.gif, just /Images/player.gif. This is from a method in the class ImagesLoader which is called when an object from PlayerSprite is created. The main class is DreamGame. I'm running the code right from Eclipse using the Run option with no special parameters
Trying to figure out how to find which class loader is loading the class. Sorry, compared to most people I'm pretty new at this.
Okay, this is what getClassLoader() gets me: sun.misc.Launcher$AppClassLoader#4ba778
getClass().getResource(getClass().getName() + ".class") returns /home/gixugif/Documents/projects/DreamGame/bin/ImagesLoader.class
The image file is being put in bin as well. To double check I deleted the file from bin, cleaned the project, and ran it. Still having the same problem, and the image file is back in bin
Basically, Class.getResourceAsStream doesn't do what you think it does.
It tries to get a resource relative to that class's classloader - so unless you have a classloader with your filesystem root directory as its root, that won't find the file you're after.
It sounds like you should quite possibly really have something like:
BufferedImage = ImageIO.read(getClass().getResourceAsStream("/Images/player.gif"))
(EDIT: The original code shown was different, and had a full file system path.)
and you make sure that the images are copied into an appropriate place for the classloader of the current class to pick up the Images directory. When you package it into a jar file, you'd want the Images directory in there too.
EDIT: This bit may be the problem:
First of all, yes I did add the image folder to my classpath.
The images folder shouldn't be in the classpath - the parent of the Images folder should be, so that then when the classloader looks for an Images directory, it will find it under its root.
If you use resourceAsStream "/" referes to the root of the classpath entry, not to the root of the file system. looking at the path you are using this might be the reason.
If you load something from some home path you probably should use a FileInputStream. getResourceAsStream is for stuff that you deploy with your app.

Categories