Program: 78972
Project: 78972
Buggy source:
/** 
 * Determines the bounding box of the character at the given index into the string.  The bounds are returned in local coordinates.  If the index is invalid a null rectangle is returned. The screen coordinates returned are "unscrolled coordinates" if the JTextComponent is contained in a JScrollPane in which case the resulting rectangle should be composed with the parent coordinates.  A good algorithm to use is: <nf> Accessible a: AccessibleText at = a.getAccessibleText(); AccessibleComponent ac = a.getAccessibleComponent(); Rectangle r = at.getCharacterBounds(); Point p = ac.getLocation(); r.x += p.x; r.y += p.y; </nf> Note: the JTextComponent must have a valid size (e.g. have been added to a parent container whose ancestor container is a valid top-level window) for this method to be able to return a meaningful (non-null) value.
 * @param i the index into the String >= 0
 * @return the screen coordinates of the character's bounding box
 */
public Rectangle getCharacterBounds(int i){
  if (i < 0 || i > model.getLength() - 1) {
    return null;
  }
  TextUI ui=getUI();
  if (ui == null) {
    return null;
  }
  Rectangle rect=null;
  Rectangle alloc=getRootEditorRect();
  if (alloc == null) {
    return null;
  }
  if (model instanceof AbstractDocument) {
    ((AbstractDocument)model).readLock();
  }
  try {
    View rootView=ui.getRootView(JTextComponent.this);
    if (rootView != null) {
      rootView.setSize(alloc.width,alloc.height);
      Shape bounds=rootView.modelToView(i,Position.Bias.Forward,i + 1,Position.Bias.Backward,alloc);
      rect=(bounds instanceof Rectangle) ? (Rectangle)bounds : bounds.getBounds();
    }
  }
 catch (  BadLocationException e) {
  }
 finally {
    if (model instanceof AbstractDocument) {
      ((AbstractDocument)model).readUnlock();
    }
  }
  return rect;
}

Fixed version (ground truth):
/** 
 * Determines the bounding box of the character at the given index into the string.  The bounds are returned in local coordinates.  If the index is invalid a null rectangle is returned. The screen coordinates returned are "unscrolled coordinates" if the JTextComponent is contained in a JScrollPane in which case the resulting rectangle should be composed with the parent coordinates.  A good algorithm to use is: <pre> Accessible a: AccessibleText at = a.getAccessibleText(); AccessibleComponent ac = a.getAccessibleComponent(); Rectangle r = at.getCharacterBounds(); Point p = ac.getLocation(); r.x += p.x; r.y += p.y; </pre> Note: the JTextComponent must have a valid size (e.g. have been added to a parent container whose ancestor container is a valid top-level window) for this method to be able to return a meaningful (non-null) value.
 * @param i the index into the String &ge; 0
 * @return the screen coordinates of the character's bounding box
 */
public Rectangle getCharacterBounds(int i){
  if (i < 0 || i > model.getLength() - 1) {
    return null;
  }
  TextUI ui=getUI();
  if (ui == null) {
    return null;
  }
  Rectangle rect=null;
  Rectangle alloc=getRootEditorRect();
  if (alloc == null) {
    return null;
  }
  if (model instanceof AbstractDocument) {
    ((AbstractDocument)model).readLock();
  }
  try {
    View rootView=ui.getRootView(JTextComponent.this);
    if (rootView != null) {
      rootView.setSize(alloc.width,alloc.height);
      Shape bounds=rootView.modelToView(i,Position.Bias.Forward,i + 1,Position.Bias.Backward,alloc);
      rect=(bounds instanceof Rectangle) ? (Rectangle)bounds : bounds.getBounds();
    }
  }
 catch (  BadLocationException e) {
  }
 finally {
    if (model instanceof AbstractDocument) {
      ((AbstractDocument)model).readUnlock();
    }
  }
  return rect;
}