【问题标题】:Java Swing heavy/slow paintComponent - any advice?Java Swing 重/慢paintComponent - 有什么建议吗?
【发布时间】:2014-06-30 01:19:14
【问题描述】:

我正在制作一个基于滚动 2D 地图/图块的游戏。每个图块(存储为 tile[21][11] - 每个地图总共 231 个图块)最多可以包含 21 个值(存储为 int[3][7])。全屏时,我一次可以看到大约 8 张地图。

平均而言,绘制每张地图大约需要 0.03 秒(通过 System.nanoTime 找到)。问题是,一旦屏幕上出现超过 1 个地图,Swing 事件轮询就会明显变慢。

有什么解决办法吗?我无法一次绘制地图以将其另存为图像,因为它具有涉及移动演员的透明度,因此更改过于频繁。此外,我认为我不能调用paintComponent 中的线程来绘制地图而不会出现故障,但我并不积极。

【问题讨论】:

  • 背景图像和图块应绘制为 BufferedImages。屏幕外的图像应该以某种方式缓存,并在需要时显示出来。您可以通过调用带参数的方法的重载来限制重绘区域。
  • 不要害怕使用多个BufferedImages 作为图层来增强效果(后/中/前景)。一般来说,这些应该只是你需要的那么大,只有在新内容发生变化时才拼接
  • 另请参阅duplicate
  • 享元模式 == 好。 1+ 到@trashgod 的答案(但在很久以前给出)。
  • 我的 Tiles 不是任何类型的 JComponent,它只是数据。我将他们的容器称为“地图窗格”,它在其paintComponent 中绘制所有图块。绘制时,所有瓦片共享一个称为“瓦片集”的缓冲图像,它们的数据告诉代码要绘制哪个部分。我认为这是我能得到的最轻量级的。绘画仍然很快,但就像我说的那样,它足以减慢用户输入处理。

标签: java performance swing paint event-dispatch-thread


【解决方案1】:

我的Tiles 不是任何类型的JComponent,它们只是数据。我将他们的容器称为MapPane,它会在其paintComponent 中绘制所有图块。

同样,JTable 单元格只是在JComponent 中呈现的数据;提到here 的享元模式仍然适用:目标是省略渲染不可见单元格的任何努力。 Profileself-time 以优化渲染;在KineticModel 引用的here 中检查了一些方法。

不需要缩放的BufferedImage 是最好的。如果您必须缩放,请尝试与插值类型相关的RenderingHints。如果合成成本太高,使用SwingWorker在后台构建地图; publish() 他们可用时,process() 他们在 EDT 上,如 here 所示。

【讨论】:

    猜你喜欢
    • 2012-11-24
    • 2018-12-13
    • 2015-06-08
    • 2014-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多