@Override
	protected void paintComponent(Graphics gc) {
		super.paintComponent(GraphicsUtilities.prepare(gc));
		drawBackground(gc);

		Shape origClip = gc.getClip();
		Rectangle clip = gc.getClipBounds();
		Insets insets = getInsets();
		Rectangle bounds = new Rectangle(insets.left, insets.top, getWidth() - (insets.left + insets.right), getHeight() - (insets.top + insets.bottom));
		boolean active = isFocusOwner();
		int first = getFirstRowToDisplay();
		int last = getLastRowToDisplay();
		boolean isPrinting = PrintUtilities.isPrinting(this);
		boolean showIndent = showIndent();

		for (int rowIndex = first; rowIndex <= last; rowIndex++) {
			Row row = mModel.getRowAtIndex(rowIndex);
			if (!mModel.isRowFiltered(row)) {
				bounds.height = row.getHeight();
				if (bounds.y >= clip.y || bounds.y + bounds.height + (mDrawRowDividers ? 1 : 0) >= clip.y) {
					if (bounds.y > clip.y + clip.height) {
						break;
					}

					boolean rowSelected = !isPrinting && mModel.isRowSelected(row);
					if (!mDrawingDragImage || mDrawingDragImage && rowSelected) {
						Rectangle colBounds = new Rectangle(bounds);
						Composite savedComposite = null;
						boolean isFirstCol = true;
						int shift = 0;

						for (Column col : mModel.getColumns()) {
							if (col.isVisible()) {
								colBounds.width = col.getWidth();
								if (clip.intersects(colBounds)) {
									boolean dragging = mSourceDragColumn == col;
									gc.clipRect(colBounds.x, colBounds.y, colBounds.width, colBounds.height);
									if (dragging) {
										savedComposite = ((Graphics2D) gc).getComposite();
										((Graphics2D) gc).setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f));
									}
									if (showIndent && isFirstCol) {
										shift = mModel.getIndentWidth(row, col);
										colBounds.x += shift;
										colBounds.width -= shift;
										if (row.canHaveChildren()) {
											StdImage image = getDisclosureControl(row);
											gc.drawImage(image, colBounds.x - image.getWidth(), 1 + colBounds.y + (colBounds.height - image.getHeight()) / 2, null);
										}
									}
									// Under some circumstances, the width calculations
									// for cells are off by one pixel when printing...
									// so far, the only way I've found to compensate is
									// to put this hack in.
									if (isPrinting) {
										colBounds.width++;
									}
									col.drawRowCell(this, gc, colBounds, row, rowSelected, active);
									if (isPrinting) {
										colBounds.width--;
									}
									if (showIndent && isFirstCol) {
										colBounds.x -= shift;
										colBounds.width += shift;
									}
									if (dragging) {
										((Graphics2D) gc).setComposite(savedComposite);
									}
									gc.setClip(origClip);
								}
								colBounds.x += colBounds.width + 1;
								isFirstCol = false;
							}
						}

						if (mDrawingDragImage) {
							if (mDragClip == null) {
								mDragClip = new Rectangle(bounds);
							} else {
								mDragClip.add(bounds);
							}
						}
					}
				}
				bounds.y += bounds.height + (mDrawRowDividers ? 1 : 0);
			}
		}

		if (mDragChildInsertIndex != -1) {
			drawDragRowInsertionMarker(gc, mDragParentRow, mDragChildInsertIndex);
		}
	}