OSDN Git Service

Merged gcj-eclipse branch to trunk.
[pf3gnuchains/gcc-fork.git] / libjava / classpath / javax / swing / plaf / metal / MetalButtonUI.java
1 /* MetalButtonUI.java
2    Copyright (C) 2005 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
39 package javax.swing.plaf.metal;
40
41 import java.awt.Color;
42 import java.awt.Component;
43 import java.awt.Font;
44 import java.awt.FontMetrics;
45 import java.awt.Graphics;
46 import java.awt.Rectangle;
47
48 import javax.swing.AbstractButton;
49 import javax.swing.ButtonModel;
50 import javax.swing.JButton;
51 import javax.swing.JComponent;
52 import javax.swing.JToolBar;
53 import javax.swing.SwingConstants;
54 import javax.swing.UIManager;
55 import javax.swing.plaf.ComponentUI;
56 import javax.swing.plaf.UIResource;
57 import javax.swing.plaf.basic.BasicButtonUI;
58
59 /**
60  * A UI delegate for the {@link JButton} component.
61  *
62  * @author Roman Kennke (roman@kennke.org)
63  */
64 public class MetalButtonUI
65   extends BasicButtonUI
66 {
67
68   /**
69    * The shared button UI.
70    */
71   private static MetalButtonUI sharedUI;
72
73   /**
74    * The color used to draw the focus rectangle around the text and/or icon.
75    */
76   protected Color focusColor;
77     
78   /**
79    * The background color for the button when it is pressed.
80    */
81   protected Color selectColor;
82
83   /**
84    * The color for disabled button labels.
85    */
86   protected Color disabledTextColor;
87
88   /**
89    * Returns a UI delegate for the specified component.
90    * 
91    * @param c  the component (should be a subclass of {@link AbstractButton}).
92    * 
93    * @return A new instance of <code>MetalButtonUI</code>.
94    */
95   public static ComponentUI createUI(JComponent c) 
96   {
97     if (sharedUI == null)
98       sharedUI = new MetalButtonUI();
99     return sharedUI;
100   }
101
102   /**
103    * Creates a new instance.
104    */
105   public MetalButtonUI()
106   {
107     super();
108   }
109
110   /**
111    * Returns the color for the focus border.
112    *
113    * @return the color for the focus border
114    */
115   protected Color getFocusColor()
116   {
117     focusColor = UIManager.getColor(getPropertyPrefix() + "focus");
118     return focusColor;
119   }
120
121   /**
122    * Returns the color that indicates a selected button.
123    *
124    * @return the color that indicates a selected button
125    */
126   protected Color getSelectColor()
127   {
128     selectColor = UIManager.getColor(getPropertyPrefix() + "select");
129     return selectColor;
130   }
131
132   /**
133    * Returns the color for the text label of disabled buttons.
134    *
135    * @return the color for the text label of disabled buttons
136    */
137   protected Color getDisabledTextColor()
138   {
139     disabledTextColor = UIManager.getColor(getPropertyPrefix()
140                                            + "disabledText");
141     return disabledTextColor;
142   }
143
144   /**
145    * Installs the default settings for the specified button.
146    * 
147    * @param button  the button.
148    * 
149    * @see #uninstallDefaults(AbstractButton)
150    */
151   public void installDefaults(AbstractButton button)
152   {
153     // This is overridden to be public, for whatever reason.
154     super.installDefaults(button);
155   }
156
157   /**
158    * Removes the defaults added by {@link #installDefaults(AbstractButton)}.
159    */
160   public void uninstallDefaults(AbstractButton button) 
161   {
162     // This is overridden to be public, for whatever reason.
163     super.uninstallDefaults(button);
164   }
165
166   /**
167    * Paints the background of the button to indicate that it is in the
168    * "pressed" state.
169    * 
170    * @param g  the graphics context.
171    * @param b  the button.
172    */
173   protected void paintButtonPressed(Graphics g, AbstractButton b) 
174   { 
175     if (b.isContentAreaFilled())
176     {
177       Rectangle area = b.getVisibleRect();
178       g.setColor(getSelectColor());
179       g.fillRect(area.x, area.y, area.width, area.height);
180     }
181   }
182     
183   /** 
184    * Paints the focus rectangle around the button text and/or icon.
185    * 
186    * @param g  the graphics context.
187    * @param b  the button.
188    * @param viewRect  the button bounds.
189    * @param textRect  the text bounds.
190    * @param iconRect  the icon bounds.
191    */
192   protected void paintFocus(Graphics g, AbstractButton b, Rectangle viewRect,
193           Rectangle textRect, Rectangle iconRect) 
194   {
195     if (b.isEnabled() && b.hasFocus() && b.isFocusPainted())
196     {
197       Color savedColor = g.getColor();
198       g.setColor(getFocusColor());
199       Rectangle focusRect = iconRect.union(textRect);
200       g.drawRect(focusRect.x - 1, focusRect.y,
201                  focusRect.width + 1, focusRect.height);
202       g.setColor(savedColor);
203     }
204   }
205     
206   /**
207    * Paints the button text.
208    * 
209    * @param g  the graphics context.
210    * @param c  the button.
211    * @param textRect  the text bounds.
212    * @param text  the text to display.
213    */
214   protected void paintText(Graphics g, JComponent c, Rectangle textRect,
215           String text) 
216   {
217     AbstractButton b = (AbstractButton) c;
218     Font f = b.getFont();
219     g.setFont(f);
220     FontMetrics fm = g.getFontMetrics(f);
221
222     if (b.isEnabled())
223       {
224         g.setColor(b.getForeground());
225         g.drawString(text, textRect.x, textRect.y + fm.getAscent());
226       }
227     else
228       {
229         g.setColor(getDisabledTextColor());
230         g.drawString(text, textRect.x, textRect.y + fm.getAscent());
231       }  
232   }
233
234   /**
235    * If the property <code>Button.gradient</code> is set, then a gradient is
236    * painted as background, otherwise the normal superclass behaviour is
237    * called.
238    */
239   public void update(Graphics g, JComponent c)
240   {
241     AbstractButton b = (AbstractButton) c;
242     if ((b.getBackground() instanceof UIResource)
243         && b.isContentAreaFilled() && b.isEnabled())
244       {
245         ButtonModel m = b.getModel();
246         String uiKey = "Button.gradient";
247         if (! isToolbarButton(b))
248           {
249             if (! m.isArmed() && ! m.isPressed() && isDrawingGradient(uiKey))
250               {
251                 MetalUtils.paintGradient(g, 0, 0, b.getWidth(), b.getHeight(),
252                                          SwingConstants.VERTICAL,
253                                          uiKey);
254                 paint(g, c);
255                 return;
256               }
257           }
258         else if (m.isRollover() && isDrawingGradient(uiKey))
259           {
260             MetalUtils.paintGradient(g, 0, 0, b.getWidth(), b.getHeight(),
261                                      SwingConstants.VERTICAL,
262                                      uiKey);
263             paint(g, c);
264             return;
265           }
266       }
267     // Fallback if we didn't have any of the two above cases.
268     super.update(g, c);
269   }
270
271   /**
272    * Returns <code>true</code> when the button is a toolbar button,
273    * <code>false</code> otherwise.
274    *
275    * @param b the button component to test
276    *
277    * @return <code>true</code> when the button is a toolbar button,
278    *         <code>false</code> otherwise
279    */
280   private boolean isToolbarButton(Component b)
281   {
282     Component parent = b.getParent();
283     return parent instanceof JToolBar;
284   }
285
286   /**
287    * Returns <code>true</code> if we should draw the button gradient,
288    * <code>false</code> otherwise.
289    *
290    * @param uiKey the UIManager key for the gradient
291    *
292    * @return <code>true</code> if we should draw the button gradient,
293    *         <code>false</code> otherwise
294    */
295   private boolean isDrawingGradient(String uiKey)
296   {
297     return (UIManager.get(uiKey) != null);
298   }
299 }