Search code examples
javadrivermultiple-monitorsbufferstrategy

Java buffer strategy Multi Driver display


I am creating an application in java using the buffer strategy. The only problem is when I use the buffer strategy maximized on my integrated graphics, it crashes with this error:

Exception in thread "Thread-2" java.lang.IllegalStateException: Buffers have not been created

I believe the reason for it crashing is me using an AMD video-card and integrated graphics on a multi-monitor set, or in other words, two monitors are using the AMD video-card's graphics and one monitor is using the integrated graphics.

In result, I can't maximize my application on the igpu ran monitor, but can maximize my window on the monitors operated by the video card.

Do you have an explanation on why Java is giving me crap? Also, is there a solution so I can maximize my window on my igpu ran monitor too?

This is how the buffers are being created and used:

Side note, whenever the Graphics object is being used, I use g.drawImage(BufferedImage, x, y, null);

    private void render() {
    BufferStrategy bs = this.getBufferStrategy();
    if(bs == null) {
        this.createBufferStrategy(3); //creation
                                      //this being a class that implements Runnable
        return;
    }

    Graphics g = bs.getDrawGraphics(); //bufferstrategy is converted to graphics here

    g.setColor(Color.black);
    g.fillRect(0, 0, mutableWidth, mutableHeight);

    handler.render(g); //Graphics is transported to hundreds of objects to get displayed

    g.dispose();
    bs.show();
}

I believe you don't need to read the whole class that implements runnable, but just in case you do:

package GenRuntime;

import GenRuntime.GameObjects.Block.Block;
import GenRuntime.Handler.Handler;
import UI.UIInput.KeyInput;
import Resources.Initializer;

import java.awt.*;
import java.awt.image.BufferStrategy;

public class Game extends Canvas implements Runnable {

    private static final long serialVersionUID = -240840600533728354L;

    public static final int WIDTH = 800, HEIGHT = WIDTH /12 * 9;

    private int mutableWidth, mutableHeight;
    private int windowXLoc, windowYLoc;

    private Thread thread;
    private boolean running = false;

    private Handler handler;

    Window window;

    public Game() {
        handler = new Handler();
        this.addKeyListener((new KeyInput(handler)));

        window = new Window(WIDTH, HEIGHT, "Survior", this);
        mutableHeight = HEIGHT;
        mutableWidth = WIDTH;
    }

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

    public synchronized void stop() {
        try {
            thread.join();
            running = false;
        } catch(Exception e) {
            e.printStackTrace();
        }
    }

    public int Frames;

    public void run() {
        long lastTime = System.nanoTime();
        double amountOfTicks = 60.0;
        double ns = 1000000000 / amountOfTicks;
        double delta = 0;
        long timer = System.currentTimeMillis();
        int frames = 0;
        while (running) {
            long now = System.nanoTime();
            delta += (now-lastTime) / ns;
            lastTime = now;
            while (delta >= 1) {
                tick();
                delta--;
            }

            if (running)
                render();
            frames++;

            if(System.currentTimeMillis() - timer > 1000) {
                timer += 1000;
                Frames = frames;
                System.out.println("FPS: " + frames);
                frames = 0;
            }
        }
    }

    private void tick() {
        handler.tick();
    }

    private void render() {
        BufferStrategy bs = this.getBufferStrategy();
        if(bs == null) {
            this.createBufferStrategy(3);
            return;
        }

        Graphics g = bs.getDrawGraphics();

        g.setColor(Color.black);
        g.fillRect(0, 0, mutableWidth, mutableHeight);

        handler.render(g);

        g.dispose();
        bs.show();
    }

    public static void main(String[] args) {
        Initializer.init();

        Block b = new Block();
        new Game();
    }

    //The rest of the code is getter and setter methods. Don't worry about them

    public void setSize(int width, int height) {
        mutableHeight = height;
        mutableWidth = width;
    }

    public void setSize(Dimension dim) {
        mutableWidth = dim.width;
        mutableHeight = dim.height;
    }

    public void setWindowLoc(int x, int y) {
        windowXLoc = x;
        windowYLoc = y;
    }

    public void setWindowLoc(Point p) {
        windowXLoc = p.x;
        windowYLoc = p.y;
    }
    public int getMutableWidth() {
        return mutableWidth;
    }

    public int getMutableHeight() {
        return mutableHeight;
    }

    public int getWindowXLoc() {
        return windowXLoc;
    }

    public int getWindowYLoc() {
        return windowYLoc;
    }
}

Solution

  • The answer is posted at this link: java: IllegalStateException - Buffers have not been created

    I have a multi driver issue that is fixed by adding -Dsun.java2d.d3d=false to my java command line (or VM arguments)