java在移动对象上的高效重绘

java在移动对象上的高效重绘,java,swing,graphics,awt,repaint,Java,Swing,Graphics,Awt,Repaint,我想知道在我的情况下,什么是最有效的重新粉刷方式,以及如何进行 我有一个JFrame,包含一个JPanel。此JPanel包含一些AWT图形。有些图形是固定的,它们不会移动。此面板中的某些其他图形(位于固定图形的顶部)确实会移动。布局每3秒更新一次。固定图形需要相当多的数学来绘制,因此我可能不想重新绘制所有图形,而只绘制移动图形 这就是我想到的可能性: 将固定图形和移动图形放置在两个单独的面板中,并仅重新绘制一个面板,该面板相互重叠 将两个不同的图形对象添加到面板(一个用于固定图形,一个用于移动

我想知道在我的情况下,什么是最有效的重新粉刷方式,以及如何进行

我有一个
JFrame
,包含一个
JPanel
。此
JPanel
包含一些AWT图形。有些图形是固定的,它们不会移动。此面板中的某些其他图形(位于固定图形的顶部)确实会移动。布局每3秒更新一次。固定图形需要相当多的数学来绘制,因此我可能不想重新绘制所有图形,而只绘制移动图形

这就是我想到的可能性:

  • 将固定图形和移动图形放置在两个单独的面板中,并仅重新绘制一个面板,该面板相互重叠
  • 将两个不同的
    图形
    对象添加到面板(一个用于固定图形,一个用于移动)并仅重新绘制一个图形对象。(这可能吗?)
  • 也许还有别的方式我不知道

  • 如果背景在窗口的生命周期内从未更改,则可以在构建时执行一次所有复杂的计算,并为其创建一个
    buffereImage
    对象

    然后在重新绘制中,使用

    graphics.drawImage( bufferedImage, ... )
    
    这应该比每次重新绘制时重新计算背景要快得多,因为您要反复使用相同的
    buffereImage

    编辑 如果调整了窗口的大小,您可以使用

    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) {           
            //...
        }
    });
    

    正如其他人所说,对固定对象使用
    buffereImage
    。对于移动的对象,应计算需要重新绘制的区域的边界(即,所有移动的对象的旧边界框并集和新边界框)。首先向下单击该区域的固定图形部分,然后单击移动的对象


    如果还没有,你也应该调查一下。通常,在屏幕外缓冲区绘图,然后准备好后再切换到屏幕是一种更好的体验。

    “固定的图形需要一点安静的数学来绘制..”将它们绘制到
    缓冲区图像
    ,然后首先绘制图像。@AndrewThompson然后每次我仍然必须重新绘制缓冲区图像,对吗?如何确保在调整窗口大小时重新计算BuffereImage?“…在调整窗口大小时重新计算?”是否需要重新计算,或只是拉伸以填充新大小?“那么我每次还是要重新绘制BuffereImage,对吗?”当然,但绘制图像非常快。@Xander更新了回答,以解决您的调整大小问题我实现了这个解决方案,但与直接在面板上绘制图形相比,我在将图形绘制到BuffereImage然后再绘制到面板时,会损失很多质量。为什么会这样?关于如何解决这个问题,你有什么建议吗?听起来你的缓冲图像与你的面板相比不是一个好的尺寸?也许缩放会使图像变得太块状?如果是这样的话,请尝试我的第二种解决方案,即在调整组件大小时重新创建BuffereImage