mirror of git://gcc.gnu.org/git/gcc.git
				
				
				
			
		
			
				
	
	
		
			637 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			Java
		
	
	
	
			
		
		
	
	
			637 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			Java
		
	
	
	
| /* BasicButtonUI.java --
 | |
|    Copyright (C) 2002, 2004, 2005  Free Software Foundation, Inc.
 | |
| 
 | |
| This file is part of GNU Classpath.
 | |
| 
 | |
| GNU Classpath is free software; you can redistribute it and/or modify
 | |
| it under the terms of the GNU General Public License as published by
 | |
| the Free Software Foundation; either version 2, or (at your option)
 | |
| any later version.
 | |
| 
 | |
| GNU Classpath is distributed in the hope that it will be useful, but
 | |
| WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | |
| General Public License for more details.
 | |
| 
 | |
| You should have received a copy of the GNU General Public License
 | |
| along with GNU Classpath; see the file COPYING.  If not, write to the
 | |
| Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 | |
| 02110-1301 USA.
 | |
| 
 | |
| Linking this library statically or dynamically with other modules is
 | |
| making a combined work based on this library.  Thus, the terms and
 | |
| conditions of the GNU General Public License cover the whole
 | |
| combination.
 | |
| 
 | |
| As a special exception, the copyright holders of this library give you
 | |
| permission to link this library with independent modules to produce an
 | |
| executable, regardless of the license terms of these independent
 | |
| modules, and to copy and distribute the resulting executable under
 | |
| terms of your choice, provided that you also meet, for each linked
 | |
| independent module, the terms and conditions of the license of that
 | |
| module.  An independent module is a module which is not derived from
 | |
| or based on this library.  If you modify this library, you may extend
 | |
| this exception to your version of the library, but you are not
 | |
| obligated to do so.  If you do not wish to do so, delete this
 | |
| exception statement from your version. */
 | |
| 
 | |
| 
 | |
| package javax.swing.plaf.basic;
 | |
| 
 | |
| import java.awt.Dimension;
 | |
| import java.awt.Font;
 | |
| import java.awt.FontMetrics;
 | |
| import java.awt.Graphics;
 | |
| import java.awt.Insets;
 | |
| import java.awt.Rectangle;
 | |
| import java.beans.PropertyChangeEvent;
 | |
| import java.beans.PropertyChangeListener;
 | |
| 
 | |
| import javax.swing.AbstractButton;
 | |
| import javax.swing.ButtonModel;
 | |
| import javax.swing.Icon;
 | |
| import javax.swing.JButton;
 | |
| import javax.swing.JComponent;
 | |
| import javax.swing.LookAndFeel;
 | |
| import javax.swing.SwingUtilities;
 | |
| import javax.swing.UIManager;
 | |
| import javax.swing.plaf.ButtonUI;
 | |
| import javax.swing.plaf.ComponentUI;
 | |
| import javax.swing.plaf.UIResource;
 | |
| import javax.swing.text.View;
 | |
| 
 | |
| /**
 | |
|  * A UI delegate for the {@link JButton} component.
 | |
|  */
 | |
| public class BasicButtonUI extends ButtonUI
 | |
| {
 | |
|   /**
 | |
|    * Cached rectangle for layouting the label. Used in paint() and
 | |
|    * BasicGraphicsUtils.getPreferredButtonSize().
 | |
|    */
 | |
|   static Rectangle viewR = new Rectangle();
 | |
| 
 | |
|   /**
 | |
|    * Cached rectangle for layouting the label. Used in paint() and
 | |
|    * BasicGraphicsUtils.getPreferredButtonSize().
 | |
|    */
 | |
|   static Rectangle iconR = new Rectangle();
 | |
| 
 | |
|   /**
 | |
|    * Cached rectangle for layouting the label. Used in paint() and
 | |
|    * BasicGraphicsUtils.getPreferredButtonSize().
 | |
|    */
 | |
|   static Rectangle textR = new Rectangle();
 | |
| 
 | |
|   /**
 | |
|    * Cached Insets instance, used in paint().
 | |
|    */
 | |
|   static Insets cachedInsets;
 | |
| 
 | |
|   /**
 | |
|    * The shared button UI.
 | |
|    */
 | |
|   private static BasicButtonUI sharedUI;
 | |
| 
 | |
|   /**
 | |
|    * The shared BasicButtonListener.
 | |
|    */
 | |
|   private static BasicButtonListener sharedListener;
 | |
| 
 | |
|   /**
 | |
|    * A constant used to pad out elements in the button's layout and
 | |
|    * preferred size calculations.
 | |
|    */
 | |
|   protected int defaultTextIconGap = 4;
 | |
| 
 | |
|   /**
 | |
|    * A constant added to the defaultTextIconGap to adjust the text
 | |
|    * within this particular button.
 | |
|    */
 | |
|   protected int defaultTextShiftOffset;
 | |
| 
 | |
|   private int textShiftOffset;
 | |
| 
 | |
|   /**
 | |
|    * Factory method to create an instance of BasicButtonUI for a given
 | |
|    * {@link JComponent}, which should be an {@link AbstractButton}.
 | |
|    *
 | |
|    * @param c The component.
 | |
|    *
 | |
|    * @return A new UI capable of drawing the component
 | |
|    */
 | |
|   public static ComponentUI createUI(final JComponent c)
 | |
|   {
 | |
|     if (sharedUI == null)
 | |
|       sharedUI = new BasicButtonUI();
 | |
|     return sharedUI;
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Returns the default gap between the button's text and icon (in pixels).
 | |
|    *
 | |
|    * @param b  the button (ignored).
 | |
|    *
 | |
|    * @return The gap.
 | |
|    */
 | |
|   public int getDefaultTextIconGap(AbstractButton b)
 | |
|   {
 | |
|     return defaultTextIconGap;
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Sets the text shift offset to zero.
 | |
|    *
 | |
|    * @see #setTextShiftOffset()
 | |
|    */
 | |
|   protected void clearTextShiftOffset()
 | |
|   {
 | |
|     textShiftOffset = 0;
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Returns the text shift offset.
 | |
|    *
 | |
|    * @return The text shift offset.
 | |
|    *
 | |
|    * @see #clearTextShiftOffset()
 | |
|    * @see #setTextShiftOffset()
 | |
|    */
 | |
|   protected int getTextShiftOffset()
 | |
|   {
 | |
|     return textShiftOffset;
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Sets the text shift offset to the value in {@link #defaultTextShiftOffset}.
 | |
|    *
 | |
|    * @see #clearTextShiftOffset()
 | |
|    */
 | |
|   protected void setTextShiftOffset()
 | |
|   {
 | |
|     textShiftOffset = defaultTextShiftOffset;
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Returns the prefix for the UI defaults property for this UI class.
 | |
|    * This is 'Button' for this class.
 | |
|    *
 | |
|    * @return the prefix for the UI defaults property
 | |
|    */
 | |
|   protected String getPropertyPrefix()
 | |
|   {
 | |
|     return "Button.";
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Installs the default settings.
 | |
|    *
 | |
|    * @param b  the button (<code>null</code> not permitted).
 | |
|    */
 | |
|   protected void installDefaults(AbstractButton b)
 | |
|   {
 | |
|     String prefix = getPropertyPrefix();
 | |
|     // Install colors and font.
 | |
|     LookAndFeel.installColorsAndFont(b, prefix + "background",
 | |
|                                      prefix + "foreground", prefix + "font");
 | |
|     // Install border.
 | |
|     LookAndFeel.installBorder(b, prefix + "border");
 | |
| 
 | |
|     // Install margin property.
 | |
|     if (b.getMargin() == null || b.getMargin() instanceof UIResource)
 | |
|       b.setMargin(UIManager.getInsets(prefix + "margin"));
 | |
| 
 | |
|     // Install rollover property.
 | |
|     Object rollover = UIManager.get(prefix + "rollover");
 | |
|     if (rollover != null)
 | |
|       LookAndFeel.installProperty(b, "rolloverEnabled", rollover);
 | |
| 
 | |
|     // Fetch default textShiftOffset.
 | |
|     defaultTextShiftOffset = UIManager.getInt(prefix + "textShiftOffset");
 | |
| 
 | |
|     // Make button opaque if needed.
 | |
|     if (b.isContentAreaFilled())
 | |
|       LookAndFeel.installProperty(b, "opaque", Boolean.TRUE);
 | |
|     else
 | |
|       LookAndFeel.installProperty(b, "opaque", Boolean.FALSE);
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Removes the defaults added by {@link #installDefaults(AbstractButton)}.
 | |
|    *
 | |
|    * @param b  the button (<code>null</code> not permitted).
 | |
|    */
 | |
|   protected void uninstallDefaults(AbstractButton b)
 | |
|   {
 | |
|     // The other properties aren't uninstallable.
 | |
|     LookAndFeel.uninstallBorder(b);
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Creates and returns a new instance of {@link BasicButtonListener}.  This
 | |
|    * method provides a hook to make it easy for subclasses to install a
 | |
|    * different listener.
 | |
|    *
 | |
|    * @param b  the button.
 | |
|    *
 | |
|    * @return A new listener.
 | |
|    */
 | |
|   protected BasicButtonListener createButtonListener(AbstractButton b)
 | |
|   {
 | |
|     // Note: The RI always returns a new instance here. However,
 | |
|     // the BasicButtonListener class is perfectly suitable to be shared
 | |
|     // between multiple buttons, so we return a shared instance here
 | |
|     // for efficiency.
 | |
|     if (sharedListener == null)
 | |
|       sharedListener = new BasicButtonListener(b);
 | |
|     return sharedListener;
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Installs listeners for the button.
 | |
|    *
 | |
|    * @param b  the button (<code>null</code> not permitted).
 | |
|    */
 | |
|   protected void installListeners(AbstractButton b)
 | |
|   {
 | |
|     BasicButtonListener listener = createButtonListener(b);
 | |
|     if (listener != null)
 | |
|       {
 | |
|         b.addChangeListener(listener);
 | |
|         b.addPropertyChangeListener(listener);
 | |
|         b.addFocusListener(listener);
 | |
|         b.addMouseListener(listener);
 | |
|         b.addMouseMotionListener(listener);
 | |
|       }
 | |
|     // Fire synthetic property change event to let the listener update
 | |
|     // the TextLayout cache.
 | |
|     listener.propertyChange(new PropertyChangeEvent(b, "font", null,
 | |
|                                                     b.getFont()));
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Uninstalls listeners for the button.
 | |
|    *
 | |
|    * @param b  the button (<code>null</code> not permitted).
 | |
|    */
 | |
|   protected void uninstallListeners(AbstractButton b)
 | |
|   {
 | |
|     BasicButtonListener listener = getButtonListener(b);
 | |
|     if (listener != null)
 | |
|       {
 | |
|         b.removeChangeListener(listener);
 | |
|         b.removePropertyChangeListener(listener);
 | |
|         b.removeFocusListener(listener);
 | |
|         b.removeMouseListener(listener);
 | |
|         b.removeMouseMotionListener(listener);
 | |
|       }
 | |
|   }
 | |
| 
 | |
|   protected void installKeyboardActions(AbstractButton b)
 | |
|   {
 | |
|     BasicButtonListener listener = getButtonListener(b);
 | |
|     if (listener != null)
 | |
|       listener.installKeyboardActions(b);
 | |
|   }
 | |
| 
 | |
|   protected void uninstallKeyboardActions(AbstractButton b)
 | |
|   {
 | |
|     BasicButtonListener listener = getButtonListener(b);
 | |
|     if (listener != null)
 | |
|       listener.uninstallKeyboardActions(b);
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Install the BasicButtonUI as the UI for a particular component.
 | |
|    * This means registering all the UI's listeners with the component,
 | |
|    * and setting any properties of the button which are particular to
 | |
|    * this look and feel.
 | |
|    *
 | |
|    * @param c The component to install the UI into
 | |
|    */
 | |
|   public void installUI(final JComponent c)
 | |
|   {
 | |
|     super.installUI(c);
 | |
|     if (c instanceof AbstractButton)
 | |
|       {
 | |
|         AbstractButton b = (AbstractButton) c;
 | |
|         installDefaults(b);
 | |
|         // It is important to install the listeners before installing
 | |
|         // the keyboard actions, because the keyboard actions
 | |
|         // are actually installed on the listener instance.
 | |
|         installListeners(b);
 | |
|         installKeyboardActions(b);
 | |
|         BasicHTML.updateRenderer(b, b.getText());
 | |
|       }
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Uninstalls the UI from the component.
 | |
|    *
 | |
|    * @param c the component from which to uninstall the UI
 | |
|    */
 | |
|   public void uninstallUI(JComponent c)
 | |
|   {
 | |
|     if (c instanceof AbstractButton)
 | |
|       {
 | |
|         AbstractButton b = (AbstractButton) c;
 | |
|         uninstallKeyboardActions(b);
 | |
|         uninstallListeners(b);
 | |
|         uninstallDefaults(b);
 | |
|         BasicHTML.updateRenderer(b, "");
 | |
|         b.putClientProperty(BasicGraphicsUtils.CACHED_TEXT_LAYOUT, null);
 | |
|       }
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Calculates the minimum size for the specified component.
 | |
|    *
 | |
|    * @param c the component for which to compute the minimum size
 | |
|    *
 | |
|    * @return the minimum size for the specified component
 | |
|    */
 | |
|   public Dimension getMinimumSize(JComponent c)
 | |
|   {
 | |
|     Dimension size = getPreferredSize(c);
 | |
|     // When the HTML view has a minimum width different from the preferred
 | |
|     // width, then substract this here accordingly. The height is not
 | |
|     // affected by that.
 | |
|     View html = (View) c.getClientProperty(BasicHTML.propertyKey);
 | |
|     if (html != null)
 | |
|       {
 | |
|         size.width -= html.getPreferredSpan(View.X_AXIS)
 | |
|                       - html.getPreferredSpan(View.X_AXIS);
 | |
|       }
 | |
|     return size;
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Calculates the maximum size for the specified component.
 | |
|    *
 | |
|    * @param c the component for which to compute the maximum size
 | |
|    *
 | |
|    * @return the maximum size for the specified component
 | |
|    */
 | |
|   public Dimension getMaximumSize(JComponent c)
 | |
|   {
 | |
|     Dimension size = getPreferredSize(c);
 | |
|     // When the HTML view has a maximum width different from the preferred
 | |
|     // width, then add this here accordingly. The height is not
 | |
|     // affected by that.
 | |
|     View html = (View) c.getClientProperty(BasicHTML.propertyKey);
 | |
|     if (html != null)
 | |
|       {
 | |
|         size.width += html.getMaximumSpan(View.X_AXIS)
 | |
|                       - html.getPreferredSpan(View.X_AXIS);
 | |
|       }
 | |
|     return size;
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Calculate the preferred size of this component, by delegating to
 | |
|    * {@link BasicGraphicsUtils#getPreferredButtonSize}.
 | |
|    *
 | |
|    * @param c The component to measure
 | |
|    *
 | |
|    * @return The preferred dimensions of the component
 | |
|    */
 | |
|   public Dimension getPreferredSize(JComponent c)
 | |
|   {
 | |
|     AbstractButton b = (AbstractButton) c;
 | |
|     Dimension d = BasicGraphicsUtils.getPreferredButtonSize(b,
 | |
|                                                            b.getIconTextGap());
 | |
|     return d;
 | |
|   }
 | |
| 
 | |
|   static Icon currentIcon(AbstractButton b)
 | |
|   {
 | |
|     Icon i = b.getIcon();
 | |
|     ButtonModel model = b.getModel();
 | |
| 
 | |
|     if (model.isPressed() && b.getPressedIcon() != null && b.isEnabled())
 | |
|       i = b.getPressedIcon();
 | |
| 
 | |
|     else if (model.isRollover())
 | |
|       {
 | |
|         if (b.isSelected() && b.getRolloverSelectedIcon() != null)
 | |
|           i = b.getRolloverSelectedIcon();
 | |
|         else if (b.getRolloverIcon() != null)
 | |
|           i = b.getRolloverIcon();
 | |
|       }
 | |
| 
 | |
|     else if (b.isSelected() && b.isEnabled())
 | |
|       {
 | |
|         if (b.isEnabled() && b.getSelectedIcon() != null)
 | |
|           i = b.getSelectedIcon();
 | |
|         else if (b.getDisabledSelectedIcon() != null)
 | |
|           i = b.getDisabledSelectedIcon();
 | |
|       }
 | |
| 
 | |
|     else if (! b.isEnabled() && b.getDisabledIcon() != null)
 | |
|       i = b.getDisabledIcon();
 | |
| 
 | |
|     return i;
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Paint the component, which is an {@link AbstractButton}, according to
 | |
|    * its current state.
 | |
|    *
 | |
|    * @param g The graphics context to paint with
 | |
|    * @param c The component to paint the state of
 | |
|    */
 | |
|   public void paint(Graphics g, JComponent c)
 | |
|   {
 | |
|     AbstractButton b = (AbstractButton) c;
 | |
| 
 | |
|     Insets i = c.getInsets(cachedInsets);
 | |
|     viewR.x = i.left;
 | |
|     viewR.y = i.top;
 | |
|     viewR.width = c.getWidth() - i.left - i.right;
 | |
|     viewR.height = c.getHeight() - i.top - i.bottom;
 | |
|     textR.x = 0;
 | |
|     textR.y = 0;
 | |
|     textR.width = 0;
 | |
|     textR.height = 0;
 | |
|     iconR.x = 0;
 | |
|     iconR.y = 0;
 | |
|     iconR.width = 0;
 | |
|     iconR.height = 0;
 | |
| 
 | |
|     Font f = c.getFont();
 | |
|     g.setFont(f);
 | |
|     Icon icon = b.getIcon();
 | |
|     String text = b.getText();
 | |
|     text = SwingUtilities.layoutCompoundLabel(c, g.getFontMetrics(f),
 | |
|                                               text, icon,
 | |
|                                               b.getVerticalAlignment(),
 | |
|                                               b.getHorizontalAlignment(),
 | |
|                                               b.getVerticalTextPosition(),
 | |
|                                               b.getHorizontalTextPosition(),
 | |
|                                               viewR, iconR, textR,
 | |
|                                               text == null ? 0
 | |
|                                                          : b.getIconTextGap());
 | |
| 
 | |
|     ButtonModel model = b.getModel();
 | |
|     if (model.isArmed() && model.isPressed())
 | |
|       paintButtonPressed(g, b);
 | |
| 
 | |
|     if (icon != null)
 | |
|       paintIcon(g, c, iconR);
 | |
|     if (text != null)
 | |
|       {
 | |
|         View html = (View) b.getClientProperty(BasicHTML.propertyKey);
 | |
|         if (html != null)
 | |
|           html.paint(g, textR);
 | |
|         else
 | |
|           paintText(g, b, textR, text);
 | |
|       }
 | |
|     if (b.isFocusOwner() && b.isFocusPainted())
 | |
|       paintFocus(g, b, viewR, textR, iconR);
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Paint any focus decoration this {@link JComponent} might have.  The
 | |
|    * component, which in this case will be an {@link AbstractButton},
 | |
|    * should only have focus decoration painted if it has the focus, and its
 | |
|    * "focusPainted" property is <code>true</code>.
 | |
|    *
 | |
|    * @param g Graphics context to paint with
 | |
|    * @param b Button to paint the focus of
 | |
|    * @param vr Visible rectangle, the area in which to paint
 | |
|    * @param tr Text rectangle, contained in visible rectangle
 | |
|    * @param ir Icon rectangle, contained in visible rectangle
 | |
|    *
 | |
|    * @see AbstractButton#isFocusPainted()
 | |
|    * @see JComponent#hasFocus()
 | |
|    */
 | |
|   protected void paintFocus(Graphics g, AbstractButton b, Rectangle vr,
 | |
|                             Rectangle tr, Rectangle ir)
 | |
|   {
 | |
|     // In the BasicLookAndFeel no focus border is drawn. This can be
 | |
|     // overridden in subclasses to implement such behaviour.
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Paint the icon for this component. Depending on the state of the
 | |
|    * component and the availability of the button's various icon
 | |
|    * properties, this might mean painting one of several different icons.
 | |
|    *
 | |
|    * @param g Graphics context to paint with
 | |
|    * @param c Component to paint the icon of
 | |
|    * @param iconRect Rectangle in which the icon should be painted
 | |
|    */
 | |
|   protected void paintIcon(Graphics g, JComponent c, Rectangle iconRect)
 | |
|   {
 | |
|     AbstractButton b = (AbstractButton) c;
 | |
|     Icon i = currentIcon(b);
 | |
| 
 | |
|     if (i != null)
 | |
|       {
 | |
|         ButtonModel m = b.getModel();
 | |
|         if (m.isPressed() && m.isArmed())
 | |
|           {
 | |
|             int offs = getTextShiftOffset();
 | |
|             i.paintIcon(c, g, iconRect.x + offs, iconRect.y + offs);
 | |
|           }
 | |
|         else
 | |
|           i.paintIcon(c, g, iconRect.x, iconRect.y);
 | |
|       }
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Paints the background area of an {@link AbstractButton} in the pressed
 | |
|    * state.  This means filling the supplied area with a darker than normal
 | |
|    * background.
 | |
|    *
 | |
|    * @param g The graphics context to paint with
 | |
|    * @param b The button to paint the state of
 | |
|    */
 | |
|   protected void paintButtonPressed(Graphics g, AbstractButton b)
 | |
|   {
 | |
|     if (b.isContentAreaFilled() && b.isOpaque())
 | |
|       {
 | |
|         Rectangle area = new Rectangle();
 | |
|         SwingUtilities.calculateInnerArea(b, area);
 | |
|         g.setColor(UIManager.getColor(getPropertyPrefix() + "shadow"));
 | |
|         g.fillRect(area.x, area.y, area.width, area.height);
 | |
|       }
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Paints the "text" property of an {@link AbstractButton}.
 | |
|    *
 | |
|    * @param g The graphics context to paint with
 | |
|    * @param c The component to paint the state of
 | |
|    * @param textRect The area in which to paint the text
 | |
|    * @param text The text to paint
 | |
|    */
 | |
|   protected void paintText(Graphics g, JComponent c, Rectangle textRect,
 | |
|                            String text)
 | |
|   {
 | |
|     AbstractButton b = (AbstractButton) c;
 | |
|     Font f = b.getFont();
 | |
|     g.setFont(f);
 | |
|     FontMetrics fm = g.getFontMetrics(f);
 | |
| 
 | |
|     if (b.isEnabled())
 | |
|       {
 | |
|         g.setColor(b.getForeground());
 | |
|         // FIXME: Underline mnemonic.
 | |
|         BasicGraphicsUtils.drawString(b, g, text, -1, textRect.x,
 | |
|                                       textRect.y + fm.getAscent());
 | |
|       }
 | |
|     else
 | |
|       {
 | |
|         String prefix = getPropertyPrefix();
 | |
|         g.setColor(UIManager.getColor(prefix + "disabledText"));
 | |
|         // FIXME: Underline mnemonic.
 | |
|         BasicGraphicsUtils.drawString(b, g, text, -1, textRect.x,
 | |
|                                       textRect.y + fm.getAscent());
 | |
|       }
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Paints the "text" property of an {@link AbstractButton}.
 | |
|    *
 | |
|    * @param g The graphics context to paint with
 | |
|    * @param b The button to paint the state of
 | |
|    * @param textRect The area in which to paint the text
 | |
|    * @param text The text to paint
 | |
|    *
 | |
|    * @since 1.4
 | |
|    */
 | |
|   protected void paintText(Graphics g, AbstractButton b, Rectangle textRect,
 | |
|                            String text)
 | |
|   {
 | |
|     paintText(g, (JComponent) b, textRect, text);
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * A helper method that finds the BasicButtonListener for the specified
 | |
|    * button. This is there because this UI class is stateless and
 | |
|    * shared for all buttons, and thus can't store the listener
 | |
|    * as instance field. (We store our shared instance in sharedListener,
 | |
|    * however, subclasses may override createButtonListener() and we would
 | |
|    * be lost in this case).
 | |
|    *
 | |
|    * @param b the button
 | |
|    *
 | |
|    * @return the UI event listener
 | |
|    */
 | |
|   private BasicButtonListener getButtonListener(AbstractButton b)
 | |
|   {
 | |
|     // The listener gets installed as PropertyChangeListener,
 | |
|     // so look for it in the list of property change listeners.
 | |
|     PropertyChangeListener[] listeners = b.getPropertyChangeListeners();
 | |
|     BasicButtonListener l = null;
 | |
|     for (int i = 0; listeners != null && l == null && i < listeners.length;
 | |
|            i++)
 | |
|       {
 | |
|         if (listeners[i] instanceof BasicButtonListener)
 | |
|           l = (BasicButtonListener) listeners[i];
 | |
|       }
 | |
|     return l;
 | |
|   }
 | |
| }
 |