2

After looking through multiple other questions similar, I still seem to have this problem. This seems to be the only relavent post, but it still does not answer my question. The issue I'm having is in my main function I establish a boolean, but in a function I call after that it gives me an NPE. Shown here:

public class Display extends JFrame {
private static final long serialVersionUID = 1L;

public JPanel gp = (JPanel) getGlassPane();
public Images i;
public ActualGameClass p;
public Draw d;
public Controls c;
public boolean AllLoaded = false;

public Display(){
    i = new Images();
    gp.setVisible(true);
    c = new Controls(this, d);
    c.loadControls();
    p = new ActualGameClass();
    d = new Draw(p, i);
    i.loadImages();
    System.out.println(c.ControlsLoaded);
    AllLoaded = true;
    gp.setLayout(new GridLayout(1, 1, 0, 0));
    this.setLayout(new GridLayout(1, 1, 0, 0));

    gp.add(d, p);
    this.add(i);
    p.Game();
}

then in the class ActualGameClass.java

public void Game(){
    if(Main.f.AllLoaded){
    //game
    }
}

When I run this code, it points me to the

if(Main.f.AllLoaded)

saying there is an NPE.

Because it was requested and I'm having trouble formatting in the comments: Main is just what I use to set a window in JFrame here's the relevant class

public class Main {

public static Display f = new Display();
public static int w =
        Main.f.ResChoiceW + 0;
public static int h = 
        Main.f.ResChoiceH +22; //Top Bar of GP renders as 22px
public static void main(String args[]){
    f.setSize(w, h);
    f.setResizable(false);
    f.setVisible(true);
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    f.setTitle("Eddy's Adventures");
    f.setLocationRelativeTo(null);
    f.setAlwaysOnTop(false);
}

and the Stacktrace

Exception in thread "main" java.lang.ExceptionInInitializerError
    Caused by: java.lang.NullPointerException
        at com.fireFlower.pasterino.ActualGameClass.Game(ActualGameClass.java:24)
        at com.fireFlower.pasterino.Display.<init>(Display.java:31)
        at com.fireFlower.pasterino.Main.<clinit>(Main.java:7)
5
  • 2
    What is .f and where is Main? Also, show the stacktrace. Commented Mar 6, 2014 at 1:11
  • Please post the whole class if it's not too big. This is not enough information to answer your question. Commented Mar 6, 2014 at 1:17
  • 1
    @user3386026 a boolean can;t be null, but Main.f might be. Commented Mar 6, 2014 at 1:20
  • 2
    You could narrow it down to whether Main is null or f is null. If you can't use the IDE to tell, before the line that gives you problems insert System.out.println("Main == null is " + (Main==null)); System.out.println("f == null is " + (Main.f==null)); Commented Mar 6, 2014 at 1:21
  • @aliteralmind I added the whole class Commented Mar 6, 2014 at 1:23

2 Answers 2

4

Because you're running p.Game(); inside of the Display constructor and that references a variable that is also assigned inside the constructor of Display, you will be referencing an incompletely constructed Display object.

This should help with understanding: http://vlkan.com/blog/post/2014/02/14/java-safe-publication/

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

4 Comments

how do you suggest I fix this issue, since I want 'p.Game()' to run but anytime I try to call it with a function out of Display it is not yet constructed.
Can you elaborate how the Display object is incomplete? Since p.Game() is the last line of code in the constructor, I don't understand how it would be a problem. It's not a good idea to recursively call back to itself (Display-->Game-->Display), but I don't understand how it's breaking things. Not doubting your answer, just not understanding it.
@aliteralmind Just have a look at the link. It revolves around multi-thread access to shared objects and they do a better job of explaining it than I can.
@user3386026 A better design is to remove the boolean entirely and add a delegator method which you call explicitly to start the game.
0

To continue from @JustinJasmann`s answer:

  1. Eliminate the call to p.Game() in your Display constructor. Recursive calls should be avoided unless you really know what you're doing.

  2. Eliminate the AllLoaded variable entirely

  3. Change void Game() to void Game(Display disp)

  4. As the last line in your main (I think), call Game(f).

And consider naming your variables to be more indicative of what they are, and to follow naming conventions:

f         --> disp
void Game --> void startGame   //Functions should start with lowercase.
w         --> resNum  ??
h         --> resNumH

and so on.

Comments

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.