I cant get it to work! NullPointerExeption at first awt.Graphics Object

I am writing a game with AWT having it as an applet. I intend NOT to use anything outside of Java 1.1

For my Game i thought that i ATLEAST need the following classes:

MainGame, Level, Unit.

I Started writing Level. wrote a fewe methods for it such as

drawGras(int grastype)

And started to write MainGame to see if they would work together. it's is/is going to be my first Java application where i actually know what object orienting is... I have already wrote a game in Java but with out knowing what a class or what object orienting realy is(the game works rather good to) but this time i wanted to use object orienting but came up with problems =( if first posted in "New to Javaprogramming" but they couldn't help me and advice me here

My previous post: http://forum.java.sun.com/thread.jsp?forum=54&thread=290558

--

Here's my code:

import java.awt.*;

publicclass MainGameextends java.applet.Applet

implements Runnable{

Thread runner;

Image ImgLevel, ImgUnit;

public MainGame(){

Level nr1 =new Level();

nr1.init();

nr1.setGround(300);

nr1.drawGras(1);

nr1.CalcGraphics();

nr1.drawSky(1);

Image ImgLevel = nr1.getLevelImage();

}

publicvoid paint(Graphics g){

g.drawImage(ImgLevel,0,0,this);

}

publicvoid update(Graphics g){

paint(g);

}

publicvoid init(){

MainGame Game =new MainGame();

}

publicvoid stop(){

runner =null;

System.exit(1);

}

publicvoid start(){

if(runner ==null){

runner =new Thread(this);

runner.start();

}

}

void Pause(int time){

try{

Thread.sleep(time);

}catch(InterruptedException e){

System.out.println(e.toString());

}

}

publicvoid run(){

Thread thisThread = Thread.currentThread();

while(thisThread == runner){

}

}

}

class Levelextends java.applet.Applet{

Font BigText =new Font("Arial", Font.PLAIN, 36);

Font Normal =new Font("Arial", Font.PLAIN, 14);

Font Bold =new Font("Arial", Font.BOLD, 14);

Graphics GrLevel;

int pattern, sky, GroundtoWalk, Ground;

Color BgColor =new Color(166,202,240);

Color gras1 =new Color(0,255,0);

Color gras2 =new Color(0,200,0);

Color gras3 =new Color(0,100,0);

Image ImgLevel;

void setBgColor(int r,int g,int b){

BgColor =new Color(r,g,b);

}

void CalcGraphics(){

ImgLevel = createImage(800,600);

GrLevel = ImgLevel.getGraphics();

}

void setGround(int GrounD){

Ground = GrounD;

}

void GroundToWalkADD(int addToGround){

GroundtoWalk = Ground + addToGround;

}

void setGroundToWalk(int GrToWalk){

GroundtoWalk = GrToWalk;

}

publicvoid init(){

System.out.println("Init 1");// This was placed here when i was checking how far it got when debuging

CalcGraphics();

System.out.println("Init 2");

drawGras(1);

System.out.println("Init 3");

repaint();

System.out.println("Init 4");

}

Image getLevelImage(){

return ImgLevel;

}

publicvoid paint(Graphics g){

g.drawImage(ImgLevel,0,0,this);

}

publicvoid update(Graphics g){

paint(g);

}

void drawGras(int pt){

GrLevel.setColor(BgColor);

GrLevel.fillRect(0,0,800,600);

switch(pt){

case 1:

GrLevel.setColor(gras1);

GrLevel.fillRect(0,GroundtoWalk,800,300);

GrLevel.setClip(0,GroundtoWalk,800,300);

for(int i = 0; 890>i;i=i+5){

GrLevel.setColor(gras2);

GrLevel.drawLine(0+i,GroundtoWalk,-190+i,GroundtoWalk+300);

}

for(int i=950; 0<i; i=i-5){

GrLevel.setColor(gras3);

GrLevel.drawLine(890-i,GroundtoWalk,1000-i,GroundtoWalk+300);

}

break;

case 2:

GrLevel.setColor(gras2);

GrLevel.fillRect(0,GroundtoWalk+5,800,300);

for(int i = 0; 890>i;i=i+5){

GrLevel.setColor(gras3);

GrLevel.drawLine(0+i,GroundtoWalk,-190+i,GroundtoWalk+300);

}

for(int i=950; 0<i; i=i-5){

GrLevel.setColor(gras1);

GrLevel.drawLine(890-i,GroundtoWalk,1000-i,GroundtoWalk+300);

}

break;

case 3:

GrLevel.setColor(gras3);

GrLevel.fillRect(0,GroundtoWalk+10,800,300);

for(int i = 0; 800>i; i=i+20){

GrLevel.fillArc(0+i,GroundtoWalk,20,20,180,-180);

}

break;

}

pattern = pt;

}

int getGrasPattern(){

return pattern;

}

void drawSky(int cl){

GrLevel.setColor(BgColor);

GrLevel.fillRect(0,0,800,155);

switch(cl){

case 1:

for(int y = 0;y<7;y++){

for(int x = 0;x<800;x=x+20){

GrLevel.setColor(Color.white);

GrLevel.drawArc(x,y*20,20,20,180,180);

GrLevel.setColor(Color.red);

GrLevel.drawArc(x,y*20+4,20,20,180,180);

GrLevel.setColor(Color.yellow);

GrLevel.drawArc(x,y*20+2,20,20,180,180);

GrLevel.setColor(Color.green);

GrLevel.drawArc(x,y*20+8,20,20,180,180);

GrLevel.setColor(Color.blue);

GrLevel.drawArc(x,y*20+12,20,20,180,180);

GrLevel.setColor(Color.pink);

GrLevel.drawArc(x,y*20+16,20,20,180,180);

}

}

break;

case 2:

GrLevel.setColor(Color.gray);

break;

}

sky = cl;

GrLevel.setFont(BigText);

GrLevel.setColor(Color.black);

GrLevel.fillRect(0,0,800,50);

GrLevel.setColor(Color.white);

GrLevel.drawString("Score Tabel - comming someday",((size().width)/2)-260, 40);

}

int getSkyTyp(){

return sky;

}

}

}

I tested running the code of class Level by puting it into Level.java and compiled it...ran it with appletviewer and it worked as it was intended to.

But when i compiled it with MainGame... and in the HTML started MainGame.class,.....applet didn't intializeand i got the following error messege:

Init 1

java.lang.NullPointerException

at Level.CalcGraphics(MainGame.java:84)

at MainGame.<init>(MainGame.java:11)

Line 82:void CalcGraphics() {

Line 83:ImgLevel = createImage(800,600);

Line 84:GrLevel = ImgLevel.getGraphics(); // The First awt.Graphics object

Line 85:}

Line 9:public MainGame() {

Line 10:Level nr1 = new Level();

Line 11:nr1.CalcGraphics(); // calling the method above -> same error first awt.Graphics Object.

-

If i change it os that "drawGras" comes first it's first awt.Graphics Line will show the same error

-

Hope some one can and will help me

[12117 byte] By [mihalyB] at [2007-9-27 16:23:30]
# 1

As per the documentation of java.awt.Component.createImage(int,int):

Creates an off-screen drawable image to be used for double buffering.

Parameters:

width - the specified width

height - the specified height

Returns:

an off-screen drawable image, which can be used for double buffering. The return value may be null if the component is not displayable. This will always happen if GraphicsEnvironment.isHeadless() returns true.

Since:

JDK1.0

The key part is '...may be null if the component is not displayable.'

You should put your graphics initialization code in start(), which will be called when your applet is ready to go. Before then, your applet is not displayable. (Also, remember to dispose() your graphics in your stop() method, if not sooner.)

Dorceon at 2007-7-6 0:41:45 > top of Java-index,Other Topics,Java Game Development...
# 2

> As per the documentation of

> java.awt.Component.createImage(int,int):

> Creates an off-screen drawable image to be used for

> double buffering.

>

> Parameters:

> width - the specified width

> height - the specified height

> Returns:

> an off-screen drawable image, which can be used for

> double buffering. The return value may be null if the

> component is not displayable. This will always happen

> if GraphicsEnvironment.isHeadless() returns true.

> Since:

> JDK1.0

its not

ImgLevel = createImage(800,600);

that's making the problem but The first awt.Graphics Object in class Level, no mather which on it is =((

>

> The key part is '...may be null if the component is

> not displayable.'

> You should put your graphics initialization code in

> start(), which will be called when your applet is

> ready to go. Before then, your applet is not

> displayable. (Also, remember to dispose() your

> graphics in your stop() method, if not sooner.)

for the part writen above...I'll try to change it like you are saying.

Thanx for your help!

mihalyB at 2007-7-6 0:41:45 > top of Java-index,Other Topics,Java Game Development...
# 3

OK, first off... You only want one class extending Applet. What I would do is have Level extend Panel. Then do something like this...

MainGame(){

Level nrl=new Level();

ImageLevel il=nrl.getLevelImage();

add(Level);//adds the Level panel to your Applet Container

}

class Level extends Panel{

Level(){ //use a Level constructor instead of everything you have in init

//everything you have in init EXCEPT repaint, as it should be unnecessary

..

}

cbisbee at 2007-7-6 0:41:45 > top of Java-index,Other Topics,Java Game Development...
# 4
forgot... You'll also want to add your setGround and drawSky methods to the Level constructor... It just makes more sense to have Level draw its own stuff unless you NEED MainGame to do it for it.
cbisbee at 2007-7-6 0:41:45 > top of Java-index,Other Topics,Java Game Development...
# 5

> forgot... You'll also want to add your setGround and

> drawSky methods to the Level constructor... It just

> makes more sense to have Level draw its own stuff

> unless you NEED MainGame to do it for it.

The methods for doing it is locaded in Level but i wanna call them from MainGame because ->

I am planing to have more then one Level

There are diffrent typs of gras ands sky for the Level(s) and that should be controled from MainGame.

mihalyB at 2007-7-6 0:41:45 > top of Java-index,Other Topics,Java Game Development...
# 6

> OK, first off... You only want one class extending

> Applet. What I would do is have Level extend Panel.

> Then do something like this...

I changed it to extends Panel

no differnce =(

> > MainGame(){

>Level nrl=new Level();

>ImageLevel il=nrl.getLevelImage();

>add(Level);//adds the Level panel to your Applet Container

after that i adde "add(Level)" it would compile...ytou know the couldn't reslove symbol error.

> }

>

> class Level extends Panel{

> Level(){ //use a Level constructor instead of everything you have in init

> //everything you have in init EXCEPT repaint, as it should be unnecessary

> }

I alsow made the other changes as you said... with making a constructor...still same error the first awt.Graphics object makes an NullPointerExeption

But thanx for your help!

mihalyB at 2007-7-6 0:41:45 > top of Java-index,Other Topics,Java Game Development...
# 7

ok, then...

use a constructor:

Level(int GrassType, int SkyType, int GroundType){

setGround(GroundType);

setSky(SkyType);

setGrass(GrassType);//or whatever you call the methods... this has the idea

}

so inside your MainGame(){

Level lvl=new Level(1,1,300);

}

for the NPE, I'd now try...

change the method in Level: getLevelImage(){

CalcGraphics();

drawGrass(1);

}

and then call getLevelImage() from the MainGame.start()

The idea comes from the guy above who mentioned that the Applet can't create an image until it starts... So maybe that's it?

cbisbee at 2007-7-6 0:41:45 > top of Java-index,Other Topics,Java Game Development...
# 8

> ok, then...

>

> use a constructor:

>

> Level(int GrassType, int SkyType, int GroundType){

> setGround(GroundType);

> setSky(SkyType);

> setGrass(GrassType);//or whatever you call the

> methods... this has the idea

> }

>

> so inside your MainGame(){

> Level lvl=new Level(1,1,300);

> }

>

> for the NPE, I'd now try...

>

> change the method in Level: getLevelImage(){

> CalcGraphics();

> drawGrass(1);

> }

>

> and then call getLevelImage() from the

> MainGame.start()

>

> The idea comes from the guy above who mentioned that

> the Applet can't create an image until it starts...

> So maybe that's it?

Thanx alot! I'll try that to morrow....right now i need to go to sleep =)

mihalyB at 2007-7-6 0:41:45 > top of Java-index,Other Topics,Java Game Development...
# 9
**** it!!! it still wont work! =(((((I don't wanna give up on this but its just wont work =(
mihalyB at 2007-7-6 0:41:45 > top of Java-index,Other Topics,Java Game Development...
# 10

Is it still the same exception?

The reason I said that the problem lies with when you were calling createImage is because that method is returning null because the Applet is not displayable. You don't get the NullPointerException until you try get a Graphics from it because up until that point, for all the jvm knows, you want that reference to be null. It's not until you try to call a method on it that it realizes there's a problem.

Dorceon at 2007-7-6 0:41:45 > top of Java-index,Other Topics,Java Game Development...
# 11

> Is it still the same exception?

> The reason I said that the problem lies with when you

> were calling createImage is because that method is

> returning null because the Applet is not displayable.

> You don't get the NullPointerException until you try

> get a Graphics from it because up until that point,

> for all the jvm knows, you want that reference to be

> null. It's not until you try to call a method on it

> that it realizes there's a problem.

Yea i still get the same exeption =(

It sound real what you are saying but what can I do about this?

mihalyB at 2007-7-6 0:41:45 > top of Java-index,Other Topics,Java Game Development...
# 12

Try removing the code from Level's init() method. Change paint to:

if(ImgLevel==null)

{

ImgLevel=createImage(800,600);

GrLevel = ImgLevel.getGraphics();

//whatever functions you use to draw on GrLevel

//i.e.

drawGras(1);

GrLevel.dispose();

}

g.drawImage(ImgLevel,0,0,this);

This way you'll still only ever draw ImgLevel once, but since you're in the midst of painting, you know that your component is displayable; if createImage will ever work, it's here.

Dorceon at 2007-7-6 0:41:45 > top of Java-index,Other Topics,Java Game Development...
# 13

There seems to be some other stuff going on, ie. from the constructor of MainGame, so for this to work, you might have to clean some of that up. In any event, you should avoid calling createImage until you're sure you're displayable; paint() is a place where you're sure you're displayable, so try moving all the drawing code into those.

Also, you seem to call drawing methods from outside Level, so I guess you won't want to dispose the Graphics right away.

So in short, move all code that draws, or that calls code that draws, out of constructors and into paint() methods. Use something like I sugested above to make sure you only allocate and draw one image; do that the first time you paint; thereafter just copy that image into the given Graphics like you were doing.

Dorceon at 2007-7-6 0:41:45 > top of Java-index,Other Topics,Java Game Development...