Program: 24452
Project: 24452
Buggy source:
@Override public void paint(Graphics g){
  g.setFont(new Font("String_Node_Str",Font.BOLD,11));
  for (int i=0; i < 16; i++) {
    int currentY=height - startY - (15 - i) * (barHeight + whiteSpaceHeight);
    String rank=i + 1 + "String_Node_Str";
    if (i < 9)     rank="String_Node_Str" + rank;
    g.setColor(Color.LIGHT_GRAY);
    g.drawOval(14 - 2,currentY - 1,19,19);
    g.drawLine(14 + 18,currentY + 8,14 + 18 + 16,currentY + 8);
    g.drawLine(14 + 18,currentY + 9,14 + 18 + 16,currentY + 9);
    g.drawOval(width - 31 - 2,currentY - 1,19,19);
    g.drawLine(width - 31 - 2,currentY + 8,width - 31 - 2- 16,currentY + 8);
    g.drawLine(width - 31 - 2,currentY + 9,width - 31 - 2- 16,currentY + 9);
    g.setColor(Color.BLACK);
    g.drawString(rank,14,currentY + 12);
    g.drawString(rank,width - 31,currentY + 12);
  }
  g.drawString("String_Node_Str",8,centerY - 84);
  g.drawString("String_Node_Str",width - 40,centerY - 84);
  for (int i=0; i < 22; i++) {
    LinkedList<Book.BookStats> currentBucket=buckets.get(i);
    int currentX=rankingWidth + i * intervalWidth;
    Iterator<Book.BookStats> it=currentBucket.listIterator();
    g.setFont(new Font("String_Node_Str",Font.PLAIN,9));
    while (it.hasNext()) {
      Book.BookStats stat=it.next();
      int currentY=height - startY - (16 - stat.ranking) * (barHeight + whiteSpaceHeight);
      if (state == State.OVERALL || stat.owner == currentBook)       g.setColor(stat.owner.colour);
 else       g.setColor(new Color(224,224,224));
      g.fillRect(currentX,currentY,intervalWidth / 2,barHeight);
      if (stat.next != null && stat.week + 1 == stat.next.week) {
        int nextY=height - startY - (16 - stat.next.ranking) * (barHeight + whiteSpaceHeight);
        int y[]={currentY,nextY,nextY + barHeight,currentY + barHeight};
        int x[]={currentX + intervalWidth / 2,currentX + intervalWidth,currentX + intervalWidth,currentX + intervalWidth / 2};
        g.fillPolygon(x,y,4);
      }
      if (stat.isFirst && (state == State.OVERALL || currentBook == stat.owner)) {
        g.setColor(Color.WHITE);
        if (stat.owner.title.length() < 8)         g.drawString(stat.owner.title,currentX + 2,currentY + 12);
 else         g.drawString(stat.owner.title.substring(0,8) + "String_Node_Str",currentX + 2,currentY + 12);
      }
      if (state == State.DETAIL && stat.owner == currentBook) {
        g.setFont(new Font("String_Node_Str",Font.BOLD,11));
        g.setColor(Color.BLACK);
        g.drawString(stat.ranking + "String_Node_Str",currentX + intervalWidth / 4 - 4,currentY - 4);
      }
    }
    g.setFont(new Font("String_Node_Str",Font.BOLD,11));
    g.setColor(Color.BLACK);
    g.drawString("String_Node_Str" + (i + 1),currentX,height - 32);
    if (bookColour != null) {
      int xOffset=(int)((ScrollPane)(this.getParent())).getScrollPosition().getX() + 400 - 150;
      FontMetrics metric=getFontMetrics(g.getFont());
      int stringWidth=metric.stringWidth(bookName);
      g.clearRect(0,height - 20,width,22);
      g.setColor(Color.GRAY);
      g.fillRect(xOffset + 2,height - 20 + 2,300,20);
      g.setColor(bookColour);
      g.fillRect(xOffset,height - 20,300,20);
      g.setColor(Color.WHITE);
      g.drawString(bookName,xOffset + (300 - stringWidth) / 2,height - 17 + 11);
      if (state == state.DETAIL) {
        int windowOffsetX=xOffset - 245;
        int windowOffsetY=15;
        int windowWidth=400;
        int windowHeight=150;
        FontMetrics fmet;
        Font heading=new Font("String_Node_Str",Font.BOLD,16);
        fmet=getFontMetrics(heading);
        g.setFont(heading);
        g.clearRect(0,0,width,windowHeight + 25);
        String title=currentBook.title;
        String author=currentBook.author;
        String desc=currentBook.description;
        g.setColor(Color.GRAY);
        g.fillRect(windowOffsetX + 2,windowOffsetY + 2,windowWidth,windowHeight);
        g.setColor(bookColour);
        g.fillRect(windowOffsetX,windowOffsetY,windowWidth,windowHeight);
        g.setColor(Color.WHITE);
        g.drawImage(currentBook.novelPic,windowOffsetX + (windowWidth * 2 / 3) + 30,20,90,135,this);
        g.drawImage(currentBook.tagPic,xOffset + 250,5,210,180,this);
        int headingWidth=(fmet.stringWidth(title));
        if (headingWidth < windowWidth) {
          windowOffsetY+=20;
          g.drawString(title,windowOffsetX + (windowWidth / 2) - (headingWidth / 2),windowOffsetY);
        }
 else {
          String title1=title.substring(0,title.length() / 2);
          int title1Width=(fmet.stringWidth(title1));
          String title2=title.substring(title.length() / 2);
          int title12Width=(fmet.stringWidth(title2));
          windowOffsetY+=15;
          g.drawString(title1,windowOffsetX + (windowWidth / 2) - (title1Width / 2),windowOffsetY);
          windowOffsetY+=15;
          g.drawString(title2,windowOffsetX + (windowWidth / 2) - (title12Width / 2),windowOffsetY);
        }
        g.setFont(new Font("String_Node_Str",Font.ITALIC,14));
        fmet=getFontMetrics(new Font("String_Node_Str",Font.ITALIC,14));
        windowOffsetY+=15;
        g.drawString(author,windowOffsetX + (windowWidth / 2) - (fmet.stringWidth(author)) / 2,windowOffsetY);
        g.setFont(new Font("String_Node_Str",Font.ITALIC,10));
        fmet=getFontMetrics(new Font("String_Node_Str",Font.ITALIC,10));
        windowOffsetY+=20;
        int descwidth=fmet.stringWidth(desc);
        if (descwidth < (windowWidth * 2) / 3) {
          g.drawString(desc,windowOffsetX + (windowWidth / 3) - (descwidth / 2),windowOffsetY);
        }
 else         if (descwidth / 2 < (windowWidth * 2) / 3) {
          String desc1=desc.substring(0,desc.length() / 2);
          String desc2=desc.substring(desc.length() / 2);
          g.drawString(desc1,windowOffsetX + (windowWidth / 3) - (fmet.stringWidth(desc1)) / 2,windowOffsetY);
          windowOffsetY+=10;
          g.drawString(desc2,windowOffsetX + (windowWidth / 3) - (fmet.stringWidth(desc2)) / 2,windowOffsetY);
        }
 else {
          String desc1=desc.substring(0,desc.length() / 3);
          String desc2=desc.substring(desc.length() / 3,desc.length() * 2 / 3);
          String desc3=desc.substring(desc.length() * 2 / 3);
          g.drawString(desc1,windowOffsetX + (windowWidth / 3) - (fmet.stringWidth(desc1)) / 2,windowOffsetY);
          windowOffsetY+=10;
          g.drawString(desc2,windowOffsetX + (windowWidth / 3) - (fmet.stringWidth(desc2)) / 2,windowOffsetY);
          windowOffsetY+=10;
          g.drawString(desc3,windowOffsetX + (windowWidth / 3) - (fmet.stringWidth(desc3)) / 2,windowOffsetY);
        }
      }
    }
 else {
      g.clearRect(0,height - 20,width,22);
    }
  }
}

Fixed version (ground truth):
@Override public void paint(Graphics g){
  g.setFont(new Font("String_Node_Str",Font.BOLD,11));
  for (int i=0; i < 16; i++) {
    int currentY=height - startY - (15 - i) * (barHeight + whiteSpaceHeight);
    String rank=i + 1 + "String_Node_Str";
    if (i < 9)     rank="String_Node_Str" + rank;
    g.setColor(Color.LIGHT_GRAY);
    g.drawOval(14 - 2,currentY - 1,19,19);
    g.drawLine(14 + 18,currentY + 8,14 + 18 + 16,currentY + 8);
    g.drawLine(14 + 18,currentY + 9,14 + 18 + 16,currentY + 9);
    g.drawOval(width - 31 - 2,currentY - 1,19,19);
    g.drawLine(width - 31 - 2,currentY + 8,width - 31 - 2- 16,currentY + 8);
    g.drawLine(width - 31 - 2,currentY + 9,width - 31 - 2- 16,currentY + 9);
    g.setColor(Color.BLACK);
    g.drawString(rank,14,currentY + 12);
    g.drawString(rank,width - 31,currentY + 12);
  }
  g.drawString("String_Node_Str",8,centerY - 84);
  g.drawString("String_Node_Str",width - 40,centerY - 84);
  for (int i=0; i < 22; i++) {
    LinkedList<Book.BookStats> currentBucket=buckets.get(i);
    int currentX=rankingWidth + i * intervalWidth;
    Iterator<Book.BookStats> it=currentBucket.listIterator();
    g.setFont(new Font("String_Node_Str",Font.PLAIN,9));
    while (it.hasNext()) {
      Book.BookStats stat=it.next();
      int currentY=height - startY - (16 - stat.ranking) * (barHeight + whiteSpaceHeight);
      if (state == State.OVERALL || stat.owner == currentBook)       g.setColor(stat.owner.colour);
 else       g.setColor(new Color(224,224,224));
      g.fillRect(currentX,currentY,intervalWidth / 2,barHeight);
      if (stat.next != null && stat.week + 1 == stat.next.week) {
        int nextY=height - startY - (16 - stat.next.ranking) * (barHeight + whiteSpaceHeight);
        int y[]={currentY,nextY,nextY + barHeight,currentY + barHeight};
        int x[]={currentX + intervalWidth / 2,currentX + intervalWidth,currentX + intervalWidth,currentX + intervalWidth / 2};
        g.fillPolygon(x,y,4);
      }
      if (stat.isFirst && (state == State.OVERALL || currentBook == stat.owner)) {
        g.setColor(Color.WHITE);
        if (stat.owner.title.length() < 8)         g.drawString(stat.owner.title,currentX + 2,currentY + 12);
 else         g.drawString(stat.owner.title.substring(0,8) + "String_Node_Str",currentX + 2,currentY + 12);
      }
      if (state == State.DETAIL && stat.owner == currentBook) {
        g.setFont(new Font("String_Node_Str",Font.BOLD,11));
        g.setColor(Color.BLACK);
        if (stat.ranking < 10)         g.drawString(stat.ranking + "String_Node_Str",currentX + intervalWidth / 4 - 4,currentY - 4);
 else         g.drawString(stat.ranking + "String_Node_Str",currentX + intervalWidth / 4 - 8,currentY - 4);
      }
    }
    g.setFont(new Font("String_Node_Str",Font.BOLD,11));
    g.setColor(Color.BLACK);
    g.drawString("String_Node_Str" + (i + 1),currentX,height - 32);
    if (bookColour != null) {
      int xOffset=(int)((ScrollPane)(this.getParent())).getScrollPosition().getX() + 400 - 150;
      FontMetrics metric=getFontMetrics(g.getFont());
      int stringWidth=metric.stringWidth(bookName);
      g.clearRect(0,height - 20,width,22);
      g.setColor(Color.GRAY);
      g.fillRect(xOffset + 2,height - 20 + 2,300,20);
      g.setColor(bookColour);
      g.fillRect(xOffset,height - 20,300,20);
      g.setColor(Color.WHITE);
      g.drawString(bookName,xOffset + (300 - stringWidth) / 2,height - 17 + 11);
      if (state == state.DETAIL) {
        int windowOffsetX=xOffset - 245;
        int windowOffsetY=15;
        int windowWidth=400;
        int windowHeight=150;
        FontMetrics fmet;
        Font heading=new Font("String_Node_Str",Font.BOLD,16);
        fmet=getFontMetrics(heading);
        g.setFont(heading);
        g.clearRect(0,0,width,windowHeight + 25);
        String title=currentBook.title;
        String author=currentBook.author;
        String desc=currentBook.description;
        g.setColor(Color.GRAY);
        g.fillRect(windowOffsetX + 2,windowOffsetY + 2,windowWidth,windowHeight);
        g.setColor(bookColour);
        g.fillRect(windowOffsetX,windowOffsetY,windowWidth,windowHeight);
        g.setColor(Color.WHITE);
        g.drawImage(currentBook.novelPic,windowOffsetX + (windowWidth * 2 / 3) + 30,20,90,135,this);
        g.drawImage(currentBook.tagPic,xOffset + 250,5,210,180,this);
        int headingWidth=(fmet.stringWidth(title));
        if (headingWidth < windowWidth) {
          windowOffsetY+=20;
          g.drawString(title,windowOffsetX + (windowWidth / 2) - (headingWidth / 2),windowOffsetY);
        }
 else {
          String title1=title.substring(0,title.length() / 2);
          int title1Width=(fmet.stringWidth(title1));
          String title2=title.substring(title.length() / 2);
          int title12Width=(fmet.stringWidth(title2));
          windowOffsetY+=15;
          g.drawString(title1,windowOffsetX + (windowWidth / 2) - (title1Width / 2),windowOffsetY);
          windowOffsetY+=15;
          g.drawString(title2,windowOffsetX + (windowWidth / 2) - (title12Width / 2),windowOffsetY);
        }
        g.setFont(new Font("String_Node_Str",Font.ITALIC,14));
        fmet=getFontMetrics(new Font("String_Node_Str",Font.ITALIC,14));
        windowOffsetY+=15;
        g.drawString(author,windowOffsetX + (windowWidth / 2) - (fmet.stringWidth(author)) / 2,windowOffsetY);
        g.setFont(new Font("String_Node_Str",Font.ITALIC,10));
        fmet=getFontMetrics(new Font("String_Node_Str",Font.ITALIC,10));
        windowOffsetY+=20;
        int descwidth=fmet.stringWidth(desc);
        if (descwidth < (windowWidth * 2) / 3) {
          g.drawString(desc,windowOffsetX + (windowWidth / 3) - (descwidth / 2),windowOffsetY);
        }
 else         if (descwidth / 2 < (windowWidth * 2) / 3) {
          String desc1=desc.substring(0,desc.length() / 2);
          String desc2=desc.substring(desc.length() / 2);
          g.drawString(desc1,windowOffsetX + (windowWidth / 3) - (fmet.stringWidth(desc1)) / 2,windowOffsetY);
          windowOffsetY+=10;
          g.drawString(desc2,windowOffsetX + (windowWidth / 3) - (fmet.stringWidth(desc2)) / 2,windowOffsetY);
        }
 else {
          String desc1=desc.substring(0,desc.length() / 3);
          String desc2=desc.substring(desc.length() / 3,desc.length() * 2 / 3);
          String desc3=desc.substring(desc.length() * 2 / 3);
          g.drawString(desc1,windowOffsetX + (windowWidth / 3) - (fmet.stringWidth(desc1)) / 2,windowOffsetY);
          windowOffsetY+=10;
          g.drawString(desc2,windowOffsetX + (windowWidth / 3) - (fmet.stringWidth(desc2)) / 2,windowOffsetY);
          windowOffsetY+=10;
          g.drawString(desc3,windowOffsetX + (windowWidth / 3) - (fmet.stringWidth(desc3)) / 2,windowOffsetY);
        }
      }
    }
 else {
      g.clearRect(0,height - 20,width,22);
    }
  }
}