1 /*
   2  * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 package javax.swing;
  26 
  27 import java.beans.ConstructorProperties;
  28 
  29 import java.awt.*;
  30 import java.awt.event.*;
  31 import java.awt.image.*;
  32 
  33 import javax.swing.plaf.*;
  34 import javax.swing.event.*;
  35 import javax.accessibility.*;
  36 
  37 import java.io.ObjectOutputStream;
  38 import java.io.ObjectInputStream;
  39 import java.io.IOException;
  40 
  41 
  42 /**
  43  * An implementation of a "push" button.
  44   * <p>
  45  * Buttons can be configured, and to some degree controlled, by
  46  * <code><a href="Action.html">Action</a></code>s.  Using an
  47  * <code>Action</code> with a button has many benefits beyond directly
  48  * configuring a button.  Refer to <a href="Action.html#buttonActions">
  49  * Swing Components Supporting <code>Action</code></a> for more
  50  * details, and you can find more information in <a
  51  * href="http://java.sun.com/docs/books/tutorial/uiswing/misc/action.html">How
  52  * to Use Actions</a>, a section in <em>The Java Tutorial</em>.
  53  * <p>
  54  * See <a href="http://java.sun.com/docs/books/tutorial/uiswing/components/button.html">How to Use Buttons, Check Boxes, and Radio Buttons</a>
  55  * in <em>The Java Tutorial</em>
  56  * for information and examples of using buttons.
  57  * <p>
  58  * <strong>Warning:</strong> Swing is not thread safe. For more
  59  * information see <a
  60  * href="package-summary.html#threading">Swing's Threading
  61  * Policy</a>.
  62  * <p>
  63  * <strong>Warning:</strong>
  64  * Serialized objects of this class will not be compatible with
  65  * future Swing releases. The current serialization support is
  66  * appropriate for short term storage or RMI between applications running
  67  * the same version of Swing.  As of 1.4, support for long term storage
  68  * of all JavaBeans<sup><font size="-2">TM</font></sup>
  69  * has been added to the <code>java.beans</code> package.
  70  * Please see {@link java.beans.XMLEncoder}.
  71  *
  72  * @beaninfo
  73  *   attribute: isContainer false
  74  * description: An implementation of a \"push\" button.
  75  *
  76  * @author Jeff Dinkins
  77  */
  78 @SuppressWarnings("serial")
  79 public class JButton extends AbstractButton implements Accessible {
  80 
  81     /**
  82      * @see #getUIClassID
  83      * @see #readObject
  84      */
  85     private static final String uiClassID = "ButtonUI";
  86 
  87     /**
  88      * Creates a button with no set text or icon.
  89      */
  90     public JButton() {
  91         this(null, null);
  92     }
  93 
  94     /**
  95      * Creates a button with an icon.
  96      *
  97      * @param icon  the Icon image to display on the button
  98      */
  99     public JButton(Icon icon) {
 100         this(null, icon);
 101     }
 102 
 103     /**
 104      * Creates a button with text.
 105      *
 106      * @param text  the text of the button
 107      */
 108     @ConstructorProperties({"text"})
 109     public JButton(String text) {
 110         this(text, null);
 111     }
 112 
 113     /**
 114      * Creates a button where properties are taken from the
 115      * <code>Action</code> supplied.
 116      *
 117      * @param a the <code>Action</code> used to specify the new button
 118      *
 119      * @since 1.3
 120      */
 121     public JButton(Action a) {
 122         this();
 123         setAction(a);
 124     }
 125 
 126     /**
 127      * Creates a button with initial text and an icon.
 128      *
 129      * @param text  the text of the button
 130      * @param icon  the Icon image to display on the button
 131      */
 132     public JButton(String text, Icon icon) {
 133         // Create the model
 134         setModel(new DefaultButtonModel());
 135 
 136         // initialize
 137         init(text, icon);
 138     }
 139 
 140     /**
 141      * Resets the UI property to a value from the current look and
 142      * feel.
 143      *
 144      * @see JComponent#updateUI
 145      */
 146     public void updateUI() {
 147         setUI((ButtonUI)UIManager.getUI(this));
 148     }
 149 
 150 
 151     /**
 152      * Returns a string that specifies the name of the L&amp;F class
 153      * that renders this component.
 154      *
 155      * @return the string "ButtonUI"
 156      * @see JComponent#getUIClassID
 157      * @see UIDefaults#getUI
 158      * @beaninfo
 159      *        expert: true
 160      *   description: A string that specifies the name of the L&amp;F class.
 161      */
 162     public String getUIClassID() {
 163         return uiClassID;
 164     }
 165 
 166 
 167     /**
 168      * Gets the value of the <code>defaultButton</code> property,
 169      * which if <code>true</code> means that this button is the current
 170      * default button for its <code>JRootPane</code>.
 171      * Most look and feels render the default button
 172      * differently, and may potentially provide bindings
 173      * to access the default button.
 174      *
 175      * @return the value of the <code>defaultButton</code> property
 176      * @see JRootPane#setDefaultButton
 177      * @see #isDefaultCapable
 178      * @beaninfo
 179      *  description: Whether or not this button is the default button
 180      */
 181     public boolean isDefaultButton() {
 182         JRootPane root = SwingUtilities.getRootPane(this);
 183         if (root != null) {
 184             return root.getDefaultButton() == this;
 185         }
 186         return false;
 187     }
 188 
 189     /**
 190      * Gets the value of the <code>defaultCapable</code> property.
 191      *
 192      * @return the value of the <code>defaultCapable</code> property
 193      * @see #setDefaultCapable
 194      * @see #isDefaultButton
 195      * @see JRootPane#setDefaultButton
 196      */
 197     public boolean isDefaultCapable() {
 198         return defaultCapable;
 199     }
 200 
 201     /**
 202      * Sets the <code>defaultCapable</code> property,
 203      * which determines whether this button can be
 204      * made the default button for its root pane.
 205      * The default value of the <code>defaultCapable</code>
 206      * property is <code>true</code> unless otherwise
 207      * specified by the look and feel.
 208      *
 209      * @param defaultCapable <code>true</code> if this button will be
 210      *        capable of being the default button on the
 211      *        <code>RootPane</code>; otherwise <code>false</code>
 212      * @see #isDefaultCapable
 213      * @beaninfo
 214      *        bound: true
 215      *    attribute: visualUpdate true
 216      *  description: Whether or not this button can be the default button
 217      */
 218     public void setDefaultCapable(boolean defaultCapable) {
 219         boolean oldDefaultCapable = this.defaultCapable;
 220         this.defaultCapable = defaultCapable;
 221         firePropertyChange("defaultCapable", oldDefaultCapable, defaultCapable);
 222     }
 223 
 224     /**
 225      * Overrides <code>JComponent.removeNotify</code> to check if
 226      * this button is currently set as the default button on the
 227      * <code>RootPane</code>, and if so, sets the <code>RootPane</code>'s
 228      * default button to <code>null</code> to ensure the
 229      * <code>RootPane</code> doesn't hold onto an invalid button reference.
 230      */
 231     public void removeNotify() {
 232         JRootPane root = SwingUtilities.getRootPane(this);
 233         if (root != null && root.getDefaultButton() == this) {
 234             root.setDefaultButton(null);
 235         }
 236         super.removeNotify();
 237     }
 238 
 239     /**
 240      * See readObject() and writeObject() in JComponent for more
 241      * information about serialization in Swing.
 242      */
 243     private void writeObject(ObjectOutputStream s) throws IOException {
 244         s.defaultWriteObject();
 245         if (getUIClassID().equals(uiClassID)) {
 246             byte count = JComponent.getWriteObjCounter(this);
 247             JComponent.setWriteObjCounter(this, --count);
 248             if (count == 0 && ui != null) {
 249                 ui.installUI(this);
 250             }
 251         }
 252     }
 253 
 254 
 255     /**
 256      * Returns a string representation of this <code>JButton</code>.
 257      * This method is intended to be used only for debugging purposes, and the
 258      * content and format of the returned string may vary between
 259      * implementations. The returned string may be empty but may not
 260      * be <code>null</code>.
 261      *
 262      * @return  a string representation of this <code>JButton</code>
 263      */
 264     protected String paramString() {
 265         String defaultCapableString = (defaultCapable ? "true" : "false");
 266 
 267         return super.paramString() +
 268             ",defaultCapable=" + defaultCapableString;
 269     }
 270 
 271 
 272 /////////////////
 273 // Accessibility support
 274 ////////////////
 275 
 276     /**
 277      * Gets the <code>AccessibleContext</code> associated with this
 278      * <code>JButton</code>. For <code>JButton</code>s,
 279      * the <code>AccessibleContext</code> takes the form of an
 280      * <code>AccessibleJButton</code>.
 281      * A new <code>AccessibleJButton</code> instance is created if necessary.
 282      *
 283      * @return an <code>AccessibleJButton</code> that serves as the
 284      *         <code>AccessibleContext</code> of this <code>JButton</code>
 285      * @beaninfo
 286      *       expert: true
 287      *  description: The AccessibleContext associated with this Button.
 288      */
 289     public AccessibleContext getAccessibleContext() {
 290         if (accessibleContext == null) {
 291             accessibleContext = new AccessibleJButton();
 292         }
 293         return accessibleContext;
 294     }
 295 
 296     /**
 297      * This class implements accessibility support for the
 298      * <code>JButton</code> class.  It provides an implementation of the
 299      * Java Accessibility API appropriate to button user-interface
 300      * elements.
 301      * <p>
 302      * <strong>Warning:</strong>
 303      * Serialized objects of this class will not be compatible with
 304      * future Swing releases. The current serialization support is
 305      * appropriate for short term storage or RMI between applications running
 306      * the same version of Swing.  As of 1.4, support for long term storage
 307      * of all JavaBeans<sup><font size="-2">TM</font></sup>
 308      * has been added to the <code>java.beans</code> package.
 309      * Please see {@link java.beans.XMLEncoder}.
 310      */
 311     @SuppressWarnings("serial")
 312     protected class AccessibleJButton extends AccessibleAbstractButton {
 313 
 314         /**
 315          * Get the role of this object.
 316          *
 317          * @return an instance of AccessibleRole describing the role of the
 318          * object
 319          * @see AccessibleRole
 320          */
 321         public AccessibleRole getAccessibleRole() {
 322             return AccessibleRole.PUSH_BUTTON;
 323         }
 324     } // inner class AccessibleJButton
 325 }