1. /*
  2. * @(#)BasicRadioButtonUI.java 1.58 01/11/29
  3. *
  4. * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package javax.swing.plaf.basic;
  8. import java.awt.*;
  9. import java.awt.event.*;
  10. import javax.swing.*;
  11. import javax.swing.border.*;
  12. import javax.swing.plaf.*;
  13. /**
  14. * RadioButtonUI implementation for BasicRadioButtonUI
  15. *
  16. * @version 1.58 11/29/01
  17. * @author Jeff Dinkins
  18. */
  19. public class BasicRadioButtonUI extends BasicToggleButtonUI
  20. {
  21. private final static BasicRadioButtonUI radioButtonUI = new BasicRadioButtonUI();
  22. protected Icon icon;
  23. private boolean defaults_initialized = false;
  24. private final static String propertyPrefix = "RadioButton" + ".";
  25. // ********************************
  26. // Create PLAF
  27. // ********************************
  28. public static ComponentUI createUI(JComponent b) {
  29. return radioButtonUI;
  30. }
  31. protected String getPropertyPrefix() {
  32. return propertyPrefix;
  33. }
  34. // ********************************
  35. // Install PLAF
  36. // ********************************
  37. protected void installDefaults(AbstractButton b){
  38. super.installDefaults(b);
  39. if(!defaults_initialized) {
  40. icon = UIManager.getIcon(getPropertyPrefix() + "icon");
  41. defaults_initialized = true;
  42. }
  43. }
  44. // ********************************
  45. // Uninstall PLAF
  46. // ********************************
  47. protected void uninstallDefaults(AbstractButton b){
  48. super.uninstallDefaults(b);
  49. defaults_initialized = false;
  50. }
  51. public Icon getDefaultIcon() {
  52. return icon;
  53. }
  54. /* These Dimensions/Rectangles are allocated once for all
  55. * RadioButtonUI.paint() calls. Re-using rectangles
  56. * rather than allocating them in each paint call substantially
  57. * reduced the time it took paint to run. Obviously, this
  58. * method can't be re-entered.
  59. */
  60. private static Dimension size = new Dimension();
  61. private static Rectangle viewRect = new Rectangle();
  62. private static Rectangle iconRect = new Rectangle();
  63. private static Rectangle textRect = new Rectangle();
  64. /**
  65. * paint the radio button
  66. */
  67. public synchronized void paint(Graphics g, JComponent c) {
  68. AbstractButton b = (AbstractButton) c;
  69. ButtonModel model = b.getModel();
  70. Font f = c.getFont();
  71. g.setFont(f);
  72. FontMetrics fm = g.getFontMetrics();
  73. size = b.getSize(size);
  74. viewRect.x = viewRect.y = 0;
  75. viewRect.width = size.width;
  76. viewRect.height = size.height;
  77. iconRect.x = iconRect.y = iconRect.width = iconRect.height = 0;
  78. textRect.x = textRect.y = textRect.width = textRect.height = 0;
  79. Icon altIcon = b.getIcon();
  80. Icon selectedIcon = null;
  81. Icon disabledIcon = null;
  82. String text = SwingUtilities.layoutCompoundLabel(
  83. c, fm, b.getText(), altIcon != null ? altIcon : getDefaultIcon(),
  84. b.getVerticalAlignment(), b.getHorizontalAlignment(),
  85. b.getVerticalTextPosition(), b.getHorizontalTextPosition(),
  86. viewRect, iconRect, textRect, getDefaultTextIconGap(b));
  87. // fill background
  88. if(c.isOpaque()) {
  89. g.setColor(b.getBackground());
  90. g.fillRect(0,0, size.width, size.height);
  91. }
  92. // Paint the radio button
  93. if(altIcon != null) {
  94. if(!model.isEnabled()) {
  95. altIcon = b.getDisabledIcon();
  96. } else if(model.isPressed() && model.isArmed()) {
  97. altIcon = b.getPressedIcon();
  98. if(altIcon == null) {
  99. // Use selected icon
  100. altIcon = b.getSelectedIcon();
  101. }
  102. } else if(model.isSelected()) {
  103. if(b.isRolloverEnabled() && model.isRollover()) {
  104. altIcon = (Icon) b.getRolloverSelectedIcon();
  105. if (altIcon == null) {
  106. altIcon = (Icon) b.getSelectedIcon();
  107. }
  108. }
  109. else {
  110. altIcon = (Icon) b.getSelectedIcon();
  111. }
  112. } else if(b.isRolloverEnabled() && model.isRollover()) {
  113. altIcon = (Icon) b.getRolloverIcon();
  114. }
  115. if(altIcon == null) {
  116. altIcon = b.getIcon();
  117. }
  118. altIcon.paintIcon(c, g, iconRect.x, iconRect.y);
  119. } else {
  120. getDefaultIcon().paintIcon(c, g, iconRect.x, iconRect.y);
  121. }
  122. // Draw the Text
  123. if(text != null) {
  124. if(model.isEnabled()) {
  125. // *** paint the text normally
  126. g.setColor(b.getForeground());
  127. BasicGraphicsUtils.drawString(g,text,model.getMnemonic(),
  128. textRect.x,
  129. textRect.y + fm.getAscent());
  130. } else {
  131. // *** paint the text disabled
  132. g.setColor(b.getBackground().brighter());
  133. BasicGraphicsUtils.drawString(g,text,model.getMnemonic(),
  134. textRect.x + 1,
  135. textRect.y + fm.getAscent() + 1);
  136. g.setColor(b.getBackground().darker());
  137. BasicGraphicsUtils.drawString(g,text,model.getMnemonic(),
  138. textRect.x,
  139. textRect.y + fm.getAscent());
  140. }
  141. if(b.hasFocus() && b.isFocusPainted() &&
  142. textRect.width > 0 && textRect.height > 0 ) {
  143. paintFocus(g, textRect, size);
  144. }
  145. }
  146. }
  147. protected void paintFocus(Graphics g, Rectangle textRect, Dimension size){
  148. }
  149. /* These Insets/Rectangles are allocated once for all
  150. * RadioButtonUI.getPreferredSize() calls. Re-using rectangles
  151. * rather than allocating them in each call substantially
  152. * reduced the time it took getPreferredSize() to run. Obviously,
  153. * this method can't be re-entered.
  154. */
  155. private static Rectangle prefViewRect = new Rectangle();
  156. private static Rectangle prefIconRect = new Rectangle();
  157. private static Rectangle prefTextRect = new Rectangle();
  158. private static Insets prefInsets = new Insets(0, 0, 0, 0);
  159. /**
  160. * The preferred size of the radio button
  161. */
  162. public Dimension getPreferredSize(JComponent c) {
  163. if(c.getComponentCount() > 0) {
  164. return null;
  165. }
  166. AbstractButton b = (AbstractButton) c;
  167. String text = b.getText();
  168. Icon buttonIcon = (Icon) b.getIcon();
  169. if(buttonIcon == null) {
  170. buttonIcon = getDefaultIcon();
  171. }
  172. Font font = b.getFont();
  173. FontMetrics fm = b.getToolkit().getFontMetrics(font);
  174. prefViewRect.x = prefViewRect.y = 0;
  175. prefViewRect.width = Short.MAX_VALUE;
  176. prefViewRect.height = Short.MAX_VALUE;
  177. prefIconRect.x = prefIconRect.y = prefIconRect.width = prefIconRect.height = 0;
  178. prefTextRect.x = prefTextRect.y = prefTextRect.width = prefTextRect.height = 0;
  179. SwingUtilities.layoutCompoundLabel(
  180. c, fm, text, buttonIcon,
  181. b.getVerticalAlignment(), b.getHorizontalAlignment(),
  182. b.getVerticalTextPosition(), b.getHorizontalTextPosition(),
  183. prefViewRect, prefIconRect, prefTextRect,
  184. text == null ? 0 : getDefaultTextIconGap(b));
  185. // find the union of the icon and text rects (from Rectangle.java)
  186. int x1 = Math.min(prefIconRect.x, prefTextRect.x);
  187. int x2 = Math.max(prefIconRect.x + prefIconRect.width,
  188. prefTextRect.x + prefTextRect.width);
  189. int y1 = Math.min(prefIconRect.y, prefTextRect.y);
  190. int y2 = Math.max(prefIconRect.y + prefIconRect.height,
  191. prefTextRect.y + prefTextRect.height);
  192. int width = x2 - x1;
  193. int height = y2 - y1;
  194. prefInsets = b.getInsets(prefInsets);
  195. width += prefInsets.left + prefInsets.right;
  196. height += prefInsets.top + prefInsets.bottom;
  197. return new Dimension(width, height);
  198. }
  199. }