paintBackingStore(g);
Point viewPosition = getViewPosition(); int dx = viewPosition.x - lastPaintPosition.x; int dy = viewPosition.y - lastPaintPosition.y; boolean canBlit = computeBlit(dx, dy, cachedBlitFrom, cachedBlitTo, cachedBlitSize, cachedBlitPaint); if (canBlit && isPaintRoot) {  g.copyArea(cachedBlitFrom.x, cachedBlitFrom.y, cachedBlitSize.width, cachedBlitSize.height, cachedBlitTo.x - cachedBlitFrom.x, cachedBlitTo.y - cachedBlitFrom.y);  Shape oldClip = g.getClip(); g.clipRect(cachedBlitPaint.x, cachedBlitPaint.y, cachedBlitPaint.width, cachedBlitPaint.height); try { paintSimple(g); } finally { g.setClip(oldClip); } }   else paintSimple(g); lastPaintPosition.setLocation(getViewPosition());
  void paintBlit(Graphics g)  {    // We cannot perform blitted painting as it is described in Sun's API docs.    // There it is suggested that this painting method should blit directly    // on the parent window's surface. This is not possible because when using    // Swing's double buffering (at least our implementation), it would    // immediatly be painted when the buffer is painted on the screen. For this    // to work we would need a kind of hole in the buffer image. And honestly    // I find this method not very elegant.    // The alternative, blitting directly on the buffer image, is also not    // possible because the buffer image gets cleared everytime when an opaque    // parent component is drawn on it.    // What we do instead is falling back to the backing store approach which    // is in fact a mixed blitting/backing store approach where the blitting    // is performed on the backing store image and this is then drawn to the    // graphics context. This is very robust and works independent of the    // painting mechanism that is used by Swing. And it should have comparable    // performance characteristics as the blitting method.    paintBackingStore(g);  }