1. /*
  2. * @(#)JToggleButton.java 1.39 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;
  8. import java.awt.*;
  9. import java.awt.event.*;
  10. import javax.swing.event.*;
  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 two-state button.
  18. * The <code>JRadioButton</code> and <code>JCheckBox</code> classes
  19. * are subclasses of this class.
  20. * <p>
  21. * For the keyboard keys used by this component in the standard Look and
  22. * Feel (L&F) renditions, see the
  23. * <a href="doc-files/Key-Index.html#JToggleButton">JToggleButton</a> key assignments.
  24. * <p>
  25. * <strong>Warning:</strong>
  26. * Serialized objects of this class will not be compatible with
  27. * future Swing releases. The current serialization support is appropriate
  28. * for short term storage or RMI between applications running the same
  29. * version of Swing. A future release of Swing will provide support for
  30. * long term persistence.
  31. *
  32. * @beaninfo
  33. * attribute: isContainer false
  34. *
  35. * @see JRadioButton
  36. * @see JCheckBox
  37. * @version 1.39 11/29/01
  38. * @author Jeff Dinkins
  39. */
  40. public class JToggleButton extends AbstractButton implements Accessible {
  41. /**
  42. * @see #getUIClassID
  43. * @see #readObject
  44. */
  45. private static final String uiClassID = "ToggleButtonUI";
  46. /**
  47. * Creates an initially unselected toggle button
  48. * without setting the text or image.
  49. */
  50. public JToggleButton () {
  51. this(null, null, false);
  52. }
  53. /**
  54. * Creates an initially unselected toggle button
  55. * with the specified image but no text.
  56. *
  57. * @param icon the image that the button should display
  58. */
  59. public JToggleButton(Icon icon) {
  60. this(null, icon, false);
  61. }
  62. /**
  63. * Creates a toggle button with the specified image
  64. * and selection state, but no text.
  65. *
  66. * @param icon the image that the button should display
  67. * @param selected if true, the button is initially selected;
  68. * otherwise, the button is initially unselected
  69. */
  70. public JToggleButton(Icon icon, boolean selected) {
  71. this(null, icon, selected);
  72. }
  73. /**
  74. * Creates an unselected toggle button with the specified text.
  75. *
  76. * @param text the string displayed on the toggle button
  77. */
  78. public JToggleButton (String text) {
  79. this(text, null, false);
  80. }
  81. /**
  82. * Creates a toggle button with the specified text
  83. * and selection state.
  84. *
  85. * @param text the string displayed on the toggle button
  86. * @param selected if true, the button is initially selected;
  87. * otherwise, the button is initially unselected
  88. */
  89. public JToggleButton (String text, boolean selected) {
  90. this(text, null, selected);
  91. }
  92. /**
  93. * Creates a toggle button that has the specified text and image,
  94. * and that is initially unselected.
  95. *
  96. * @param text the string displayed on the button
  97. * @param icon the image that the button should display
  98. */
  99. public JToggleButton(String text, Icon icon) {
  100. this(text, icon, false);
  101. }
  102. /**
  103. * Creates a toggle button with the specified text, image, and
  104. * selection state.
  105. *
  106. * @param text the text of the toggle button.
  107. * @param selected if true, the button is initially selected;
  108. * otherwise, the button is initially unselected
  109. */
  110. public JToggleButton (String text, Icon icon, boolean selected) {
  111. // Create the model
  112. setModel(new ToggleButtonModel());
  113. model.setSelected(selected);
  114. // initialize
  115. init(text, icon);
  116. }
  117. /**
  118. * Notification from the UIFactory that the L&F
  119. * has changed.
  120. *
  121. * @see JComponent#updateUI
  122. */
  123. public void updateUI() {
  124. setUI((ButtonUI)UIManager.getUI(this));
  125. }
  126. /**
  127. * Returns a string that specifies the name of the l&f class
  128. * that renders this component.
  129. *
  130. * @return String "ToggleButtonUI"
  131. * @see JComponent#getUIClassID
  132. * @see UIDefaults#getUI
  133. * @beaninfo
  134. * description: A string that specifies the name of the L&F class
  135. */
  136. public String getUIClassID() {
  137. return uiClassID;
  138. }
  139. // *********************************************************************
  140. /**
  141. * The ToggleButton model
  142. * <p>
  143. * <strong>Warning:</strong>
  144. * Serialized objects of this class will not be compatible with
  145. * future Swing releases. The current serialization support is appropriate
  146. * for short term storage or RMI between applications running the same
  147. * version of Swing. A future release of Swing will provide support for
  148. * long term persistence.
  149. */
  150. public static class ToggleButtonModel extends DefaultButtonModel {
  151. /**
  152. * Creates a new ToggleButton Model
  153. */
  154. public ToggleButtonModel () {
  155. }
  156. /**
  157. * Checks if the button is selected.
  158. */
  159. public boolean isSelected() {
  160. if(group != null) {
  161. return group.isSelected(this);
  162. } else {
  163. return (stateMask & SELECTED) != 0;
  164. }
  165. }
  166. /**
  167. * Sets the selected state of the button.
  168. * @param b true selects the toggle button,
  169. * false deselects the toggle button.
  170. */
  171. public void setSelected(boolean b) {
  172. // if (this.isSelected() == b) {
  173. // return;
  174. // }
  175. if(group != null) {
  176. // use the group model instead
  177. group.setSelected(this, b);
  178. } else {
  179. if (b) {
  180. stateMask |= SELECTED;
  181. } else {
  182. stateMask &= ~SELECTED;
  183. }
  184. }
  185. // Send ChangeEvent
  186. fireStateChanged();
  187. // Send ItemEvent
  188. fireItemStateChanged(
  189. new ItemEvent(this,
  190. ItemEvent.ITEM_STATE_CHANGED,
  191. this,
  192. this.isSelected() ? ItemEvent.SELECTED : ItemEvent.DESELECTED));
  193. }
  194. /**
  195. * Sets the pressed state of the toggle button.
  196. */
  197. public void setPressed(boolean b) {
  198. if ((isPressed() == b) || !isEnabled()) {
  199. return;
  200. }
  201. if (b == false && isArmed()) {
  202. setSelected(!this.isSelected());
  203. }
  204. if (b) {
  205. stateMask |= PRESSED;
  206. } else {
  207. stateMask &= ~PRESSED;
  208. }
  209. fireStateChanged();
  210. if(!isPressed() && isArmed()) {
  211. fireActionPerformed(
  212. new ActionEvent(this, ActionEvent.ACTION_PERFORMED,
  213. getActionCommand())
  214. );
  215. }
  216. }
  217. }
  218. /**
  219. * See readObject() and writeObject() in JComponent for more
  220. * information about serialization in Swing.
  221. */
  222. private void writeObject(ObjectOutputStream s) throws IOException {
  223. s.defaultWriteObject();
  224. if ((ui != null) && (getUIClassID().equals(uiClassID))) {
  225. ui.installUI(this);
  226. }
  227. }
  228. /**
  229. * Returns a string representation of this JToggleButton. This method
  230. * is intended to be used only for debugging purposes, and the
  231. * content and format of the returned string may vary between
  232. * implementations. The returned string may be empty but may not
  233. * be <code>null</code>.
  234. *
  235. * @return a string representation of this JToggleButton.
  236. */
  237. protected String paramString() {
  238. return super.paramString();
  239. }
  240. /////////////////
  241. // Accessibility support
  242. ////////////////
  243. /**
  244. * Get the AccessibleContext associated with this JComponent
  245. *
  246. * @return the AccessibleContext of this JComponent
  247. * @beaninfo
  248. * expert: true
  249. * description: The AccessibleContext associated with this ToggleButton.
  250. */
  251. public AccessibleContext getAccessibleContext() {
  252. if (accessibleContext == null) {
  253. accessibleContext = new AccessibleJToggleButton();
  254. }
  255. return accessibleContext;
  256. }
  257. /**
  258. * The class used to obtain the accessible role for this object.
  259. * <p>
  260. * <strong>Warning:</strong>
  261. * Serialized objects of this class will not be compatible with
  262. * future Swing releases. The current serialization support is appropriate
  263. * for short term storage or RMI between applications running the same
  264. * version of Swing. A future release of Swing will provide support for
  265. * long term persistence.
  266. */
  267. protected class AccessibleJToggleButton extends AccessibleAbstractButton
  268. implements ItemListener {
  269. public AccessibleJToggleButton() {
  270. super();
  271. JToggleButton.this.addItemListener(this);
  272. }
  273. /**
  274. * Fire accessible property change events when the state of the
  275. * toggle button changes.
  276. */
  277. public void itemStateChanged(ItemEvent e) {
  278. JToggleButton tb = (JToggleButton) e.getSource();
  279. if (JToggleButton.this.accessibleContext != null) {
  280. if (tb.isSelected()) {
  281. JToggleButton.this.accessibleContext.firePropertyChange(
  282. AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
  283. null, AccessibleState.CHECKED);
  284. } else {
  285. JToggleButton.this.accessibleContext.firePropertyChange(
  286. AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
  287. AccessibleState.CHECKED, null);
  288. }
  289. }
  290. }
  291. /**
  292. * Get the role of this object.
  293. *
  294. * @return an instance of AccessibleRole describing the role of the
  295. * object
  296. */
  297. public AccessibleRole getAccessibleRole() {
  298. return AccessibleRole.TOGGLE_BUTTON;
  299. }
  300. } // inner class AccessibleJToggleButton
  301. }