BufferyStrategy возвращает ошибку

Я пытаюсь создать игру, поэтому я начал создавать все методы и способы рисования, чтобы я мог начать работу с графикой, но когда я создаю свой bufferyStrategy, java возвращает ошибку.

Почему происходит эта ошибка?

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)

Это источник:

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();
    }

}

и родительский класс:

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;
    }

}

Что я делаю неправильно?

2 ответа

Похоже, ваш render() вызывается до того, как ваш Canvas (Frame) будет добавлен к равноправному компоненту.

Попробуйте явно добавить ваш экземпляр Frame в контейнер, JFrame в вашем конструкторе Frame:

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);
        }

Я попытался выполнить это с этим, и я не получаю исключения и Черный экран.

Пересмотрев ваш код, я предлагаю вам дать каждому классу доброе имя.

Плохое именование, например, Frame расширяет Canvas, создаст беспорядок.

А если вы используете Swing, то для вас есть встроенная буферизированная стратегия, например, стратегия с двойной буферизацией.

пожалуйста, дайте больше информации.

В настоящее время я реорганизовал ваш код и сделал пример следующим образом:

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;
}
Другие вопросы по тегам