1. /*
  2. * @(#)JRadioButton.java 1.74 03/12/19
  3. *
  4. * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package javax.swing;
  8. import java.awt.*;
  9. import java.awt.event.*;
  10. import java.beans.*;
  11. import javax.swing.plaf.*;
  12. import javax.accessibility.*;
  13. import java.io.ObjectOutputStream;
  14. import java.io.ObjectInputStream;
  15. import java.io.IOException;
  16. /**
  17. * An implementation of a radio button -- an item that can be selected or
  18. * deselected, and which displays its state to the user.
  19. * Used with a {@link ButtonGroup} object to create a group of buttons
  20. * in which only one button at a time can be selected. (Create a ButtonGroup
  21. * object and use its <code>add</code> method to include the JRadioButton objects
  22. * in the group.)
  23. * <blockquote>
  24. * <strong>Note:</strong>
  25. * The ButtonGroup object is a logical grouping -- not a physical grouping.
  26. * Tocreate a button panel, you should still create a {@link JPanel} or similar
  27. * container-object and add a {@link javax.swing.border.Border} to it to set it off from surrounding
  28. * components.
  29. * </blockquote>
  30. * <p>
  31. * See <a href="http://java.sun.com/docs/books/tutorial/uiswing/components/button.html">How to Use Buttons, Check Boxes, and Radio Buttons</a>
  32. * in <em>The Java Tutorial</em>
  33. * for further documentation.
  34. * <p>
  35. * <strong>Warning:</strong>
  36. * Serialized objects of this class will not be compatible with
  37. * future Swing releases. The current serialization support is
  38. * appropriate for short term storage or RMI between applications running
  39. * the same version of Swing. As of 1.4, support for long term storage
  40. * of all JavaBeans<sup><font size="-2">TM</font></sup>
  41. * has been added to the <code>java.beans</code> package.
  42. * Please see {@link java.beans.XMLEncoder}.
  43. *
  44. * @beaninfo
  45. * attribute: isContainer false
  46. * description: A component which can display it's state as selected or deselected.
  47. *
  48. * @see ButtonGroup
  49. * @see JCheckBox
  50. * @version 1.74 12/19/03
  51. * @author Jeff Dinkins
  52. */
  53. public class JRadioButton extends JToggleButton implements Accessible {
  54. /**
  55. * @see #getUIClassID
  56. * @see #readObject
  57. */
  58. private static final String uiClassID = "RadioButtonUI";
  59. /**
  60. * Creates an initially unselected radio button
  61. * with no set text.
  62. */
  63. public JRadioButton () {
  64. this(null, null, false);
  65. }
  66. /**
  67. * Creates an initially unselected radio button
  68. * with the specified image but no text.
  69. *
  70. * @param icon the image that the button should display
  71. */
  72. public JRadioButton(Icon icon) {
  73. this(null, icon, false);
  74. }
  75. /**
  76. * Creates a radiobutton where properties are taken from the
  77. * Action supplied.
  78. *
  79. * @since 1.3
  80. */
  81. public JRadioButton(Action a) {
  82. this();
  83. setAction(a);
  84. }
  85. /**
  86. * Creates a radio button with the specified image
  87. * and selection state, but no text.
  88. *
  89. * @param icon the image that the button should display
  90. * @param selected if true, the button is initially selected;
  91. * otherwise, the button is initially unselected
  92. */
  93. public JRadioButton(Icon icon, boolean selected) {
  94. this(null, icon, selected);
  95. }
  96. /**
  97. * Creates an unselected radio button with the specified text.
  98. *
  99. * @param text the string displayed on the radio button
  100. */
  101. public JRadioButton (String text) {
  102. this(text, null, false);
  103. }
  104. /**
  105. * Creates a radio button with the specified text
  106. * and selection state.
  107. *
  108. * @param text the string displayed on the radio button
  109. * @param selected if true, the button is initially selected;
  110. * otherwise, the button is initially unselected
  111. */
  112. public JRadioButton (String text, boolean selected) {
  113. this(text, null, selected);
  114. }
  115. /**
  116. * Creates a radio button that has the specified text and image,
  117. * and that is initially unselected.
  118. *
  119. * @param text the string displayed on the radio button
  120. * @param icon the image that the button should display
  121. */
  122. public JRadioButton(String text, Icon icon) {
  123. this(text, icon, false);
  124. }
  125. /**
  126. * Creates a radio button that has the specified text, image,
  127. * and selection state.
  128. *
  129. * @param text the string displayed on the radio button
  130. * @param icon the image that the button should display
  131. */
  132. public JRadioButton (String text, Icon icon, boolean selected) {
  133. super(text, icon, selected);
  134. setBorderPainted(false);
  135. setHorizontalAlignment(LEADING);
  136. }
  137. /**
  138. * Resets the UI property to a value from the current look and feel.
  139. *
  140. * @see JComponent#updateUI
  141. */
  142. public void updateUI() {
  143. setUI((ButtonUI)UIManager.getUI(this));
  144. }
  145. /**
  146. * Returns the name of the L&F class
  147. * that renders this component.
  148. *
  149. * @return String "RadioButtonUI"
  150. * @see JComponent#getUIClassID
  151. * @see UIDefaults#getUI
  152. * @beaninfo
  153. * expert: true
  154. * description: A string that specifies the name of the L&F class.
  155. */
  156. public String getUIClassID() {
  157. return uiClassID;
  158. }
  159. /**
  160. * Factory method which sets the <code>ActionEvent</code> source's
  161. * properties according to values from the Action instance. The
  162. * properties which are set may differ for subclasses.
  163. * By default, the properties which get set are <code>Text, Mnemonic,
  164. * Enabled, ActionCommand</code>, and <code>ToolTipText</code>.
  165. *
  166. * @param a the Action from which to get the properties, or null
  167. * @since 1.3
  168. * @see Action
  169. * @see #setAction
  170. */
  171. protected void configurePropertiesFromAction(Action a) {
  172. String[] types = { Action.MNEMONIC_KEY, Action.NAME,
  173. Action.SHORT_DESCRIPTION,
  174. Action.ACTION_COMMAND_KEY, "enabled" };
  175. configurePropertiesFromAction(a, types);
  176. }
  177. /**
  178. * Factory method which creates the PropertyChangeListener
  179. * used to update the ActionEvent source as properties change on
  180. * its Action instance. Subclasses may override this in order
  181. * to provide their own PropertyChangeListener if the set of
  182. * properties which should be kept up to date differs from the
  183. * default properties (Text, Icon, Enabled, ToolTipText).
  184. *
  185. * Note that PropertyChangeListeners should avoid holding
  186. * strong references to the ActionEvent source, as this may hinder
  187. * garbage collection of the ActionEvent source and all components
  188. * in its containment hierarchy.
  189. *
  190. * @since 1.3
  191. * @see Action
  192. * @see #setAction
  193. */
  194. protected PropertyChangeListener createActionPropertyChangeListener(Action a) {
  195. return new AbstractActionPropertyChangeListener(this, a) {
  196. public void propertyChange(PropertyChangeEvent e) {
  197. String propertyName = e.getPropertyName();
  198. AbstractButton button = (AbstractButton)getTarget();
  199. if (button == null) { //WeakRef GC'ed in 1.2
  200. Action action = (Action)e.getSource();
  201. action.removePropertyChangeListener(this);
  202. } else {
  203. if (propertyName.equals(Action.NAME)) {
  204. String text = (String) e.getNewValue();
  205. button.setText(text);
  206. button.repaint();
  207. } else if (propertyName.equals(Action.SHORT_DESCRIPTION)) {
  208. String text = (String) e.getNewValue();
  209. button.setToolTipText(text);
  210. } else if (propertyName.equals("enabled")) {
  211. Boolean enabledState = (Boolean) e.getNewValue();
  212. button.setEnabled(enabledState.booleanValue());
  213. button.repaint();
  214. } else if (propertyName.equals(Action.ACTION_COMMAND_KEY)) {
  215. button.setActionCommand((String)e.getNewValue());
  216. }
  217. }
  218. }
  219. };
  220. }
  221. /**
  222. * See readObject() and writeObject() in JComponent for more
  223. * information about serialization in Swing.
  224. */
  225. private void writeObject(ObjectOutputStream s) throws IOException {
  226. s.defaultWriteObject();
  227. if (getUIClassID().equals(uiClassID)) {
  228. byte count = JComponent.getWriteObjCounter(this);
  229. JComponent.setWriteObjCounter(this, --count);
  230. if (count == 0 && ui != null) {
  231. ui.installUI(this);
  232. }
  233. }
  234. }
  235. /**
  236. * Returns a string representation of this JRadioButton. This method
  237. * is intended to be used only for debugging purposes, and the
  238. * content and format of the returned string may vary between
  239. * implementations. The returned string may be empty but may not
  240. * be <code>null</code>.
  241. *
  242. * @return a string representation of this JRadioButton.
  243. */
  244. protected String paramString() {
  245. return super.paramString();
  246. }
  247. /////////////////
  248. // Accessibility support
  249. ////////////////
  250. /**
  251. * Gets the AccessibleContext associated with this JRadioButton.
  252. * For JRadioButtons, the AccessibleContext takes the form of an
  253. * AccessibleJRadioButton.
  254. * A new AccessibleJRadioButton instance is created if necessary.
  255. *
  256. * @return an AccessibleJRadioButton that serves as the
  257. * AccessibleContext of this JRadioButton
  258. * @beaninfo
  259. * expert: true
  260. * description: The AccessibleContext associated with this Button
  261. */
  262. public AccessibleContext getAccessibleContext() {
  263. if (accessibleContext == null) {
  264. accessibleContext = new AccessibleJRadioButton();
  265. }
  266. return accessibleContext;
  267. }
  268. /**
  269. * This class implements accessibility support for the
  270. * <code>JRadioButton</code> class. It provides an implementation of the
  271. * Java Accessibility API appropriate to radio button
  272. * user-interface elements.
  273. * <p>
  274. * <strong>Warning:</strong>
  275. * Serialized objects of this class will not be compatible with
  276. * future Swing releases. The current serialization support is
  277. * appropriate for short term storage or RMI between applications running
  278. * the same version of Swing. As of 1.4, support for long term storage
  279. * of all JavaBeans<sup><font size="-2">TM</font></sup>
  280. * has been added to the <code>java.beans</code> package.
  281. * Please see {@link java.beans.XMLEncoder}.
  282. */
  283. protected class AccessibleJRadioButton extends AccessibleJToggleButton {
  284. /**
  285. * Get the role of this object.
  286. *
  287. * @return an instance of AccessibleRole describing the role of the object
  288. * @see AccessibleRole
  289. */
  290. public AccessibleRole getAccessibleRole() {
  291. return AccessibleRole.RADIO_BUTTON;
  292. }
  293. } // inner class AccessibleJRadioButton
  294. }