Whenever i try to draw an image with paintComponent and ImageIcon i get a NullPointerException from an unknown source, then pointing to my image getter and the thread start.
Image getter
ImageIcon image = new ImageIcon(this.getClass().getResource("C:/Users/Rhys/Desktop/workspace/Mindcracker RPG/Res/Background.jpg"));
Thanks for any answers
Use the JavaDoc:
this.getClass().getResource() only for acquiring resources on the ClassPath where / represents the default package.
You are supplying a fully qualified path which won't work.
What you need to do is use this constructor:
public ImageIcon(String filename)
Creates an ImageIcon from the specified file.
The specified String can be a file name or a file path. When
specifying a path, use the Internet-standard forward-slash ("/") as a
separator. (The string is converted to an URL, so the forward-slash
works on all systems.)
For example, specify:
new ImageIcon("C:/Users/Rhys/Desktop/workspace/Mindcracker RPG/Res/Background.jpg");
note that there is a space in the path there and this path eventually gets converted into a file::// URL so you might want to take that into consideration
Related
I want to load a font in a SWT. My ttf file is in the resources/fonts directory of my Maven project. I try to load it like this:
URL fontURL = MyClass.class.getResource("/fonts/myfont.ttf");
boolean fontLoaded = display.loadFont(fontURL.getPath());
But the resulting boolean is always false. I tried to prompt the result of fontURL.getPath(), and it is something like /C:/Users/myuser/Documents/.... If I copy this result in a String, remove the first / and try to call display.loadFont() with it, it works.
Another weird thing is that this is not the only resource I load this way. For example, this is how I load the icon of the window:
URL iconURL = MyClass.class.getResource("/images/myicon.png");
Image icon = new Image(display, iconURL.getPath());
shell.setImage(icon);
And it works fine. The only file posing problem is the font file. Does anybody know why ?
The reason for / at the beginning is that getPath of the URL class returns the URL path defined by RFC 2396 (see javadocs).
As for why it's working for the Image constructor and not for loadFont() method, the answer can be found in the implementation.
The constructor uses FileInputStream which internally normalizes the path, whereas loadFont() has a native implementation for loading which does not support such path.
Since in both cases a file path is expected, what you want to do is normalize the path yourself using either File constructor or Paths.get(url.toURI()).toString() method.
I am trying to load an image to use as an icon in my application. The appropriate method according to this tutorial is:
protected ImageIcon createImageIcon(String path, String description)
{
java.net.URL imgURL = getClass().getResource(path);
if (imgURL != null) {
return new ImageIcon(imgURL, description);
} else {
System.err.println("Couldn't find file: " + path);
return null;
}
}
So, I placed the location of the file, and passed it as a parameter to this function. This didn't work, i.e. imgURL was null. When I tried creating the ImageIcon by passing in the path explicitly:
ImageIcon icon = new ImageIcon(path,"My Icon Image");
It worked great! So the application can pick up the image from an explicitly defined path, but didn't pick up the image using getResources(). In both cases, the value of the path variable is the same. Why wouldn't it work? How are resources found by the class loader?
Thanks.
getClass().getResource(path) loads resources from the classpath, not from a filesystem path.
You can request a path in this format:
/package/path/to/the/resource.ext
Even the bytes for creating the classes in memory are found this way:
my.Class -> /my/Class.class
and getResource will give you a URL which can be used to retrieve an InputStream.
But... I'd recommend using directly getClass().getResourceAsStream(...) with the same argument, because it returns directly the InputStream and don't have to worry about creating a (probably complex) URL object that has to know how to create the InputStream.
In short: try using getResourceAsStream and some constructor of ImageIcon that uses an InputStream as an argument.
Classloaders
Be careful if your app has many classloaders. If you have a simple standalone application (no servers or complex things) you shouldn't worry. I don't think it's the case provided ImageIcon was capable of finding it.
Edit: classpath
getResource is—as mattb says—for loading resources from the classpath (from your .jar or classpath directory). If you are bundling an app it's nice to have altogether, so you could include the icon file inside the jar of your app and obtain it this way.
As a noobie I was confused by this until I realized that the so called "path" is the path relative to the MyClass.class file in the file system and not the MyClass.java file. My IDE copies the resources (like xx.jpg, xx.xml) to a directory local to the MyClass.class. For example, inside a pkg directory called "target/classes/pkg. The class-file location may be different for different IDE's and depending on how the build is structured for your application. You should first explore the file system and find the location of the MyClass.class file and the copied location of the associated resource you are seeking to extract. Then determine the path relative to the MyClass.class file and write that as a string value with "dots" and "slashes".
For example, here is how I make an app1.fxml file available to my javafx application where the relevant "MyClass.class" is implicitly "Main.class". The Main.java file is where this line of resource-calling code is contained. In my specific case the resources are copied to a location at the same level as the enclosing package folder. That is: /target/classes/pkg/Main.class and /target/classes/app1.fxml. So paraphrasing...the relative reference "../app1.fxml" is "start from Main.class, go up one directory level, now you can see the resource".
FXMLLoader loader = new FXMLLoader();
loader.setLocation(getClass().getResource("../app1.fxml"));
Note that in this relative-path string "../app1.fxml", the first two dots reference the directory enclosing Main.class and the single "." indicates a file extension to follow. After these details become second nature, you will forget why it was confusing.
getResource by example:
package szb.testGetResource;
public class TestGetResource {
private void testIt() {
System.out.println("test1: "+TestGetResource.class.getResource("test.css"));
System.out.println("test2: "+getClass().getResource("test.css"));
}
public static void main(String[] args) {
new TestGetResource().testIt();
}
}
output:
test1: file:/home/szb/projects/test/bin/szb/testGetResource/test.css
test2: file:/home/szb/projects/test/bin/szb/testGetResource/test.css
getResourceAsStream() look inside of your resource folder. So the fil shold be placed inside of the defined resource-folder
i.e if the file reside in /src/main/resources/properties --> then the path should be /properties/yourFilename.
getClass.getResourceAsStream(/properties/yourFilename)
Why is following code throwing this exception?
java.lang.IllegalArgumentException: Invalid URL or resource not found
Here is the code:
File ff=new File("images/a.jpg");
if (ff.exists()) {Image ii=new Image(ff.getPath());}
From the Javadocs:
All URLs supported by URL can be passed to the constructor. If the
passed string is not a valid URL, but a path instead, the Image is
searched on the classpath in that case.
The path you get is a relative path, but not (necessarily) relative to the classpath, which is how the Image constructor is interpreting it.
Try
Image ii=new Image(ff.toURI().toURL().toExternalForm());
or, depending on how you have your project structure set up
Image ii=new Image(getClass().getResource("images/a.jpg").toExternalForm());
The second version will work if the image file is packaged along with the application in a jar file.
The code I am using to load the image is:
ImageIO.read(SpriteSheet.class.getResource(path));
The path being the path to the resource. But it would error with IllegalArgumentException. I wondered what might be causing and came to the conclusion that the resource should be added into the same path as the class.
Is it possible to load the image from another folder, like a res folder outside of the bin folder? (folder holding compiled classes)
EDIT:
So i messed around with a few things, and came to a solution. But now I have another problem. Here is my code
File sheet = new File(SpriteSheet.class.getProtectionDomain().getCodeSource().getLocation().getPath());
URI uri = sheet.toURI();
BufferedImage image = ImageIO.read(uri.toURL());
When I try to run it, it gives me an IIOException: Can't read Input File
This means that I can never actually get it work. I tried debugging by prining the URL to the console and this is the URL.
C:\Users\Amma\Abhijeet\Eclipse%20Workspace1\Test%20Game\bin
The %20 comes in the middle. Meaning that the file is and never can be acceesed. Is there anyway I can fix this?
Thanks.
Class.getResource will return null if the resource could not be found or the invoker doesn't have adequate privileges to get the resource.
All variants of ImageIO.read will throw an IllegalArgumentException if they receive a null input.
Take a look at the documentation of the getResource to understand how an absolute resource name is constructed from the given resource named and what are the rules for searching resources.
You can read images from any location as long as you have permissions to do so, the ImageIO.read method accepts a File, URL or InputStream so you have many option to do it.
I use this code to display image that locates outside the my java project, but I got NullPointerException every time and I can only use images that are inside my project directory. why ?
Icon welcomeImg = new ImageIcon(getClass().getResource("D:/img/welcome.png"));
or
Icon welcomeImg = new ImageIcon(getClass().getResource("D://img/welcome.png"));
JLabel welcomingLb = new JLabel(welcomeImg);
You do not need to use the ClassLoader class to access your file since you are giving its full path.
Try instead :
Icon welcomeImg = new ImageIcon("D:/img/welcome.png");
Source : Javadoc of ImageIcon(String filename)
getResource expects the resource to be on the classpath.
If you want to read from a random file, use a File, or use the ImageIcon constructor that takes a file name.
See: Loading resources using getClass().getResource()
Basically when you use getResource it is expecting the file to be on the Classpath. There is also a constructor for ImageIcon that takes a String filename, so you can pass the path to the Icon file directly.
Check out the JavaDoc for ImageIcon
You can try using a File, like so:
File f = new File("C:\\folder\\stuff\\MyFile.class");