1

I am trying to make a game so I started creating all the drawing methods and ways, so I can begin with the graphics work, but when I am creating my bufferyStrategy, java returns an error.

Why is that error happening?

Exception in thread "Thread-0" 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 Game.render(Game.java:28)
    at Game.run(Game.java:17)
    at Game$1.run(Game.java:45)
    at java.lang.Thread.run(Unknown Source)

This is the source:

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferStrategy;


public class Game extends Frame {

    public boolean playing = false;

    public Game() {
    }

    public void run() {
        while (playing) {
            update();
            render();
        }
    }

    public void update() {

    }

    public void render() {
        BufferStrategy b = null;
        if (super.getBufferStrategy() == null) {
            super.createBufferStrategy(3);
        }
        b = super.getBufferStrategy();
        Graphics2D g = (Graphics2D) b.getDrawGraphics();
        g.setColor(Color.BLACK);
        g.fillRect(0,  0, getWidth(), getHeight());
        g.dispose();
        b.show();
    }


    public static void main(String[] args) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                Game game = new Game();
                game.playing = true;
                game.run();
            }
        }).start();
    }

}

and the parent class:

import java.awt.Canvas;
import java.awt.Dimension;

import javax.swing.JFrame;


public class Frame extends Canvas {

    private JFrame frame = new JFrame();

    public Frame() {
        frame.setTitle("Finland2D");
        frame.setPreferredSize(new Dimension(765, 500));
        frame.pack();
        super.setVisible(true);
        frame.setVisible(true);
    }

    public JFrame getFrame() {
        return this.frame;
    }

}

What am I doing wrong?

Paul Floyd
  • 5,530
  • 5
  • 29
  • 43
Artemkller545
  • 979
  • 3
  • 21
  • 55
  • you could to move to 21th. century 1. use JFrame and JPanel, 2. override paintComponent (1st code line should be super.paintComponent) with getPreferredSize for JPanel, 3. use Swing Timer instead of Thread that at 99pct to block EventDispatchThread (nothing is repainted on the screen) – mKorbel Dec 31 '13 at 07:22
  • Is that better than using Canvas? – Artemkller545 Dec 31 '13 at 07:28
  • (Is that better than using Canvas?) - please this is question about .... – mKorbel Dec 31 '13 at 07:32
  • I don't really think this is moving to the 21st century to go for Swing; you'd either advise to look at JavaFX 2 or to move to something like LibGDX. Anything but Java2D, really. – Gimby Dec 31 '13 at 11:14
  • @user3123545 Has it worked for you yet? – StoopidDonut Jan 02 '14 at 03:28

2 Answers2

0

Reviewed your code,I suggest you to give every class a good name.

Bad-style naming ,such as Frame extends Canvas ,will make a mess.

And If you use Swing,there built-in buffered-Strategy for you,like double-buffered strategy.

please give more information.

currently,I refactored your code ,and make a sample as follow:

import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferStrategy;

import javax.swing.JFrame;
import javax.swing.SwingUtilities;

/**
 * this code still Need to improve 
 * deal with Thread related code
 *
 */
public class Game extends Canvas implements Runnable{

    public static void main(String[] args) {
        //GUI EDT thread
        SwingUtilities.invokeLater(new Runnable(){

            @Override
            public void run() {
                JFrame frame = new JFrame("Finland2D");
                frame.setPreferredSize(new Dimension(765, 500));
                final Game game = new Game();
                game.playing = true;
                frame.add(game);
                frame.pack();
                frame.setVisible(true);
                frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                frame.addWindowListener(new WindowAdapter(){

                    @Override
                    public void windowClosing(WindowEvent e) {
                        // TODO Auto-generated method stub

                        game.finish();
                        System.exit(0);
                    }

                });
                //start game thread
                new Thread(game).start();
            }
        });
    }


    public Game() {
    }
    @Override
    public void run() {
        while (playing) {
            update();
            render();
        }
    }
    public void finish() {
        playing = false;
    }
    public void update() {

    }

    public void render() {
        BufferStrategy b = null;
        if (super.getBufferStrategy() == null) {
            super.createBufferStrategy(3);
        }
        b = super.getBufferStrategy();
        Graphics2D g = (Graphics2D) b.getDrawGraphics();
        g.setColor(Color.BLACK);
        g.fillRect(0,  0, getWidth(), getHeight());
        g.dispose();
        b.show();
    }
    private static final long serialVersionUID = 1L;
    public boolean playing = false;
}
wangdq
  • 1,874
  • 17
  • 26
  • why you get IllegalStateException: Component must have a valid peer,mostly you haven't add the canvas to the frame.And you can choose to use JPanel instead of Canvas. – wangdq Dec 31 '13 at 07:49
0

It looks like your render() is getting invoked before your Canvas (Frame) is added to a peer component.

Try explicitly adding your 'Frame' instance to the container, JFrame within your Frame constructor:

private JFrame frame = new JFrame();

    public Frame() {
            frame.setTitle("Finland2D");
            frame.setPreferredSize(new Dimension(765, 500));
            frame.pack();
            super.setVisible(true);
            frame.setVisible(true);

            //Explicitly add this to the container
            frame.add(this);
        }

I tried executing it with it and I get no exception and a Black screen.

StoopidDonut
  • 8,547
  • 2
  • 33
  • 51