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 java.awt.*; 32 import java.awt.event.*; 33 import javax.swing.*; 34 import javax.swing.plaf.basic.*; 35 import javax.swing.border.*; 36 import javax.swing.plaf.*; 37 import java.io.Serializable; 38 import javax.swing.text.View; 39 40 41 /** 42 * RadioButtonUI implementation for MetalRadioButtonUI 43 * <p> 44 * <strong>Warning:</strong> 45 * Serialized objects of this class will not be compatible with 46 * future Swing releases. The current serialization support is 47 * appropriate for short term storage or RMI between applications running 48 * the same version of Swing. As of 1.4, support for long term storage 49 * of all JavaBeans™ 50 * has been added to the <code>java.beans</code> package. 51 * Please see {@link java.beans.XMLEncoder}. 52 * 53 * @author Michael C. Albers (Metal modifications) 54 * @author Jeff Dinkins (original BasicRadioButtonCode) 55 */ 56 @SuppressWarnings("serial") // Same-version serialization only 57 public class MetalRadioButtonUI extends BasicRadioButtonUI { 58 59 private static final Object METAL_RADIO_BUTTON_UI_KEY = new Object(); 60 61 /** 62 * The color of the focused radio button. 63 */ 64 protected Color focusColor; 65 66 /** 67 * The color of the selected radio button. 68 */ 69 protected Color selectColor; 70 71 /** 72 * The color of a disabled text. 73 */ 74 protected Color disabledTextColor; 75 76 private boolean defaults_initialized = false; 77 78 // ******************************** 79 // Create PlAF 80 // ******************************** 81 82 /** 83 * Returns an instance of {@code MetalRadioButtonUI}. 84 * 85 * @param c a component 86 * @return an instance of {@code MetalRadioButtonUI} 87 */ 88 public static ComponentUI createUI(JComponent c) { 89 AppContext appContext = AppContext.getAppContext(); 90 MetalRadioButtonUI metalRadioButtonUI = 91 (MetalRadioButtonUI) appContext.get(METAL_RADIO_BUTTON_UI_KEY); 92 if (metalRadioButtonUI == null) { 93 metalRadioButtonUI = new MetalRadioButtonUI(); 94 appContext.put(METAL_RADIO_BUTTON_UI_KEY, metalRadioButtonUI); 95 } 96 return metalRadioButtonUI; 97 } 98 99 // ******************************** 100 // Install Defaults 101 // ******************************** 102 public void installDefaults(AbstractButton b) { 103 super.installDefaults(b); 104 if(!defaults_initialized) { 105 focusColor = UIManager.getColor(getPropertyPrefix() + "focus"); 106 selectColor = UIManager.getColor(getPropertyPrefix() + "select"); 107 disabledTextColor = UIManager.getColor(getPropertyPrefix() + "disabledText"); 108 defaults_initialized = true; 109 } 110 LookAndFeel.installProperty(b, "opaque", Boolean.TRUE); 111 } 112 113 protected void uninstallDefaults(AbstractButton b) { 114 super.uninstallDefaults(b); 115 defaults_initialized = false; 116 } 117 118 // ******************************** 119 // Default Accessors 120 // ******************************** 121 122 /** 123 * Returns the color of the selected {@code JRadioButton}. 124 * 125 * @return the color of the selected {@code JRadioButton} 126 */ 127 protected Color getSelectColor() { 128 return selectColor; 129 } 130 131 /** 132 * Returns the color of the disabled text. 133 * 134 * @return the color of the disabled text 135 */ 136 protected Color getDisabledTextColor() { 137 return disabledTextColor; 138 } 139 140 /** 141 * Returns the color of the focused {@code JRadioButton}. 142 * 143 * @return the color of the focused {@code JRadioButton} 144 */ 145 protected Color getFocusColor() { 146 return focusColor; 147 } 148 149 150 // ******************************** 151 // Paint Methods 152 // ******************************** 153 public synchronized void paint(Graphics g, JComponent c) { 154 155 AbstractButton b = (AbstractButton) c; 156 ButtonModel model = b.getModel(); 157 158 Dimension size = c.getSize(); 159 160 int w = size.width; 161 int h = size.height; 162 163 Font f = c.getFont(); 164 g.setFont(f); 165 FontMetrics fm = SwingUtilities2.getFontMetrics(c, g, f); 166 167 Rectangle viewRect = new Rectangle(size); 168 Rectangle iconRect = new Rectangle(); 169 Rectangle textRect = new Rectangle(); 170 171 Insets i = c.getInsets(); 172 viewRect.x += i.left; 173 viewRect.y += i.top; 174 viewRect.width -= (i.right + viewRect.x); 175 viewRect.height -= (i.bottom + viewRect.y); 176 177 Icon altIcon = b.getIcon(); 178 Icon selectedIcon = null; 179 Icon disabledIcon = null; 180 181 String text = SwingUtilities.layoutCompoundLabel( 182 c, fm, b.getText(), altIcon != null ? altIcon : getDefaultIcon(), 183 b.getVerticalAlignment(), b.getHorizontalAlignment(), 184 b.getVerticalTextPosition(), b.getHorizontalTextPosition(), 185 viewRect, iconRect, textRect, b.getIconTextGap()); 186 187 // fill background 188 if(c.isOpaque()) { 189 g.setColor(b.getBackground()); 190 g.fillRect(0,0, size.width, size.height); 191 } 192 193 194 // Paint the radio button 195 if(altIcon != null) { 196 197 if(!model.isEnabled()) { 198 if(model.isSelected()) { 199 altIcon = b.getDisabledSelectedIcon(); 200 } else { 201 altIcon = b.getDisabledIcon(); 202 } 203 } else if(model.isPressed() && model.isArmed()) { 204 altIcon = b.getPressedIcon(); 205 if(altIcon == null) { 206 // Use selected icon 207 altIcon = b.getSelectedIcon(); 208 } 209 } else if(model.isSelected()) { 210 if(b.isRolloverEnabled() && model.isRollover()) { 211 altIcon = b.getRolloverSelectedIcon(); 212 if (altIcon == null) { 213 altIcon = b.getSelectedIcon(); 214 } 215 } else { 216 altIcon = b.getSelectedIcon(); 217 } 218 } else if(b.isRolloverEnabled() && model.isRollover()) { 219 altIcon = b.getRolloverIcon(); 220 } 221 222 if(altIcon == null) { 223 altIcon = b.getIcon(); 224 } 225 226 altIcon.paintIcon(c, g, iconRect.x, iconRect.y); 227 228 } else { 229 getDefaultIcon().paintIcon(c, g, iconRect.x, iconRect.y); 230 } 231 232 233 // Draw the Text 234 if(text != null) { 235 View v = (View) c.getClientProperty(BasicHTML.propertyKey); 236 if (v != null) { 237 v.paint(g, textRect); 238 } else { 239 int mnemIndex = b.getDisplayedMnemonicIndex(); 240 if(model.isEnabled()) { 241 // *** paint the text normally 242 g.setColor(b.getForeground()); 243 } else { 244 // *** paint the text disabled 245 g.setColor(getDisabledTextColor()); 246 } 247 SwingUtilities2.drawStringUnderlineCharAt(c,g,text, 248 mnemIndex, textRect.x, textRect.y + fm.getAscent()); 249 } 250 if(b.hasFocus() && b.isFocusPainted() && 251 textRect.width > 0 && textRect.height > 0 ) { 252 paintFocus(g,textRect,size); 253 } 254 } 255 } 256 257 protected void paintFocus(Graphics g, Rectangle t, Dimension d){ 258 g.setColor(getFocusColor()); 259 g.drawRect(t.x-1, t.y-1, t.width+1, t.height+1); 260 } 261 }