1 /*
  2  * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
  3  * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  4  *
  5  *
  6  *
  7  *
  8  *
  9  *
 10  *
 11  *
 12  *
 13  *
 14  *
 15  *
 16  *
 17  *
 18  *
 19  *
 20  *
 21  *
 22  *
 23  *
 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="https://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="https://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  */
 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&trade;
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 }
326