public void paint(Graphics g) {
    g2d = (Graphics2D) g;

    RenderingHints rh =
        new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

    rh.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);

    g2d.setRenderingHints(rh);

    // Set the font for displaying the text information on the screen.
    g2d.setFont(new Font("Purisa", Font.PLAIN, 14));

    // Set to gray and fill info window
    g2d.setColor(new Color(240, 240, 240));
    g2d.fillRect(0, 0, infoWidth, windowHeight);

    // Set to white and fill the plot window
    g2d.setColor(new Color(255, 255, 255));
    g2d.fillRect(infoWidth, 0, windowWidth, windowHeight);

    //  Draw the axes
    g2d.setColor(new Color(0, 0, 0));
    g2d.setStroke(new BasicStroke(3, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
    // y axis
    g2d.drawLine(
        infoWidth + (axesWidth * 3 / 4) - 5,
        windowHeight - axesWidth * 3 / 4,
        infoWidth + (axesWidth * 3 / 4) - 5,
        edgeBuffer);
    // x axis
    g2d.drawLine(
        infoWidth + (axesWidth * 3 / 4),
        windowHeight - axesWidth * 3 / 4,
        windowWidth - edgeBuffer,
        windowHeight - axesWidth * 3 / 4);

    // Draw the ticks
    g2d.setStroke(new BasicStroke(2, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
    for (int i = 0; i < numTicks; i++) {
      // Horizontal ticks on y axis
      int vertTickPoint = i * ((windowHeight - axesWidth * 3 / 4) - edgeBuffer) / (numTicks - 1);
      g2d.drawLine(
          infoWidth + (axesWidth * 3 / 4) - tickLength - 5,
          edgeBuffer + vertTickPoint,
          infoWidth + (axesWidth * 3 / 4) + tickLength - 5,
          edgeBuffer + vertTickPoint);
      g2d.drawString(
          (float) (numTicks - 1 - i) * ((float) numReqs / (float) (numTicks - 1)) + "",
          infoWidth + (axesWidth * 3 / 4) - 60,
          edgeBuffer + vertTickPoint + 5);

      // Vertical ticks on x axis
      int horTickPoint =
          i * ((windowWidth - edgeBuffer) - (infoWidth + (axesWidth * 3 / 4))) / (numTicks - 1);
      g2d.drawLine(
          horTickPoint + (infoWidth + (axesWidth * 3 / 4)),
          windowHeight - axesWidth * 3 / 4 - tickLength,
          horTickPoint + (infoWidth + (axesWidth * 3 / 4)),
          windowHeight - axesWidth * 3 / 4 + tickLength);
      g2d.drawString(
          (float) (i) * ((float) execTime / (float) (numTicks - 1)) + "",
          horTickPoint + (infoWidth + (axesWidth * 3 / 4)) - 22,
          windowHeight - axesWidth * 3 / 4 + tickLength + 15);
    }

    // Draw the stepfunctionlines
    for (StepFunctionLine l : randLines) {
      l.setGraphics(g2d);
      l.drawStep();
    }

    for (int i = 0; i < lines.size(); i++) {
      if (show[i] == true) {
        lines.get(i).setGraphics(g2d);
        lines.get(i).drawStep();
      }
    }

    // Draw the plot info
    g2d.setColor(new Color(0, 0, 0));
    g2d.drawString("Coverage: " + matrixFile, 17, 30);
    g2d.drawString("Timing: " + timeFile, 17, 50);
    g2d.drawString("Test Cases: " + lines.get(0).getNumTests(), 17, 70);
    // g2d.drawString("Execution Time: " + lines.get(0).getExecutionTime()+ " ms", 17, 70);

    // Draw a separator box
    g2d.drawRect(0, 0, infoWidth - 1, 85);

    ////////////////// Original and Reverse

    g2d.setStroke(new BasicStroke(2, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
    // Draw vert lines between to delimit original/reverse buttons
    for (int i = 0; i <= 1; i++) {
      g2d.drawLine(
          originalGridStartX + i * gridSpacingX,
          originalGridStartY,
          originalGridStartX + i * gridSpacingX,
          originalGridStartY + oTechniques.length * gridSpacingY);
    }

    // Draw hor lines between to delimit original/reverse button grids
    for (int i = 0; i <= oTechniques.length; i++) {
      g2d.drawLine(
          originalGridStartX,
          originalGridStartY + i * gridSpacingY,
          originalGridStartX + gridSpacingX,
          originalGridStartY + i * gridSpacingY);
    }

    // Draw the text labels for the technique buttons
    for (int i = 0; i < oTechniques.length; i++) {
      g2d.drawString(
          oTechniques[i],
          originalGridStartX - originalLabelsOffsetX,
          originalGridStartY + originalLabelsOffsetY + i * gridSpacingY);
    }

    // The buttons
    for (int i = 0; i < 2; i++) {
      if (show[i] == true) {
        int row = i / 1;
        int col = i % 1;

        g2d.fillRect(
            originalGridStartX + col * gridSpacingX + buttonInsetX / 2,
            originalGridStartY + row * gridSpacingY + buttonInsetY / 2,
            gridSpacingX - buttonInsetX,
            gridSpacingY - buttonInsetY);
      }
    }

    // Labels over the controls
    g2d.drawString("Prioritization Techniques", originalGridStartX - 46, originalGridStartY - 30);
    g2d.drawString("Random Prioritizations", scrollBarStartX + 65, scrollBarStartY - 30);

    ///////////////////////////  Big Button grid

    // Draw vert lines between to delimit buttons
    for (int i = 0; i <= gcm.length; i++) {
      g2d.drawLine(
          gridStartX + i * gridSpacingX,
          gridStartY,
          gridStartX + i * gridSpacingX,
          gridStartY + techniques.length * gridSpacingY);
    }

    // Draw hor lines between to delimit grids
    for (int i = 0; i <= techniques.length; i++) {
      g2d.drawLine(
          gridStartX,
          gridStartY + i * gridSpacingY,
          gridStartX + gcm.length * gridSpacingX,
          gridStartY + i * gridSpacingY);
    }

    // Draw the text labels for the technique buttons
    for (int i = 0; i < techniques.length; i++) {
      g2d.setColor(colors[i]);
      g2d.drawString(
          techniques[i],
          gridStartX - techniqueLabelsOffsetX,
          gridStartY + techniqueLabelsOffsetY + i * gridSpacingY);
    }

    g2d.setColor(Color.BLACK);
    // Draw the gcm labels for the technique buttons
    for (int i = 0; i < gcm.length; i++) {
      g2d.drawString(
          gcm[i], gridStartX + gcmLabelsOffsetX + i * gridSpacingX, gridStartY - gcmLabelsOffsetY);
    }

    // The buttons
    for (int i = 2; i < lines.size(); i++) {
      g2d.setColor(colors[(i - 2) / gcm.length]);
      if (show[i] == true) {
        int row = (i - 2) / gcm.length;
        int col = (i - 2) % gcm.length;

        g2d.fillRect(
            gridStartX + col * gridSpacingX + buttonInsetX / 2,
            gridStartY + row * gridSpacingY + buttonInsetY / 2,
            gridSpacingX - buttonInsetX,
            gridSpacingY - buttonInsetY);
      }
    }

    // Scroll Bar
    // g2d.drawLine(scrollBarStartX, scrollBarStartY, scrollBarStartX+scrollBarLength,
    // scrollBarStartY);
    g2d.setColor(Color.WHITE);
    g2d.fillRect(
        scrollBarStartX,
        scrollBarStartY - ((gridSpacingY - buttonInsetY) / 2),
        scrollBarLength,
        gridSpacingY - buttonInsetY);
    g2d.setColor(new Color(200, 200, 200));
    g2d.fillRect(
        scrollBoxX,
        scrollBoxY - ((gridSpacingY - buttonInsetY) / 2),
        gridSpacingX - buttonInsetX,
        gridSpacingY - buttonInsetY);
    g2d.setColor(Color.BLACK);
    g2d.setFont(new Font("Purisa", Font.PLAIN, 18));
    g2d.drawString(numRand + "", scrollBoxX + 26, scrollBoxY + 7);
    g2d.setFont(new Font("Purisa", Font.PLAIN, 14));

    // Stats for random
    g2d.drawString("Avg CE: " + aveRandCE, scrollBarStartX - 5, scrollBarStartY + 29);
    g2d.drawString(
        "Running Avg CE: " + runningAveRandCE, scrollBarStartX - 5, scrollBarStartY + 49);
    g2d.drawString("St. Dev.: " + randSTDev, scrollBarStartX - 5, scrollBarStartY + 69);
    g2d.drawString(
        "Running St. Dev. " + runningRandSTDev, scrollBarStartX - 5, scrollBarStartY + 89);

    // axis labels
    g2d.setColor(Color.black);
    g2d.drawString(
        "Execution Time (ms)",
        (windowWidth - infoWidth) / 2 + infoWidth - 35,
        windowHeight - axesWidth * 3 / 4 + 45);

    g2d.translate((infoWidth + 15), (windowHeight / 2));
    g2d.rotate(-Math.PI / 2);
    g2d.drawString("Covered Requirements", -55, -2);
    g2d.rotate(Math.PI / 2);
  }