1 /* 2 * Copyright (c) 1998, 2019, 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™ 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 */ 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.isEmpty()) { 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 }