2 Copyright (C) 2002, 2004 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
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)
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.
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
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
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. */
38 package javax.swing.plaf.basic;
40 import java.awt.Color;
41 import java.awt.Dimension;
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;
50 import javax.swing.Icon;
51 import javax.swing.JComponent;
52 import javax.swing.JLabel;
53 import javax.swing.SwingUtilities;
54 import javax.swing.UIDefaults;
55 import javax.swing.UIManager;
56 import javax.swing.plaf.ComponentUI;
57 import javax.swing.plaf.LabelUI;
61 * This is the Basic Look and Feel class for the JLabel. One BasicLabelUI
62 * object is used to paint all JLabels that utilize the Basic Look and Feel.
64 public class BasicLabelUI extends LabelUI implements PropertyChangeListener
66 /** The labelUI that is shared by all labels. */
67 protected static BasicLabelUI labelUI;
70 * Creates a new BasicLabelUI object.
78 * Creates and returns a UI for the label. Since one UI is shared by all
79 * labels, this means creating only if necessary and returning the shared
82 * @param c The {@link JComponent} that a UI is being created for.
84 * @return A label UI for the Basic Look and Feel.
86 public static ComponentUI createUI(JComponent c)
89 labelUI = new BasicLabelUI();
94 * Returns the preferred size of this component as calculated by the
95 * {@link #layoutCL(JLabel, FontMetrics, String, Icon, Rectangle, Rectangle,
98 * @param c This {@link JComponent} to get a preferred size for.
100 * @return The preferred size.
102 public Dimension getPreferredSize(JComponent c)
104 JLabel lab = (JLabel)c;
105 Rectangle vr = new Rectangle();
106 Rectangle ir = new Rectangle();
107 Rectangle tr = new Rectangle();
108 Insets insets = lab.getInsets();
109 FontMetrics fm = lab.getToolkit().getFontMetrics(lab.getFont());
110 layoutCL(lab, fm, lab.getText(), lab.getIcon(), vr, ir, tr);
111 Rectangle cr = tr.union(ir);
112 return new Dimension(insets.left + cr.width + insets.right,
113 insets.top + cr.height + insets.bottom);
118 * This method returns the minimum size of the {@link JComponent} given. If
119 * this method returns null, then it is up to the Layout Manager to give
120 * this component a minimum size.
122 * @param c The {@link JComponent} to get a minimum size for.
124 * @return The minimum size.
126 public Dimension getMinimumSize(JComponent c)
128 return getPreferredSize(c);
132 * This method returns the maximum size of the {@link JComponent} given. If
133 * this method returns null, then it is up to the Layout Manager to give
134 * this component a maximum size.
136 * @param c The {@link JComponent} to get a maximum size for.
138 * @return The maximum size.
140 public Dimension getMaximumSize(JComponent c)
142 return getPreferredSize(c);
146 * The method that paints the label according to its current state.
148 * @param g The {@link Graphics} object to paint with.
149 * @param c The {@link JComponent} to paint.
151 public void paint(Graphics g, JComponent c)
153 JLabel b = (JLabel) c;
155 Font saved_font = g.getFont();
157 Rectangle tr = new Rectangle();
158 Rectangle ir = new Rectangle();
159 Rectangle vr = new Rectangle();
161 Font f = c.getFont();
164 FontMetrics fm = g.getFontMetrics(f);
166 vr = SwingUtilities.calculateInnerArea(c, vr);
173 Icon icon = (b.isEnabled()) ? b.getIcon() : b.getDisabledIcon();
175 String text = layoutCL(b, fm, b.getText(), icon, vr, ir, tr);
178 icon.paintIcon(b, g, ir.x, ir.y);
179 if (text != null && ! text.equals(""))
182 paintEnabledText(b, g, text, tr.x, tr.y + fm.getAscent());
184 paintDisabledText(b, g, text, tr.x, tr.y + fm.getAscent());
186 g.setFont(saved_font);
190 * This method is simply calls SwingUtilities's layoutCompoundLabel.
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.
200 * @return A possibly clipped version of the text.
202 protected String layoutCL(JLabel label, FontMetrics fontMetrics,
203 String text, Icon icon, Rectangle viewR,
204 Rectangle iconR, Rectangle textR)
206 return SwingUtilities.layoutCompoundLabel(label, fontMetrics, text, icon,
207 label.getVerticalAlignment(),
208 label.getHorizontalAlignment(),
209 label.getVerticalTextPosition(),
210 label.getHorizontalTextPosition(),
212 label.getIconTextGap());
216 * Paints the text if the label is disabled. By default, this paints the
217 * clipped text returned by layoutCompoundLabel using the
218 * background.brighter() color. It also paints the same text using the
219 * background.darker() color one pixel to the right and one pixel down.
221 * @param l The {@link JLabel} being painted.
222 * @param g The {@link Graphics} object to paint with.
223 * @param s The String to paint.
224 * @param textX The x coordinate of the start of the baseline.
225 * @param textY The y coordinate of the start of the baseline.
227 protected void paintDisabledText(JLabel l, Graphics g, String s, int textX,
230 Color saved_color = g.getColor();
232 g.setColor(l.getBackground().brighter());
234 int mnemIndex = l.getDisplayedMnemonicIndex();
237 BasicGraphicsUtils.drawStringUnderlineCharAt(g, s, mnemIndex, textX,
240 g.drawString(s, textX, textY);
242 g.setColor(l.getBackground().darker());
244 BasicGraphicsUtils.drawStringUnderlineCharAt(g, s, mnemIndex, textX + 1,
247 g.drawString(s, textX + 1, textY + 1);
249 g.setColor(saved_color);
253 * Paints the text if the label is enabled. The text is painted using the
256 * @param l The {@link JLabel} being painted.
257 * @param g The {@link Graphics} object to paint with.
258 * @param s The String to paint.
259 * @param textX The x coordinate of the start of the baseline.
260 * @param textY The y coordinate of the start of the baseline.
262 protected void paintEnabledText(JLabel l, Graphics g, String s, int textX,
265 Color saved_color = g.getColor();
266 g.setColor(l.getForeground());
268 int mnemIndex = l.getDisplayedMnemonicIndex();
271 BasicGraphicsUtils.drawStringUnderlineCharAt(g, s, mnemIndex, textX,
274 g.drawString(s, textX, textY);
276 g.setColor(saved_color);
280 * This method installs the UI for the given {@link JComponent}. This
281 * method will install the component, defaults, listeners, and keyboard
284 * @param c The {@link JComponent} that this UI is being installed on.
286 public void installUI(JComponent c)
289 if (c instanceof JLabel)
291 JLabel l = (JLabel) c;
293 installComponents(l);
296 installKeyboardActions(l);
301 * This method uninstalls the UI for the given {@link JComponent}. This
302 * method will uninstall the component, defaults, listeners, and keyboard
305 * @param c The {@link JComponent} that this UI is being installed on.
307 public void uninstallUI(JComponent c)
309 super.uninstallUI(c);
310 if (c instanceof JLabel)
312 JLabel l = (JLabel) c;
314 uninstallKeyboardActions(l);
315 uninstallListeners(l);
316 uninstallDefaults(l);
317 uninstallComponents(l);
322 * This method installs the components for this {@link JLabel}.
324 * @param c The {@link JLabel} to install components for.
326 protected void installComponents(JLabel c)
328 //FIXME: fix javadoc + implement.
332 * This method uninstalls the components for this {@link JLabel}.
334 * @param c The {@link JLabel} to uninstall components for.
336 protected void uninstallComponents(JLabel c)
338 //FIXME: fix javadoc + implement.
342 * This method installs the defaults that are defined in the Basic look and
343 * feel for this {@link JLabel}.
345 * @param c The {@link JLabel} to install defaults for.
347 protected void installDefaults(JLabel c)
349 UIDefaults defaults = UIManager.getLookAndFeelDefaults();
351 c.setForeground(defaults.getColor("Label.foreground"));
352 c.setBackground(defaults.getColor("Label.background"));
353 c.setFont(defaults.getFont("Label.font"));
354 //XXX: There are properties we don't use called disabledForeground
355 //and disabledShadow.
359 * This method uninstalls the defaults that are defined in the Basic look
360 * and feel for this {@link JLabel}.
362 * @param c The {@link JLabel} to uninstall defaults for.
364 protected void uninstallDefaults(JLabel c)
366 c.setForeground(null);
367 c.setBackground(null);
372 * This method installs the keyboard actions for the given {@link JLabel}.
374 * @param l The {@link JLabel} to install keyboard actions for.
376 protected void installKeyboardActions(JLabel l)
382 * This method uninstalls the keyboard actions for the given {@link JLabel}.
384 * @param l The {@link JLabel} to uninstall keyboard actions for.
386 protected void uninstallKeyboardActions(JLabel l)
392 * This method installs the listeners for the given {@link JLabel}. The UI
393 * delegate only listens to the label.
395 * @param c The {@link JLabel} to install listeners for.
397 protected void installListeners(JLabel c)
399 c.addPropertyChangeListener(this);
403 * This method uninstalls the listeners for the given {@link JLabel}. The UI
404 * delegate only listens to the label.
406 * @param c The {@link JLabel} to uninstall listeners for.
408 protected void uninstallListeners(JLabel c)
410 c.removePropertyChangeListener(this);
414 * This method is called whenever any JLabel's that use this UI has one of
415 * their properties change.
417 * @param e The {@link PropertyChangeEvent} that describes the change.
419 public void propertyChange(PropertyChangeEvent e)
421 JLabel c = (JLabel) e.getSource();