简体   繁体   English

为什么我的jscrollpane导致java swing中的奇怪绘制调用?

[英]Why does my jscrollpane result in odd paint calls in java swing?

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

... 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. 这是简单的JScrollPane我正在做的事情 - 我有一个组件,我将它添加到滚动窗格,我将滚动窗格添加到父组件。 You can see this behavior even in the first image scrolling demo @ the swing tutorial . 即使在第一个图像滚动演示@ swing教程中,您也可以看到此行为。

  2. If the answer to #1 is 'nope': can anyone think of a good way to deal with this ? 如果#1的答案是'不',那么有人能想出一个很好的方法来解决这个问题吗? 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 :-) 我无法想象这比重新渲染要快得多,但任何洞察力都值得赞赏:-)

I've ran into this issue in the .NET world. 我在.NET世界中遇到过这个问题。 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. 然后,当您完成后,将整个图像一下子绘制到显示器表面上。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM