1 /*
   2  * Copyright (c) 1997, 2013, 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://docs.oracle.com/javase/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://docs.oracle.com/javase/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&trade;
  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  * @since 1.2
  78  */
  79 @SuppressWarnings("serial")
  80 public class JButton extends AbstractButton implements Accessible {
  81 
  82     /**
  83      * @see #getUIClassID
  84      * @see #readObject
  85      */
  86     private static final String uiClassID = "ButtonUI";
  87 
  88     /**
  89      * Creates a button with no set text or icon.
  90      */
  91     public JButton() {
  92         this(null, null);
  93     }
  94 
  95     /**
  96      * Creates a button with an icon.
  97      *
  98      * @param icon  the Icon image to display on the button
  99      */
 100     public JButton(Icon icon) {
 101         this(null, icon);
 102     }
 103 
 104     /**
 105      * Creates a button with text.
 106      *
 107      * @param text  the text of the button
 108      */
 109     @ConstructorProperties({"text"})
 110     public JButton(String text) {
 111         this(text, null);
 112     }
 113 
 114     /**
 115      * Creates a button where properties are taken from the
 116      * <code>Action</code> supplied.
 117      *
 118      * @param a the <code>Action</code> used to specify the new button
 119      *
 120      * @since 1.3
 121      */
 122     public JButton(Action a) {
 123         this();
 124         setAction(a);
 125     }
 126 
 127     /**
 128      * Creates a button with initial text and an icon.
 129      *
 130      * @param text  the text of the button
 131      * @param icon  the Icon image to display on the button
 132      */
 133     public JButton(String text, Icon icon) {
 134         // Create the model
 135         setModel(new DefaultButtonModel());
 136 
 137         // initialize
 138         init(text, icon);
 139     }
 140 
 141     /**
 142      * Resets the UI property to a value from the current look and
 143      * feel.
 144      *
 145      * @see JComponent#updateUI
 146      */
 147     public void updateUI() {
 148         setUI((ButtonUI)UIManager.getUI(this));
 149     }
 150 
 151 
 152     /**
 153      * Returns a string that specifies the name of the L&amp;F class
 154      * that renders this component.
 155      *
 156      * @return the string "ButtonUI"
 157      * @see JComponent#getUIClassID
 158      * @see UIDefaults#getUI
 159      * @beaninfo
 160      *        expert: true
 161      *   description: A string that specifies the name of the L&amp;F class.
 162      */
 163     public String getUIClassID() {
 164         return uiClassID;
 165     }
 166 
 167 
 168     /**
 169      * Gets the value of the <code>defaultButton</code> property,
 170      * which if <code>true</code> means that this button is the current
 171      * default button for its <code>JRootPane</code>.
 172      * Most look and feels render the default button
 173      * differently, and may potentially provide bindings
 174      * to access the default button.
 175      *
 176      * @return the value of the <code>defaultButton</code> property
 177      * @see JRootPane#setDefaultButton
 178      * @see #isDefaultCapable
 179      * @beaninfo
 180      *  description: Whether or not this button is the default button
 181      */
 182     public boolean isDefaultButton() {
 183         JRootPane root = SwingUtilities.getRootPane(this);
 184         if (root != null) {
 185             return root.getDefaultButton() == this;
 186         }
 187         return false;
 188     }
 189 
 190     /**
 191      * Gets the value of the <code>defaultCapable</code> property.
 192      *
 193      * @return the value of the <code>defaultCapable</code> property
 194      * @see #setDefaultCapable
 195      * @see #isDefaultButton
 196      * @see JRootPane#setDefaultButton
 197      */
 198     public boolean isDefaultCapable() {
 199         return defaultCapable;
 200     }
 201 
 202     /**
 203      * Sets the <code>defaultCapable</code> property,
 204      * which determines whether this button can be
 205      * made the default button for its root pane.
 206      * The default value of the <code>defaultCapable</code>
 207      * property is <code>true</code> unless otherwise
 208      * specified by the look and feel.
 209      *
 210      * @param defaultCapable <code>true</code> if this button will be
 211      *        capable of being the default button on the
 212      *        <code>RootPane</code>; otherwise <code>false</code>
 213      * @see #isDefaultCapable
 214      * @beaninfo
 215      *        bound: true
 216      *    attribute: visualUpdate true
 217      *  description: Whether or not this button can be the default button
 218      */
 219     public void setDefaultCapable(boolean defaultCapable) {
 220         boolean oldDefaultCapable = this.defaultCapable;
 221         this.defaultCapable = defaultCapable;
 222         firePropertyChange("defaultCapable", oldDefaultCapable, defaultCapable);
 223     }
 224 
 225     /**
 226      * Overrides <code>JComponent.removeNotify</code> to check if
 227      * this button is currently set as the default button on the
 228      * <code>RootPane</code>, and if so, sets the <code>RootPane</code>'s
 229      * default button to <code>null</code> to ensure the
 230      * <code>RootPane</code> doesn't hold onto an invalid button reference.
 231      */
 232     public void removeNotify() {
 233         JRootPane root = SwingUtilities.getRootPane(this);
 234         if (root != null && root.getDefaultButton() == this) {
 235             root.setDefaultButton(null);
 236         }
 237         super.removeNotify();
 238     }
 239 
 240     /**
 241      * See readObject() and writeObject() in JComponent for more
 242      * information about serialization in Swing.
 243      */
 244     private void writeObject(ObjectOutputStream s) throws IOException {
 245         s.defaultWriteObject();
 246         if (getUIClassID().equals(uiClassID)) {
 247             byte count = JComponent.getWriteObjCounter(this);
 248             JComponent.setWriteObjCounter(this, --count);
 249             if (count == 0 && ui != null) {
 250                 ui.installUI(this);
 251             }
 252         }
 253     }
 254 
 255 
 256     /**
 257      * Returns a string representation of this <code>JButton</code>.
 258      * This method is intended to be used only for debugging purposes, and the
 259      * content and format of the returned string may vary between
 260      * implementations. The returned string may be empty but may not
 261      * be <code>null</code>.
 262      *
 263      * @return  a string representation of this <code>JButton</code>
 264      */
 265     protected String paramString() {
 266         String defaultCapableString = (defaultCapable ? "true" : "false");
 267 
 268         return super.paramString() +
 269             ",defaultCapable=" + defaultCapableString;
 270     }
 271 
 272 
 273 /////////////////
 274 // Accessibility support
 275 ////////////////
 276 
 277     /**
 278      * Gets the <code>AccessibleContext</code> associated with this
 279      * <code>JButton</code>. For <code>JButton</code>s,
 280      * the <code>AccessibleContext</code> takes the form of an
 281      * <code>AccessibleJButton</code>.
 282      * A new <code>AccessibleJButton</code> instance is created if necessary.
 283      *
 284      * @return an <code>AccessibleJButton</code> that serves as the
 285      *         <code>AccessibleContext</code> of this <code>JButton</code>
 286      * @beaninfo
 287      *       expert: true
 288      *  description: The AccessibleContext associated with this Button.
 289      */
 290     public AccessibleContext getAccessibleContext() {
 291         if (accessibleContext == null) {
 292             accessibleContext = new AccessibleJButton();
 293         }
 294         return accessibleContext;
 295     }
 296 
 297     /**
 298      * This class implements accessibility support for the
 299      * <code>JButton</code> class.  It provides an implementation of the
 300      * Java Accessibility API appropriate to button user-interface
 301      * elements.
 302      * <p>
 303      * <strong>Warning:</strong>
 304      * Serialized objects of this class will not be compatible with
 305      * future Swing releases. The current serialization support is
 306      * appropriate for short term storage or RMI between applications running
 307      * the same version of Swing.  As of 1.4, support for long term storage
 308      * of all JavaBeans&trade;
 309      * has been added to the <code>java.beans</code> package.
 310      * Please see {@link java.beans.XMLEncoder}.
 311      */
 312     @SuppressWarnings("serial")
 313     protected class AccessibleJButton extends AccessibleAbstractButton {
 314 
 315         /**
 316          * Get the role of this object.
 317          *
 318          * @return an instance of AccessibleRole describing the role of the
 319          * object
 320          * @see AccessibleRole
 321          */
 322         public AccessibleRole getAccessibleRole() {
 323             return AccessibleRole.PUSH_BUTTON;
 324         }
 325     } // inner class AccessibleJButton
 326 }