Home > Enterprise >  Exception in thread "main" java.lang.NullPointerException: Cannot invoke "java.net.UR
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "java.net.UR

Time:10-24

Not Sure what is wrong. I have the console error,

Exception in thread "main" java.lang.NullPointerException: Cannot invoke "java.net.URL.toExternalForm()" because "location" is null
import java.awt.Color;
    
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.ImageIcon;
import javax.swing.JButton;
    
public class TrippieMain {
    
    public static void main(String[] args) {
        new TrippieMain();
    }

    public TrippieMain(){           
        createUI();
    }

    public void createUI(){
            
        JFrame window = new JFrame();
        window.setSize(800, 600);
        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        window.getContentPane().setBackground(Color.black);
        window.setLayout(null);
            
        JPanel trippiePanel = new JPanel();
        trippiePanel.setBounds(100, 220, 200, 200);
        trippiePanel.setBackground(Color.black);
        window.add(trippiePanel);
            
        ImageIcon trippie = new ImageIcon(getClass().getClassLoader().getResource("trippie200x2001.png"));
            
        JButton trippieButton = new JButton();
        trippieButton.setBackground(Color.black);
        trippieButton.setFocusPainted(false);
        trippieButton.setBorder(null);
        trippieButton.setIcon(trippie);
        trippiePanel.add(trippieButton);
            
        window.setVisible(true);
    }
}

CodePudding user response:

Null Pointer Exceptions are not that hard to fix. Most of the time, the exception message tells you what the problem is. This is not the case for this issue. However, the exception message tells you enough to figure this out.

Long story short, the NullPointerException is thrown because you don't understand how to use getClass().getClassLoader().getResource() in the proper context. For what you are trying to do, you don't even need to use that. You can simply pass a simpler, valid argument to the ImageIcon constructor.

Let's check the ImageIcon constructors to see which one you should use.

ImageIcon(); // Creates an uninitialized image icon.
ImageIcon(byte[]); // Creates an ImageIcon from an array of bytes which were read from an image file containing a supported image format, such as GIF, JPEG, or (as of 1.3) PNG.
ImageIcon(Image); // Creates an ImageIcon from an image object.
ImageIcon(String); // Creates an ImageIcon from the specified file. The String can be a file name or a file path.
ImageIcon(URL); // Creates an ImageIcon from the specified URL.

Based on the argument you are using in your post, it seems you can pass either the file name or the file path directly into the ImageIcon constructor. At worst, you can pass the full path to the image.

If your image is inside your project, one way to get the full path is by using System.getProperty("user.dir"). This property returns the path from where the Java application was launched. This is basically your project. This is a great approach because this path will most likely change. For example, during development, this path can change between developers in a team. Then, when the code is deployed, it will most likely be in a different path. The important thing is that in every case, this path will be resolved by the system automatically for you. You can also pass a relative path from the project's root and should work just the same.

Then, all you need to do is append the relative path to your image for the project's root directory. Do this and your problem will be solved.

So... assuming you have an "images" folder as a subfolder of your project's root directory, you need to replace this line:

 ImageIcon trippie = new ImageIcon(getClass().getClassLoader().getResource("trippie200x2001.png"));

with something like this:

ImageIcon trippie = new ImageIcon("./images/trippie200x2001.png");

or with something like this:

ImageIcon trippie = new ImageIcon(System.getProperty("user.dir")   "/images/trippie200x2001.png");

Using your code with my own image, I was able to successfully launch your application

enter image description here

UPDATE:

In my excitement, I forgot to answer the fundamental question for this issue: How do you fix the location is "null" problem using getClass().getClassLoader().getResource()? This is simple... When you invoke getResource(), the expected behavior is that "resources" must be contained in the src path for your project. Anything not in the classpath, will not be found; hence the NPE.

Since you were passing "trippie200x2001.png", this image is expected to be inside the src folder in your project. For my example, since I was using "images/trippie200x2001.png", the expected behavior is that "images" be a package inside src and the image in question be inside that package (folder).

CodePudding user response:

Resource paths must start with a /

ImageIcon(getClass().getClassLoader().getResource("/trippie200x2001.png"));

  • Related