简体   繁体   中英

NullPointerException

After compiling my application in Netbeans and running the application in Netbeans it works just fine.

All images load fine.

Trying to double click execute the application results in nothing happening.

Trying run from command line gives this error:

Exception in thread "main" java.lang.NullPointerException
     at Entity.<init>(Entity.java:24)
     at Actor.<init>(Actor.java:5)
     at TileEngine.drawMap(TileEngine.java:52)
     at GraphicsCanvas.<init>(GraphicsCanvas.java:32)
     at Main.<init>(Main.java:22)
     at Main.main(Main.java:18)

Compiling outside of Netbeans leaves no errors and execution is fine.

After trial and error of commenting I've came to these the anonymous call to Actor that is causing the problem. Here is function of the code that when commented out does not throw the exception. I cant seem to find anything wrong with it.

public class Actor extends Entity
{
    Actor(String filename, int x, int y)
    {
        super(filename, x, y);
    }
}


void drawMap(String imgWalkable, String imgNotWalkable, GraphicsCanvas gp)
    {
        // Since each 1 tile is a tile that can be walked on
        // we need to set the 1 tile to something you can walk on.
        // The tiles that cannot be walked on are the ones that are 0

        for (int x = 0; x < WID; x++)
        {
            for (int y = 0; y < HEI; y++)
            {
                if (GRID[x][y] == 1)
                    gp.add(new Actor(imgWalkable, x * TILE_WID, y * TILE_HEI));
                //else
                    //gp.add(new Actor(imgNotWalkable, x * TILE_WID, y * TILE_HEI));
            }
        }
    }

I have further traced this error to BufferedImage in my Entity class.

public class Entity extends JLabel
{
    Entity(String filename, int x, int y)
    {
        this.x = x;
        this.y = y;
        this.setLocation(this.x, this.y);
        bImg = loadImage(filename);
        this.setSize(bImg.getWidth(), bImg.getHeight());
        ImageIcon icon = new ImageIcon(bImg);
        setIcon(icon);
    }

    public BufferedImage loadImage(String filename) {
        BufferedImage tmp = null;
        try {
            tmp = ImageIO.read(getClass().getResource(filename));
        } catch (Exception e) { }
        return tmp;
    }
}

After removing loadImage function and instead loading the image like this:

Entity(String filename, int x, int y)
    {
        try {
        bImg = ImageIO.read(getClass().getResource(filename)); //LINE 25
        } catch (IOException ex) {
            Logger.getLogger(Entity.class.getName()).log(Level.SEVERE, null, ex);
        }

        this.x = x;
        this.y = y;
        this.setLocation(this.x, this.y);
        //bImg = loadImage(filename);
        //loadImage(bImg, filename);
        this.setSize(bImg.getWidth(), bImg.getHeight());
        Icon icon = new ImageIcon(bImg);
        setIcon(icon);
        setVisible(isAlive);
    }

This new error is received:

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException: input == null!
     at javax.imageio.ImageIO.read(ImageIO.java:1362)
     at Entity.<init>(Entity.java:25)
Entity.<init>(Entity.java:24)

This tells you that the exception is being thrown at line 24 of "Entity.java". YOU DON'T TELL US WHICH LINE THAT IS (tsk, tsk, tsk!!) ... but I expect it is this one:

this.setSize(bImg.getWidth(), bImg.getHeight());

and that it is happening because loadImage is returning null .

Another problem (though not the cause of the NPE) is that the following line uses this.x and this.y before they have been initialized. In fact, the constructor doesn't initialize them at all!!

Yet another problem is that your loadImage method is explicitly coded to catch and ignore exceptions, and return null . So basically, if the image read does fail for any reason, you will never know about it. This casts considerable doubt on your assertion that the image is being successfully loaded. And even if this is not the cause of your problem, squashing exceptions like that is extremely bad practice .

this.setLocation(this.x, this.y);

EDIT

The problem is now in this line:

bImg = ImageIO.read(getClass().getResource(filename)); //LINE 25

and the problem is that getClass().getResource(filename) is returning null and passing it to ImageIO.read which is throwing the NPE as a result. The javadoc for Class.getResource(String) says that the method returns null if the resource cannot be found.

THAT is your problem. If you don't believe this diagnosis, add some traceprints to see what getClass().getResource(filename) actually returning.

Is the fileName being passed to loadImage a relative path? If so, it could successfully load the image from within the IDE but not from outside it. That would let the file load correctly within the IDE but may result in a null pointer exception from other environments. If that is the case, using an absolute path may fix the issue.

If you use getResource() , like you are doing in the line where the error now happens:

bImg = ImageIO.read(getClass().getResource(filename));

then Java will look for the file to load on the classpath. What does filename contain? Is it in the right place so that it can be found relative to the classpath?

Also, catching and ignoring exceptions, as you're doing in your Entity.loadImage() method:

try {
    tmp = ImageIO.read(getClass().getResource(filename));
} catch (Exception e) { }

is one of the worst sins you can commit as a Java developer. Don't do that; at least log the exception, handle it some other way, or declare that the method it happens in throws it. For example:

// Declare that the method might throw IOException
public BufferedImage loadImage(String filename) throws IOException {
    // ...

    // No need to try / catch the exception now
    tmp = ImageIO.read(getClass().getResource(filename));
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM