0

I am currently coding the game of Snake for my computer science class. However, I ran into a lot of difficulties (since I am the only one in my block that is working alone) and I had to restart.

Right now I am just trying to make an array of objects (named Snake) from the second class (Segment) I made.

I get a NullPointerException on line 26: g.fillRect(xValue, yValue, size, size); Where should I get an instance of Graphics to call this method on?

import java.awt.*;
import java.applet.*;

public class Segment extends Applet
{
   private Graphics g;

   private int xValue;
   private int yValue;
   private int size;

   public Segment () {}

  public Segment(int x, int y)
  {
  xValue = x;
  yValue = y;

  size = 10;

  drawSegment(g);
   }

   public void drawSegment(Graphics g)
   {
      g.fillRect(xValue, yValue, size, size);
   }

  }

import java.awt.*;
import java.applet.*;

public class SnakeGame extends Applet
{
   private Segment[] snake;
   private Graphics g;

   private int length;
   private int sxValue;
   private int syValue;

   public SnakeGame()
   {
      length = 6;
      snake = new Segment[length];
      sxValue = 100;
      syValue = 100;

      for (int c = 0; c < snake.length; c++)
      {
         snake[c] = new Segment(sxValue, syValue);
         sxValue = sxValue + 10;     
      }

      drawSnake(g);

    }

   public void drawSnake(Graphics g)
   {
      for(int counter = 0; counter < length; counter++)
      {
          snake[counter].drawSegment(g);

      }  
    }


}

However, I keep getting errors such as

java.lang.NullPointerException
at Segment.drawSegment(Segment.java:26)
at Segment.<init>(Segment.java:21)
at SnakeGame.<init>(SnakeGame.java:22)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:408)
at java.lang.Class.newInstance(Class.java:433)
at sun.applet.AppletPanel.createApplet(AppletPanel.java:799)
at sun.applet.AppletPanel.runLoader(AppletPanel.java:728)
at sun.applet.AppletPanel.run(AppletPanel.java:378)
at java.lang.Thread.run(Thread.java:745)
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
  • Please identify line # **26** in your `Segment.java` file. – PM 77-1 Jun 06 '15 at 20:39
  • 1
    possible duplicate of [What is a Null Pointer Exception, and how do I fix it?](http://stackoverflow.com/questions/218384/what-is-a-null-pointer-exception-and-how-do-i-fix-it) – PM 77-1 Jun 06 '15 at 20:39
  • @PM77-1 this refenrence surely helps, but doesn't solve the problem. The `null` object is identified, but it's not clear how to get an instance. – Nick Volynkin Jun 06 '15 at 20:55
  • @NickVolynkin : I had such [concern](http://meta.stackoverflow.com/questions/283306/rapid-closing-of-java-lang-nullpointerexception-questions) once. Apparently community at large does not want to spoon feed answers for each particular case. – PM 77-1 Jun 06 '15 at 21:14
  • @PM77-1 maybe it would be good in such cases to explicitly ask "why does `a` have null value?", clearly pointing at the string and variable which produce an exception. This job wasn't done in this question by the OP, so your flag was an appropriate one. – Nick Volynkin Jun 06 '15 at 21:22

2 Answers2

1

You declare Graphics g; and do not instantiate it. So you pass a null value to drawSegment(Graphics g) and try to call g.fillRect(xValue, yValue, size, size); on that null object.

The java.awt.Graphics class you're using is just an abstract class. The object needs to be instantiated with some implementation - either by you or the framework.

Since you're using an Applet, which inherits the Component, try Component.getGraphics() to get a graphics object.

private Graphics g = getGraphics();

Then, you call drawing methods in constructors. That's not a good practice. Instantiating an object (an applet, here) and drawing it is not the same.

Also, each class here has its own variable for Graphics. It seems that a single instance should be used for all drawing, passed to each drawable object.

Nick Volynkin
  • 14,023
  • 6
  • 43
  • 67
  • I have always declared Graphics g; in my past codes, since it has never worked without it in the past for me... but what should I pass to drawSegment then, that's where I am getting super confused. – Ciara Larence Jun 06 '15 at 20:46
  • @CiaraLarence did it work in the past codes? Did you instantiate that object somehow? – Nick Volynkin Jun 06 '15 at 20:54
  • It worked in the past codes, since in a different snake class (restarted, so its an old one now) I declared Graphics g, and then the first time it was used was g.setColor(color) but I never actually instantiated. the segment class will run with no errors now, but nothing shows up in the applet. and when I run the SnakeGame class, I get all of my errors. – Ciara Larence Jun 06 '15 at 21:00
  • @CiaraLarence well, calling any method on a `null` object could never run without an exceptiion. Try the code from the last edit. – Nick Volynkin Jun 06 '15 at 21:03
  • How would I make it not a null object? the coding from my old class wont work since I am trying a completely different approach to making the game. That's why I am getting stuck. My teacher had me restart, and gave me the task of just getting the snake array to be drawn. – Ciara Larence Jun 06 '15 at 21:06
  • @CiaraLarence I've pointed at the mistakes that I could see, but it is not enough. Maybe it would be useful to look at some working code and understand how it works. Sorry, cannot help more. – Nick Volynkin Jun 06 '15 at 21:17
1

Get a Graphics object from within the paint(Graphics) or paintComponent(Graphics) method of the custom painted component. That time (when requested to do so by the JVM) is the time that an AWT/Swing GUI should be painted. See Performing Custom Painting for more details and working source.

General tips/questions.

  1. Why code an applet? If it is due to the teacher specifying it, please refer them to Why CS teachers should stop teaching Java applets.
  2. Why use AWT? See this answer for many good reasons to abandon AWT using components in favor of Swing.
  3. It is generally considered better to do custom rendering in a Panel, Canvas or JPanel that is added to the top level container, rather than the container itself. This is more easily adaptable in that we might show the panel in an applet, frame, dialog or a layout constraint of another panel. There are also other advantages.
  4. There are two applets above, but only SnakeGame should be an applet. The Segment class should instead just know how to draw itself to a Graphics object when asked to do so. Then SnakeGame can store a list of Segment objects and (when requested) draw each in turn.
  5. Don't declare a constructor for an applet, since there is no way to ensure it is called on the Event Dispatch Thread. Do everything 'the first time only' in the init() method. But seriously, avoid applets as they are an obsolescent technology that will give you nothing but headaches.
Community
  • 1
  • 1
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433