1 /*
2  * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 
26 package javax.swing.plaf.metal;
27 
28 import sun.swing.SwingUtilities2;
29 import sun.awt.AppContext;
30 
31 import javax.swing.*;
32 import javax.swing.border.*;
33 import javax.swing.plaf.basic.*;
34 import java.awt.*;
35 import java.awt.event.*;
36 import java.beans.*;
37 import javax.swing.plaf.*;
38 
39 /**
40  * MetalButtonUI implementation
41  * <p>
42  * <strong>Warning:</strong>
43  * Serialized objects of this class will not be compatible with
44  * future Swing releases. The current serialization support is
45  * appropriate for short term storage or RMI between applications running
46  * the same version of Swing.  As of 1.4, support for long term storage
47  * of all JavaBeans&trade;
48  * has been added to the <code>java.beans</code> package.
49  * Please see {@link java.beans.XMLEncoder}.
50  *
51  * @author Tom Santos
52  */
53 @SuppressWarnings("serial") // Same-version serialization only
54 public class MetalButtonUI extends BasicButtonUI {
55 
56     // NOTE: These are not really needed, but at this point we can't pull
57     // them. Their values are updated purely for historical reasons.
58     /**
59      * The color of the focused button.
60      */
61     protected Color focusColor;
62 
63     /**
64      * The color of the selected button.
65      */
66     protected Color selectColor;
67 
68     /**
69      * The color of the disabled color.
70      */
71     protected Color disabledTextColor;
72 
73     private static final Object METAL_BUTTON_UI_KEY = new Object();
74 
75     // ********************************
76     //          Create PLAF
77     // ********************************
78 
79     /**
80      * Returns an instance of {@code MetalButtonUI}.
81      *
82      * @param c a component
83      * @return an instance of {@code MetalButtonUI}
84      */
createUI(JComponent c)85     public static ComponentUI createUI(JComponent c) {
86         AppContext appContext = AppContext.getAppContext();
87         MetalButtonUI metalButtonUI =
88                 (MetalButtonUI) appContext.get(METAL_BUTTON_UI_KEY);
89         if (metalButtonUI == null) {
90             metalButtonUI = new MetalButtonUI();
91             appContext.put(METAL_BUTTON_UI_KEY, metalButtonUI);
92         }
93         return metalButtonUI;
94     }
95 
96     // ********************************
97     //          Install
98     // ********************************
installDefaults(AbstractButton b)99     public void installDefaults(AbstractButton b) {
100         super.installDefaults(b);
101     }
102 
uninstallDefaults(AbstractButton b)103     public void uninstallDefaults(AbstractButton b) {
104         super.uninstallDefaults(b);
105     }
106 
107     // ********************************
108     //         Create Listeners
109     // ********************************
createButtonListener(AbstractButton b)110     protected BasicButtonListener createButtonListener(AbstractButton b) {
111         return super.createButtonListener(b);
112     }
113 
114 
115     // ********************************
116     //         Default Accessors
117     // ********************************
118 
119     /**
120      * Returns the color of the selected button.
121      *
122      * @return the color of the selected button
123      */
getSelectColor()124     protected Color getSelectColor() {
125         selectColor = UIManager.getColor(getPropertyPrefix() + "select");
126         return selectColor;
127     }
128 
129     /**
130      * Returns the color of a disabled text.
131      *
132      * @return the color of a disabled text
133      */
getDisabledTextColor()134     protected Color getDisabledTextColor() {
135         disabledTextColor = UIManager.getColor(getPropertyPrefix() +
136                                                "disabledText");
137         return disabledTextColor;
138     }
139 
140     /**
141      * Returns the color of the focused button.
142      *
143      * @return the color of the focused button
144      */
getFocusColor()145     protected Color getFocusColor() {
146         focusColor = UIManager.getColor(getPropertyPrefix() + "focus");
147         return focusColor;
148     }
149 
150     // ********************************
151     //          Paint
152     // ********************************
153     /**
154      * If necessary paints the background of the component, then
155      * invokes <code>paint</code>.
156      *
157      * @param g Graphics to paint to
158      * @param c JComponent painting on
159      * @throws NullPointerException if <code>g</code> or <code>c</code> is
160      *         null
161      * @see javax.swing.plaf.ComponentUI#update
162      * @see javax.swing.plaf.ComponentUI#paint
163      * @since 1.5
164      */
update(Graphics g, JComponent c)165     public void update(Graphics g, JComponent c) {
166         AbstractButton button = (AbstractButton)c;
167         if ((c.getBackground() instanceof UIResource) &&
168                   button.isContentAreaFilled() && c.isEnabled()) {
169             ButtonModel model = button.getModel();
170             if (!MetalUtils.isToolBarButton(c)) {
171                 if (!model.isArmed() && !model.isPressed() &&
172                         MetalUtils.drawGradient(
173                         c, g, "Button.gradient", 0, 0, c.getWidth(),
174                         c.getHeight(), true)) {
175                     paint(g, c);
176                     return;
177                 }
178             }
179             else if (model.isRollover() && MetalUtils.drawGradient(
180                         c, g, "Button.gradient", 0, 0, c.getWidth(),
181                         c.getHeight(), true)) {
182                 paint(g, c);
183                 return;
184             }
185         }
186         super.update(g, c);
187     }
188 
paintButtonPressed(Graphics g, AbstractButton b)189     protected void paintButtonPressed(Graphics g, AbstractButton b) {
190         if ( b.isContentAreaFilled() ) {
191             Dimension size = b.getSize();
192             g.setColor(getSelectColor());
193             g.fillRect(0, 0, size.width, size.height);
194         }
195     }
196 
paintFocus(Graphics g, AbstractButton b, Rectangle viewRect, Rectangle textRect, Rectangle iconRect)197     protected void paintFocus(Graphics g, AbstractButton b,
198                               Rectangle viewRect, Rectangle textRect, Rectangle iconRect){
199 
200         Rectangle focusRect = new Rectangle();
201         String text = b.getText();
202         boolean isIcon = b.getIcon() != null;
203 
204         // If there is text
205         if ( text != null && !text.equals( "" ) ) {
206             if ( !isIcon ) {
207                 focusRect.setBounds( textRect );
208             }
209             else {
210                 focusRect.setBounds( iconRect.union( textRect ) );
211             }
212         }
213         // If there is an icon and no text
214         else if ( isIcon ) {
215             focusRect.setBounds( iconRect );
216         }
217 
218         g.setColor(getFocusColor());
219         g.drawRect((focusRect.x-1), (focusRect.y-1),
220                   focusRect.width+1, focusRect.height+1);
221 
222     }
223 
224 
paintText(Graphics g, JComponent c, Rectangle textRect, String text)225     protected void paintText(Graphics g, JComponent c, Rectangle textRect, String text) {
226         AbstractButton b = (AbstractButton) c;
227         ButtonModel model = b.getModel();
228         FontMetrics fm = SwingUtilities2.getFontMetrics(c, g);
229         int mnemIndex = b.getDisplayedMnemonicIndex();
230 
231         /* Draw the Text */
232         if(model.isEnabled()) {
233             /*** paint the text normally */
234             g.setColor(b.getForeground());
235         }
236         else {
237             /*** paint the text disabled ***/
238             g.setColor(getDisabledTextColor());
239         }
240         SwingUtilities2.drawStringUnderlineCharAt(c, g,text,mnemIndex,
241                                   textRect.x, textRect.y + fm.getAscent());
242     }
243 }
244