java高效重绘移动对象

时间:2015-10-02 20:34:28

标签: java swing graphics awt repaint

我想知道在我的情况下最有效的重绘方法是什么,以及如何去做。

我有JFrame,其中包含JPanel。此JPanel包含一些AWT图形。其中一些图形是固定的,它们不会移动。此面板中的其他一些图形(在固定图形之上)会移动。布局每3秒更新一次。固定的图形需要相当多的数学绘制,所以我可能不想重新绘制所有图形,但只重绘移动的图形。

这是我提出的可能性:

  1. 将固定图形和移动图形放在两个单独的面板上,只重绘一个相互重叠的面板。
  2. 向面板添加两个不同的Graphics对象(一个用于固定图形,一个用于移动),仅重绘一个图形对象。 (这甚至可能吗?)
  3. 也许还有其他一些我不知道的方式?

2 个答案:

答案 0 :(得分:3)

与其他人一样,使用BufferedImage作为固定对象。对于移动对象,您应该计算需要重绘的区域的边界(即,对于移动的所有对象,旧边界框联合w /新边界框)。首先将该区域的固定图形部分向下,然后将移动的对象blit。

如果您还没有,也应该查看double buffering。绘制到屏幕外缓冲区然后在准备好时翻转到屏幕通常是一种更好的体验。

答案 1 :(得分:2)

如果窗口的生命周期中背景永远不会改变,那么你可以在构造时完成所有复杂的计算,并为它创建一个BufferedImage对象。

然后在重绘中,使用

将图像绘制到图形对象上
graphics.drawImage( bufferedImage, ... )

这比重新计算每次重绘的背景要快得多,因为你一遍又一遍地重复使用相同的BufferedImage

修改 如果调整窗口大小,您可以使用

扩展bufferedImage,如果它足够好用于您的目的
boolean Graphics.drawImage(Image img,
   int dstx1, int dsty1, int dstx2, int dsty2,
   int srcx1, int srcy1, int srcx2, int srcy2,
   ImageObserver observer);

方法,其中坐标是窗口的当前大小。

如果您需要在调整大小的窗口上重新计算背景图像,可以添加一个侦听器来侦听调整大小事件。

this.addComponentListener(new ComponentAdapter() 
{  
    public void componentResized(ComponentEvent evt) {           
        //...
    }
});