交换到全屏独占模式后,BufferStrategy.getDrawGraphics()有时会失败

时间:2011-06-04 03:15:50

标签: java

我使用BufferStrategy等初始化扩展的jFrame,在屏幕上获得一个漂亮的动画圆圈。我已经设置了一个关键监听器(在update-draw线程之外),它告诉update-draw线程更改为全屏独占模式,而不进行更新或绘制,直到更改完成。这通常有效,但有时,更新绘制线程的绘制部分(更新到目前为止没有任何作用)将有一个异常并在切换后立即崩溃。大多数情况下,它不会造成这种崩溃,但即使这对任何程序都是不可接受的。

编辑:啊,它又完成了。值得注意的是,它确实在切换后的几帧内完成了它,并且似乎只在我的计算机启动后第一次运行时才这样做!这是堆栈跟踪:

java.lang.IllegalStateException: Buffers have not been created
at sun.awt.windows.WComponentPeer.getBackBuffer(Unknown Source)
at java.awt.Component$FlipBufferStrategy.getBackBuffer(Unknown Source)
at java.awt.Component$FlipBufferStrategy.updateInternalBuffers(Unknown Source)
at java.awt.Component$FlipBufferStrategy.revalidate(Unknown Source)
at java.awt.Component$FlipBufferStrategy.revalidate(Unknown Source)
at java.awt.Component$FlipBufferStrategy.getDrawGraphics(Unknown Source)
at albeyamakiir.lightspeed.LightSpeedFrame.screenUpdate(LightSpeedFrame.java:194)
at albeyamakiir.lightspeed.LightSpeedFrame.run(LightSpeedFrame.java:187)
at java.lang.Thread.run(Unknown Source)

结束编辑。

我怀疑某种线程问题,但这就是为什么我告诉它在线程内的全屏模式和窗口模式之间进行更改,因此在使用显示器时不会尝试访问任何内容。

相关代码: 从JFrame构造函数中提取:

initWindow();
if(fullScreen){
    initFullscreen();
}
//Setting graphics buffer strategy
createBufferStrategy(2);//double-buffered
bufferStrategy = getBufferStrategy();

screenUpdate()的整体(在update-draw循环中):

try{
        graphics = bufferStrategy.getDrawGraphics();
        gameRender(graphics);
        graphics.dispose();
        if(!bufferStrategy.contentsLost()){
            bufferStrategy.show();
        }else{
            System.out.println("Contents Lost");
        }

        //Sync the display on some systems. (I'm told that on Linux, this fixes event queue problems)
        Toolkit.getDefaultToolkit().sync();
    }catch (Exception e){
        e.printStackTrace();  
        dontExit = false;
    }

gameRender()只是绘制一个随机椭圆。

此外:

private void initFullscreen(){
    if (!gDevice.isFullScreenSupported()){
        System.out.println("Full-screen exclusive mode not supported");
    }else{
        gDevice.setFullScreenWindow(this);

        validate();

        setDisplayMode(resolutionX, resolutionY, 32);//TODO: set to current resolution instead

        fullScreen = true;
    }
}

private void disableFullscreen(){
    gDevice.setFullScreenWindow(null);

    fullScreen = false;
}

编辑:所以,我猜我的问题归结为;为什么BufferStrategy会改变状态,改变什么状态,以及如何防止它?如果它真的只出现在启动后第一次运行,并且在更改为全屏后几帧,则该错误最为奇特。

Edit2:这是可编辑和可运行的来源:[Zip文件] http://www.albeyamakiir.hostzi.com/web_documents/LighSpeedFrame.zip

2 个答案:

答案 0 :(得分:2)

确认您正在event dispatch thread上构建GUI。

答案 1 :(得分:1)

我不知道出了什么问题,但我应该尝试将您的代码与用Ivo Wetzel编写的Bonsai游戏引擎中的代码进行比较,该代码用Java编写。我把它用于我的一些游戏。它的工作非常完美。但请记住,如果您使用引擎,鼠标事件会出现一些错误(取决于是否启用全屏模式),我认为位置不正确...

如果问题是“独家全屏模式”,那么您可以尝试使用一些技巧设置全屏框架:

frame.setUndecorated(true);
frame.setPreferredSize(Toolkit.getDefaultToolkit().getScreenSize());
frame.setAlwaysOnTop(true);
frame.pack();