with a bunch of images typically 4 times the width of my paint area. Whenever i scroll the daw track I check (in my paint function) if any of the image cache images covers the area. If it does, I use it with g.drawImage(image, xPos, yPos, width, height...). If not I paint the usual way.
The image cache is held fresh with a Timeslicethread whose usetimeslice() constantly checks the track position. If it discovers the image cache is *beginning* to run dry, it creates a new Image like image = slice->createComponentSnapshot(Rectangle<int>(xPos, 0, 4 * vpWidth, slice->getHeight()), false);
I had some occasional hickups deep down in the the paint undergrowth, but that was cured with a ScopedLock preventing the normal paint thread Timeslicethread accessing my paint function simultaneously.
Before, my daw had to redraw every (visible) track whener I scrolled even a single pixel (if I didn't use any native scroll functions, which I got tired of for other reasons). Now it just splats part of an image to the screen. Much faster...