Source for javax.swing.plaf.basic.BasicLabelUI

   1: /* BasicLabelUI.java
   2:  Copyright (C) 2002, 2004 Free Software Foundation, Inc.
   3: 
   4:  This file is part of GNU Classpath.
   5: 
   6:  GNU Classpath is free software; you can redistribute it and/or modify
   7:  it under the terms of the GNU General Public License as published by
   8:  the Free Software Foundation; either version 2, or (at your option)
   9:  any later version.
  10: 
  11:  GNU Classpath is distributed in the hope that it will be useful, but
  12:  WITHOUT ANY WARRANTY; without even the implied warranty of
  13:  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14:  General Public License for more details.
  15: 
  16:  You should have received a copy of the GNU General Public License
  17:  along with GNU Classpath; see the file COPYING.  If not, write to the
  18:  Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  19:  02110-1301 USA.
  20: 
  21:  Linking this library statically or dynamically with other modules is
  22:  making a combined work based on this library.  Thus, the terms and
  23:  conditions of the GNU General Public License cover the whole
  24:  combination.
  25: 
  26:  As a special exception, the copyright holders of this library give you
  27:  permission to link this library with independent modules to produce an
  28:  executable, regardless of the license terms of these independent
  29:  modules, and to copy and distribute the resulting executable under
  30:  terms of your choice, provided that you also meet, for each linked
  31:  independent module, the terms and conditions of the license of that
  32:  module.  An independent module is a module which is not derived from
  33:  or based on this library.  If you modify this library, you may extend
  34:  this exception to your version of the library, but you are not
  35:  obligated to do so.  If you do not wish to do so, delete this
  36:  exception statement from your version. */
  37: 
  38: package javax.swing.plaf.basic;
  39: 
  40: import java.awt.Color;
  41: import java.awt.Dimension;
  42: import java.awt.Font;
  43: import java.awt.FontMetrics;
  44: import java.awt.Graphics;
  45: import java.awt.Insets;
  46: import java.awt.Rectangle;
  47: import java.beans.PropertyChangeEvent;
  48: import java.beans.PropertyChangeListener;
  49: 
  50: import javax.swing.Icon;
  51: import javax.swing.JComponent;
  52: import javax.swing.JLabel;
  53: import javax.swing.LookAndFeel;
  54: import javax.swing.SwingUtilities;
  55: import javax.swing.plaf.ComponentUI;
  56: import javax.swing.plaf.LabelUI;
  57: 
  58: /**
  59:  * This is the Basic Look and Feel class for the JLabel.  One BasicLabelUI
  60:  * object is used to paint all JLabels that utilize the Basic Look and Feel.
  61:  */
  62: public class BasicLabelUI extends LabelUI implements PropertyChangeListener
  63: {
  64:   /** The labelUI that is shared by all labels. */
  65:   protected static BasicLabelUI labelUI;
  66: 
  67:   /**
  68:    * Creates a new BasicLabelUI object.
  69:    */
  70:   public BasicLabelUI()
  71:   {
  72:     super();
  73:   }
  74: 
  75:   /**
  76:    * Creates and returns a UI for the label. Since one UI is shared by  all
  77:    * labels, this means creating only if necessary and returning the  shared
  78:    * UI.
  79:    *
  80:    * @param c The {@link JComponent} that a UI is being created for.
  81:    *
  82:    * @return A label UI for the Basic Look and Feel.
  83:    */
  84:   public static ComponentUI createUI(JComponent c)
  85:   {
  86:     if (labelUI == null)
  87:       labelUI = new BasicLabelUI();
  88:     return labelUI;
  89:   }
  90: 
  91:   /**
  92:    * Returns the preferred size of this component as calculated by the
  93:    * {@link #layoutCL(JLabel, FontMetrics, String, Icon, Rectangle, Rectangle, 
  94:    * Rectangle)} method.
  95:    *
  96:    * @param c This {@link JComponent} to get a preferred size for.
  97:    *
  98:    * @return The preferred size.
  99:    */
 100:   public Dimension getPreferredSize(JComponent c)
 101:   {
 102:     JLabel lab = (JLabel) c;
 103:     Rectangle vr = new Rectangle();
 104:     Rectangle ir = new Rectangle();
 105:     Rectangle tr = new Rectangle();
 106:     Insets insets = lab.getInsets();
 107:     FontMetrics fm = lab.getToolkit().getFontMetrics(lab.getFont());
 108:     layoutCL(lab, fm, lab.getText(), lab.getIcon(), vr, ir, tr);
 109:     Rectangle cr = tr.union(ir);
 110:     return new Dimension(insets.left + cr.width + insets.right, insets.top
 111:         + cr.height + insets.bottom);
 112: 
 113:   }
 114: 
 115:   /**
 116:    * This method returns the minimum size of the {@link JComponent} given. If
 117:    * this method returns null, then it is up to the Layout Manager to give
 118:    * this component a minimum size.
 119:    *
 120:    * @param c The {@link JComponent} to get a minimum size for.
 121:    *
 122:    * @return The minimum size.
 123:    */
 124:   public Dimension getMinimumSize(JComponent c)
 125:   {
 126:     return getPreferredSize(c);
 127:   }
 128: 
 129:   /**
 130:    * This method returns the maximum size of the {@link JComponent} given. If
 131:    * this method returns null, then it is up to the Layout Manager to give
 132:    * this component a maximum size.
 133:    *
 134:    * @param c The {@link JComponent} to get a maximum size for.
 135:    *
 136:    * @return The maximum size.
 137:    */
 138:   public Dimension getMaximumSize(JComponent c)
 139:   {
 140:     return getPreferredSize(c);
 141:   }
 142: 
 143:   /**
 144:    * The method that paints the label according to its current state.
 145:    * 
 146:    * @param g The {@link Graphics} object to paint with.
 147:    * @param c The {@link JComponent} to paint.
 148:    */
 149:   public void paint(Graphics g, JComponent c)
 150:   {
 151:     JLabel b = (JLabel) c;
 152: 
 153:     Font saved_font = g.getFont();
 154: 
 155:     Rectangle tr = new Rectangle();
 156:     Rectangle ir = new Rectangle();
 157:     Rectangle vr = new Rectangle();
 158: 
 159:     Font f = c.getFont();
 160: 
 161:     g.setFont(f);
 162:     FontMetrics fm = g.getFontMetrics(f);
 163: 
 164:     vr = SwingUtilities.calculateInnerArea(c, vr);
 165: 
 166:     if (vr.width < 0)
 167:       vr.width = 0;
 168:     if (vr.height < 0)
 169:       vr.height = 0;
 170: 
 171:     Icon icon = (b.isEnabled()) ? b.getIcon() : b.getDisabledIcon();
 172: 
 173:     String text = layoutCL(b, fm, b.getText(), icon, vr, ir, tr);
 174: 
 175:     if (icon != null)
 176:       icon.paintIcon(b, g, ir.x, ir.y);        
 177: 
 178:     if (text != null && !text.equals(""))
 179:     {
 180:       if (b.isEnabled())
 181:         paintEnabledText(b, g, text, tr.x, tr.y + fm.getAscent());
 182:       else
 183:         paintDisabledText(b, g, text, tr.x, tr.y + fm.getAscent());
 184:     }
 185: 
 186:     g.setFont(saved_font);
 187:   }
 188: 
 189:   /**
 190:    * This method is simply calls SwingUtilities's layoutCompoundLabel.
 191:    * 
 192:    * @param label The label to lay out.
 193:    * @param fontMetrics The FontMetrics for the font used.
 194:    * @param text The text to paint.
 195:    * @param icon The icon to draw.
 196:    * @param viewR The entire viewable rectangle.
 197:    * @param iconR The icon bounds rectangle.
 198:    * @param textR The text bounds rectangle.
 199:    * 
 200:    * @return A possibly clipped version of the text.
 201:    */
 202:   protected String layoutCL(JLabel label, FontMetrics fontMetrics, String text,
 203:       Icon icon, Rectangle viewR, Rectangle iconR, Rectangle textR)
 204:   {
 205:     return SwingUtilities.layoutCompoundLabel(label, fontMetrics, text, icon,
 206:         label.getVerticalAlignment(), label.getHorizontalAlignment(), label
 207:             .getVerticalTextPosition(), label.getHorizontalTextPosition(),
 208:         viewR, iconR, textR, label.getIconTextGap());
 209:   }
 210: 
 211:   /**
 212:    * Paints the text if the label is disabled. By default, this paints the
 213:    * clipped text returned by layoutCompoundLabel using the
 214:    * background.brighter() color. It also paints the same text using the
 215:    * background.darker() color one pixel to the right and one pixel down.
 216:    *
 217:    * @param l The {@link JLabel} being painted.
 218:    * @param g The {@link Graphics} object to paint with.
 219:    * @param s The String to paint.
 220:    * @param textX The x coordinate of the start of the baseline.
 221:    * @param textY The y coordinate of the start of the baseline.
 222:    */
 223:   protected void paintDisabledText(JLabel l, Graphics g, String s, int textX,
 224:       int textY)
 225:   {
 226:     Color saved_color = g.getColor();
 227: 
 228:     g.setColor(l.getBackground().brighter());
 229: 
 230:     int mnemIndex = l.getDisplayedMnemonicIndex();
 231: 
 232:     if (mnemIndex != -1)
 233:       BasicGraphicsUtils.drawStringUnderlineCharAt(g, s, mnemIndex, textX,
 234:           textY);
 235:     else
 236:       g.drawString(s, textX, textY);
 237: 
 238:     g.setColor(l.getBackground().darker());
 239:     if (mnemIndex != -1)
 240:       BasicGraphicsUtils.drawStringUnderlineCharAt(g, s, mnemIndex, textX + 1,
 241:           textY + 1);
 242:     else
 243:       g.drawString(s, textX + 1, textY + 1);
 244: 
 245:     g.setColor(saved_color);
 246:   }
 247: 
 248:   /**
 249:    * Paints the text if the label is enabled. The text is painted using the
 250:    * foreground color.
 251:    *
 252:    * @param l The {@link JLabel} being painted.
 253:    * @param g The {@link Graphics} object to paint with.
 254:    * @param s The String to paint.
 255:    * @param textX The x coordinate of the start of the baseline.
 256:    * @param textY The y coordinate of the start of the baseline.
 257:    */
 258:   protected void paintEnabledText(JLabel l, Graphics g, String s, int textX,
 259:       int textY)
 260:   {
 261:     Color saved_color = g.getColor();
 262:     g.setColor(l.getForeground());
 263: 
 264:     int mnemIndex = l.getDisplayedMnemonicIndex();
 265: 
 266:     if (mnemIndex != -1)
 267:       BasicGraphicsUtils.drawStringUnderlineCharAt(g, s, mnemIndex, textX,
 268:           textY);
 269:     else
 270:       g.drawString(s, textX, textY);
 271: 
 272:     g.setColor(saved_color);
 273:   }
 274: 
 275:   /**
 276:    * This method installs the UI for the given {@link JComponent}.  This
 277:    * method will install the component, defaults, listeners,  and keyboard
 278:    * actions.
 279:    *
 280:    * @param c The {@link JComponent} that this UI is being installed on.
 281:    */
 282:   public void installUI(JComponent c)
 283:   {
 284:     super.installUI(c);
 285:     if (c instanceof JLabel)
 286:     {
 287:       JLabel l = (JLabel) c;
 288: 
 289:       installComponents(l);
 290:       installDefaults(l);
 291:       installListeners(l);
 292:       installKeyboardActions(l);
 293:     }
 294:   }
 295: 
 296:   /**
 297:    * This method uninstalls the UI for the given {@link JComponent}. This
 298:    * method will uninstall the component, defaults, listeners,  and keyboard
 299:    * actions.
 300:    *
 301:    * @param c The {@link JComponent} that this UI is being installed on.
 302:    */
 303:   public void uninstallUI(JComponent c)
 304:   {
 305:     super.uninstallUI(c);
 306:     if (c instanceof JLabel)
 307:     {
 308:       JLabel l = (JLabel) c;
 309: 
 310:       uninstallKeyboardActions(l);
 311:       uninstallListeners(l);
 312:       uninstallDefaults(l);
 313:       uninstallComponents(l);
 314:     }
 315:   }
 316: 
 317:   /**
 318:    * This method installs the components for this {@link JLabel}.
 319:    *
 320:    * @param c The {@link JLabel} to install components for.
 321:    */
 322:   protected void installComponents(JLabel c)
 323:   {
 324:     //FIXME: fix javadoc + implement.
 325:   }
 326: 
 327:   /**
 328:    * This method uninstalls the components for this {@link JLabel}.
 329:    *
 330:    * @param c The {@link JLabel} to uninstall components for.
 331:    */
 332:   protected void uninstallComponents(JLabel c)
 333:   {
 334:     //FIXME: fix javadoc + implement.
 335:   }
 336: 
 337:   /**
 338:    * This method installs the defaults that are defined in  the Basic look and
 339:    * feel for this {@link JLabel}.
 340:    *
 341:    * @param c The {@link JLabel} to install defaults for.
 342:    */
 343:   protected void installDefaults(JLabel c)
 344:   {
 345:     LookAndFeel.installColorsAndFont(c, "Label.background", "Label.foreground",
 346:                                      "Label.font");
 347:     //XXX: There are properties we don't use called disabledForeground
 348:     //and disabledShadow.
 349:   }
 350: 
 351:   /**
 352:    * This method uninstalls the defaults that are defined in the Basic look
 353:    * and feel for this {@link JLabel}.
 354:    *
 355:    * @param c The {@link JLabel} to uninstall defaults for.
 356:    */
 357:   protected void uninstallDefaults(JLabel c)
 358:   {
 359:     c.setForeground(null);
 360:     c.setBackground(null);
 361:     c.setFont(null);
 362:   }
 363: 
 364:   /**
 365:    * This method installs the keyboard actions for the given {@link JLabel}.
 366:    *
 367:    * @param l The {@link JLabel} to install keyboard actions for.
 368:    */
 369:   protected void installKeyboardActions(JLabel l)
 370:   {
 371:     //FIXME: implement.
 372:   }
 373: 
 374:   /**
 375:    * This method uninstalls the keyboard actions for the given {@link JLabel}.
 376:    *
 377:    * @param l The {@link JLabel} to uninstall keyboard actions for.
 378:    */
 379:   protected void uninstallKeyboardActions(JLabel l)
 380:   {
 381:     //FIXME: implement.
 382:   }
 383: 
 384:   /**
 385:    * This method installs the listeners for the  given {@link JLabel}. The UI
 386:    * delegate only listens to  the label.
 387:    *
 388:    * @param c The {@link JLabel} to install listeners for.
 389:    */
 390:   protected void installListeners(JLabel c)
 391:   {
 392:     c.addPropertyChangeListener(this);
 393:   }
 394: 
 395:   /**
 396:    * This method uninstalls the listeners for the given {@link JLabel}. The UI
 397:    * delegate only listens to the label.
 398:    *
 399:    * @param c The {@link JLabel} to uninstall listeners for.
 400:    */
 401:   protected void uninstallListeners(JLabel c)
 402:   {
 403:     c.removePropertyChangeListener(this);
 404:   }
 405: 
 406:   /**
 407:    * This method is called whenever any JLabel's that use this UI has one of
 408:    * their properties change.
 409:    *
 410:    * @param e The {@link PropertyChangeEvent} that describes the change.
 411:    */
 412:   public void propertyChange(PropertyChangeEvent e)
 413:   {
 414:     // What to do here?
 415:   }
 416: }