public void paintComponent(Graphics g) {
		Graphics2D g2 = (Graphics2D) g;

		RenderingHints renderHints = new RenderingHints(
				RenderingHints.KEY_ANTIALIASING,
				RenderingHints.VALUE_ANTIALIAS_ON);
		renderHints.put(RenderingHints.KEY_RENDERING,
				RenderingHints.VALUE_RENDER_QUALITY);
		renderHints.put(RenderingHints.KEY_ALPHA_INTERPOLATION,
				RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);

		g2.setRenderingHints(renderHints);

		// paper color background
		g2.setBackground(new Color(251, 255, 235));
		g2.clearRect(0, 0, getWidth(), getHeight());

		// draw the grid for graph paper
		g2.setColor(new Color(197, 214, 162));
		for (int i = 0; i < getWidth(); i += 20) {
			g2.drawLine(i, 0, i, getHeight());
		}
		for (int i = 0; i < getHeight(); i += 20) {
			g2.drawLine(0, i, getWidth(), i);
		}

		// draw a background image if loaded
		if (bg != null) {
			g2.drawImage(bg, 0, 0, bg.getWidth(), bg.getHeight(), 0, 0,
					bg.getWidth(), bg.getHeight(), null);
		}

		// draw highlighted strokes
		if (highlightStrokes.size() > 0) {
			if (drawBlur && highlightImage != null) {
				g2.drawImage(highlightImage, (int) highlightBox.x,
						(int) highlightBox.y, (int) highlightBox.x
								+ (int) highlightBox.width,
						(int) highlightBox.y + (int) highlightBox.height, 0, 0,
						highlightImage.getWidth(), highlightImage.getHeight(),
						null);
			} else {
				g2.setColor(HIGHLIGHT_COLOR);
				g2.setStroke(highlightStroke);
				for (Stroke stroke : highlightStrokes) {
					ShapePainter.draw(g2, QuadPath.buildQuadPath(stroke));
				}
			}
		}

		if (areasWrong.size() > 0) {
			g2.setColor(INCORRECT_COLOR);
			for (BoundingBox area : areasWrong) {
				g2.fillRect((int) area.x, (int) area.y, (int) area.width,
						(int) area.height);
				// draw some kind of ghostly, fuzzy outline or shape behind
				// the normal strokes where there is something missing/wrong
			}
		}
	}