【问题标题】:Why does my jscrollpane result in odd paint calls in java swing?为什么我的 jscrollpane 会在 java swing 中导致奇怪的绘制调用?
【发布时间】:2010-10-08 16:17:14
【问题描述】:

我有一个例程,可以在滚动窗格内绘制一个非常大的图形。在添加到滚动窗格之前,它太大了,无法绘制 - 内存要求将是几场演出。

由于图表的大小,我在滚动窗格子项的绘制方法中渲染图表。效果很好,但是我注意到每次移动滚动条时,我的绘制例程都会被调用两次——一次是剪切矩形等于滚动到的未覆盖区域,第二次是剪切矩形等于视口的尺寸.

例如,如果我的视口是 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]

...因为我在绘制例程中渲染这会导致闪烁(我尽可能快地进行计算,但我猜会有一点延迟)。问题:

  1. 有谁知道如何防止第二次绘制调用?这是我在这里做的简单的 JScrollPane 东西 - 我有一个组件,我将它添加到滚动窗格中,我将滚动窗格添加到父组件。即使在第一个图像滚动演示 @the swing tutorial 中,您也可以看到这种行为。

  2. 如果 #1 的答案是“不”:谁能想出一个好的方法来处理这个问题?我应该在某种图像缓冲区中绘制,跟踪最近的绘制调用并尽可能复制图像?我无法想象这比重新渲染要快得多,但任何见解都值得赞赏:-)

【问题讨论】:

    标签: java swing graphics jscrollpane


    【解决方案1】:

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

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

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

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

    【讨论】:

    • 我唯一的问题是我无法缓冲整个图像 - 它太大了。这意味着我需要在绘制缓冲部分时保留它们,在调用paint() 时检查覆盖范围并根据需要将它们缝合在一起。我想我会试一试,但我会推迟看看是否有其他人有任何想法
    • 好吧,双缓冲仍然可以发挥作用。只需在屏幕外表面(可见部分的大小)上渲染您需要的内容。完成后,一举将整个图像绘制到显示表面上。
    • 实际上,这行得通。谢谢 :-) 滚动有点慢,但闪烁消失了。对不起,我没有先得到它@ - 我的愚蠢无法与你的毅力相提并论;-)
    • 哦,不用担心。在你发表评论之前,我实际上并不明白你画的东西那么大。唯一能让它更快的方法是改进你的绘图逻辑,但总会有一些延迟。祝你好运。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-01
    • 2014-09-18
    • 1970-01-01
    • 2018-09-16
    • 1970-01-01
    相关资源
    最近更新 更多