BufferImage Nullpointers while using a 2D BufferImage Array

Basically, what I’m trying to accomplish here is to import an image, and then cut it up into numerous images, which are squares. (A Tile-Sheet, if you will) and then render it back to the screen, however, I’m running into some issues, these issues, being nullpointers.

Please excuse my personal conventional methods, as I prefer to align my brackets.

package com.lpstudios.mapeditor;

import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

public class SpriteSheet 
{

	public int xSize, ySize;
	
	public int rows, columns;
	
	public BufferedImage spriteSheet;
	
	public BufferedImage[][] sprites;
	
	public SpriteSheet(String dir, int xSize, int ySize)
	{
		this.xSize = xSize;
		this.ySize = ySize;
		try 
		{
			this.spriteSheet = ImageIO.read(new File(dir));
			this.rows = this.spriteSheet.getHeight() / this.ySize;
			this.columns = this.spriteSheet.getWidth() / this.xSize;
			
			for(int xAxis = 0; xAxis < this.columns; xAxis++)
			{
				for(int yAxis = 0; yAxis < this.rows; yAxis++)
				{
					try 
					{
						sprites[xAxis][yAxis] = spriteSheet.getSubimage(xAxis * this.xSize, yAxis * this.ySize, this.xSize, this.ySize);
					} 
					catch(NullPointerException e)
					{
						System.out.println("[Error]: Null while Loading");
					}
				}
			}
			
		} 
		catch(IOException e)
		{
			e.printStackTrace();
		}
		
		sprites = new BufferedImage[columns][rows];
		System.out.println(sprites.length);
	}
	
	public void render(Graphics g) 
	{
		for(int xAxis = 0; xAxis < this.columns; xAxis++)
		{
			for(int yAxis = 0; yAxis < this.rows; yAxis++)
			{
				try 
				{
					g.drawImage(sprites[xAxis][yAxis], xAxis * this.xSize, yAxis * this.ySize, this.xSize, this.ySize, null);
				} 
				catch(NullPointerException e)
				{
					System.out.println("[Error]: Null while Drawing");
				}
			}
		}
	}
	
}


The above code when constructed will throw some NullPointer errors while loading, however, some tiles will still come out, while using my image of choice, the length of the sprites array comes out to equal 16 at 32x32, and 64 at 8x8, however when I try to draw this (See render(Graphics g)), it does not throw any errors, however it does not draw anything, strange right?

Now, I tried to debug this, by tossing this code in the render() method below the drawImage code.

System.out.println(sprites[xAxis][yAxis].toString());

Which made it then throw the null-pointer, I’m not sure what’s going on with this, ideas?

You need to move your line that says

sprite = new BufferedImage[columns][rows]

to be before you add anything to your array. You’re trying to populate it before giving it a size, so those indices don’t exist.
That’s all I noticed.*

*I am not nearly at good as Java or it’s rules as most of the people around here, but with my limited knowledge of the actual workings of Java, that’s how I understand it to work.

Unless I’m missing something really obvious you are created the sprites array at the bottom of the constructor after you have tried to load the various sprite chunks, it should be near the top after you have calculated the number of rows and columns.


public class SpriteSheet 
{
...   
   
   public SpriteSheet(String dir, int xSize, int ySize)
   {
         ...

         this.rows = this.spriteSheet.getHeight() / this.ySize;
         this.columns = this.spriteSheet.getWidth() / this.xSize;
         
         // CREATE 2D ARRAY HERE
         sprites = new BufferedImage[columns][rows];

         for(int xAxis = 0; xAxis < this.columns; xAxis++)
         {
            for(int yAxis = 0; yAxis < this.rows; yAxis++)
            {
                ...
  
// NOT HERE    
//      sprites = new BufferedImage[columns][rows];

...


As an aside, it might be better to pass in the required number of rows and columns and calculate the width-height of each chunk rather than the other way around, that way your sprite sheet can be used for arbitrary sized images. As things stand you sort of need to know how big it is before calling the method which sort of defeats the point.

Hope this helps.

  • stride