Java-Gaming.org    
Featured games (78)
games approved by the League of Dukes
Games in Showcase (430)
Games in Android Showcase (89)
games submitted by our members
Games in WIP (468)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  NullPointer exception?  (Read 998 times)
0 Members and 1 Guest are viewing this topic.
Offline kutucuk

Senior Member


Medals: 5
Exp: 3 years



« Posted 2013-03-21 20:02:58 »

Hi,
I was trying to follow Killer Game Programming in Java but I failed to do so (Too tough for me for now - I need to get a good understanding about game loops and all those delta and other variables first). Then I tried to follow Black Art of Java Game Programming. Looks easier.
It does all stuff on an applet and I hate applets. So I tried to convert it to a JFrame application.
I figured init() is like a constructor, start() would be my main method, stop() would be performed by JFrame and run() is a Thread method (no need to convert). So, I converted it into a JFrame app.

It worked, but with a little problem:
Quote
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
   at Broadway.paint(MyFrame.java:42)
   at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
   at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
   at javax.swing.RepaintManager.prePaintDirtyRegions(Unknown Source)
   at javax.swing.RepaintManager.access$700(Unknown Source)
... Goes on
So I figured I forgot to initiate something. The 42nd line is this:
1  
offScreen.setColor(Color.BLACK); //offScreen is the Graphics object I use for double buffering

But I actually initiated it in the constructor. Here is my full code which can compile and show the error:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import javax.swing.JFrame;

public class MyFrame extends JFrame implements Runnable {

   Graphics offScreen; // That's how the book tells me to implement it
  Image buffer;

   int a = 5;
   int b = 3;
   int locx, locy, width, height;
   int aWidth = 400;
   int aHeight = 400;

   static final int REFRESH_RATE = 50; // Sleep duration. The lower this is,the faster the rectangle.

   public MyFrame() {
      setDefaultCloseOperation(EXIT_ON_CLOSE);
      setBackground(Color.black);
      setSize(aWidth, aHeight);
      locx = 80;
      locy = 100;
      width = 110;
      height = 90;
      setVisible(true);

      buffer = createImage(aWidth, aHeight); // Creating an image in the same size as JFrame
     offScreen = buffer.getGraphics(); // It is initialized man...
  }

   public static void main(String args[]) {
      MyFrame b = new MyFrame();
      Thread animation = new Thread(b);
      if (animation != null) {
         animation.start();
      }
   }

   public void paint(Graphics g) {
      offScreen.setColor(Color.BLACK);
      offScreen.fillRect(0, 0, aWidth, aHeight);
      offScreen.setColor(Color.blue);
      offScreen.fillRect(80, 200, 220, 90);
      offScreen.fillRect(100, 10, 90, 80);
      offScreen.setColor(Color.lightGray);
      offScreen.fillRect(locx, locy, width, height);
      g.drawImage(buffer, 0, 0, this); // Why is this "g" instead of "offScreen"? Figure.                          
  }

   public void update(Graphics g) { // Book tells this is needed. Figure why.
     paint(g); // Also look into 'active rendering' thing. This looks nasty.
  }

   public void updateRectangle() {
      locx += a;
      locy += b;
      if (locx >= 290 || locx <= 0) {
         a = -a;
      }
      if (locy >= 310 || locy <= 0) {
         b = -b;
      }

   }

   public void run() {
      while (true) {
         repaint(); // It's said that calling repaint() is not a guaranteed way.              
        updateRectangle();
         try {
            Thread.sleep(REFRESH_RATE);
         } catch (Exception exc) {
         }
      }
   }
}
Offline opiop65

JGO Kernel


Medals: 131
Projects: 7
Exp: 3 years


Team Alluminum


« Reply #1 - Posted 2013-03-21 20:17:39 »

You never created a new instance of offscreen

Offline kutucuk

Senior Member


Medals: 5
Exp: 3 years



« Reply #2 - Posted 2013-03-21 20:24:40 »

Hmm... I thought I did it here:
1  
2  
      buffer = createImage(aWidth, aHeight);
      offScreen = buffer.getGraphics(); .
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline opiop65

JGO Kernel


Medals: 131
Projects: 7
Exp: 3 years


Team Alluminum


« Reply #3 - Posted 2013-03-21 20:30:25 »

No, you're just somehow assigning a method or something to an object. The
1  
offscreen
object is still never initialized. You need to create one and then call
1  
offScreen = buffer.getGraphics();

Offline Sparky83

Senior Member


Medals: 6
Projects: 1



« Reply #4 - Posted 2013-03-21 20:38:36 »

I think the problem really is that it should be ordered in another way:


1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
   public MyFrame() {
      setDefaultCloseOperation(EXIT_ON_CLOSE);
      setBackground(Color.black);
      setSize(aWidth, aHeight);
      buffer = createImage(aWidth, aHeight); // Creating an image in the same size as JFrame
     offScreen = buffer.getGraphics(); // It is initialized man...
     locx = 80;
      locy = 100;
      width = 110;
      height = 90;
      setVisible(true);
   }


The problem could be, that with "setVisible(true)" he already wants to paint the JFrame and it's contents. And in paint, he needs the Graphics object offScreen. And at this point it is not initialized. Try it this way. Smiley
Offline kutucuk

Senior Member


Medals: 5
Exp: 3 years



« Reply #5 - Posted 2013-03-21 20:46:07 »

No that's not either. Actually, that way it never runs.

But I figured it out. Pay attention to my paint() method and see my new one:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
public void paint(Graphics g) {
      if(offScreen !=null){
      offScreen.setColor(Color.BLACK);
      offScreen.fillRect(0, 0, aWidth, aHeight);
      offScreen.setColor(Color.blue);
      offScreen.fillRect(80, 200, 220, 90);
      offScreen.fillRect(100, 10, 90, 80);
      offScreen.setColor(Color.lightGray);
      offScreen.fillRect(locx, locy, width, height);
      }
      g.drawImage(buffer, 0, 0, this);                          
   }

I thought if the app starts, it eventually gets something Cheesy

But I really like to learn why it is null there...
Offline Sparky83

Senior Member


Medals: 6
Projects: 1



« Reply #6 - Posted 2013-03-21 21:05:24 »

I think there is truth in what I said before:
Quote
The problem could be, that with "setVisible(true)" he already wants to paint the JFrame and it's contents. And in paint, he needs the Graphics object offScreen. And at this point it is not initialized.

But I didn't see that createImage() is a method of the Component JFrame. And this method returns:
Quote
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.
So no wonder that it doesn't start when doing as I said. Wink You could fix this by using a BufferedImage and creating it yourself with:
1  
buffer = new BufferedImage(aWidth, aHeight, BufferedImage.TYPE_4BYTE_ABGR);


So your code would be:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;

import javax.swing.JFrame;

public class MyFrame extends JFrame implements Runnable {

   Graphics offScreen; // That's how the book tells me to implement it
  BufferedImage buffer;

   int a = 5;
   int b = 3;
   int locx, locy, width, height;
   int aWidth = 400;
   int aHeight = 400;

   static final int REFRESH_RATE = 50; // Sleep duration. The lower this is,the faster the rectangle.

   public MyFrame() {
      setDefaultCloseOperation(EXIT_ON_CLOSE);
      setBackground(Color.black);
      setSize(aWidth, aHeight);
      buffer = new BufferedImage(aWidth, aHeight, BufferedImage.TYPE_4BYTE_ABGR); // Creating an image in the same size as JFrame
     offScreen = buffer.getGraphics(); // It is initialized man...
     locx = 80;
      locy = 100;
      width = 110;
      height = 90;
      setVisible(true);
   }
[...]


You could also let buffer be of type Image, because BufferedImage is extending Image and its polymorph.
Offline kutucuk

Senior Member


Medals: 5
Exp: 3 years



« Reply #7 - Posted 2013-03-21 21:31:11 »

Thanks a ton Sparky83!

So, setVisible(true) also calls paint to draw the frame huh... And when it calls it, because I haven't initialized my offScreen object, there is a null pointer exception.

Then what I did by my "if" fix was to make g object draw an empty frame (buffer was initialized, but was empty), so the next time offScreen was initialized already, hence it acted as I wanted it to act.

So mainly my problem was a null image object, not a null Graphics object? This is the only way I could completely make sense of it.
Offline Sparky83

Senior Member


Medals: 6
Projects: 1



« Reply #8 - Posted 2013-03-21 21:41:01 »

So mainly my problem was a null image object, not a null Graphics object? This is the only way I could completely make sense of it.
The way I wanted you to do it, it was a problem of the null image object. The way you did it, it is both but mostly a problem of the Graphics object offScreen being null. It was just not initialized already. But after the Image is created and the Graphics object of the Image obtained and stored in offScreen, it works.

But I think you get it quite right. You could debug this part of you program and trace the steps it does. This only works good if you have linked your JDK with it's source in eclipse or something.
Offline kutucuk

Senior Member


Medals: 5
Exp: 3 years



« Reply #9 - Posted 2013-03-23 04:06:49 »

The way you did it, it is both but mostly a problem of the Graphics object offScreen being null. It was just not initialized already. But after the Image is created and the Graphics object of the Image obtained and stored in offScreen, it works.

So, in my original code, Graphics object was null, because the image it was supposed to getGraphics() was also null, right?
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline cubus

Junior Member


Medals: 2



« Reply #10 - Posted 2013-03-23 04:24:04 »

no, because then you would have had the NullPointerException in the line

1  
offScreen = buffer.getGraphics();

because buffer would have been null.

the problem in the original code was, like Sparky83 said, that you called setVisible(true) before
1  
2  
buffer = createImage(aWidth, aHeight); // Creating an image in the same size as JFrame
offScreen = buffer.getGraphics(); // It is initialized man...


in the original code the order was:
setVisible()
repaint() < this was called from the AWT thread "in the background" because you called setVisible()
buffer = createImage()
...

btw, you create an offscreen that has the size of the frame including the frame border. so if you paint to the offscreen with
1  
2  
offScreen.setColor(Color.red);
offScreen.fillRect(buffer.getWidth() - 1, buffer.getHeight() - 1, 1, 1);

you will not see the red pixel.
you could call setUndecorated(true) before setVisible(true), which will give you a frame without border.

or, even better, add an other Component to the Frame's ContentPane (or replace the ContentPane) and create your offscreen in the doLayout() method of that Component.
this way you can handle when the Frame gets resized and create an offscreen that always has the same size as the ContentPane.

Offline kutucuk

Senior Member


Medals: 5
Exp: 3 years



« Reply #11 - Posted 2013-03-23 06:46:14 »

no, because then you would have had the NullPointerException in the line

1  
offScreen = buffer.getGraphics();

because buffer would have been null.

the problem in the original code was, like Sparky83 said, that you called setVisible(true) before
1  
2  
buffer = createImage(aWidth, aHeight); // Creating an image in the same size as JFrame
offScreen = buffer.getGraphics(); // It is initialized man...


in the original code the order was:
setVisible()
repaint() < this was called from the AWT thread "in the background" because you called setVisible()
buffer = createImage()
...
Thanks for the explanation. I guess now I truly understand what Sparky told. setVisible calls repaint and what repaint does is to call paint(), and because I used a Graphics object that was not initialized, it naturally threw NullPointerException.
And because my method of creating image required a visible frame, the other way did not work either.

And by using "if", I basicly skipped these stuff and thus it had the chance to create the image and thus, offScreen object.

Right? Cheesy

btw, you create an offscreen that has the size of the frame including the frame border. so if you paint to the offscreen with
1  
2  
offScreen.setColor(Color.red);
offScreen.fillRect(buffer.getWidth() - 1, buffer.getHeight() - 1, 1, 1);

you will not see the red pixel.
you could call setUndecorated(true) before setVisible(true), which will give you a frame without border.

or, even better, add an other Component to the Frame's ContentPane (or replace the ContentPane) and create your offscreen in the doLayout() method of that Component.
this way you can handle when the Frame gets resized and create an offscreen that always has the same size as the ContentPane.
I realize that frames count too when I set size. Thanks.

And, I could escape this problem by simply drawing everything on a JPanel and then adding it to the JFrame, right?

Man if my theories are correct, then I will be very happy. It would be like a milestone for me.
Offline cubus

Junior Member


Medals: 2



« Reply #12 - Posted 2013-03-23 08:18:10 »

Quote from: kutucuk
And by using "if", I basicly skipped these stuff and thus it had the chance to create the image and thus, offScreen object.

Right? Cheesy
right. in the first paint() the if statement protected you from the NPE, and in further paint() you had the offscreen already created.

Quote from: kutucuk
And, I could escape this problem by simply drawing everything on a JPanel and then adding it to the JFrame, right?
almost right Wink
you would first create a subclass of JPanel and override the paint(Graphics g) method.
(in this method you use the param "g" to draw onto the JPanel.)
then add an instance of your JPanel subclass to the JFrame and then call the JFrame's setVisible(true).
Offline kutucuk

Senior Member


Medals: 5
Exp: 3 years



« Reply #13 - Posted 2013-03-23 10:45:01 »

Perfect.
Hey, is there any way I can show my appreciation except for a post saying thanks?
Offline Sparky83

Senior Member


Medals: 6
Projects: 1



« Reply #14 - Posted 2013-03-23 10:54:15 »

Perfect.
Hey, is there any way I can show my appreciation except for a post saying thanks?
Well, there is an appreciate button at the top right corner of each post. *g*
Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

theagentd (6 views)
2014-04-24 23:00:44

xsi3rr4x (83 views)
2014-04-15 18:08:23

BurntPizza (75 views)
2014-04-15 03:46:01

UprightPath (86 views)
2014-04-14 17:39:50

UprightPath (69 views)
2014-04-14 17:35:47

Porlus (86 views)
2014-04-14 15:48:38

tom_mai78101 (109 views)
2014-04-10 04:04:31

BurntPizza (169 views)
2014-04-08 23:06:04

tom_mai78101 (265 views)
2014-04-05 13:34:39

trollwarrior1 (217 views)
2014-04-04 12:06:45
Escape Analysis
by Roquen
2014-04-25 11:42:09

Escape Analysis
by Roquen
2014-04-25 11:37:01

Escape Analysis
by Roquen
2014-04-25 10:38:58

Escape Analysis
by Roquen
2014-04-25 10:22:13

List of Learning Resources
by SHC
2014-04-18 03:17:39

List of Learning Resources
by Longarmx
2014-04-08 03:14:44

Good Examples
by matheus23
2014-04-05 13:51:37

Good Examples
by Grunnt
2014-04-03 15:48:46
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!