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