1. /*
  2. * @(#)JButton.java 1.93 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.util.EventListener;
  9. import java.awt.*;
  10. import java.awt.event.*;
  11. import java.awt.image.*;
  12. import javax.swing.plaf.*;
  13. import javax.swing.event.*;
  14. import javax.accessibility.*;
  15. import java.io.ObjectOutputStream;
  16. import java.io.ObjectInputStream;
  17. import java.io.IOException;
  18. /**
  19. * An implementation of a "push" button.
  20. * See <a href="http://java.sun.com/docs/books/tutorial/uiswing/components/button.html">How to Use Buttons, Check Boxes, and Radio Buttons</a>
  21. * in <em>The Java Tutorial</em>
  22. * for information and examples of using buttons.
  23. * <p>
  24. * For the keyboard keys used by this component in the standard Look and
  25. * Feel (L&F) renditions, see the
  26. * <a href="doc-files/Key-Index.html#JButton"><code>JButton</code> key assignments</a>.
  27. * <p>
  28. * <strong>Warning:</strong>
  29. * Serialized objects of this class will not be compatible with
  30. * future Swing releases. The current serialization support is
  31. * appropriate for short term storage or RMI between applications running
  32. * the same version of Swing. As of 1.4, support for long term storage
  33. * of all JavaBeans<sup><font size="-2">TM</font></sup>
  34. * has been added to the <code>java.beans</code> package.
  35. * Please see {@link java.beans.XMLEncoder}.
  36. *
  37. * @beaninfo
  38. * attribute: isContainer false
  39. * description: An implementation of a \"push\" button.
  40. *
  41. * @version 1.93 01/23/03
  42. * @author Jeff Dinkins
  43. */
  44. public class JButton extends AbstractButton implements Accessible {
  45. /**
  46. * @see #getUIClassID
  47. * @see #readObject
  48. */
  49. private static final String uiClassID = "ButtonUI";
  50. private boolean defaultCapable = true;
  51. /**
  52. * Creates a button with no set text or icon.
  53. */
  54. public JButton() {
  55. this(null, null);
  56. }
  57. /**
  58. * Creates a button with an icon.
  59. *
  60. * @param icon the Icon image to display on the button
  61. */
  62. public JButton(Icon icon) {
  63. this(null, icon);
  64. }
  65. /**
  66. * Creates a button with text.
  67. *
  68. * @param text the text of the button
  69. */
  70. public JButton(String text) {
  71. this(text, null);
  72. }
  73. /**
  74. * Creates a button where properties are taken from the
  75. * <code>Action</code> supplied.
  76. *
  77. * @param a the <code>Action</code> used to specify the new button
  78. *
  79. * @since 1.3
  80. */
  81. public JButton(Action a) {
  82. this();
  83. setAction(a);
  84. }
  85. /**
  86. * Creates a button with initial text and an icon.
  87. *
  88. * @param text the text of the button
  89. * @param icon the Icon image to display on the button
  90. */
  91. public JButton(String text, Icon icon) {
  92. // Create the model
  93. setModel(new DefaultButtonModel());
  94. // initialize
  95. init(text, icon);
  96. }
  97. /**
  98. * Resets the UI property to a value from the current look and
  99. * feel.
  100. *
  101. * @see JComponent#updateUI
  102. */
  103. public void updateUI() {
  104. setUI((ButtonUI)UIManager.getUI(this));
  105. }
  106. /**
  107. * Returns a string that specifies the name of the L&F class
  108. * that renders this component.
  109. *
  110. * @return the string "ButtonUI"
  111. * @see JComponent#getUIClassID
  112. * @see UIDefaults#getUI
  113. * @beaninfo
  114. * expert: true
  115. * description: A string that specifies the name of the L&F class.
  116. */
  117. public String getUIClassID() {
  118. return uiClassID;
  119. }
  120. /**
  121. * Gets the value of the <code>defaultButton</code> property,
  122. * which if <code>true</code> means that this button is the current
  123. * default button for its <code>JRootPane</code>.
  124. * Most look and feels render the default button
  125. * differently, and may potentially provide bindings
  126. * to access the default button.
  127. *
  128. * @return the value of the <code>defaultButton</code> property
  129. * @see JRootPane#setDefaultButton
  130. * @see #isDefaultCapable
  131. * @beaninfo
  132. * description: Whether or not this button is the default button
  133. */
  134. public boolean isDefaultButton() {
  135. JRootPane root = SwingUtilities.getRootPane(this);
  136. if (root != null) {
  137. return root.getDefaultButton() == this;
  138. }
  139. return false;
  140. }
  141. /**
  142. * Gets the value of the <code>defaultCapable</code> property.
  143. *
  144. * @return the value of the <code>defaultCapable</code> property
  145. * @see #setDefaultCapable
  146. * @see #isDefaultButton
  147. * @see JRootPane#setDefaultButton
  148. */
  149. public boolean isDefaultCapable() {
  150. return defaultCapable;
  151. }
  152. /**
  153. * Sets the <code>defaultCapable</code> property,
  154. * which determines whether this button can be
  155. * made the default button for its root pane.
  156. * The default value of the <code>defaultCapable</code>
  157. * property is <code>true</code> unless otherwise
  158. * specified by the look and feel.
  159. *
  160. * @param defaultCapable <code>true</code> if this button will be
  161. * capable of being the default button on the
  162. * <code>RootPane</code> otherwise <code>false</code>
  163. * @see #isDefaultCapable
  164. * @beaninfo
  165. * bound: true
  166. * attribute: visualUpdate true
  167. * description: Whether or not this button can be the default button
  168. */
  169. public void setDefaultCapable(boolean defaultCapable) {
  170. boolean oldDefaultCapable = this.defaultCapable;
  171. this.defaultCapable = defaultCapable;
  172. firePropertyChange("defaultCapable", oldDefaultCapable, defaultCapable);
  173. }
  174. /**
  175. * Overrides <code>JComponent.removeNotify</code> to check if
  176. * this button is currently set as the default button on the
  177. * <code>RootPane</code>, and if so, sets the <code>RootPane</code>'s
  178. * default button to <code>null</code> to ensure the
  179. * <code>RootPane</code> doesn't hold onto an invalid button reference.
  180. */
  181. public void removeNotify() {
  182. JRootPane root = SwingUtilities.getRootPane(this);
  183. if (root != null && root.getDefaultButton() == this) {
  184. root.setDefaultButton(null);
  185. }
  186. super.removeNotify();
  187. }
  188. /**
  189. * Factory method which sets the <code>AbstractButton</code>'s properties
  190. * according to values from the <code>Action</code> instance.
  191. * The properties which get set may differ for <code>AbstractButton</code>
  192. * subclasses. By default, the properties which get set are
  193. * <code>Text, Icon, Enabled, ToolTipText, ActionCommand</code>, and
  194. * <code>Mnemonic</code>.
  195. *
  196. * @param a the <code>Action</code> from which to get the
  197. * properties, or <code>null</code>
  198. * @since 1.3
  199. * @see Action
  200. * @see #setAction
  201. */
  202. protected void configurePropertiesFromAction(Action a) {
  203. // properties that we want to configure from Action. We handle
  204. // Action.NAME differently from AbstractButton, so we don't call
  205. // super.configurePropertiesFromAction(a) here.
  206. String[] types = { Action.MNEMONIC_KEY, Action.SHORT_DESCRIPTION,
  207. Action.SMALL_ICON, Action.ACTION_COMMAND_KEY,
  208. "enabled" };
  209. configurePropertiesFromAction(a, types);
  210. Boolean hide = (Boolean)getClientProperty("hideActionText");
  211. setText((( a != null && (hide == null || hide!=Boolean.TRUE))
  212. ? (String)a.getValue(Action.NAME)
  213. : null));
  214. }
  215. /**
  216. * See readObject() and writeObject() in JComponent for more
  217. * information about serialization in Swing.
  218. */
  219. private void writeObject(ObjectOutputStream s) throws IOException {
  220. s.defaultWriteObject();
  221. if (getUIClassID().equals(uiClassID)) {
  222. byte count = JComponent.getWriteObjCounter(this);
  223. JComponent.setWriteObjCounter(this, --count);
  224. if (count == 0 && ui != null) {
  225. ui.installUI(this);
  226. }
  227. }
  228. }
  229. /**
  230. * Returns a string representation of this <code>JButton</code>.
  231. * This method is intended to be used only for debugging purposes, and the
  232. * content and format of the returned string may vary between
  233. * implementations. The returned string may be empty but may not
  234. * be <code>null</code>.
  235. *
  236. * @return a string representation of this <code>JButton</code>
  237. */
  238. protected String paramString() {
  239. String defaultCapableString = (defaultCapable ? "true" : "false");
  240. return super.paramString() +
  241. ",defaultCapable=" + defaultCapableString;
  242. }
  243. /////////////////
  244. // Accessibility support
  245. ////////////////
  246. /**
  247. * Gets the <code>AccessibleContext</code> associated with this
  248. * <code>JButton</code>. For <code>JButton</code>s,
  249. * the <code>AccessibleContext</code> takes the form of an
  250. * <code>AccessibleJButton</code>.
  251. * A new <code>AccessibleJButton</code> instance is created if necessary.
  252. *
  253. * @return an <code>AccessibleJButton</code> that serves as the
  254. * <code>AccessibleContext</code> of this <code>JButton</code>
  255. * @beaninfo
  256. * expert: true
  257. * description: The AccessibleContext associated with this Button.
  258. */
  259. public AccessibleContext getAccessibleContext() {
  260. if (accessibleContext == null) {
  261. accessibleContext = new AccessibleJButton();
  262. }
  263. return accessibleContext;
  264. }
  265. /**
  266. * This class implements accessibility support for the
  267. * <code>JButton</code> class. It provides an implementation of the
  268. * Java Accessibility API appropriate to button user-interface
  269. * elements.
  270. * <p>
  271. * <strong>Warning:</strong>
  272. * Serialized objects of this class will not be compatible with
  273. * future Swing releases. The current serialization support is
  274. * appropriate for short term storage or RMI between applications running
  275. * the same version of Swing. As of 1.4, support for long term storage
  276. * of all JavaBeans<sup><font size="-2">TM</font></sup>
  277. * has been added to the <code>java.beans</code> package.
  278. * Please see {@link java.beans.XMLEncoder}.
  279. */
  280. protected class AccessibleJButton extends AccessibleAbstractButton {
  281. /**
  282. * Get the role of this object.
  283. *
  284. * @return an instance of AccessibleRole describing the role of the
  285. * object
  286. * @see AccessibleRole
  287. */
  288. public AccessibleRole getAccessibleRole() {
  289. return AccessibleRole.PUSH_BUTTON;
  290. }
  291. } // inner class AccessibleJButton
  292. }