Frames | No Frames |
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: }