index++;
  private void paintChildrenWithOverlap(Graphics g)  {    Shape originalClip = g.getClip();    Rectangle inner = SwingUtilities.calculateInnerArea(this, rectCache);    g.clipRect(inner.x, inner.y, inner.width, inner.height);    Component[] children = getComponents();    // Find the rectangles that need to be painted for each child component.    // We push on this list arrays that have the Rectangles to be painted as    // the first elements and the component to be painted as the last one.    // Later we go through that list in reverse order and paint the rectangles.    ArrayList paintRegions = new ArrayList(children.length);    ArrayList paintRectangles = new ArrayList();    ArrayList newPaintRects = new ArrayList();    paintRectangles.add(g.getClipBounds());    ArrayList componentRectangles = new ArrayList();    // Go through children from top to bottom and find out their paint    // rectangles.    int index = 0;    while (paintRectangles.size() > 0 && index < children.length)      {        Component comp = children[index];        if (! comp.isVisible())          continue;        Rectangle compBounds = comp.getBounds();        boolean isOpaque = comp instanceof JComponent                           && ((JComponent) comp).isOpaque();        // Add all the current paint rectangles that intersect with the        // component to the component's paint rectangle array.        for (int i = paintRectangles.size() - 1; i >= 0; i--)          {            Rectangle r = (Rectangle) paintRectangles.get(i);            if (r.intersects(compBounds))              {                Rectangle compRect = r.intersection(compBounds);                componentRectangles.add(compRect);                // If the component is opaque, split up each paint rect and                // add paintRect - compBounds to the newPaintRects array.                if (isOpaque)                  {                    int x, y, w, h;                    Rectangle rect = new Rectangle();                    // The north retangle.                    x = Math.max(compBounds.x, r.x);                    y = r.y;                    w = Math.min(compBounds.width, r.width + r.x - x);                    h = compBounds.y - r.y;                    rect.setBounds(x, y, w, h);                    if (! rect.isEmpty())                      {                        newPaintRects.add(rect);                        rect = new Rectangle();                      }                    // The south rectangle.                    x = Math.max(compBounds.x, r.x);                    y = compBounds.y + compBounds.height;                    w = Math.min(compBounds.width, r.width + r.x - x);                    h = r.height - (compBounds.y - r.y) - compBounds.height;                    rect.setBounds(x, y, w, h);                    if (! rect.isEmpty())                      {                        newPaintRects.add(rect);                        rect = new Rectangle();                      }                    // The west rectangle.                    x = r.x;                    y = r.y;                    w = compBounds.x - r.x;                    h = r.height;                    rect.setBounds(x, y, w, h);                    if (! rect.isEmpty())                      {                        newPaintRects.add(rect);                        rect = new Rectangle();                      }                    // The east rectangle.                    x = compBounds.x + compBounds.width;                    y = r.y;                    w = r.width - (compBounds.x - r.x) - compBounds.width;                    h = r.height;                    rect.setBounds(x, y, w, h);                    if (! rect.isEmpty())                      {                        newPaintRects.add(rect);                      }                  }                else                  {                    // Not opaque, need to reuse the current paint rectangles                    // for the next component.                    newPaintRects.add(r);                  }                              }            else              {                newPaintRects.add(r);              }          }        // Replace the paintRectangles with the new split up        // paintRectangles.        paintRectangles.clear();        paintRectangles.addAll(newPaintRects);        newPaintRects.clear();        // Store paint rectangles if there are any for the current component.        int compRectsSize = componentRectangles.size();        if (compRectsSize > 0)          {            componentRectangles.add(comp);            paintRegions.add(componentRectangles);            componentRectangles = new ArrayList();          }        index++;      }    // paintingTile becomes true just before we start painting the component's    // children.    paintingTile = true;    // We must go through the painting regions backwards, because the    // topmost components have been added first, followed by the components    // below.    int prEndIndex = paintRegions.size() - 1;    for (int i = prEndIndex; i >= 0; i--)      {        // paintingTile must be set to false before we begin to start painting        // the last tile.        if (i == 0)          paintingTile = false;        ArrayList paintingRects = (ArrayList) paintRegions.get(i);        // The last element is always the component.        Component c = (Component) paintingRects.get(paintingRects.size() - 1);        int endIndex = paintingRects.size() - 2;        for (int j = 0; j <= endIndex; j++)          {            Rectangle cBounds = c.getBounds();            Rectangle bounds = (Rectangle) paintingRects.get(j);            Rectangle oldClip = g.getClipBounds();            if (oldClip == null)              oldClip = bounds;            boolean translated = false;            try              {                g.setClip(bounds);                g.translate(cBounds.x, cBounds.y);                translated = true;                c.paint(g);              }            finally              {                if (translated)                  g.translate(-cBounds.x, -cBounds.y);                g.setClip(oldClip);              }          }      }    g.setClip(originalClip);  }