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