public void removeComplaint(String complaint) {
   RenderableBlock rb = RenderableBlock.getRenderableBlock(blockID);
   if (rb.hasComplaint()) {
     Complaint balloon = rb.getComplaint();
     String ct = balloon.getText().replaceFirst("(?s)(Error|Warning):" + complaint + "\n", "");
     if (ct.length() == 0) {
       rb.removeComplaint();
     } else {
       balloon.setText(ct);
       balloon.reformBlockNote();
     }
   }
 }
 public static void showRuntimeComplaint(RenderableBlock rb, String complaint) {
   Complaint balloon = rb.getComplaint();
   balloon.getBlockNoteLabel().setActive(true);
   if (!rb.isVisible()) {
     rb.getTopmost().setCollapsed(false);
   }
   balloon.setText("Error: " + complaint + "\n");
   balloon.getBlockNoteLabel().setActive(true);
   balloon.getBlockNoteLabel().setBackground(ERROR_COLOR);
   complaintRect = rb.getBounds().union(balloon.getBounds());
   balloon.reformBlockNote();
   // TODO(user) scrollToShowRectangle doesn't seem to work properly at the Swing level
   Workspace.getInstance().getBlockCanvas().scrollToShowRectangle(complaintRect);
 }
 /**
  * Called from various places that find fault with a block during yail production. It puts a
  * message in the block's Complaint balloon.
  *
  * @param complaint
  * @param severe true means fatal error
  */
 public void complain(String complaint, boolean severe) {
   if (severe) {
     compileErrors.add(complaint);
   }
   RenderableBlock rb = RenderableBlock.getRenderableBlock(blockID);
   String message = (severe ? "Error" : "Warning") + ": " + complaint + "\n";
   Complaint balloon = rb.getComplaint();
   if (!balloon.getText().contains(message)) {
     balloon.setText(message + balloon.getText());
   }
   balloon.getBlockNoteLabel().setActive(severe);
   balloon.getBlockNoteLabel().setBackground(severe ? ERROR_COLOR : WARNING_COLOR);
   if (!rb.isVisible()) {
     // The only way this block is not visible is if it belongs to a collapsed
     // clump. Expand the whole clump so user can see the complaint.
     rb.getTopmost().setCollapsed(false);
   }
   complaintRect = complaintRect.union(rb.getBounds().union(balloon.getBounds()));
   balloon.reformBlockNote();
 }