4

I am currently working on a game written in Java. For this I´m using JFrames, JPanels and JButtons.

To select the level you want to play, you have to select a world and then chose a level.

After launching the game, a new instance of my WorldSelection gets created, and after pressing a button, the chosen world gets set and a new instance of LevelSelection is created.

When pressing a Button there, the level gets set.

Here is my problem:

In the Game class, the update method checks the selected world and the level 60 times a second, and if both have selected values, it creates a new instance of a Stage/Level.

The moment I press a button to set the Level, I get a NullPointerException, even if the value it checks has a value.

This does not happen all of the time; half of the time it works (no Exception is thrown) and the other 50% an exception is thrown.

Exception in thread "main" java.lang.NullPointerException
at Game.update(Game.java:41)
at Game.run(Game.java:23)
at Game.start(Game.java:34)
at Game.<init>(Game.java:10)
at Game.main(Game.java:77)

Here is my Code:

Game class:

public class Game {
private boolean running;
private WorldSelection ws;
private boolean chosen = false;

public Game() {
    ws = new WorldSelection();
    start();
}

public void run() {             // game loop
    long lastTime = System.nanoTime();
    long timer = System.currentTimeMillis();
    final double ns = 1000000000.0 / 60.0;
    double delta = 0;
    while (running) {
        long now = System.nanoTime();
        delta += (now - lastTime) / ns;
        lastTime = now;
        while (delta >= 1) {
            update();
            delta--;
        }
        if (System.currentTimeMillis() - timer == 1000) {
            timer += 1000;
        }
    }
}

public void start() {
    running = true;
    run();
}

private void update() {

    if (!chosen) {
        if (ws.getWorld() == 1) {
            if (ws.ls.getLevel() == 1) {
                chosen = true;
                //creates new stage here
            }
            if (ws.ls.getLevel() == 2) {
                chosen = true;
                //creates new stage here
            }
            if (ws.ls.getLevel() == 3) {
                chosen = true;
                //creates new stage here
            }
        }

        else if (ws.getWorld() == 2) {
            if (ws.ls.getLevel() == 1) {
                chosen = true;
                //creates new stage here
            }
            if (ws.ls.getLevel() == 2) {
                chosen = true;
                //creates new stage here
            }
            if (ws.ls.getLevel() == 3) {
                chosen = true;
                //creates new stage here
            }
        }
    }
    else {
        //game updates here
    }

}

public static void main(String[] args) {
    Game game = new Game();
}

}

WorldSelection class:

import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class WorldSelection implements ActionListener {
public JFrame frame;
private int width, height;
private int world = 0;
private JButton button1;
public LevelSelection ls;
private JPanel panel; 

public WorldSelection() {

    this.width = 900;
    this.height = 506;
    frame = new JFrame();
    frame.setSize(width, height);
    frame.setResizable(false);
    frame.setTitle("Quentins Adventure");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setLocationRelativeTo(null);

    panel = new JPanel();
    panel.setBackground(Color.black);

    button1 = new JButton("World 1");
    button1.setBackground(Color.LIGHT_GRAY);
    button1.setSize(120, 44);
    button1.setLocation(80, 350);
    button1.addActionListener(this);

    panel.add(button1);

    frame.add(panel);

    frame.setVisible(true);
}

public void actionPerformed(ActionEvent e) {
    if(e.getSource() == button1){
        setWorld(1);
        ls = new LevelSelection(235,268);
        frame.setVisible(false);
    }
}

public int getWorld() {
    return world;
}

public void setWorld(int world) {
    this.world = world;
}
}

LevelSelection class:

import java.awt.Color;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class LevelSelection implements ActionListener {
    public JFrame frame;
    private int width, height, buttonSize = 50;
    private int level = 0;
    private JButton button1;
    private Font font;
    private JPanel panel;


public LevelSelection(int bPosX,int bPosY) {


        this.width = 900;
        this.height = 506;
        frame = new JFrame();
        frame.setSize(width, height);
        frame.setResizable(false);
        frame.setTitle("Quentins Adventure - Wold Selection");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);

        panel = new JPanel();
        panel.setBackground(Color.black);

        button1 = new JButton("1");
        button1.setBackground(Color.LIGHT_GRAY);
        button1.setFont(font);
        button1.setSize(buttonSize, buttonSize);
        button1.setLocation(bPosX, bPosY);
        button1.addActionListener(this);

        panel.add(button1);

        frame.add(panel);
        frame.setVisible(true);
    }


@Override
public void actionPerformed(ActionEvent e) {
    if(e.getSource() == button1){
        setLevel(1);
        frame.dispose();
    }
    }


public int getLevel() {
    return level;
}


public void setLevel(int level) {
    this.level = level;
}

}
2
  • 1
    Could you highlight the code on the line where the NPE occurs? Commented Jul 18, 2017 at 17:00
  • Where did you initialize ls value of ws?, btw, you should check if an object is null before using its methods to avoid this kind of exception. Commented Jul 18, 2017 at 17:10

2 Answers 2

7

You setWorld and then do ls = new LevelSelection(235, 268);

It means that there is moment in time when ws.getWorld() == 1 is true, but ws.ls is null.

But it is not only problem with your code. You code is not thread safe which may lead to huge of bugs which is amount very difficult to find.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks alot for your fast response, it´s working now! :) If you dont mind, could you explain how i could make the code "thread safe", I dont really know how fixing this would look like, since I just started working with java, and in school we arent tought how to make something thread safe:( Anyway, thanks alot!
It is advanced topic. Impossible to explain in few sentences.
1

In your class WorldSelection, reference of class LevelSelection is created but that is initialized in ActionPerformed(). Thus before that reference of LevelSelection ls is pointing to null.

1 Comment

@user2441511 Thank you so much :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.