In the spirit of my last few AWT patches, I pulled all the lightweight handling out of GLightweightPeer into the AWT. The idea is that the GLightweightPeer can't do anything on it's own anyway, and the AWT can do all this stuff as well, only more efficient. So what I did is:

- make GLightweightPeer a complete stub, basically
- let the Toolkit use one shared instance of GLightweightPeer for all lightweight components, basically only a marker object now - rewrote some parts of Component and Container so that only heavyweight peers are bothered to do real stuff. The lightweight 'translation' is handled inside Component/Container now - some methods used recursive calls, which looks good in CS courses, but in the real world the iterative approach is more effcient (think about all those saved method calls, local variables, stack unwinding etc et al). I have reimplemented this as iterative algos

All this should save us some bytes per component and some cycles in many Component method calls.

I have checked this against Mauve with no regressions (at least none caused by that patch). Also, some Swing apps (I tested our Demo, the Java2D demo and foxhunt) still seem to work pretty.

Is this ok for everybody to go into the release?

2006-07-27  Roman Kennke  <[EMAIL PROTECTED]>

        * java/awt/Component.java
        (getToolkit): Search for heavyweight parent and query the
        heavyweight's peer.
        (checkImage(Image,int,int,ImageObserver)): Likewise.
        (checkImage(ImageProducer)): Likewise.
        (createImage(int,int)): Likewise.
        (createVolatileImage(int,int)): Likewise.
        (createVolatileImage(int,int,ImageCapabilities)): Likewise.
        (getFontMetrics): Likewise.
        (getGraphics): Likewise.
        (getLocationOnScreen): Likewise.
        (prepareImage): Likewise.
        (setCursor): Likewise.
        (repaint): Added null check.
        * java/awt/Container.java
        (insets): For lightweights, return (0,0,0,0).
        * java/awt/Toolkit.java
        (lightweightPeer): New static field.
        (createComponent): Return shared instance of GLightweightPeer.
        * gnu/java/awt/peer/GLightweightPeer.java: Made all methods
        stubs and added comment.

/Roman
Index: gnu/java/awt/peer/GLightweightPeer.java
===================================================================
RCS file: /cvsroot/classpath/classpath/gnu/java/awt/peer/GLightweightPeer.java,v
retrieving revision 1.9
diff -u -1 -2 -r1.9 GLightweightPeer.java
--- gnu/java/awt/peer/GLightweightPeer.java	7 May 2006 00:13:45 -0000	1.9
+++ gnu/java/awt/peer/GLightweightPeer.java	27 Jul 2006 20:40:27 -0000
@@ -45,321 +45,382 @@
 import java.awt.Component;
 import java.awt.Cursor;
 import java.awt.Dimension;
 import java.awt.Font;
 import java.awt.FontMetrics;
 import java.awt.Graphics;
 import java.awt.GraphicsConfiguration;
 import java.awt.Image;
 import java.awt.Insets;
 import java.awt.Point;
 import java.awt.Rectangle;
 import java.awt.Toolkit;
-import java.awt.event.MouseAdapter;
-import java.awt.event.MouseEvent;
 import java.awt.event.PaintEvent;
 import java.awt.image.ColorModel;
 import java.awt.image.ImageObserver;
 import java.awt.image.ImageProducer;
 import java.awt.image.VolatileImage;
-import java.awt.peer.ComponentPeer;
 import java.awt.peer.ContainerPeer;
 import java.awt.peer.LightweightPeer;
 
-/*
- * Another possible implementation strategy for lightweight peers is
- * to make GLightweightPeer a placeholder class that implements
- * LightweightPeer.  Then the Component and Container classes could
- * identify a peer as lightweight and handle it specially.  The
- * current approach is probably more clear but less efficient.
- */
-
 /**
  * A stub class that implements the ComponentPeer and ContainerPeer
  * interfaces using callbacks into the Component and Container
  * classes.  GLightweightPeer allows the Component and Container
  * classes to treat lightweight and heavyweight peers in the same way.
  *
  * Lightweight components are painted directly onto their parent
  * containers through an Image object provided by the toolkit.
  */
 public class GLightweightPeer 
   implements LightweightPeer, ContainerPeer
 {
-  private Component comp;
-
-  private Insets containerInsets;
-
-  public GLightweightPeer(Component comp)
+  public GLightweightPeer()
   {
-    this.comp = comp;
+    // Nothing to do here.
   }
 
   // -------- java.awt.peer.ContainerPeer implementation:
   
   public Insets insets()
   {
-    return getInsets ();
+    // Nothing to do here for lightweights.
+    return null;
   }
   
   public Insets getInsets()
   {
-    if (containerInsets == null)
-      containerInsets = new Insets (0,0,0,0);
-    return containerInsets;
+    // Nothing to do here for lightweights.
+    return null;
   }
   
   public void beginValidate()
   {
+    // Nothing to do here for lightweights.
   }
   
   public void endValidate()
   {
+    // Nothing to do here for lightweights.
   }
   
   public void beginLayout()
   {
+    // Nothing to do here for lightweights.
   }
   
   public void endLayout()
   {
+    // Nothing to do here for lightweights.
   }
   
   public boolean isPaintPending()
   {
+    // Nothing to do here for lightweights.
     return false;
   }
 
   // -------- java.awt.peer.ComponentPeer implementation:
 
   public int checkImage(Image img, int width, int height, ImageObserver o)
   {
-    return comp.getToolkit().checkImage(img, width, height, o);
+    // Nothing to do here for lightweights.
+    return -1;
   }
 
   public Image createImage(ImageProducer prod)
   {
-    return comp.getToolkit().createImage(prod);
+    // Nothing to do here for lightweights.
+    return null;
   }
 
   /* This method is not called. */
   public Image createImage(int width, int height)
   {
+    // Nothing to do here for lightweights.
     return null;
   }
 
-  public void disable() {}
+  public void disable()
+  {
+    // Nothing to do here for lightweights.
+  }
 
-  public void dispose() {}
+  public void dispose()
+  {
+    // Nothing to do here for lightweights.
+  }
 
-  public void enable() {}
+  public void enable()
+  {
+    // Nothing to do here for lightweights.
+  }
 
   public GraphicsConfiguration getGraphicsConfiguration()
   {
+    // Nothing to do here for lightweights.
     return null;
   }
 
   public FontMetrics getFontMetrics(Font f)
   {
-    return comp.getToolkit().getFontMetrics(f);
+    // Nothing to do here for lightweights.
+    return null;
   }
 
   /* Returning null here tells the Component object that called us to
    * use its parent's Graphics. */
   public Graphics getGraphics()
   {
+    // Nothing to do here for lightweights.
     return null;
   }
 
   public Point getLocationOnScreen()
   {
-    Point parentLocation = comp.getParent().getLocationOnScreen();
-    return new Point (parentLocation.x + comp.getX(),
-                      parentLocation.y + comp.getY());
+    // Nothing to do here for lightweights.
+    return null;
   }
 
   public Dimension getMinimumSize()
   {
-    return new Dimension(comp.getWidth(), comp.getHeight());
+    return minimumSize();
   }
 
-  /* A lightweight component's preferred size is equivalent to its
-   * Component width and height values. */
   public Dimension getPreferredSize()
   {
-    return new Dimension(comp.getWidth(), comp.getHeight());
+    return preferredSize();
   }
 
   /* Returning null here tells the Component object that called us to
    * use its parent's Toolkit. */
   public Toolkit getToolkit()
   {
+    // Nothing to do here for lightweights.
     return null;
   }
 
-  public void handleEvent(AWTEvent e) {}
+  public void handleEvent(AWTEvent e)
+  {
+    // Nothing to do here for lightweights.
+  }
 
-  public void hide() {}
+  public void hide()
+  {
+    // Nothing to do here for lightweights.
+  }
 
   public boolean isFocusable() 
   {
+    // Nothing to do here for lightweights.
     return false;
   }
 
   public boolean isFocusTraversable()
   {
+    // Nothing to do here for lightweights.
     return false;
   }
 
   public Dimension minimumSize()
   {
-    return getMinimumSize();
+    return new Dimension(0, 0);
   }
 
   public Dimension preferredSize()
   {
-    return getPreferredSize();
+    return new Dimension(0, 0);
   }
 
-  public void paint(Graphics graphics) {}
+  public void paint(Graphics graphics)
+  {
+    // Nothing to do here for lightweights.
+  }
 
   public boolean prepareImage(Image img, int width, int height,
 			      ImageObserver o)
   {
-    return comp.getToolkit().prepareImage(img, width, height, o);
+    // Nothing to do here for lightweights.
+    return false;
   }
 
-  public void print(Graphics graphics) {}
+  public void print(Graphics graphics)
+  {
+    // Nothing to do here for lightweights.
+  }
 
   public void repaint(long tm, int x, int y, int width, int height)
   {
-    Component p = comp.getParent();
-    if (p != null)
-      p.repaint(tm, x + comp.getX(), y + comp.getY(), width, height);
+    // Nothing to do here for lightweights.
   }
 
-  public void requestFocus() {}
+  public void requestFocus()
+  {
+    // Nothing to do here for lightweights.
+  }
 
-  public boolean requestFocus(Component source, boolean bool1, boolean bool2, long x)
+  public boolean requestFocus(Component source, boolean bool1, boolean bool2,
+                              long x)
   {
+    // Nothing to do here for lightweights.
     return false;
   }
 
-  public void reshape(int x, int y, int width, int height) {}
+  public void reshape(int x, int y, int width, int height)
+  {
+    // Nothing to do here for lightweights.
+  }
 
-  public void setBackground(Color color) {}
+  public void setBackground(Color color)
+  {
+    // Nothing to do here for lightweights.
+  }
 
-  public void setBounds(int x, int y, int width, int height) {}
+  public void setBounds(int x, int y, int width, int height)
+  {
+    // Nothing to do here for lightweights.
+  }
 
   /**
    * Sets the cursor on the heavy-weight parent peer.
    * Called by the MouseListener on mouse enter.
    */
   public void setCursor(Cursor cursor)
   {
-    Component p = comp.getParent();
-    while (p != null && p.isLightweight())
-      p = p.getParent();
-
-    if (p != null)
-      {
-	// Don't actually change the cursor of the component
-	// otherwise other childs inherit this cursor.
-	ComponentPeer peer = p.getPeer();
-	if (peer != null)
-	  peer.setCursor(cursor);
-      }
+    // Nothing to do here for lightweights.
   }
 
-  public void setEnabled(boolean enabled) {}
+  public void setEnabled(boolean enabled)
+  {
+    // Nothing to do here for lightweights.
+  }
 
-  public void setEventMask(long eventMask) {}
+  public void setEventMask(long eventMask)
+  {
+    // Nothing to do here for lightweights.
+  }
 
-  public void setFont(Font font) {}
+  public void setFont(Font font)
+  {
+    // Nothing to do here for lightweights.
+  }
 
-  public void setForeground(Color color) {}
+  public void setForeground(Color color)
+  {
+    // Nothing to do here for lightweights.
+  }
 
-  public void setVisible(boolean visible) {}
+  public void setVisible(boolean visible)
+  {
+    // Nothing to do here for lightweights.
+  }
 
-  public void show() {}
+  public void show()
+  {
+    // Nothing to do here for lightweights.
+  }
 
-  public ColorModel getColorModel ()
+  public ColorModel getColorModel()
   {
-    return comp.getColorModel ();
+    // Nothing to do here for lightweights.
+    return null;
   }
 
   public boolean isObscured()
   {
+    // Nothing to do here for lightweights.
     return false;
   }
 
   public boolean canDetermineObscurity()
   {
+    // Nothing to do here for lightweights.
     return false;
   }
 
-  public void coalescePaintEvent(PaintEvent e) { }
+  public void coalescePaintEvent(PaintEvent e)
+  {
+    // Nothing to do here for lightweights.
+  }
 
-  public void updateCursorImmediately() { }
+  public void updateCursorImmediately()
+  {
+    // Nothing to do here for lightweights.
+  }
 
   public VolatileImage createVolatileImage(int width, int height) 
   { 
+    // Nothing to do here for lightweights.
     return null; 
   }
 
   public boolean handlesWheelScrolling()
   {
+    // Nothing to do here for lightweights.
     return false;
   }
 
   public void createBuffers(int x, BufferCapabilities capabilities) 
-    throws AWTException { }
+    throws AWTException
+  {
+    // Nothing to do here for lightweights.
+  }
 
   public Image getBackBuffer()
   {
+    // Nothing to do here for lightweights.
     return null;
   }
 
-  public void flip(BufferCapabilities.FlipContents contents) { }
+  public void flip(BufferCapabilities.FlipContents contents)
+  {
+    // Nothing to do here for lightweights.
+  }
 
-  public void destroyBuffers() { }
+  public void destroyBuffers()
+  {
+    // Nothing to do here for lightweights.
+  }
 
   public boolean isRestackSupported()
   {
+    // Nothing to do here for lightweights.
     return false;
   }
 
   public void cancelPendingPaint(int x, int y, int width, int height)
   {
-    
+    // Nothing to do here for lightweights.
   }
 
   public void restack()
   {
-    
+    // Nothing to do here for lightweights.
   }
 
   public Rectangle getBounds()
   {
+    // Nothing to do here for lightweights.
     return null;
   }
 
   public void reparent(ContainerPeer parent)
   {
-    
+    // Nothing to do here for lightweights.
   }
 
   public void setBounds(int x, int y, int z, int width, int height)
   {
-    
+    // Nothing to do here for lightweights.
   }
 
   public boolean isReparentSupported()
   {
-    return false;
+    // Nothing to do here for lightweights.
+    return true;
   }
 
   public void layout()
   {
-    
+    // Nothing to do here for lightweights.
   }
 }
Index: java/awt/Component.java
===================================================================
RCS file: /cvsroot/classpath/classpath/java/awt/Component.java,v
retrieving revision 1.139
diff -u -1 -2 -r1.139 Component.java
--- java/awt/Component.java	27 Jul 2006 14:29:27 -0000	1.139
+++ java/awt/Component.java	27 Jul 2006 20:40:31 -0000
@@ -732,34 +732,41 @@
   {
     return treeLock;
   }
 
   /**
    * Returns the toolkit in use for this component. The toolkit is associated
    * with the frame this component belongs to.
    *
    * @return the toolkit for this component
    */
   public Toolkit getToolkit()
   {
-    if (peer != null)
+    // Only heavyweight peers can handle this.
+    ComponentPeer p = peer;
+    Component comp = this;
+    while (p instanceof LightweightPeer)
       {
-        Toolkit tk = peer.getToolkit();
-        if (tk != null)
-          return tk;
+        comp = comp.parent;
+        p = comp == null ? null : comp.peer;
       }
-    // Get toolkit for lightweight component.
-    if (parent != null)
-      return parent.getToolkit();
-    return Toolkit.getDefaultToolkit();
+
+    Toolkit tk = null;
+    if (p != null)
+      {
+        tk = peer.getToolkit();
+      }
+    if (tk == null)
+      tk = Toolkit.getDefaultToolkit();
+    return tk;
   }
 
   /**
    * Tests whether or not this component is valid. A invalid component needs
    * to have its layout redone.
    *
    * @return true if this component is valid
    * @see #validate()
    * @see #invalidate()
    */
   public boolean isValid()
   {
@@ -1024,25 +1031,25 @@
    * @deprecated use [EMAIL PROTECTED] #setVisible(boolean)} instead
    */
   public void hide()
   {
     if (isVisible())
       {
         // Need to lock the tree here to avoid races and inconsistencies.
         synchronized (getTreeLock())
           {
             visible = false;
 
             // Avoid NullPointerExceptions by creating a local reference.
-            ComponentPeer currentPeer=peer;
+            ComponentPeer currentPeer = peer;
             if (currentPeer != null)
               {
                 currentPeer.hide();
 
                 // Fire hierarchy event.
                 fireHierarchyEvent(HierarchyEvent.HIERARCHY_CHANGED,
                                    this, parent,
                                    HierarchyEvent.SHOWING_CHANGED);
                 // The JDK repaints the component before invalidating the
                 // parent. So do we. This only applies for lightweights.
                 if (peer instanceof LightweightPeer)
                   repaint();
@@ -1283,26 +1290,44 @@
   public Point getLocationOnScreen()
   {
     if (! isShowing())
       throw new IllegalComponentStateException("component "
                                                + getClass().getName()
                                                + " not showing");
 
     // Need to lock the tree here. We get crazy races and explosions when
     // the tree changes while we are trying to find the location of this
     // component.
     synchronized (getTreeLock())
       {
-        // We know peer != null here.
-        return peer.getLocationOnScreen();
+        // Only a heavyweight peer can answer the question for the screen
+        // location. So we are going through the hierarchy until we find
+        // one and add up the offsets while doing so.
+        int offsX = 0;
+        int offsY = 0;
+        ComponentPeer p = peer;
+        Component comp = this;
+        while (p instanceof LightweightPeer)
+          {
+            offsX += comp.x;
+            offsY += comp.y;
+            comp = comp.parent;
+            p = comp == null ? null: comp.peer;
+          }
+        // Now we have a heavyweight component.
+        assert ! (p instanceof LightweightPeer);
+        Point loc = p.getLocationOnScreen();
+        loc.x += offsX;
+        loc.y += offsY;
+        return loc;
       }
   }
 
   /**
    * Returns the location of this component's top left corner relative to
    * its parent component.
    *
    * @return the location of this component
    * @deprecated use [EMAIL PROTECTED] #getLocation()} instead
    */
   public Point location()
   {
@@ -2054,74 +2079,100 @@
       }
   }
 
   /**
    * Returns a graphics object for this component. Returns <code>null</code>
    * if this component is not currently displayed on the screen.
    *
    * @return a graphics object for this component
    * @see #paint(Graphics)
    */
   public Graphics getGraphics()
   {
-    if (peer != null)
+    // Only heavyweight peers can handle this.
+    ComponentPeer p = peer;
+    Component comp = this;
+    int offsX = 0;
+    int offsY = 0;
+    while (p instanceof LightweightPeer)
+      {
+        offsX += comp.x;
+        offsY += comp.y;
+        comp = comp.parent;
+        p = comp == null ? null : comp.peer;
+      }
+
+    Graphics gfx = null;
+    if (p != null)
       {
-        Graphics gfx = peer.getGraphics();
-        // Create peer for lightweights.
-        if (gfx == null && parent != null)
-          {
-            gfx = parent.getGraphics();
-            gfx.clipRect(getX(), getY(), getWidth(), getHeight());
-            gfx.translate(getX(), getY());
-            return gfx;
-          }
+        assert ! (p instanceof LightweightPeer);
+        gfx = p.getGraphics();
+        gfx.translate(offsX, offsY);
+        gfx.clipRect(0, 0, width, height);
         gfx.setFont(font);
-        return gfx;
       }
-    return null;
+    return gfx;
   }
 
   /**
    * Returns the font metrics for the specified font in this component.
    *
    * @param font the font to retrieve metrics for
    * @return the font metrics for the specified font
    * @throws NullPointerException if font is null
    * @see #getFont()
    * @see Toolkit#getFontMetrics(Font)
    */
   public FontMetrics getFontMetrics(Font font)
   {
-    return peer == null ? getToolkit().getFontMetrics(font)
-      : peer.getFontMetrics(font);
+    ComponentPeer p = peer;
+    Component comp = this;
+    while (p instanceof LightweightPeer)
+      {
+        comp = comp.parent;
+        p = comp.peer;
+      }
+
+    return p == null ? getToolkit().getFontMetrics(font)
+           : p.getFontMetrics(font);
   }
 
   /**
    * Sets the cursor for this component to the specified cursor. The cursor
    * is displayed when the point is contained by the component, and the
    * component is visible, displayable, and enabled. This is inherited by
    * subcomponents unless they set their own cursor.
    *
    * @param cursor the new cursor for this component
    * @see #isEnabled()
    * @see #isShowing()
    * @see #getCursor()
    * @see #contains(int, int)
    * @see Toolkit#createCustomCursor(Image, Point, String)
    */
   public void setCursor(Cursor cursor)
   {
     this.cursor = cursor;
-    if (peer != null)
-      peer.setCursor(cursor);
+
+    // Only heavyweight peers handle this.
+    ComponentPeer p = peer;
+    Component comp = this;
+    while (p instanceof LightweightPeer)
+      {
+        comp = comp.parent;
+        p = comp == null ? null : comp.peer;
+      }
+
+    if (p != null)
+      p.setCursor(cursor);
   }
 
   /**
    * Returns the cursor for this component. If not set, this is inherited
    * from the parent, or from Cursor.getDefaultCursor().
    *
    * @return the cursor for this component
    */
   public Cursor getCursor()
   {
     if (cursor != null)
       return cursor;
@@ -2274,25 +2325,25 @@
     int pw = width;
     int ph = height;
     Component par = this;
     while (par != null && p instanceof LightweightPeer)
       {
         px += par.x; 
         py += par.y; 
         // We perform some boundary checking to restrict the paint
         // region to this component.
         pw = Math.min(pw, par.width);
         ph = Math.min(ph, par.height);
         par = par.parent;
-        p = par.peer;
+        p = par == null ? null : par.peer;
       }
 
     // Now send an UPDATE event to the heavyweight component that we've found.
     if (par != null && par.isVisible() && p != null && pw > 0 && ph > 0)
       {
         assert ! (p instanceof LightweightPeer);
         PaintEvent pe = new PaintEvent(par, PaintEvent.UPDATE,
                                        new Rectangle(px, py, pw, ph));
         getToolkit().getSystemEventQueue().postEvent(pe);
       }
   }
 
@@ -2372,87 +2423,124 @@
       }
     return (flags & (ALLBITS | ABORT | ERROR)) == 0;
   }
 
   /**
    * Creates an image from the specified producer.
    *
    * @param producer the image procedure to create the image from
    * @return the resulting image
    */
   public Image createImage(ImageProducer producer)
   {
+    // Only heavyweight peers can handle this.
+    ComponentPeer p = peer;
+    Component comp = this;
+    while (p instanceof LightweightPeer)
+      {
+        comp = comp.parent;
+        p = comp == null ? null : comp.peer;
+      }
+
     // Sun allows producer to be null.
-    if (peer != null)
-      return peer.createImage(producer);
+    Image im;
+    if (p != null)
+      im = p.createImage(producer);
     else
-      return getToolkit().createImage(producer);
+      im = getToolkit().createImage(producer);
+    return im;
   }
 
   /**
    * Creates an image with the specified width and height for use in
    * double buffering. Headless environments do not support images.
    *
    * @param width the width of the image
    * @param height the height of the image
    * @return the requested image, or null if it is not supported
    */
   public Image createImage (int width, int height)
   {
     Image returnValue = null;
     if (!GraphicsEnvironment.isHeadless ())
       {
-	if (isLightweight () && parent != null)
-	  returnValue = parent.createImage (width, height);
-	else if (peer != null)
-	  returnValue = peer.createImage (width, height);
+        // Only heavyweight peers can handle this.
+        ComponentPeer p = peer;
+        Component comp = this;
+        while (p instanceof LightweightPeer)
+          {
+            comp = comp.parent;
+            p = comp == null ? null : comp.peer;
+          }
+
+        returnValue = p.createImage(width, height);
       }
     return returnValue;
   }
 
   /**
    * Creates an image with the specified width and height for use in
    * double buffering. Headless environments do not support images.
    *
    * @param width the width of the image
    * @param height the height of the image
    * @return the requested image, or null if it is not supported
    * @since 1.4
    */
   public VolatileImage createVolatileImage(int width, int height)
   {
-    if (peer != null)
-      return peer.createVolatileImage(width, height);
-    return null;
+    // Only heavyweight peers can handle this.
+    ComponentPeer p = peer;
+    Component comp = this;
+    while (p instanceof LightweightPeer)
+      {
+        comp = comp.parent;
+        p = comp == null ? null : comp.peer;
+      }
+
+    VolatileImage im = null;
+    if (p != null)
+      im = p.createVolatileImage(width, height);
+    return im;
   }
 
   /**
    * Creates an image with the specified width and height for use in
    * double buffering. Headless environments do not support images. The image
    * will support the specified capabilities.
    *
    * @param width the width of the image
    * @param height the height of the image
    * @param caps the requested capabilities
    * @return the requested image, or null if it is not supported
    * @throws AWTException if a buffer with the capabilities cannot be created
    * @since 1.4
    */
   public VolatileImage createVolatileImage(int width, int height,
                                            ImageCapabilities caps)
     throws AWTException
   {
-    if (peer != null)
-      return peer.createVolatileImage(width, height);
-    return null;
+    // Only heavyweight peers can handle this.
+    ComponentPeer p = peer;
+    Component comp = this;
+    while (p instanceof LightweightPeer)
+      {
+        comp = comp.parent;
+        p = comp == null ? null : comp.peer;
+      }
+
+    VolatileImage im = null;
+    if (p != null)
+      im = peer.createVolatileImage(width, height);
+    return im;
   }
 
   /**
    * Prepares the specified image for rendering on this component.
    *
    * @param image the image to prepare for rendering
    * @param observer the observer to notify of image preparation status
    * @return true if the image is already fully prepared
    * @throws NullPointerException if image is null
    */
   public boolean prepareImage(Image image, ImageObserver observer)
   {
@@ -2464,28 +2552,39 @@
    * Prepares the specified image for rendering on this component at the
    * specified scaled width and height
    *
    * @param image the image to prepare for rendering
    * @param width the scaled width of the image
    * @param height the scaled height of the image
    * @param observer the observer to notify of image preparation status
    * @return true if the image is already fully prepared
    */
   public boolean prepareImage(Image image, int width, int height,
                               ImageObserver observer)
   {
-    if (peer != null)
-	return peer.prepareImage(image, width, height, observer);
+    // Only heavyweight peers handle this.
+    ComponentPeer p = peer;
+    Component comp = this;
+    while (p instanceof LightweightPeer)
+      {
+        comp = comp.parent;
+        p = comp == null ? null : comp.peer;
+      }
+
+    boolean retval;
+    if (p != null)
+	retval = p.prepareImage(image, width, height, observer);
     else
-	return getToolkit().prepareImage(image, width, height, observer);
+	retval = getToolkit().prepareImage(image, width, height, observer);
+    return retval;
   }
 
   /**
    * Returns the status of the loading of the specified image. The value
    * returned will be those flags defined in <code>ImageObserver</code>.
    *
    * @param image the image to check on
    * @param observer the observer to notify of image loading progress
    * @return the image observer flags indicating the status of the load
    * @see #prepareImage(Image, int, int, ImageObserver)
    * @see Toolkit#checkImage(Image, int, int, ImageObserver)
    * @throws NullPointerException if image is null
@@ -2501,27 +2600,39 @@
    *
    * @param image the image to check on
    * @param width the scaled image width
    * @param height the scaled image height
    * @param observer the observer to notify of image loading progress
    * @return the image observer flags indicating the status of the load
    * @see #prepareImage(Image, int, int, ImageObserver)
    * @see Toolkit#checkImage(Image, int, int, ImageObserver)
    */
   public int checkImage(Image image, int width, int height,
                         ImageObserver observer)
   {
-    if (peer != null)
-      return peer.checkImage(image, width, height, observer);
-    return getToolkit().checkImage(image, width, height, observer);
+    // Only heavyweight peers handle this.
+    ComponentPeer p = peer;
+    Component comp = this;
+    while (p instanceof LightweightPeer)
+      {
+        comp = comp.parent;
+        p = comp == null ? null : comp.peer;
+      }
+
+    int retval;
+    if (p != null)
+      retval = p.checkImage(image, width, height, observer);
+    else
+      retval = getToolkit().checkImage(image, width, height, observer);
+    return retval;
   }
 
   /**
    * Sets whether paint messages delivered by the operating system should be
    * ignored. This does not affect messages from AWT, except for those
    * triggered by OS messages. Setting this to true can allow faster
    * performance in full-screen mode or page-flipping.
    *
    * @param ignoreRepaint the new setting for ignoring repaint events
    * @see #getIgnoreRepaint()
    * @see BufferStrategy
    * @see GraphicsDevice#setFullScreenWindow(Window)
Index: java/awt/Container.java
===================================================================
RCS file: /cvsroot/classpath/classpath/java/awt/Container.java,v
retrieving revision 1.102
diff -u -1 -2 -r1.102 Container.java
--- java/awt/Container.java	27 Jul 2006 14:29:27 -0000	1.102
+++ java/awt/Container.java	27 Jul 2006 20:40:31 -0000
@@ -199,28 +199,30 @@
     return insets ();
   }
 
   /**
    * Returns the insets for this container, which is the space used for
    * borders, the margin, etc.
    *
    * @return The insets for this container.
    * @deprecated use [EMAIL PROTECTED] #getInsets()} instead
    */
   public Insets insets()
   {
-    if (peer == null)
-      return new Insets (0, 0, 0, 0);
-
-    return ((ContainerPeer) peer).getInsets ();
+    Insets i;
+    if (peer == null || peer instanceof LightweightPeer)
+      i = new Insets (0, 0, 0, 0);
+    else
+      i = ((ContainerPeer) peer).getInsets ();
+    return i;
   }
 
   /**
    * Adds the specified component to this container at the end of the
    * component list.
    *
    * @param comp The component to add to the container.
    *
    * @return The same component that was added.
    */
   public Component add(Component comp)
   {
Index: java/awt/Toolkit.java
===================================================================
RCS file: /cvsroot/classpath/classpath/java/awt/Toolkit.java,v
retrieving revision 1.43
diff -u -1 -2 -r1.43 Toolkit.java
--- java/awt/Toolkit.java	15 Jul 2006 08:02:23 -0000	1.43
+++ java/awt/Toolkit.java	27 Jul 2006 20:40:32 -0000
@@ -122,24 +122,29 @@
   protected final Map desktopProperties = new Properties();
 
   protected final PropertyChangeSupport desktopPropsSupport
     = new PropertyChangeSupport(this);
 
   /**
    * All registered AWTEventListener objects. This is package private, so the
    * event queue can efficiently access this list.
    */
   AWTEventListenerProxy[] awtEventListeners;
 
   /**
+   * The shared peer for all lightweight components.
+   */
+  private GLightweightPeer lightweightPeer;
+
+  /**
    * Default constructor for subclasses.
    */
   public Toolkit()
   {
     awtEventListeners = new AWTEventListenerProxy[0];
   }
 
   /**
    * Creates a peer object for the specified <code>Button</code>.
    *
    * @param target The <code>Button</code> to create the peer for.
    * 
@@ -370,25 +375,27 @@
   /**
    * Creates a peer object for the specified <code>Component</code>.  The
    * peer returned by this method is not a native windowing system peer
    * with its own native window.  Instead, this method allows the component
    * to draw on its parent window as a "lightweight" widget.
    *
    * @param target The <code>Component</code> to create the peer for.
    *
    * @return The peer for the specified <code>Component</code> object.
    */
   protected LightweightPeer createComponent(Component target)
   {
-    return new GLightweightPeer(target);
+    if (lightweightPeer == null)
+      lightweightPeer = new GLightweightPeer();
+    return lightweightPeer;
   }
 
   /**
    * Creates a peer object for the specified font name.
    *
    * @param name The font to create the peer for.
    * @param style The font style to create the peer for.
    *
    * @return The peer for the specified font name.
    *
    * @deprecated
    */

Reply via email to