为什么我的 jscrollpane 会在 java swing 中产生奇怪的绘制调用?

发布于 2024-07-13 17:38:06 字数 850 浏览 5 评论 0原文

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

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

例如,如果我的视口是 245x195 & 我向下滚动 3 个像素,我的绘制例程被调用,设置如下:

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

... 因为我在绘制例程中渲染,这会导致闪烁(我的计算速度与我可以,但我猜会有一点延迟)。 问题:

  1. 有人知道如何防止第二次绘制调用吗?这是我在这里做的普通 JScrollPane 东西 - 我有一个组件,我将其添加到滚动窗格,我添加滚动窗格到父组件。 即使在第一个图像滚动演示中,您也可以看到此行为@ swing 教程

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

I've got a routine that paints an insanely large graph inside a scroll pane. It's too big to paint before adding to the scrollpane - the menory requirements would be several gigs.

Because of the size of the graph I'm rendering the chart within the paint method of the scrollpane's child. Which works out well, however I'm noticing that every time a scrollbar is moved my paint routine is called twice - once with a clipping rect equal to the uncovered area scrolled to, and a second time with the clipping rect equal to the viewport's dimensions.

For example if my viewport is 245x195 & I scroll down by 3 pixels my paint routine gets called with g.getClipBounds() set as follows:

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

... because I render within the paint routine this is causing flicker (I do my calcs as fast as I can, but there is a wee bit of a delay I guess). Questions:

  1. Does anyone know how to prevent the 2nd paint call? This is plain-jane JScrollPane stuff I'm doing here - I have a component, I add it to the scrollpane, I add the scrollpane to a parent component. You can see this behavior even in the first image scrolling demo @ the swing tutorial.

  2. If the answer to #1 is 'nope': can anyone think of a good way to deal with this ? Should I paint to some sort of image buffer, track recent paint calls & copy the image where possible ? I cannot imagine this being much faster than re-rendering, but any insight appreciated :-)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

单身情人 2024-07-20 17:38:06

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

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

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

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

I've ran into this issue in the .NET world. Double buffering should solve your problem.

If you're rendering directly onto a surface that is shown on the screen, you have no control over when the "showing" actually happens. What typically happens is: you start rendering, the not-yet-finished image is being displayed on the screen, you finish rendering, and then that is finally shown on the screen.

If you begin your rendering logic by clearing to a background color, then this will appear like a flash. Double buffering prevents this because it's always displaying from a completed render. The worst that could happen is slight 'tearing' but that's only noticeable in quickly changing animations.

Even if you only want to render part of a gigantic image, you can still use this technique. Simply render what you need onto an off-screen surface (which is the size of the visible portion you want). And then when you're done, draw the entire image onto your display surface in one fell swoop.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文