user3161533
user3161533

Reputation: 487

Java: simple but unusual NullPointerException

I'm stuck on something that is usually really simple. I'm getting a NullPointerException when calling this simple class's constructor:

import java.awt.geom.*;

public class Brick extends ColorShape {
        private int xPos = 0;
        private int yPos = 0;
        private int width = 0;
        private int height = 0;
        private Rectangle2D.Double shape;

        // constructor
        public Brick(int x, int y, int w, int h) {
            super(new Rectangle2D.Double(x, y, w, h));

            //set brick x, y, width, and height
            xPos = x;
            yPos = y;
            width = w;
            height = h;

            // update shape
            shape.setRect((double)xPos, (double)yPos, (double)width, (double)height);
        }

        public int getX() {
            return xPos;
        }

        public Rectangle2D.Double getShape() {
            return shape;
        }
    }

It gets called this way:

for (int i = 0; i < numCols; i++) {
            for (int j = 0; j < numRows; j++) {

                // initialize bricks[i][j]
                bricks[i][j].setLocation((double)(i*brickWidth), (double)(j*brickHeight));
                bricks[i][j].setSize((double)brickWidth, (double)brickHeight);
                //bricks[i][j] = new Brick(i*brickWidth, j*brickHeight, brickWidth, brickHeight);
                //bricks[i][j] = new Brick(0, 0, 0, 0);
            }
        }

No matter what I try, I always get a NullPointerException trying to initialize that class.

EDIT:

Tristan's suggestions along with changing the nested for loops to the code below fixed it

// create new bricks and store them in bricks array
        for (int i = 0; i < numCols; i++) {
            for (int j = 0; j < numRows; j++) {


                // initialize bricks[i][j]
                //bricks[i][j].setLocation((double)(i*brickWidth), (double)(j*brickHeight));
                //bricks[i][j].setSize((double)brickWidth, (double)brickHeight);
                bricks[i][j] = new Brick(i*brickWidth, j*brickHeight, brickWidth, brickHeight);
                //bricks[i][j] = new Brick(0, 0, 0, 0);
            }
        }

Upvotes: 0

Views: 126

Answers (2)

Brett Nelson
Brett Nelson

Reputation: 83

As mentioned by Tristan, the problem with the initial brick constructor is that shape has been declared but not instantiated.

That said, it is simple to instantiate shape:

public Brick(int x, int y, int w, int h) {
    super(new Rectangle2D.Double(x, y, w, h));

    //set brick x, y, width, and height
    xPos = x;
    yPos = y;
    width = w;
    height = h;
    // update shape
    // This now references a protected instance variable inherited from the parent.
    shape = (Rectangle2D.Double)super.shape;
    shape.setRect(xPos, yPos, width, height);
}

Upvotes: 0

Tristan
Tristan

Reputation: 2399

I think you are accidentally redeclaring shape as an uninitialized field. The shape you are calling setRect on has not been initialized the way you think it has.

If you have a shape in the parent class that you are trying to access, simply set its modifier to protected and remove the private shape declaration in the class you posted.

/* REMOVE THIS */
private Rectangle2D.Double shape; // uninitialized!

// constructor
public Brick(int x, int y, int w, int h) {
    super(new Rectangle2D.Double(x, y, w, h));

    //set brick x, y, width, and height
    xPos = x;
    yPos = y;
    width = w;
    height = h;
    // update shape
    // This now references a protected instance variable inherited from the parent.
    shape.setRect((double)xPos, (double)yPos, (double)width, (double)height);
}

However looking through this constructor, it seems rather off. If it is the case that the parent class has a shape itself, why do you need to set the rectangle any differently than the way you set it in the parent class?

For example, this code appears to be logically equivalent.

// Call the parents constructor to set the shape of this brick..
public Brick(int x, int y, int w, int h) {
    super(new Rectangle2D.Double(x, y, w, h));
}

Upvotes: 2

Related Questions