Index: javax/swing/JComponent.java =================================================================== RCS file: /cvsroot/classpath/classpath/javax/swing/JComponent.java,v retrieving revision 1.59 diff -u -r1.59 JComponent.java --- javax/swing/JComponent.java 22 Sep 2005 20:58:34 -0000 1.59 +++ javax/swing/JComponent.java 24 Sep 2005 20:06:40 -0000 @@ -341,6 +341,12 @@ boolean autoscrolls = false; /** + * Indicates whether the current paint call is already double buffered or + * not. + */ + static boolean isPaintingDoubleBuffered = false; + + /** * Listeners for events other than address@hidden PropertyChangeEvent} are * handled by this listener list. PropertyChangeEvents are handled in * address@hidden #changeSupport}. @@ -1449,9 +1455,24 @@ */ public void paint(Graphics g) { - paintComponent(g); - paintBorder(g); - paintChildren(g); + RepaintManager rm = RepaintManager.currentManager(this); + // We do a little stunt act here to switch on double buffering if it's + // not already on. If we are not already doublebuffered, then we jump + // into the method paintDoubleBuffered, which turns on the double buffer + // and then calls paint(g) again. In the second call we go into the else + // branch of this if statement and actually paint things to the double + // buffer. When this method completes, the call stack unwinds back to + // paintDoubleBuffered, where the buffer contents is finally drawn to the + // screen. + if (!isPaintingDoubleBuffered && isDoubleBuffered() + && rm.isDoubleBufferingEnabled()) + paintDoubleBuffered(g); + else + { + paintComponent(g); + paintBorder(g); + paintChildren(g); + } } /** @@ -1604,10 +1625,13 @@ void paintImmediately2(Rectangle r) { RepaintManager rm = RepaintManager.currentManager(this); + Graphics g = getGraphics(); + g.setClip(r.x, r.y, r.width, r.height); if (rm.isDoubleBufferingEnabled() && isDoubleBuffered()) - paintDoubleBuffered(r); + paintDoubleBuffered(g); else - paintSimple(r); + paintSimple(g); + g.dispose(); } /** @@ -1615,38 +1639,40 @@ * * @param r the area to be repainted */ - void paintDoubleBuffered(Rectangle r) + void paintDoubleBuffered(Graphics g) { + + Rectangle r = g.getClipBounds(); + if (r == null) + r = new Rectangle(0, 0, getWidth(), getHeight()); RepaintManager rm = RepaintManager.currentManager(this); // Paint on the offscreen buffer. - Image buffer = rm.getOffscreenBuffer(this, getWidth(), getHeight()); - Graphics g = buffer.getGraphics(); - Graphics g2 = getComponentGraphics(g); - g2.setClip(r.x, r.y, r.width, r.height); - paint(g2); - g2.dispose(); - g.dispose(); + synchronized (paintLock) + { + Image buffer = rm.getOffscreenBuffer(this, getWidth(), getHeight()); + Graphics g2 = buffer.getGraphics(); + g2 = getComponentGraphics(g); + g2.setClip(r.x, r.y, r.width, r.height); + isPaintingDoubleBuffered = true; + paint(g2); + isPaintingDoubleBuffered = false; + g2.dispose(); - // Paint the buffer contents on screen. - Graphics g3 = getGraphics(); - g3.setClip(r.x, r.y, r.width, r.height); - g3.drawImage(buffer, 0, 0, this); - g3.dispose(); + // Paint the buffer contents on screen. + g.drawImage(buffer, 0, 0, this); + } } /** * Performs normal painting without double buffering. * - * @param r the area to be repainted + * @param g the graphics context to use */ - void paintSimple(Rectangle r) + void paintSimple(Graphics g) { - Graphics g = getGraphics(); Graphics g2 = getComponentGraphics(g); paint(g2); - g2.dispose(); - g2.dispose(); } /**