优化Java图形处理

3
我有一个为我的Java应用程序绘制的自定义UI。目前,我从头开始绘制整个UI。我知道UI的某些部分是静态的。我知道我可以将这些静态部分保存为图像,但这样做是否会提高性能(因为即使图像也必须在每个帧中绘制)?
在UI绘制完成后,保存Graphics2D对象的引用并将其分配给新的图形对象每帧是否可行(从绘制所有静态组件的点开始)?
提前感谢, Alan

我非常确定,所以我不会把这个作为答案。我认为你可以重写paint()方法并只绘制更新的项目,但这将要求你始终知道需要重新绘制什么。如果你只是想加快速度,也许可以看看这个:http://java.sun.com/docs/books/tutorial/extra/fullscreen/doublebuf.html - Viele
当你说“我从头开始绘制整个UI”时,你是在哪里进行这个操作的?你有一个自定义的JComponent还是有一个包含多个自定义组件的JFrame? - Justin
3个回答

2

在每一帧中,您不需要重新绘制所有内容。因此,如果您的UI有静态部分(甚至是动态部分,您知道自上一帧以来它们没有更改),则根本不需要重绘它们。

在我的代码中(主要是Swing游戏和模拟),我通常尝试遵循以下规则:

  1. 预先准备好静态图像(例如用于UI元素的BufferedImage纹理)
  2. 为每个UI元素单独覆盖paintComponent()方法以进行绘画
  3. 仅当我知道某些内容已更改时才调用任何给定UI元素的repaint()方法
  4. 为动画调用基于计时器的repaint()循环,但仅在正在进行动画处理的UI部分上调用它(例如嵌套的JPanel)

这种方法似乎工作得很好,并且表现良好(尽管如果有改进方法,我欢迎评论!)


3a. 让repaint方法检查一个dirty布尔值,当组件需要重新绘制时将其设置为true。 我认为这就是Swing用来加速重绘过程的方法。 - Gilbert Le Blanc

2
这里有两种主要的优化方法。第一种是确保在重新绘制UI时,通常通过调用repaint来完成,要确保调用指定已更改的矩形的repaint版本。只需使矩形足够大以包含实际更改的部分,而不是静态部分。为了使其有效,您还必须注意在paint()中传递给您的Graphics2D对象中的clipRect。系统使用它告诉您需要重新绘制的内容,通常是您传递给repaint的矩形。不要绘制完全位于该矩形外部的任何内容。
您还可以通过将界面的静态部分缓存到图像中来获得显着的性能提升。编写图像是将事物显示在屏幕上最快的方法。我的测量结果表明,即使是几个简单的绘图基元,小图像也比它们更快。但是,您需要确保图像特征与屏幕匹配,可以使用createCompatibleImage()。
当然,您可能会使用大量内存来获得这种加速。我建议在实施之前进行测试以确定是否需要进行图像缓存。

1

如果屏幕的某些部分完全静态,则永远不要重新绘制该部分。不要进行全屏/窗口清除,只需清除屏幕/窗口中始终变化的部分。

这样,您就不会不必要地重新绘制静态图像。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接