public void guiLoop() throws Exception
	{
		final Graphics g = getGraphics();
		final Graphics2D g2d = (Graphics2D)g;
		long lastLeft = -1;
		int headerScrollerX = 0;
		double scrollTs = (double)System.currentTimeMillis() / 1000.0;

		addMouseListener(this);

		for(;;)
		{
			long now = System.currentTimeMillis();
			long left = (long)config.getSleepTime() - ((now - lastRefresh) / 1000);
			final int rowHeight = (getHeight() - (config.getShowHeader() ? config.getUpperRowBorderHeight() : 0)) / config.getNRows();
			int characterSize = rowHeight - 1;

			configureRendered(g2d, true);

			if (left <= 0)
			{
				lastRefresh = now;
				CoffeeSaint.log.add("*** Update PROBLEMS " + left);
				// g.fillRect(0, 0, getWidth(), getHeight());
				repaint();
				coffeeSaint.cleanUp();
			}

			movingPartsSemaphore.acquireUninterruptibly();
			if (currentRow == null) {
				for(ScrollableContent currentMovingPart : windowMovingParts) {
					currentMovingPart.scrollView(g2d, config.getScrollingPixelsPerSecond());
				}

				boolean drawnCounter = false;
				Position counterPosition = config.getCounterPosition();
				if (config.getCounter() && lastLeft != left && counterPosition != null) {
					drawCounter(g, counterPosition, getWidth(), getHeight(), rowHeight, (int)left);
					lastLeft = left;
					drawnCounter = true;
				}

				if (bordersParameters != null && (windowMovingParts.size() > 0 || drawnCounter))
					drawBorders((Graphics2D)g, bordersParameters);
			}
			movingPartsSemaphore.release();

			if (windowMovingParts.size() > 0)
				Thread.sleep(ScrollableContent.getScrollSleep());
			else
				Thread.sleep(1000);
		}
	}