Illegal State Exception when creating new Bufferstrategy

matthewtory picture matthewtory · Jun 3, 2012 · Viewed 12.5k times · Source

When I am trying to figure out how to use bufferstrategies, and overall just improving how I write my code and cleaning things up. When I run the following code, I get an error when I "createBufferStrategy(3)"

    package Game1Test;

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferStrategy;
import java.io.IOException;

import javax.swing.*;

public class Base extends Canvas implements Runnable{

    private static final long serialVersionUID = 1L;
    private boolean running = false;
    int ticks = 0;

    public Base(JFrame f) {
        setSize(f.getWidth(),f.getHeight());
        start();
    }

    public void start(){
        running = true;
        new Thread(this).start();
    }
    public void stop(){

    }
    public void run(){
        while(running){
            ticks++;
            System.out.println(ticks);
            render();

                try {
                    Thread.sleep(2);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
        }
    }
    public void render(){
        BufferStrategy bs = getBufferStrategy();
        Graphics g;
        if(bs == null){
            createBufferStrategy(3);
            requestFocus();
            return;
        }
        bs.show();
    }



}

The Base is then added with:

package Game1Test;

import java.awt.*;

import javax.swing.JFrame;

public class Screen extends JFrame{

    public final int GAME_WIDTH = 400;
    public final int GAME_HEIGHT = 400;
    public Dimension gameDim = new Dimension(GAME_WIDTH,GAME_HEIGHT);
    final String gameName = "Test";

    public Screen(){
        setSize(gameDim);
        setTitle(gameName);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setResizable(false);
        setLayout(new GridLayout());
        setVisible(true);
        setLocationRelativeTo(null);
    }
    public static void main(String[] args){
        Screen s = new Screen();
        s.add(new Base(s));
    }
}

I get the following error:

Exception in thread "Thread-2" java.lang.IllegalStateException: Component must have a valid peer
    at java.awt.Component$FlipBufferStrategy.createBuffers(Unknown Source)
    at java.awt.Component$FlipBufferStrategy.<init>(Unknown Source)
    at java.awt.Component$FlipSubRegionBufferStrategy.<init>(Unknown Source)
    at java.awt.Component.createBufferStrategy(Unknown Source)
    at java.awt.Canvas.createBufferStrategy(Unknown Source)
    at java.awt.Component.createBufferStrategy(Unknown Source)
    at java.awt.Canvas.createBufferStrategy(Unknown Source)
    at Game1Test.Base.render(Base.java:46)
    at Game1Test.Base.run(Base.java:33)
    at java.lang.Thread.run(Unknown Source)

Can someone please tell me why this is happening? and maybe a solution to this problem?

Thanks

Answer

Jeffrey picture Jeffrey · Jun 3, 2012

Taking a look at the API, this exception is thrown if the component is not displayable. In this case, that's when Canvas.peer is null. Taking a look at the peer field reveals that

The peer is set when the Component is added to a container that also is a peer

Since you are starting the update thread from your component's constructor, render could be called before your component is ever added to another container which would mean the peer is null, and then an IllegalStateException would be thrown.