Thanks to Greg and Allen for pointing me in the right direction.
(Greg:)
> When the Playhead is moved, the appropriate response is to redraw only
> those portions of the off-screen PlayableTrack image where the Playhead WAS
> and where it is NOW. This redraw can be optimized so that:
> a) if the position didn't visibly move, nothing is redrawn.
> b) if the position moved incrementally, a single blit occurs.
> c) if the position moved less than a certain distance, a single blit occurs.
> d) if the position moved farther, two blits occur.
> e) if the PlayableTrack changed, a single blit occurs.
(Allen:)
> So render the entire chart into a BufferedImage. Once. And only
> update if the component is resized or made incompatible w/the
> BufferedImage. Then in the paint() method blit the image into the
> current Graphics instance. Then composite the playhead onto the image
> using an appropriate compositing rule. This doesn't require
> repainting the track image since it's pre-rendered.
Well this is exactly what I'd been proposing; I just hadn't been sure how to
implement it. I agree completely with your assessments of the proper
algorithm; my main area of cluelessness is how to do these things in Java.
Thanks in particular for the tips about implementing my own XOR drawing and
possibly getting even trickier with low-res off-screen buffers. I'm somewhat
hoping it doesn't come to the latter trick, but you've got a point about not
relying on XOR as implemented by any given platform. Ideally I'd like to
just paint the playhead onto a fresh blit of the last valid sequence view,
or even maintain a separate off-screen image for the playhead, so hopefully
XOR won't be needed beyond the prototype code.
That reminds me, should I be planning any special tricks given that the
SequenceComponent is Scrollable? I mean, JViewport *already* maintains a
pretty large off-screen buffer independent of the JRootPane buffer, right?
It would be nice if I could reuse that somehow...
> ...
> // synchronized fetch of buffered image
> BufferedImage bi = component.getRenderingBuffer();
> ...
> Graphics2D g2d = bi.createGraphics();
> ...
> g2d.dispose();
> component.setRenderedBuffer();
Aha! This is the tip I needed. :) Clearly I need yet another book. The other
code snippets look helpful as well, but I think I ought to call it a day for
now. Just curious -- I have been using Graphic Java vols. I & II (Sun
Microsystems Press) which are generally useful guides to Swing/AWT, but do
not seem to go into enough depth around these finer graphical points. What
book would any of you recommend as a further supplement?
> What you're doing isn't going to work... You're not adhering to the Swing
> "contract" that dictates when and how to paint.
>
> I think in almost all situations you're going to want to perform *all* your
> painting inside the paint()/paintBorder()/paintChildren() methods.
Hmmm. I actually got it to work OK (sans XORMode) and it definitely seems to
be working faster than calling repaint() could. The app I'm building needs
to display up to 4 pretty high-quality synchronized videos (each about
300x300) and slave the sequence view to these videos. Believe it or not,
I've now got it working with 3 videos and semi-successfully rendering my
sequence view with a moving playhead and am managing to render the playhead
about every other frame for 30 fps videos all using my very naive algorithms
(this is prototype code). This is on OS X and a 733 G4, which is roughly our
projected baseline hardware. I'll post a stable version for the curious once
I've got one; we plan to GPL the project once its past prototyping.
===========================================================================
To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
of the message "signoff JAVA2D-INTEREST". For general help, send email to
[EMAIL PROTECTED] and include in the body of the message "help".