public static void paintLabels(Graphics gx) {
    gx.setFont(new Font(null, Font.PLAIN, 9));
    FontMetrics fm = gx.getFontMetrics();
    int hf = fm.getAscent();
    for (int i = 0; i < COMPONENTS.size(); i++) {
      BeanInstance bi = (BeanInstance)COMPONENTS.elementAt(i);
      if (!(bi.getBean() instanceof Visible)) {
	continue;
      }
      int cx = bi.getX(); int cy = bi.getY();
      int width = ((JComponent)bi.getBean()).getWidth();
      int height = ((JComponent)bi.getBean()).getHeight();
      String label = ((Visible)bi.getBean()).getVisual().getText();
      int labelwidth = fm.stringWidth(label);
      if (labelwidth < width) {
	gx.drawString(label, (cx+(width/2)) - (labelwidth / 2), cy+height+hf+2);
      } else {
	// split label

	// find mid point
	int mid = label.length() / 2;
	// look for split point closest to the mid
	int closest = label.length();
	int closestI = -1;
	for (int z = 0; z < label.length(); z++) {
	  if (label.charAt(z) < 'a') {
	    if (Math.abs(mid - z) < closest) {
	      closest = Math.abs(mid - z);
	      closestI = z;
	    }
	  }
	}
	if (closestI != -1) {
	  String left = label.substring(0, closestI);
	  String right = label.substring(closestI, label.length());
	  if (left.length() > 1 && right.length() > 1) {
	    gx.drawString(left, (cx+(width/2)) - (fm.stringWidth(left) / 2), 
			  cy+height+(hf * 1)+2);
	    gx.drawString(right, (cx+(width/2)) - (fm.stringWidth(right) / 2), 
			  cy+height+(hf * 2)+2);
	  } else {
	    gx.drawString(label, (cx+(width/2)) - (fm.stringWidth(label) / 2), 
			  cy+height+(hf * 1)+2);
	  }
	} else {
	  gx.drawString(label, (cx+(width/2)) - (fm.stringWidth(label) / 2), 
			cy+height+(hf * 1)+2);
	}
      }
    }
  }