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
26package javax.swing.plaf.metal;
27
28import sun.swing.SwingUtilities2;
29import sun.awt.AppContext;
30
31import javax.swing.*;
32import javax.swing.border.*;
33import javax.swing.plaf.basic.*;
34import java.awt.*;
35import java.awt.event.*;
36import java.beans.*;
37import 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
54public 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     */
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    // ********************************
99    public void installDefaults(AbstractButton b) {
100        super.installDefaults(b);
101    }
102
103    public void uninstallDefaults(AbstractButton b) {
104        super.uninstallDefaults(b);
105    }
106
107    // ********************************
108    //         Create Listeners
109    // ********************************
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     */
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     */
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     */
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     */
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
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
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
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