@Override
	protected void paintComponent(Graphics g) {
		Graphics2D g2d = (Graphics2D) g;
		g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
		g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
		g.drawOval(WIDTH / 2 - TABLE_DIAMETER / 2, HEIGHT / 2 - TABLE_DIAMETER / 2, TABLE_DIAMETER, TABLE_DIAMETER);

		Rectangle discardPile = getDiscardPileBounds(0);
		g2d.drawRect(discardPile.x, discardPile.y, discardPile.width - 1, discardPile.height - 1);
		Rectangle drawPile = getDrawPileBounds(0);
		g2d.drawRect(drawPile.x, drawPile.y, drawPile.width - 1, drawPile.height - 1);
		if (model.getCurrentPlayer() == model.getLocalPlayerNumber()) {
			TurnContext cx = model.getPlayer(model.getCurrentPlayer()).getCurrentContext();
			if (cx != null && !cx.choosingFaceUp) {
				int discardPileSize;
				int drawDeckSize;
				cardsReadLock.lock();
				try {
					discardPileSize = discardPileEntitiesRange.getLength();
					drawDeckSize = drawDeckEntitiesRange.getLength();
				} finally {
					cardsReadLock.unlock();
				}

				if (discardPileSize == 0)
					drawWrappedString(g2d, new Point(discardPile.x + 2, discardPile.y), "Drop card here", discardPile.width);
				else
					g2d.drawString("Drop card on previously played cards", discardPile.x, discardPile.y - 1);

				if (drawDeckSize == 0) {
					drawWrappedString(g2d, new Point(drawPile.x + 2, drawPile.y), "Click here to end turn", discardPile.width);
				} else {
					Point pt = getDrawDeckLocation(drawDeckSize - 1);
					g2d.drawString("Click the deck to end your turn", pt.x, pt.y + g2d.getFontMetrics().getAscent());
				}
			}
		}

		cardsReadLock.lock();
		try {
			for (CardEntity card : cards)
				if (!tempDrawOver.contains(card))
					draw(card, g2d);
		} finally {
			cardsReadLock.unlock();
		}
		for (CardEntity card : tempDrawOver)
			draw(card, g2d);
	}