我有一个例程可以在滚动 Pane 中绘制一个疯狂的大图。在添加到滚动 Pane 之前,它太大了以至于无法绘画-所需的内存将是几场演出。

由于图形的大小,我在滚动 Pane 的子级的paint方法中绘制了图表。效果很好,但是我注意到每次移动滚动条时,我的绘制例程都会被调用两次-一次是将裁剪矩形等于未覆盖区域滚动到第二次,第二次是将裁剪矩形等于视口(viewport)的尺寸。

例如,如果我的视口(viewport)是245x195,并且我向下滚动了3个像素,则我的绘画例程将使用g.getClipBounds()设置来调用,如下所示:

java.awt.Rectangle[x=0,y=195,width=245,height=3]
java.awt.Rectangle[x=0,y=3,width=245,height=195]

...因为我在绘画例程中进行渲染,这会导致闪烁(我会尽我所能地快速计算,但我想会有一点点延迟)。问题:
  • 有人知道如何防止第二次绘画比赛吗? 这是我在这里做的简单的JScrollPane东西-我有一个组件,将其添加到滚动 Pane ,将滚动 Pane 添加到父组件。即使在第一个图像滚动演示@ the swing tutorial中,您也可以看到此行为。
  • 如果对#1的回答是'nope':,谁能想到解决此问题的好方法? s我应该绘制某种图像缓冲区,跟踪最近的绘制调用并在可能的情况下复制图像吗?我无法想象这比重新渲染要快得多,但是任何见识都值得赞赏:-)
  • 最佳答案

    我在.NET世界中遇到了这个问题。双缓冲应该可以解决您的问题。

    如果直接在屏幕上显示的表面上渲染,则无法控制“显示”的实际时间。通常发生的情况是:开始渲染,尚未完成的图像显示在屏幕上,完成渲染,然后最终显示在屏幕上。

    如果您通过清除背景色来开始渲染逻辑,那么它将看起来像是闪烁的。双缓冲可以防止这种情况,因为它总是从完整的渲染中显示。可能发生的最坏情况是轻微的“撕裂”,但这仅在快速变化的动画中才可见。

    即使您只想渲染巨大图像的一部分,仍然可以使用此技术。只需将所需的内容渲染到屏幕外的表面上即可(这是所需可见部分的大小)。然后,完成操作后,一次将整个图像绘制到显示表面上。

    关于java - 为什么我的jscrollpane在java swing中导致奇怪的绘画调用?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/566711/

    10-13 01:14