Re: 3D displays flicker?

There is a discussion of this type of problem in the Java Programmer's
FAQ: (see below)

Let me know if you solve the problem. I haven't looked into it yet.


32.(Sect. 10) I've made a Lightweight Component (a Component directly
extending Component), and it
     keeps flickering/doesn't repaint itself properly. Why is this? 

       Lightweight Components, since they are notionally meant to be
"transparent", aren't painted directly in response
     to repaint(), but in fact, Component.repaint() goes up the stack of
Components until it finds an "Opaque"
     Heavyweight Component (necessarily a Container), and then calls
repaint() on *that*. 

     At this point, a call is eventually scheduled to
Container.update(). His first action is to call super.update, plunging
     us into Component.update(), which clears the component to the
background color, since it has been called on a
     heavyweight, and returns. Then Container.update() proceeds merrily
to call update on all contained Lightweight
     Components, recursively. 

     The bottom line: "transparency" of lightweight components will only
work correctly (without flickering) if the first
     upwardly accessible heavyweight component in the containment
hierarchy is 
         a double-buffered heavyweight Component (necessarily a
Container), or 
         a heavyweight that never updates, but always paints (i.e. one
that has overriden the default update()
         mechanism to not clear the background). 
     If this is not done, the default Component update() will always
clear the background before any repainting is done,
     leading to annoying flickering. 

     Another important point is that if your Container has its own
paint() method, that paint method of the container
     must call super.update/paint(), otherwise the contained lightweight
components will never be painted. Putting this
     all together, the minimal alteration to code to cause it to work in
this case is to place the method 

     public void update(Graphics g) {

     in the most closely containing heavyweight Container, in a
Component hierarchy where you want to smoothly
     render lightweights that do not paint areas extending past that
painted by their parents, i.e. ones that are not
     "transparent". This is dirty, but quick. 

     If you want smooth transparency, the call above should read 

       public void update(Graphics g) {
         // standard offscreen generation here.
         offg.fillRect(required background colour, full size);
         g.drawImage(myimage, 0, 0, null);

       public void paint(Graphics g) {
         // can generally expect resizes will hit update() first.
         g.drawImage(myimage, 0, 0, null);

     It's possible to intertwine these, by having this.update() calling
this.paint(), with various replacings of the argument,
     but it is clearest to override them separately, as in the example. 

Doug Lindholm wrote:
> Hi,
> I still see flicker issues with the latest versions of Java and Java3D.
> I suspect it is a Swing (lightweight) vs. 3D (heavyweight) issue.
> Cheers,
> Doug
> Ugo Taddei wrote:
> >
> > Hi Mark,
> >
> > Mark Thompson wrote:
> > >
> > > I've noticed that the 2D examples in the tutorial do not flicker when I 
> > > resize
> > > the JPanel window.
> > >
> > > However, the 3D examples do show a distinct flicker when they are resized.
> >
> > I've seen this. I *think* it was a problem with Java 1.2. The newer
> > version solved it.
> >
> > Cheers,
> >
> > Ugo
> >
> > >
> > > Is there any way to control this?  I thought Java3D 1.2 supported double-
> > > buffering (though I'm not sure this is a VisAD or Java3D issue, but 
> > > perhaps is
> > > a Swing or AWT issue).
> > >
> > > Any suggestions would be helpful.
> > > Thanks in advance.
> > >
> > > Mark

| Doug Lindholm, Software Engineer          |  E-mail: lind@xxxxxxxx   |
| Research Applications Program             |   Phone: 303-497-8374    |
| National Center for Atmospheric Research  |                          |
| P.O. Box 3000                             |     There's no place     |
| Boulder, Colorado 80307-3000              |        like $HOME        |