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.FontMetrics;
  43: import java.awt.Graphics;
  44: import java.awt.Insets;
  45: import java.awt.Rectangle;
  46: import java.beans.PropertyChangeEvent;
  47: import java.beans.PropertyChangeListener;
  48: 
  49: import javax.swing.Icon;
  50: import javax.swing.JComponent;
  51: import javax.swing.JLabel;
  52: import javax.swing.LookAndFeel;
  53: import javax.swing.SwingUtilities;
  54: import javax.swing.plaf.ComponentUI;
  55: import javax.swing.plaf.LabelUI;
  56: 
  57: /**
  58:  * This is the Basic Look and Feel class for the JLabel.  One BasicLabelUI
  59:  * object is used to paint all JLabels that utilize the Basic Look and Feel.
  60:  */
  61: public class BasicLabelUI extends LabelUI implements PropertyChangeListener
  62: {
  63:   /** The labelUI that is shared by all labels. */
  64:   protected static BasicLabelUI labelUI;
  65: 
  66:   /**
  67:    * Creates a new BasicLabelUI object.
  68:    */
  69:   public BasicLabelUI()
  70:   {
  71:     super();
  72:   }
  73: 
  74:   /**
  75:    * Creates and returns a UI for the label. Since one UI is shared by  all
  76:    * labels, this means creating only if necessary and returning the  shared
  77:    * UI.
  78:    *
  79:    * @param c The {@link JComponent} that a UI is being created for.
  80:    *
  81:    * @return A label UI for the Basic Look and Feel.
  82:    */
  83:   public static ComponentUI createUI(JComponent c)
  84:   {
  85:     if (labelUI == null)
  86:       labelUI = new BasicLabelUI();
  87:     return labelUI;
  88:   }
  89: 
  90:   /**
  91:    * Returns the preferred size of this component as calculated by the
  92:    * {@link #layoutCL(JLabel, FontMetrics, String, Icon, Rectangle, Rectangle, 
  93:    * Rectangle)} method.
  94:    *
  95:    * @param c This {@link JComponent} to get a preferred size for.
  96:    *
  97:    * @return The preferred size.
  98:    */
  99:   public Dimension getPreferredSize(JComponent c)
 100:   {
 101:     JLabel lab = (JLabel) c;
 102:     Rectangle vr = new Rectangle();
 103:     Rectangle ir = new Rectangle();
 104:     Rectangle tr = new Rectangle();
 105:     Insets insets = lab.getInsets();
 106:     FontMetrics fm = lab.getFontMetrics(lab.getFont());
 107:     layoutCL(lab, fm, lab.getText(), lab.getIcon(), vr, ir, tr);
 108:     Rectangle cr = tr.union(ir);
 109:     return new Dimension(insets.left + cr.width + insets.right, insets.top
 110:         + cr.height + insets.bottom);
 111: 
 112:   }
 113: 
 114:   /**
 115:    * This method returns the minimum size of the {@link JComponent} given. If
 116:    * this method returns null, then it is up to the Layout Manager to give
 117:    * this component a minimum size.
 118:    *
 119:    * @param c The {@link JComponent} to get a minimum size for.
 120:    *
 121:    * @return The minimum size.
 122:    */
 123:   public Dimension getMinimumSize(JComponent c)
 124:   {
 125:     return getPreferredSize(c);
 126:   }
 127: 
 128:   /**
 129:    * This method returns the maximum size of the {@link JComponent} given. If
 130:    * this method returns null, then it is up to the Layout Manager to give
 131:    * this component a maximum size.
 132:    *
 133:    * @param c The {@link JComponent} to get a maximum size for.
 134:    *
 135:    * @return The maximum size.
 136:    */
 137:   public Dimension getMaximumSize(JComponent c)
 138:   {
 139:     return getPreferredSize(c);
 140:   }
 141: 
 142:   /**
 143:    * The method that paints the label according to its current state.
 144:    * 
 145:    * @param g The {@link Graphics} object to paint with.
 146:    * @param c The {@link JComponent} to paint.
 147:    */
 148:   public void paint(Graphics g, JComponent c)
 149:   {
 150:     JLabel b = (JLabel) c;
 151: 
 152:     Rectangle tr = new Rectangle();
 153:     Rectangle ir = new Rectangle();
 154:     Rectangle vr = new Rectangle();
 155: 
 156:     FontMetrics fm = g.getFontMetrics();
 157:     vr = SwingUtilities.calculateInnerArea(c, vr);
 158: 
 159:     if (vr.width < 0)
 160:       vr.width = 0;
 161:     if (vr.height < 0)
 162:       vr.height = 0;
 163: 
 164:     Icon icon = (b.isEnabled()) ? b.getIcon() : b.getDisabledIcon();
 165: 
 166:     String text = layoutCL(b, fm, b.getText(), icon, vr, ir, tr);
 167: 
 168:     if (icon != null)
 169:       icon.paintIcon(b, g, ir.x, ir.y);        
 170: 
 171:     if (text != null && !text.equals(""))
 172:     {
 173:       if (b.isEnabled())
 174:         paintEnabledText(b, g, text, tr.x, tr.y + fm.getAscent());
 175:       else
 176:         paintDisabledText(b, g, text, tr.x, tr.y + fm.getAscent());
 177:     }
 178:   }
 179: 
 180:   /**
 181:    * This method is simply calls SwingUtilities's layoutCompoundLabel.
 182:    * 
 183:    * @param label The label to lay out.
 184:    * @param fontMetrics The FontMetrics for the font used.
 185:    * @param text The text to paint.
 186:    * @param icon The icon to draw.
 187:    * @param viewR The entire viewable rectangle.
 188:    * @param iconR The icon bounds rectangle.
 189:    * @param textR The text bounds rectangle.
 190:    * 
 191:    * @return A possibly clipped version of the text.
 192:    */
 193:   protected String layoutCL(JLabel label, FontMetrics fontMetrics, String text,
 194:       Icon icon, Rectangle viewR, Rectangle iconR, Rectangle textR)
 195:   {
 196:     return SwingUtilities.layoutCompoundLabel(label, fontMetrics, text, icon,
 197:         label.getVerticalAlignment(), label.getHorizontalAlignment(), label
 198:             .getVerticalTextPosition(), label.getHorizontalTextPosition(),
 199:         viewR, iconR, textR, label.getIconTextGap());
 200:   }
 201: 
 202:   /**
 203:    * Paints the text if the label is disabled. By default, this paints the
 204:    * clipped text returned by layoutCompoundLabel using the
 205:    * background.brighter() color. It also paints the same text using the
 206:    * background.darker() color one pixel to the right and one pixel down.
 207:    *
 208:    * @param l The {@link JLabel} being painted.
 209:    * @param g The {@link Graphics} object to paint with.
 210:    * @param s The String to paint.
 211:    * @param textX The x coordinate of the start of the baseline.
 212:    * @param textY The y coordinate of the start of the baseline.
 213:    */
 214:   protected void paintDisabledText(JLabel l, Graphics g, String s, int textX,
 215:       int textY)
 216:   {
 217:     Color saved_color = g.getColor();
 218: 
 219:     g.setColor(l.getBackground().brighter());
 220: 
 221:     int mnemIndex = l.getDisplayedMnemonicIndex();
 222: 
 223:     if (mnemIndex != -1)
 224:       BasicGraphicsUtils.drawStringUnderlineCharAt(g, s, mnemIndex, textX,
 225:           textY);
 226:     else
 227:       g.drawString(s, textX, textY);
 228: 
 229:     g.setColor(l.getBackground().darker());
 230:     if (mnemIndex != -1)
 231:       BasicGraphicsUtils.drawStringUnderlineCharAt(g, s, mnemIndex, textX + 1,
 232:           textY + 1);
 233:     else
 234:       g.drawString(s, textX + 1, textY + 1);
 235: 
 236:     g.setColor(saved_color);
 237:   }
 238: 
 239:   /**
 240:    * Paints the text if the label is enabled. The text is painted using the
 241:    * foreground color.
 242:    *
 243:    * @param l The {@link JLabel} being painted.
 244:    * @param g The {@link Graphics} object to paint with.
 245:    * @param s The String to paint.
 246:    * @param textX The x coordinate of the start of the baseline.
 247:    * @param textY The y coordinate of the start of the baseline.
 248:    */
 249:   protected void paintEnabledText(JLabel l, Graphics g, String s, int textX,
 250:       int textY)
 251:   {
 252:     Color saved_color = g.getColor();
 253:     g.setColor(l.getForeground());
 254: 
 255:     int mnemIndex = l.getDisplayedMnemonicIndex();
 256: 
 257:     if (mnemIndex != -1)
 258:       BasicGraphicsUtils.drawStringUnderlineCharAt(g, s, mnemIndex, textX,
 259:           textY);
 260:     else
 261:       g.drawString(s, textX, textY);
 262: 
 263:     g.setColor(saved_color);
 264:   }
 265: 
 266:   /**
 267:    * This method installs the UI for the given {@link JComponent}.  This
 268:    * method will install the component, defaults, listeners,  and keyboard
 269:    * actions.
 270:    *
 271:    * @param c The {@link JComponent} that this UI is being installed on.
 272:    */
 273:   public void installUI(JComponent c)
 274:   {
 275:     super.installUI(c);
 276:     if (c instanceof JLabel)
 277:     {
 278:       JLabel l = (JLabel) c;
 279: 
 280:       installComponents(l);
 281:       installDefaults(l);
 282:       installListeners(l);
 283:       installKeyboardActions(l);
 284:     }
 285:   }
 286: 
 287:   /**
 288:    * This method uninstalls the UI for the given {@link JComponent}. This
 289:    * method will uninstall the component, defaults, listeners,  and keyboard
 290:    * actions.
 291:    *
 292:    * @param c The {@link JComponent} that this UI is being installed on.
 293:    */
 294:   public void uninstallUI(JComponent c)
 295:   {
 296:     super.uninstallUI(c);
 297:     if (c instanceof JLabel)
 298:     {
 299:       JLabel l = (JLabel) c;
 300: 
 301:       uninstallKeyboardActions(l);
 302:       uninstallListeners(l);
 303:       uninstallDefaults(l);
 304:       uninstallComponents(l);
 305:     }
 306:   }
 307: 
 308:   /**
 309:    * This method installs the components for this {@link JLabel}.
 310:    *
 311:    * @param c The {@link JLabel} to install components for.
 312:    */
 313:   protected void installComponents(JLabel c)
 314:   {
 315:     //FIXME: fix javadoc + implement.
 316:   }
 317: 
 318:   /**
 319:    * This method uninstalls the components for this {@link JLabel}.
 320:    *
 321:    * @param c The {@link JLabel} to uninstall components for.
 322:    */
 323:   protected void uninstallComponents(JLabel c)
 324:   {
 325:     //FIXME: fix javadoc + implement.
 326:   }
 327: 
 328:   /**
 329:    * This method installs the defaults that are defined in  the Basic look and
 330:    * feel for this {@link JLabel}.
 331:    *
 332:    * @param c The {@link JLabel} to install defaults for.
 333:    */
 334:   protected void installDefaults(JLabel c)
 335:   {
 336:     LookAndFeel.installColorsAndFont(c, "Label.background", "Label.foreground",
 337:                                      "Label.font");
 338:     //XXX: There are properties we don't use called disabledForeground
 339:     //and disabledShadow.
 340:   }
 341: 
 342:   /**
 343:    * This method uninstalls the defaults that are defined in the Basic look
 344:    * and feel for this {@link JLabel}.
 345:    *
 346:    * @param c The {@link JLabel} to uninstall defaults for.
 347:    */
 348:   protected void uninstallDefaults(JLabel c)
 349:   {
 350:     c.setForeground(null);
 351:     c.setBackground(null);
 352:     c.setFont(null);
 353:   }
 354: 
 355:   /**
 356:    * This method installs the keyboard actions for the given {@link JLabel}.
 357:    *
 358:    * @param l The {@link JLabel} to install keyboard actions for.
 359:    */
 360:   protected void installKeyboardActions(JLabel l)
 361:   {
 362:     //FIXME: implement.
 363:   }
 364: 
 365:   /**
 366:    * This method uninstalls the keyboard actions for the given {@link JLabel}.
 367:    *
 368:    * @param l The {@link JLabel} to uninstall keyboard actions for.
 369:    */
 370:   protected void uninstallKeyboardActions(JLabel l)
 371:   {
 372:     //FIXME: implement.
 373:   }
 374: 
 375:   /**
 376:    * This method installs the listeners for the  given {@link JLabel}. The UI
 377:    * delegate only listens to  the label.
 378:    *
 379:    * @param c The {@link JLabel} to install listeners for.
 380:    */
 381:   protected void installListeners(JLabel c)
 382:   {
 383:     c.addPropertyChangeListener(this);
 384:   }
 385: 
 386:   /**
 387:    * This method uninstalls the listeners for the given {@link JLabel}. The UI
 388:    * delegate only listens to the label.
 389:    *
 390:    * @param c The {@link JLabel} to uninstall listeners for.
 391:    */
 392:   protected void uninstallListeners(JLabel c)
 393:   {
 394:     c.removePropertyChangeListener(this);
 395:   }
 396: 
 397:   /**
 398:    * This method is called whenever any JLabel's that use this UI has one of
 399:    * their properties change.
 400:    *
 401:    * @param e The {@link PropertyChangeEvent} that describes the change.
 402:    */
 403:   public void propertyChange(PropertyChangeEvent e)
 404:   {
 405:     // What to do here?
 406:   }
 407: }