Search code examples
javaswingbufferstrategy

Buffer Strategy IllegalStateException


I know this has been asked before but I still can't get it to work.

public class GUI extends JFrame implements Runnable{

    public static JPanel contentPane;
    public static Graphics2D graphics;
    public static BufferStrategy bufferStrategy;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    GUI frame = new GUI();
                    frame.setVisible(true);
                    frame.setResizable(false);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the frame.
     */
    public GUI() {
        setResizable(false);
        setTitle("Tower Defense Game");
        setIgnoreRepaint(true);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 450, 300);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        contentPane.setLayout(new BorderLayout(0, 0));
        setContentPane(contentPane);


    }

    @Override
    public void run() {

        createBufferStrategy(2);
        bufferStrategy = getBufferStrategy();
        graphics = (Graphics2D) bufferStrategy.getDrawGraphics();

        for(int infiniteVar = 0; infiniteVar == -1; infiniteVar++){

            graphics.setBackground(Color.WHITE);
            graphics.drawLine(100, 100, (int) (Math.random() * ((200-50) + 1) + 50), (int) (Math.random() * ((200-50) + 1) + 50));

            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            infiniteVar = 0;
        }
    }
}
public class Initialize {

public static void main(String[] args){

    GUI.main(args);

    GUI objGUI = new GUI();
    Thread threadGUI = new Thread(objGUI);
    threadGUI.start();
}
}

I get Exception in thread "Thread-2" java.lang.IllegalStateException: Component must have a valid peer on the line where I try to make the buffer strategy. I think I'm supposed to make the frame first, but I do call that before I make the thread that makes the buffer strategy.


Solution

  • Basically, your problem starts here...

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    GUI frame = new GUI();
                    frame.setVisible(true);
                    frame.setResizable(false);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }
    

    and is exasperated here...

    public class Initialize {
    
        public static void main(String[] args) {
    
            GUI.main(args);
    
            GUI objGUI = new GUI();
            Thread threadGUI = new Thread(objGUI);
            threadGUI.start();
        }
    }
    

    Basically, what is happening, the GUI.main method is creating a new instance of the GUI, which gets shown on the screen, then you create ANOTHER instance of GUI...

    GUI objGUI = new GUI();
    Thread threadGUI = new Thread(objGUI);
    threadGUI.start();
    

    to which you try and use to create the BufferStrategy with, but this instance is not visible on the screen (displayable, or attached to a native peer), hence your problem...

    Instead, get rid of the main method in the GUI, it's not really doing any favors for you and apply it's logic in the Initialize

    GUI frame = new GUI();
    // Better idea to do this before you make the frame visible
    // as it can change the frame borders and cause some issues
    frame.setResizable(false); 
    frame.setVisible(true);
    
    Thread thread = new Thread(frame);
    thread.start();
    

    You can also add a check in your run method to wait till the JFrame becomes displayable...

    @Override
    public void run() {
    
        while (!isDisplayable()) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException ex) {
            }
        }
        //...
    

    You should also read the JavaDocs on BufferStrategy to better understand how to manage them...