-2

I am getting a NullPointerException on an image that I have loaded. When I render the image using a JFrame everything works, however, my goal is to load each pixel into an ArrayList that contains the RBG color of that pixel. Whe nI try to use getRGB(x,y) I receive a NullPoint Exception. I have marked in the comments on the code where the error occurs. I will load my code, thank you for your time and help!

    public static void populateMapNode(BufferedImage image)
    {
        int width = image.getWidth();
        int height = image.getHeight();
        int pixel;
        int i = 0, j= 0;
        System.out.println("width = " + width);
        System.out.println("height = " + height);
        pixel = image.getRGB(j, i); //error occurs here
        System.out.println("pixel = " + pixel); 
        MapNodes.add(new MapNode(new ArrayList<MapNode>(), new MapNode(), j, i, pixel, 0, 0, 0, 0, null));
        System.out.println("do i get here?");
        for (i = 0; i < height; i++) {
            for (j = 0; j < width; j++) {
              pixel = image.getRGB(j, i);
              MapNodes.add(new MapNode(MapNode.neighbors, MapNode.neighbors.get(j-1), j, i, pixel, 0, 0, 0, 0, null));
            }
          }
    }

    public static void loadMap() //if I just go to the JFrame the picture loads.
    {
        //Util.loadImage("AntWorld.png", null);
        BufferedImage antMap = Util.loadImage("AntWorld.png", new Container());
        populateMapNode(antMap);
        JFrame frame = new JFrame();
        frame.getContentPane().setLayout(new FlowLayout());
        frame.getContentPane().add(new JLabel(new ImageIcon(antMap)));
        frame.pack();
        frame.setVisible(true);
        //System.out.println(Util.manhattanDistance(MapNode.x, MapNode.y, MapNode.parent.x, MapNode.parent.y));
    }

public static void main(String[] args) 
{
    loadMap();
}

/* helper class Util for loadImage */

import java.awt.Container;
import java.awt.MediaTracker;
import java.awt.image.BufferedImage;
import java.net.URL;

import javax.imageio.ImageIO;

public class Util
{
  /**
   * Loads a image file with the given path into a new bufferedImage. Blocks
   * until the image has finished loading. widit is the component on which the
   * images will eventually be drawn.
   * 
   * @return A buffered image containing the loaded image.
   */
  public static BufferedImage loadImage(String imagePath, Container widgit)
  {
    if (imagePath == null) return null;

    if (widgit == null)
    {
      widgit = new Container();
    }

    // Create a MediaTracker instance, to montior loading of images
    MediaTracker tracker = new MediaTracker(widgit);

    BufferedImage loadedImage = null;
    URL fileURL = null;

    try
    { // System.out.println("imagePath="+imagePath);

      imagePath = "resources/" + imagePath;
      fileURL = new URL("file:" + imagePath);

      loadedImage = ImageIO.read(fileURL);

      // Register it with media tracker
      tracker.addImage(loadedImage, 1);
      tracker.waitForAll();
    }
    catch (Exception e)
    {
      System.out.println("Cannot Open image: " + imagePath);
      e.printStackTrace();
      System.exit(0);
    }
    return loadedImage;
  }

/**************** Stack Trace ***************************/

Exception in thread "main" java.lang.NullPointerException
    at custom.MapNode.<init>(MapNode.java:32)
    at custom.Demo.populateMapNode(Demo.java:56)
    at custom.Demo.loadMap(Demo.java:72)
    at custom.Demo.main(Demo.java:91)

/***************MapNode *********************************/

package custom;

import java.util.*;
import java.io.*;

public class MapNode implements Comparable <MapNode>
{
    public static List<MapNode> neighbors = new ArrayList<MapNode>(); //Used for creating a path for an ant to follow
    public static MapNode parent = null;
    public static int x, y; //x and y coordinates for each map node (i.e. pixel)
    private int pixelWeight; //the weight or cost of each pixel based off it's color
                             //this can also be modified to contain the color of food or water
    private int hCost; // the heuristic cost from this node to another
    public int gCost; // determines which node has a smaller weight based off the pixelWeight
    private int fCost;
    private int rCost;
    private boolean isOccupied; //determines whether or not the node is occupied by food/ant/water/sea/nest

    public MapNode(Object object, Object object2, int j, int i, int rgb, int k, //These match up to corresponding variables listed above.
            int l, int m, int n, Object object3) 
    {
        MapNode.neighbors = (List<MapNode>) object;

        this.parent = (MapNode) object2;
        this.x = j;
        this.y = i;
        this.pixelWeight = rgb;
        this.hCost = k;
        this.gCost = l;
        this.fCost = m;
        this.rCost = n;
        this.isOccupied = (boolean) object3;
        // TODO Auto-generated constructor stub
    }
    public MapNode() {
        // TODO Auto-generated constructor stub
    }
    public MapNode(int x, int y) {
        this.x = x;
        this.y = y;
        // TODO Auto-generated constructor stub
    }
    /* getter and setter land starts here */
    /* getter then setter/variable */
    public int getPixelWeight(){return pixelWeight;}
    public void setPixelWeight(int pixelWeight){this.pixelWeight = pixelWeight;}

    public int getHCost(){return hCost;}
    public void setHCost(int hCost){this.hCost = hCost;}

    public int getFCost(){return fCost;}
    public void setFCost(int fCost){this.fCost = fCost;}

    public int getRCost(){return rCost;}
    public void setRCost(int rCost){this.rCost = rCost;}

    public boolean getIsOccupied(){return isOccupied;}
    public void setIsOccupied(boolean isOccupied){this.isOccupied = isOccupied;}

    /* end of getter and setter land */

    private int setHCost(MapNode end){return Math.abs(this.x - end.x) + Math.abs(this.y - end.y);} //finds heuristic cost from current node to destination

    private int setGCost(int prevGCost, int prevValue) 
    {
        if (prevValue > pixelWeight) return 1;
        if (prevValue < pixelWeight) return 2;
        return 1;
    }

    private int setRCost()
    {
        return 0;
    }

    public void setCosts(MapNode end, int prevGCost, int prevValue) 
    {
        this.hCost = setHCost(end);
        this.gCost = setGCost(prevGCost, prevValue);
        this.rCost = setRCost();
        this.fCost = this.hCost + this.gCost + this.rCost;
    }

    public boolean isPassable() //this needs to modified to determine multiple forms of occupiedness descibed in variable
    {
        if (this.pixelWeight > 255) return false;
        return true;
    }

    public boolean isAbove(MapNode a) //determines open nodes above the ant(or will this be a pixel?)
    {
        return (a.y - this.y == -1) && (a.x == this.x);
    }

    public boolean isBelow(MapNode a) //determines open nodes below the ant(or will this be a pixel?)
    {
        return (a.y - this.y == 1) && (a.x == this.x);
    }

    public boolean isLeft(MapNode a) 
    {
        return (a.x - this.x == -1) && (a.y == this.y); //determines open nodes left of the ant(or will this be a pixel?)
    }

    public boolean isRight(MapNode a) //determines open nodes right of the ant(or will this be a pixel?)
    {
        return (a.x - this.x == 1) && (a.y == this.y);
    }

    public boolean isNE(MapNode a) //determines open nodes northeast of the ant(or will this be a pixel?)
    {
        return (a.x - this.x == 1) && (a.y - this.y == -1);
    }

    public boolean isSE(MapNode a) //determines open nodes southeast of the ant(or will this be a pixel?)
    {
        return (a.x - this.x == 1) && (a.y - this.y == 1);
    }

    public boolean isNW(MapNode a) //determines open nodes northwest of the ant(or will this be a pixel?)
    {
        return (a.x - this.x == -1) && (a.y - this.y == -1);
    }

    public boolean isSW(MapNode a) //determines open nodes southwest of the ant(or will this be a pixel?)
    {
        return (a.x - this.x == -1) && (a.y - this.y == 1);
    }

    public void SetNeighbors(List<MapNode> nodes) //determines the neighbors of the current MapNode,  
    {                                             //if MapNode is not passible then the node is not added to the neightbors list
        int count = 0;
        for (MapNode n : nodes) 
        {
            if (n.isPassable()) 
            {
                if (isAbove(n) || isBelow(n) || isLeft(n) || isRight(n) || 
                    isNE(n)    || isSE(n)    || isNW(n)   || isSW(n)) 
                {
                    count++;
                    this.neighbors.add(n);
                }
            }
            if (count == 8) break; //8 directional nodes to look at
        }
    }

    /* http://stackoverflow.com/questions/15175109/equals-method-in-java */
    @Override
    public boolean equals(Object o) 
    {
        if (!(o instanceof MapNode)) return false;
        if (this.x == ((MapNode) o).x && this.y == ((MapNode) o).y) return true;
        return false;
    }

    /* http://docs.oracle.com/javase/tutorial/collections/interfaces/order.html */
    public static Comparator<MapNode> CompareNodes = new Comparator<MapNode>() 
    {
        @Override
        public int compare(MapNode a, MapNode b) 
        {
            // return (a.fCost > b.fCost ? 1 : (a.fCost == b.fCost ? 0 : 1));
            if (a.fCost > b.fCost) return +1;
            else if (a.fCost < b.fCost) return -1;
            else return 0;
        }
    };

    @Override
    public int compareTo(MapNode o) {
        // TODO Auto-generated method stub
        return 0;
    }

}
vector
  • 199
  • 1
  • 4
  • 17
  • 1
    There's no need to use `MediaTracker` when you use `ImageIO`. `ImageIO` won't return until the image is fully realised (or will throw an `IOException` if it can't be loaded – MadProgrammer Sep 03 '14 at 01:40
  • `pixel = image.getRGB(j, i);` in `populateMapNode` can't be the point of the error, as the stack trace clearly states that the `MapNode` constructor (line 32) is the point of the error... – MadProgrammer Sep 03 '14 at 01:41
  • Given the stacktrace you posted, the error is inside the constructor of MapNode, which source is not given, and happens two lines below where you indicated the error occurs. I don't even think it's related to the image pixels at all. Can you post the source of MapNode? – Simone Gianni Sep 03 '14 at 01:41
  • @Simone Gianni - I have added MapNode. Thank you. – vector Sep 03 '14 at 02:15

1 Answers1

0

Okay, so you constructor MapNode with...

MapNodes.add(new MapNode(new ArrayList<MapNode>(), new MapNode(), j, i, pixel, 0, 0, 0, 0, null));

And then you do this within the constructor...

this.isOccupied = (boolean) object3;

object3 is the last parameter to the constructor, to which you pass null

new MapNode(
    new ArrayList<MapNode>(), 
    new MapNode(), 
    j, 
    i, 
    pixel, 
    0, 
    0, 
    0, 
    0,
    null // Look ma, I'm null!!
)
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366