繁体   English   中英

java paint(g),repaint(),update(g)后端和本地重绘

[英]java paint(g), repaint(), update(g) backend and local repaints

今天,我与一群同学讨论了很多这个话题,每个人都致力于不同的想法,以“滥用” Java2D API来开发简单的2D游戏。

我正在使用扩展JComponent的类并重写paintComponent()方法来获取Graphics2D对象,然后从那里定义我的渲染逻辑。 修改后的JComponent是我覆盖的JFramecontentPane

我的问题来了:在JFrame的后端中调用paint(Graphics)repaint()update(Graphics)什么不同? 我提到从我的“帧计时器”中调用repaint()任何东西repaint()每秒调用有问题的方法50次)时,屏幕的某些部分有时会闪烁,我清楚地告诉它进行渲染的某些内容不可见(或闪烁)迅速),一切都感觉不对。 这里有什么区别? 我试图深入研究AWT后端的源代码,直到EventQueue ,在那里以某种方式管理PaintEvent但是我停在那里,以免我的脑筋从极其丑陋的代码中解脱出来。

同样,在讨论整个repaint()我们得出的“策略”是仅重绘屏幕上与模型中确定的更改相对应的位置,从而节省了CPU / GPU的功耗。 尽管仍然需要逻辑来完成这些工作(以及动画),但下一个问题是我如何“访问”已绘制屏幕的FrameBuffer ,以便可以引用我的渲染已完成的工作。

是的,我们已经经常听到很多消息,以至于Java可能不是支持我们以最佳方式寻找的所有操作的编程语言...

我的问题来了:在JFrame的后端中调用paint(Graphics),repaint()和update(Graphics)对我的屏幕有什么不同? 我提到从我的“帧计时器”中调用repaint()之外的任何东西(每秒调用有问题的方法50次)时,屏幕的某些部分有时会闪烁,我清楚地告诉它进行渲染的某些内容不可见(或闪烁)迅速),一切都感觉不对。 这里有什么区别? 我试图深入研究AWT后端的源代码,直到EventQueue,在那里以某种方式管理PaintEvent,但是我停在那里,以免我的大脑从极其丑陋的代码中解脱出来。

在Swing中计划绘画是RepaintManager的职责。 (除其他事项外)它负责确定应用程序的哪些区域需要重新粉刷,并安排这些更新发生在事件调度线程的上下文中。

何时可能发生重新绘制完全取决于重新绘制管理器。 重涂哪些区域还取决于重涂管理器,重涂管理器可以选择将多个重涂请求合并到单个重涂事件中,从而节省时间和CPU。

通常,除了不能实际创建图形上下文外,您永远不要调用paint(Graphics)update(Graphics) ,重绘管理器会为您完成此操作。 即使您要打印屏幕,也应该使用组件的print(Graphics)方法,除了它没有双重缓冲之外,还有一些与尝试将缓冲区复制回本机对等项有关的问题;)

通常会发生闪烁,因为您是在非双缓冲的上下文中绘画,例如覆盖paint而不是paintComponent 一般来说,在极少数情况下,您实际上需要重写顶级容器(如JFramepaint方法

同样,在讨论整个repaint()时,我们得出的“策略”是仅重绘屏幕上与模型中确定的更改相对应的位置,从而节省了CPU / GPU的功耗。 尽管仍然需要逻辑来完成这些工作(以及动画),但下一个问题是我如何“访问”已绘制屏幕的FrameBuffer,以便可以引用我的渲染已完成的工作。

通常,除非确实有需要,否则不要担心。 如果您对重新绘制的代码很谨慎(实际上您可以安排要重新绘制的区域,而不是重新绘制整个组件),那么您实际上就不需要关心。 确保您使用的是JComponent的祖先并使用paintComponent方法,并且获得了自动双缓冲...

另一个问题是,您真的不知道某个组件何时会自行请求重绘,例如响应鼠标移动或组件属性更改...

访问“帧缓冲区”可能实际上不是一个好主意,最好是生成自己的缓冲区(使用BufferedImage类的东西),渲染到该缓冲区,然后将其渲染到屏幕上(屏幕外缓冲)。 这样,您将生成自己的“ FrameBuffer”

现在,如果您真的很绝望,可以看看BufferStrategy

但是我建议您在进一步研究之前先看一下AWT和Swing中的绘画 ,这将使您对绘画的工作方式有更深入的了解。

而且,永远不要以为自己在控制之中,而你却没有。 如果尝试“控制”,请准备好让事情迅速浮现。 了解流程并使用它。

看一下这些(简单的)示例...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM