
/*
   A component for displaying a mirror-reversed line of text.
   The text will be centered in the available space.  This component
   is defined as a subclass of Canvas, but it acts like a Label.
   It respects the background color, foreground color and font.
   The setText(String) method can be used to change the displayed
   text.  Changing the text will also call invalidate() on this
   component.
*/

import java.awt.*;

public class MirrorLabel extends Canvas {

   // Constructor and methods meant for use public use.

   public MirrorLabel(String text) {
         // Construct a MirrorLable to display the specified text.
      this.text = text;
   }
   
   public void setText(String text) {
         // Change the displayed text.  Call invalidate so that
         // its size will be computed if its container is validated.
      this.text = text;
      invalidate();
      repaint();
   }
   
   public String getText() {
         // Return the string that is displayed by this component.
      return text;
   }
   
   // Implementation.  Not meant for public use.
   
   private String text; // The text displayed by this component.

   private Image OSC;  // An off-screen canvas holding the non-reversed text.
   private int widthOfOSC, heightOfOSC;  // Size of the off-screen canvas.

   public void update(Graphics g) {
         // Redefine update so that it calls paint without first erasing.
      paint(g);
   }
   
   public void paint(Graphics g) {
         // The paint method makes a new OSC, if necessary.  It writes
         // a non-reversed copy of the string to the the OSC, then reverses
         // the OSC as it copies it to the screen.  (Note:  color or font
         // might have changed since the last time paint() was called, so
         // I can't just reuse the old image in the OSC.)
      if (OSC == null || getSize().width != widthOfOSC || getSize().height != heightOfOSC) {
          OSC = createImage(getSize().width, getSize().height);
          widthOfOSC = getSize().width;
          heightOfOSC = getSize().height;
       }
       Graphics OSG = OSC.getGraphics();
       OSG.setColor(getBackground());
       OSG.fillRect(0, 0, widthOfOSC, heightOfOSC);
       OSG.setColor(getForeground()); 
       OSG.setFont(getFont());
       FontMetrics fm = OSG.getFontMetrics(getFont());
       int x = (widthOfOSC - fm.stringWidth(text)) / 2;
       int y = (heightOfOSC + fm.getAscent() - fm.getDescent()) / 2;
       OSG.drawString(text, x, y);
       OSG.dispose();
       g.drawImage(OSC, widthOfOSC, 0, 0, heightOfOSC,
                       0, 0, widthOfOSC, heightOfOSC, this);
   }
   
   public Dimension getMinimumSize() {
      return getPreferredSize();
   }
   
   public Dimension getPreferredSize() {
          // Compute a preferred size that will hold the string plus 
          // a border of 5 pixels.
      FontMetrics fm = getFontMetrics(getFont());
      return new Dimension(fm.stringWidth(text) + 10, 
                                fm.getAscent() + fm.getDescent() + 10);
   }

}  // end MirrorLabel
