Hi Guys

Just starting to make my first java game, im getting a few errors.
Im just trying to figure a few things about about the game loops before i get started and this is driving me crazy

when i just call the renderer to repaint after i initialize the jframe, it works...
but once i put it in a loop.... (note this is not going to be my loop, i was just trying somthing out...)
I get errors
run:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException

Any input would be greatly appreciated. I dont understand what is null and why it is null only in a loop

see my main class and renderer class below

//my main game classs

package ballgame;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import javax.swing.JFrame;

/**
 *
 * @author jonathan
 */
public class BallGame {

    private int HIEGHT;
    private int WIDTH;
    private int paddleHieght;
    private int paddleWidth;
    public Renderer Renderer;
    public static BallGame ballGame;
    boolean running = true;
    public Rectangle Paddle;
    int y = 0;

    public BallGame() {

        Dimensions();
        Renderer = new Renderer();

        JFrame jframe = new JFrame("Ball Game");  
        jframe.setResizable(false);
        jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jframe.setSize(WIDTH, HIEGHT);
         jframe.add(Renderer);
        jframe.setVisible(true);

     run();

  //  Renderer.repaint();

}

    final void run(){

        while (running){

            Renderer.repaint();
        }
    }

    void paintPaddle(Graphics g) {    
        g.setColor(Color.black);
        g.fillRect(Paddle.x,Paddle.y,Paddle.width,Paddle.height);
    }

    void Repaint(Graphics g) {
   g.setColor(Color.CYAN);
        g.fillRect(0, 0, WIDTH, HIEGHT);       
        paintPaddle(g);
    }

    void update(long Elapsed) {

    }

    final void Dimensions() {
        //here i am getting the users screen size.....
        //this is what everything will be based on....
        WIDTH = java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds().width;
        HIEGHT = java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds().height;

        paddleHieght = HIEGHT / 15;
        paddleWidth = WIDTH / 7;

        Paddle = new Rectangle(WIDTH / 2 - (paddleWidth / 2),HIEGHT - paddleHieght,paddleWidth, paddleHieght);

    }

    public static void main(String[] args) {
        ballGame = new BallGame();       
    }
}

//my renderer class

package ballgame;

import java.awt.Graphics;
import javax.swing.JPanel;

/**
 *
 * @author jonathan
 */
public class Renderer extends JPanel {

    @Override
    protected void paintComponent(Graphics g) {

        super.paintComponent(g); //To change body of generated methods, choose Tools | Templates.
        BallGame.ballGame.Repaint(g);

    }    
}

It would help if you show the entire stacktrace.

Just to give a direction to look at: a NullPointerException is caused by (trying to) accessing an instance member of a non-instantiated variable.

In your case, part of the problem is your while loop.
in your run method, comment out the while (running) { and }
You are at this point in an infinite loop repainting your screen, which sooner or later would indeed cause trouble.

Do that, and you'll no longer have an NPE. This doesn't mean it's the entire cause of your problem, though.

public Renderer Renderer;

You have a variable with exactly the same name as a class. Surprisingly this is valid Java, but it's making your code imcomprehensible.
It would be much easier to read if you follow Java conventions and start class names with a capital, variable and method names with a lower case.

But anyway...
I can't see where you call Dimensions(), so Paddle is probably uninitialised, ie its value is null

Hi guys, yes Noted, I will change the name of the Renderer.

I call demsions before initialize the jframe.

@ stultuske Thats exaccly what i dont want to do though, The thing is, when it is in this loop it doesant even seem to be called at all,
The renderer class is getting the null point exception on the 16th line of code, when calling the repaint method.

We don't know which line is the 16th in your editor! Please be more explicit.

comment out the while (running) { and }
...Thats exaccly what i dont want to do though

If you are referring to the run loop (line 44 above) then, no, that's exactly what you do want to do. Posting repaint requests as fast as the CPU will, at best, just slow your machine to a crawl.

To display an animation (game or whatever) in Swing you need a Timer to trigger an update to the game state at regular intervals, eg 60 times per second, then call repaint to update the screen to match the latest game state. I can give you a lot more info and some sample code if you are interested.

sorry i mean the 16th line in the code posted above in the renderer class

BallGame.ballGame.Repaint(g);//17 line of code in the renderering class of my program, 16th line in my post

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
    at ballgame.Renderer.paintComponent(Renderer.java:17)
    at javax.swing.JComponent.paint(JComponent.java:1056)
    at javax.swing.JComponent.paintChildren(JComponent.java:889)
    at javax.swing.JComponent.paint(JComponent.java:1065)
    at javax.swing.JComponent.paintChildren(JComponent.java:889)
    at javax.swing.JComponent.paint(JComponent.java:1065)
    at javax.swing.JLayeredPane.paint(JLayeredPane.java:586)
    at javax.swing.JComponent.paintChildren(JComponent.java:889)
    at javax.swing.JComponent.paintToOffscreen(JComponent.java:5217)
    at javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(RepaintManager.java:1579)
    at javax.swing.RepaintManager$PaintManager.paint(RepaintManager.java:1502)
    at javax.swing.RepaintManager.paint(RepaintManager.java:1272)
    at javax.swing.JComponent.paint(JComponent.java:1042)
    at java.awt.GraphicsCallback$PaintCallback.run(GraphicsCallback.java:39)
    at sun.awt.SunGraphicsCallback.runOneComponent(SunGraphicsCallback.java:79)
    at sun.awt.SunGraphicsCallback.runComponents(SunGraphicsCallback.java:116)
    at java.awt.Container.paint(Container.java:1975)
    at java.awt.Window.paint(Window.java:3904)
    at javax.swing.RepaintManager$4.run(RepaintManager.java:842)
    at javax.swing.RepaintManager$4.run(RepaintManager.java:814)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)
    at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:814)
    at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:789)
    at javax.swing.RepaintManager.prePaintDirtyRegions(RepaintManager.java:738)
    at javax.swing.RepaintManager.access$1200(RepaintManager.java:64)
    at javax.swing.RepaintManager$ProcessingRunnable.run(RepaintManager.java:1732)
    at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:756)
    at java.awt.EventQueue.access$500(EventQueue.java:97)
    at java.awt.EventQueue$3.run(EventQueue.java:709)
    at java.awt.EventQueue$3.run(EventQueue.java:703)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:726)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)

Looks l;ike a very interesting bug starting with ballGame = new BallGame(); in main.

First, new BallGame() is called. That constructor calls Renderer.repaint() which executes BallGame.ballGame.Repaint(g); then, and only then, after the constructor has returned, the variable ballGame is set to refer to the new BallGame.

So when you execute BallGame.ballGame.Repaint(g);, ballGameis still null and you get an NPE

ps You still need a Timer, not a loop!

ok Im confused, Yes i wont be inplementing a timer, im going to use a loop that i will add something to to make sure its 60fps no matter what machine, I want to get away from the timer. Ive used it for other games.

but anyway, the bug, i dont understand it, im not calling the Renderer.repaint() in that constructer, that code is commented out. Im calling the run(); which should be after ballGame has been initialised??

Thanks.

No, you call run directly in the constructor and that calls repaint, which results in a call to paintComponent - which may be before the constructor is finished, depending on how the threads are scheduled. If you want run to execute only after it then you need to call it from somewhere else or do some thread scheduling of your own.

I'm going to try this just one more time.
You should not use a loop with "something added" to get a steady fps in a Swing application. Use a java.util.Timer or ThreadPoolScheduler that will call your model update at a regular intervals (regardless of hardware) and do so without creating thread blocking problems. This is one of those absolutely basic concepts about Swing animation. Why are you opposed to it?

perfect thanks.

Well, im not sure, im just going with this link Click Here atm, but was trying to make it myself so i accually know what was going on.

In this artical they say that using the timer is still not the best way of doing it, and i anted to accually makea game as properly as i could properly make it for once :).

including (I will edit according to these suggestons)
(You have a variable with exactly the same name as a class. Surprisingly this is valid Java, but it's making your code imcomprehensible.
It would be much easier to read if you follow Java conventions and start class names with a capital, variable and method names with a lower case.)

So while i was doing this, i figured i would just try a while loop and see what happened, and than i got the null pointer, but i believe i understand what is going on now, i just wanted to know for my personal knowledge. and thanks for that. I figured because code is executed line by line that it would already be initialized.

When i get home, ill fool around a bit more and get back to you guys. Thanks for everything so far.

Interesting link - one man's opinion even if it's not so mainstream.
What he says about java,util.Timer and javax.swing.Timer is basically right, which is why the ScheduledThreadPoolExecutor is the recomended timing mechanism. It's just as easy as the others to use but gives you as much control over the threading as you want.

eg to run a method updateSimulation() immediately then every 30 mSec on a single thread:

new ScheduledThreadPoolExecutor(1).
                scheduleAtFixedRate(this::updateSimulation, 
                0, 30, MILLISECONDS);

If you really try with your own loop and thread management then maybe eventually you could make it as solid, safe, hardware/OS independent, and resiliant, but why bother?

when im going to college in september, for computer programming so i kinda wanna know what im doing before i get thier, plus the games that ive made so far with the swing timer seem to kinda jump/are not perfectly fluid. i want to try to get it smoother. like perfectly smooth rendering.

Its kindve a personal challenge for me.

Ill mark this thread as solved now because it is. you solved my bug problem, or more explained why the null was happeneing.

And thanks for the advice.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.