2011-06-04 53 views
2

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

编辑:嗯,它做了一遍。值得注意的是,虽然,它实际上它开关后几帧,它似乎只能做它的第一次运行我的电脑启动后!以下是堆栈跟踪:

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) 

End Edit。

我怀疑某种线程的问题,但是这就是为什么我告诉它的线程里面全屏和窗口模式之间进行切换,因此它不会试图在与显示器瞎搞访问任何东西。

培训相关代码:从JFrame的构造 提取物:

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

screenUpdate()(在更新拉环)的整体性:

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正在改变状态,它是如何改变的,以及如何防止它呢?如果它在启动后第一次运行时才会显示,并且在切换到全屏后显示几帧,这个bug是最奇特的。

EDIT2:这里是编译和运行的源:Zip文件] http://www.albeyamakiir.hostzi.com/web_documents/LighSpeedFrame.zip

+0

“培训相关代码:”直到你解决这个问题,你怎么能知道什么代码相关?我建议你准备并发布[SSCCE](http://pscode.org/sscce.html)。 – 2011-06-04 09:00:53

+0

@Andrew Thompson:除了main,构造函数(包含线程启动代码)和用于绘制椭圆的代码(仅用于查看显示是否打印内容),这实际上就是所有的。正如我所说,更新部分什么也不做(只是一个评论,说“把它放在这里”)。我在我的项目开始时就是对的。至于SSCCE,我唯一能做的就是Window监听器。我可以发布我的整个代码(在备份和微调之后),我从来没有见过这样做,但如果这有帮助... – AlbeyAmakiir 2011-06-04 10:42:35

+0

“我可以发布我的整个代码(在备份和微调之后)..”做一个不影响结果的重大调整,并且你有一个SSCCE。你真的*读过*链接的文章吗? – 2011-06-04 10:47:52

回答

2

验证您构建的event dispatch thread的GUI。

+1

对不起,它需要一段时间来验证,但这似乎是我的问题。非常感谢,尤其是链接。 (这就是为什么我希望java教师能够解释为什么我们需要的东西,我已经被告知,但只有在“做到这一点,它有效”的时尚,使它很容易忘记) – AlbeyAmakiir 2011-06-16 09:47:38

1

我不知道什么是错的,但我应该尝试从Ivo Wetzel代码他的游戏引擎名为Bonsai来比较你的代码,用Java编写。我用它来进行我的一些比赛。它的工作原理非常完美。但请记住,如果您使用引擎有鼠标事件(取决于全屏模式启用或不)的错误,我认为该位置是不正确的...

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

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

谢谢,我会检查出来。 – AlbeyAmakiir 2011-06-04 10:34:01