user4810293
user4810293

Reputation:

Null Pointer Exception when program not run through debugger

I am developing a game in Java for a school project. When I run my code by typing 'java game' into the command prompt, I get a null pointer exception (at game.play, line 35, "gameScreen.tick();"), however when I add a breakpoint on this line and use a debugger to investigate, the debugger shows the correct object reference and follows the program without any problems. I can't seem to work out what is wrong...

import javax.swing.*;

public class game implements Runnable {

    private screen gameScreen;

    public static void main(String[] args) {
        // put your code here
        game thisGame = new game();
        SwingUtilities.invokeLater(thisGame);
        thisGame.play();
    }

    public void run() {
        JFrame w = new JFrame();
        w.setDefaultCloseOperation(w.EXIT_ON_CLOSE);
        gameScreen = new screen();
        gameScreen = gameScreen.setUp();
        w.add(gameScreen);
        w.pack();
        w.setLocationByPlatform(true);
        w.setVisible(true);
    } 

    public void play() {
        while(true) {
            try { Thread.sleep(10); }
            catch (InterruptedException e) { }
        }
        gameScreen.tick();
    }
}

Any help would be appreciated! Thanks.

Upvotes: 2

Views: 115

Answers (2)

Naman Gala
Naman Gala

Reputation: 4692

Documentation gives below example for SwingUtilities.invokeLater method.

Runnable doHelloWorld = new Runnable() {
    public void run() {
        System.out.println("Hello World on " + Thread.currentThread());
    }
};

SwingUtilities.invokeLater(doHelloWorld);
System.out.println("This might well be displayed before the other message.");

You can see This might well be displayed before the other message. might print before Hello World on.

So in your case gameScreen = new screen(); might not be executed before gameScreen.tick();, so you are getting NPE.

Solution: You can initialize gameScreen in the default constructor of game class.

Upvotes: 3

epoch
epoch

Reputation: 16595

invokeLater() is an asynchronous call and will be invoked later as the name suggests.

Your next line calls thisGame.play() which in turn calls gameScreen.tick() after 10ms which may be uninitialized at the time.

The reason that the debugger works, is that the wait is probably long enough between method calls to allow gameScreen to be initialized by the run() method

Upvotes: 3

Related Questions