What path to put inside .getResource() - java

[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

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());

Setting imageIcon without full path

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.

Path, relative, direct

I know there were several similar questions, however, examples in them don't make things clear or I can't make profit of them - Shame on me.
So my problem is with loading images in simple app with GUI.
e.g.:
I got images in "D:\javaeclipseprog\Graphics\src\images", class and java files in "D:\javaeclipseprog\Graphics\src\app"
When I use direct path: "D:/javaeclipseprog/Graphics/src/images/icon.jpg" everything works, but as good practice I would like to get them from relative path, which as far as I know should be: "./images/icon.jpg".
Unfortunately it doesn't work.
Any help appreciated, thanks in advance.
When you are running it in eclipse, your default working directory in the project directory. That is the directory where srcis located in. In your example the project directory is:
D:/javaeclipseprog/Graphics
Therefore the correct path is:
./src/images/trophy.png
Edit: Just want to add that you could also load a file via a path relative to the class location by using the getResource method.
../../images/icon.jpg should work fine
You're going two folders up and go straight to the right folder.
Paths
A simple way to check this would be to use the Paths and Path classes and methods.
Path p1 = Paths.get("D:\\javaeclipseprog\\Graphics\\src\\app\\java.class");
Path p2 = Paths.get("..\\..\\images\\icon.jpg");
System.out.println(p1.resolve(p2).normalize()); // D:\javaeclipseprog\Graphics\src\images\icon.jpg
I'll use the inverted slash because it seems that you use windows. In this case .\ indicates that the same directory where the code is, will have the file you want to use. If you want to jump into the father of that directory, the one that contains the source, you'll use ..\
You can even do it more tan once, for example ..\..\ would be a valid path. Try adding quantities of ..\ in order to look for the directory you want. In this chase ..\src\images\icon.jpg (the parent on a java project is src)
Another important thing is that you're using / instead of \\ that would be the symbol of the directory separator on windows (\ is an special char that must be scaped using an aditional \) For portability i'd use:
String sep = System.getProperty("file.separator");
String path = ".."+sep+"src"+sep+"images"+sep+"icon.jpg"
I think what you need to use is "../images/icon.jpg".
Using it like you have it will look in the current directory, which unless I'm understanding it incorrectly, is "D:\javaeclipseprog\Graphics\src\app".

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.

Java (maven web app), getting full file path for file in resources folder?

I'm working with a project that is setup using the standard Maven directory structure so I have a folder called "resources" and within this I have made a folder called "fonts" and then put a file in it. I need to pass in the full String file path (of a file that is located, within my project structure, at resources/fonts/somefont.ttf) to an object I am using, from a 3rd party library, as below, I have searched on this for a while but have become a bit confused as to the proper way to do this. I have tried as below but it isn't able to find it. I looked at using ResourceBundle but that seemed to involve making an actual File object when I just need the path to pass into a method like the one below (don't have the actual method call in front of me so just giving an example from my memory):
FontFactory.somemethod("resources/fonts/somefont.ttf");
I had thought there was a way, with a project with standard Maven directory structure to get a file from the resource folder without having to use the full relative path from the class / package. Any advice on this is greatly appreciated.
I don't want to use a hard-coded path since different developers who work on the project have different setups and I want to include this as part of the project so that they get it directly when they checkout the project source.
This is for a web application (Struts 1.3 app) and when I look into the exploded WAR file (which I am running the project off of through Tomcat), the file is at:
<Exploded war dir>/resources/fonts/somefont.ttf
Code:
import java.io.File;
import org.springframework.core.io.*;
public String getFontFilePath(String classpathRelativePath) {
Resource rsrc = new ClassPathResource(classpathRelativePath);
return rsrc.getFile().getAbsolutePath();
}
In your case, classpathRelativePath would be something like "/resources/fonts/somefont.ttf".
You can use the below mentioned to get the path of the file:
String fileName = "/filename.extension"; //use forward slash to recognize your file
String path = this.getClass().getResource(fileName).toString();
use/pass the path to your methods.
If your resources directory is in the root of your war, that means resources/fonts/somefont.ttf would be a "virtual path" where that file is available. You can get the "real path"--the absolute file system path--from the ServletContext. Note (in the docs) that this only works if the WAR is exploded. If your container runs the app from the war file without expanding it, this method won't work.
You can look up the answer to the question on similar lines which I had
Loading XML Files during Maven Test run
The answer given by BobG should work. Though you need to keep in mind that path for the resource file is relative to path of the current class. Both resources and java source files are in classpath

Categories