@Override
	public void paintComponent(Graphics g)
	{
		mxGraph graph = graphComponent.getGraph();
		Rectangle clip = g.getClipBounds();
		updateIncrementAndUnits();

		// Fills clipping area with background.
		if (activelength > 0 && inactiveBackground != null)
		{
			g.setColor(inactiveBackground);
		}
		else
		{
			g.setColor(getBackground());
		}

		g.fillRect(clip.x, clip.y, clip.width, clip.height);

		// Draws the active region.
		g.setColor(getBackground());
		Point2D p = new Point2D.Double(activeoffset, activelength);

		if (orientation == ORIENTATION_HORIZONTAL)
		{
			g.fillRect((int) p.getX(), clip.y, (int) p.getY(), clip.height);
		}
		else
		{
			g.fillRect(clip.x, (int) p.getX(), clip.width, (int) p.getY());
		}

		double left = clip.getX();
		double top = clip.getY();
		double right = left + clip.getWidth();
		double bottom = top + clip.getHeight();

		// Fetches some global display state information
		mxPoint trans = graph.getView().getTranslate();
		double scale = graph.getView().getScale();
		double tx = trans.getX() * scale;
		double ty = trans.getY() * scale;

		// Sets the distance of the grid lines in pixels
		double stepping = increment;

		if (stepping < tickDistance)
		{
			int count = (int) Math
					.round(Math.ceil(tickDistance / stepping) / 2) * 2;
			stepping = count * stepping;
		}

		// Creates a set of strokes with individual dash offsets
		// for each direction
		((Graphics2D) g).setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
				RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
		g.setFont(labelFont);
		g.setColor(Color.black);

		int smallTick = rulerSize - rulerSize / 3;
		int middleTick = rulerSize / 2;

		// TODO: Merge into a single drawing loop for both orientations
		if (orientation == ORIENTATION_HORIZONTAL)
		{
			double xs = Math.floor((left - tx) / stepping) * stepping + tx;
			double xe = Math.ceil(right / stepping) * stepping;
			xe += (int) Math.ceil(stepping);

			for (double x = xs; x <= xe; x += stepping)
			{
				// FIXME: Workaround for rounding errors when adding stepping to
				// xs or ys multiple times (leads to double grid lines when zoom
				// is set to eg. 121%)
				double xx = Math.round((x - tx) / stepping) * stepping + tx;

				int ix = (int) Math.round(xx);
				g.drawLine(ix, rulerSize, ix, 0);

				String text = format((x - tx) / increment);
				g.drawString(text, ix + 2, labelFont.getSize());

				ix += (int) Math.round(stepping / 4);
				g.drawLine(ix, rulerSize, ix, smallTick);

				ix += (int) Math.round(stepping / 4);
				g.drawLine(ix, rulerSize, ix, middleTick);

				ix += (int) Math.round(stepping / 4);
				g.drawLine(ix, rulerSize, ix, smallTick);
			}
		}
		else
		{
			double ys = Math.floor((top - ty) / stepping) * stepping + ty;
			double ye = Math.ceil(bottom / stepping) * stepping;
			ye += (int) Math.ceil(stepping);

			for (double y = ys; y <= ye; y += stepping)
			{
				// FIXME: Workaround for rounding errors when adding stepping to
				// xs or ys multiple times (leads to double grid lines when zoom
				// is set to eg. 121%)
				y = Math.round((y - ty) / stepping) * stepping + ty;

				int iy = (int) Math.round(y);
				g.drawLine(rulerSize, iy, 0, iy);

				String text = format((y - ty) / increment);

				// Rotates the labels in the vertical ruler
				AffineTransform at = ((Graphics2D) g).getTransform();
				((Graphics2D) g).rotate(-Math.PI / 2, 0, iy);
				g.drawString(text, 1, iy + labelFont.getSize());
				((Graphics2D) g).setTransform(at);

				iy += (int) Math.round(stepping / 4);
				g.drawLine(rulerSize, iy, smallTick, iy);

				iy += (int) Math.round(stepping / 4);
				g.drawLine(rulerSize, iy, middleTick, iy);

				iy += (int) Math.round(stepping / 4);
				g.drawLine(rulerSize, iy, smallTick, iy);
			}
		}

		// Draw Mouseposition
		g.setColor(Color.green);

		if (orientation == ORIENTATION_HORIZONTAL)
		{
			g.drawLine(mouse.x, rulerSize, mouse.x, 0);
		}
		else
		{
			g.drawLine(rulerSize, mouse.y, 0, mouse.y);
		}
	}