Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/java/awt/Button.java
38829 views
/*1* Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package java.awt;2627import java.awt.peer.ButtonPeer;28import java.util.EventListener;29import java.awt.event.*;30import java.io.ObjectOutputStream;31import java.io.ObjectInputStream;32import java.io.IOException;33import javax.accessibility.*;3435/**36* This class creates a labeled button. The application can cause37* some action to happen when the button is pushed. This image38* depicts three views of a "<code>Quit</code>" button as it appears39* under the Solaris operating system:40* <p>41* <img src="doc-files/Button-1.gif" alt="The following context describes the graphic"42* style="float:center; margin: 7px 10px;">43* <p>44* The first view shows the button as it appears normally.45* The second view shows the button46* when it has input focus. Its outline is darkened to let the47* user know that it is an active object. The third view shows the48* button when the user clicks the mouse over the button, and thus49* requests that an action be performed.50* <p>51* The gesture of clicking on a button with the mouse52* is associated with one instance of <code>ActionEvent</code>,53* which is sent out when the mouse is both pressed and released54* over the button. If an application is interested in knowing55* when the button has been pressed but not released, as a separate56* gesture, it can specialize <code>processMouseEvent</code>,57* or it can register itself as a listener for mouse events by58* calling <code>addMouseListener</code>. Both of these methods are59* defined by <code>Component</code>, the abstract superclass of60* all components.61* <p>62* When a button is pressed and released, AWT sends an instance63* of <code>ActionEvent</code> to the button, by calling64* <code>processEvent</code> on the button. The button's65* <code>processEvent</code> method receives all events66* for the button; it passes an action event along by67* calling its own <code>processActionEvent</code> method.68* The latter method passes the action event on to any action69* listeners that have registered an interest in action70* events generated by this button.71* <p>72* If an application wants to perform some action based on73* a button being pressed and released, it should implement74* <code>ActionListener</code> and register the new listener75* to receive events from this button, by calling the button's76* <code>addActionListener</code> method. The application can77* make use of the button's action command as a messaging protocol.78*79* @author Sami Shaio80* @see java.awt.event.ActionEvent81* @see java.awt.event.ActionListener82* @see java.awt.Component#processMouseEvent83* @see java.awt.Component#addMouseListener84* @since JDK1.085*/86public class Button extends Component implements Accessible {8788/**89* The button's label. This value may be null.90* @serial91* @see #getLabel()92* @see #setLabel(String)93*/94String label;9596/**97* The action to be performed once a button has been98* pressed. This value may be null.99* @serial100* @see #getActionCommand()101* @see #setActionCommand(String)102*/103String actionCommand;104105transient ActionListener actionListener;106107private static final String base = "button";108private static int nameCounter = 0;109110/*111* JDK 1.1 serialVersionUID112*/113private static final long serialVersionUID = -8774683716313001058L;114115116static {117/* ensure that the necessary native libraries are loaded */118Toolkit.loadLibraries();119if (!GraphicsEnvironment.isHeadless()) {120initIDs();121}122}123124/**125* Initialize JNI field and method IDs for fields that may be126* accessed from C.127*/128private static native void initIDs();129130/**131* Constructs a button with an empty string for its label.132*133* @exception HeadlessException if GraphicsEnvironment.isHeadless()134* returns true135* @see java.awt.GraphicsEnvironment#isHeadless136*/137public Button() throws HeadlessException {138this("");139}140141/**142* Constructs a button with the specified label.143*144* @param label a string label for the button, or145* <code>null</code> for no label146* @exception HeadlessException if GraphicsEnvironment.isHeadless()147* returns true148* @see java.awt.GraphicsEnvironment#isHeadless149*/150public Button(String label) throws HeadlessException {151GraphicsEnvironment.checkHeadless();152this.label = label;153}154155/**156* Construct a name for this component. Called by getName() when the157* name is null.158*/159String constructComponentName() {160synchronized (Button.class) {161return base + nameCounter++;162}163}164165/**166* Creates the peer of the button. The button's peer allows the167* application to change the look of the button without changing168* its functionality.169*170* @see java.awt.Toolkit#createButton(java.awt.Button)171* @see java.awt.Component#getToolkit()172*/173public void addNotify() {174synchronized(getTreeLock()) {175if (peer == null)176peer = getToolkit().createButton(this);177super.addNotify();178}179}180181/**182* Gets the label of this button.183*184* @return the button's label, or <code>null</code>185* if the button has no label.186* @see java.awt.Button#setLabel187*/188public String getLabel() {189return label;190}191192/**193* Sets the button's label to be the specified string.194*195* @param label the new label, or <code>null</code>196* if the button has no label.197* @see java.awt.Button#getLabel198*/199public void setLabel(String label) {200boolean testvalid = false;201202synchronized (this) {203if (label != this.label && (this.label == null ||204!this.label.equals(label))) {205this.label = label;206ButtonPeer peer = (ButtonPeer)this.peer;207if (peer != null) {208peer.setLabel(label);209}210testvalid = true;211}212}213214// This could change the preferred size of the Component.215if (testvalid) {216invalidateIfValid();217}218}219220/**221* Sets the command name for the action event fired222* by this button. By default this action command is223* set to match the label of the button.224*225* @param command a string used to set the button's226* action command.227* If the string is <code>null</code> then the action command228* is set to match the label of the button.229* @see java.awt.event.ActionEvent230* @since JDK1.1231*/232public void setActionCommand(String command) {233actionCommand = command;234}235236/**237* Returns the command name of the action event fired by this button.238* If the command name is <code>null</code> (default) then this method239* returns the label of the button.240*/241public String getActionCommand() {242return (actionCommand == null? label : actionCommand);243}244245/**246* Adds the specified action listener to receive action events from247* this button. Action events occur when a user presses or releases248* the mouse over this button.249* If l is null, no exception is thrown and no action is performed.250* <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"251* >AWT Threading Issues</a> for details on AWT's threading model.252*253* @param l the action listener254* @see #removeActionListener255* @see #getActionListeners256* @see java.awt.event.ActionListener257* @since JDK1.1258*/259public synchronized void addActionListener(ActionListener l) {260if (l == null) {261return;262}263actionListener = AWTEventMulticaster.add(actionListener, l);264newEventsOnly = true;265}266267/**268* Removes the specified action listener so that it no longer269* receives action events from this button. Action events occur270* when a user presses or releases the mouse over this button.271* If l is null, no exception is thrown and no action is performed.272* <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"273* >AWT Threading Issues</a> for details on AWT's threading model.274*275* @param l the action listener276* @see #addActionListener277* @see #getActionListeners278* @see java.awt.event.ActionListener279* @since JDK1.1280*/281public synchronized void removeActionListener(ActionListener l) {282if (l == null) {283return;284}285actionListener = AWTEventMulticaster.remove(actionListener, l);286}287288/**289* Returns an array of all the action listeners290* registered on this button.291*292* @return all of this button's <code>ActionListener</code>s293* or an empty array if no action294* listeners are currently registered295*296* @see #addActionListener297* @see #removeActionListener298* @see java.awt.event.ActionListener299* @since 1.4300*/301public synchronized ActionListener[] getActionListeners() {302return getListeners(ActionListener.class);303}304305/**306* Returns an array of all the objects currently registered307* as <code><em>Foo</em>Listener</code>s308* upon this <code>Button</code>.309* <code><em>Foo</em>Listener</code>s are registered using the310* <code>add<em>Foo</em>Listener</code> method.311*312* <p>313* You can specify the <code>listenerType</code> argument314* with a class literal, such as315* <code><em>Foo</em>Listener.class</code>.316* For example, you can query a317* <code>Button</code> <code>b</code>318* for its action listeners with the following code:319*320* <pre>ActionListener[] als = (ActionListener[])(b.getListeners(ActionListener.class));</pre>321*322* If no such listeners exist, this method returns an empty array.323*324* @param listenerType the type of listeners requested; this parameter325* should specify an interface that descends from326* <code>java.util.EventListener</code>327* @return an array of all objects registered as328* <code><em>Foo</em>Listener</code>s on this button,329* or an empty array if no such330* listeners have been added331* @exception ClassCastException if <code>listenerType</code>332* doesn't specify a class or interface that implements333* <code>java.util.EventListener</code>334*335* @see #getActionListeners336* @since 1.3337*/338public <T extends EventListener> T[] getListeners(Class<T> listenerType) {339EventListener l = null;340if (listenerType == ActionListener.class) {341l = actionListener;342} else {343return super.getListeners(listenerType);344}345return AWTEventMulticaster.getListeners(l, listenerType);346}347348// REMIND: remove when filtering is done at lower level349boolean eventEnabled(AWTEvent e) {350if (e.id == ActionEvent.ACTION_PERFORMED) {351if ((eventMask & AWTEvent.ACTION_EVENT_MASK) != 0 ||352actionListener != null) {353return true;354}355return false;356}357return super.eventEnabled(e);358}359360/**361* Processes events on this button. If an event is362* an instance of <code>ActionEvent</code>, this method invokes363* the <code>processActionEvent</code> method. Otherwise,364* it invokes <code>processEvent</code> on the superclass.365* <p>Note that if the event parameter is <code>null</code>366* the behavior is unspecified and may result in an367* exception.368*369* @param e the event370* @see java.awt.event.ActionEvent371* @see java.awt.Button#processActionEvent372* @since JDK1.1373*/374protected void processEvent(AWTEvent e) {375if (e instanceof ActionEvent) {376processActionEvent((ActionEvent)e);377return;378}379super.processEvent(e);380}381382/**383* Processes action events occurring on this button384* by dispatching them to any registered385* <code>ActionListener</code> objects.386* <p>387* This method is not called unless action events are388* enabled for this button. Action events are enabled389* when one of the following occurs:390* <ul>391* <li>An <code>ActionListener</code> object is registered392* via <code>addActionListener</code>.393* <li>Action events are enabled via <code>enableEvents</code>.394* </ul>395* <p>Note that if the event parameter is <code>null</code>396* the behavior is unspecified and may result in an397* exception.398*399* @param e the action event400* @see java.awt.event.ActionListener401* @see java.awt.Button#addActionListener402* @see java.awt.Component#enableEvents403* @since JDK1.1404*/405protected void processActionEvent(ActionEvent e) {406ActionListener listener = actionListener;407if (listener != null) {408listener.actionPerformed(e);409}410}411412/**413* Returns a string representing the state of this <code>Button</code>.414* This method is intended to be used only for debugging purposes, and the415* content and format of the returned string may vary between416* implementations. The returned string may be empty but may not be417* <code>null</code>.418*419* @return the parameter string of this button420*/421protected String paramString() {422return super.paramString() + ",label=" + label;423}424425426/* Serialization support.427*/428429/*430* Button Serial Data Version.431* @serial432*/433private int buttonSerializedDataVersion = 1;434435/**436* Writes default serializable fields to stream. Writes437* a list of serializable <code>ActionListeners</code>438* as optional data. The non-serializable439* <code>ActionListeners</code> are detected and440* no attempt is made to serialize them.441*442* @serialData <code>null</code> terminated sequence of 0 or443* more pairs: the pair consists of a <code>String</code>444* and an <code>Object</code>; the <code>String</code>445* indicates the type of object and is one of the following:446* <code>actionListenerK</code> indicating an447* <code>ActionListener</code> object448*449* @param s the <code>ObjectOutputStream</code> to write450* @see AWTEventMulticaster#save(ObjectOutputStream, String, EventListener)451* @see java.awt.Component#actionListenerK452* @see #readObject(ObjectInputStream)453*/454private void writeObject(ObjectOutputStream s)455throws IOException456{457s.defaultWriteObject();458459AWTEventMulticaster.save(s, actionListenerK, actionListener);460s.writeObject(null);461}462463/**464* Reads the <code>ObjectInputStream</code> and if465* it isn't <code>null</code> adds a listener to466* receive action events fired by the button.467* Unrecognized keys or values will be ignored.468*469* @param s the <code>ObjectInputStream</code> to read470* @exception HeadlessException if471* <code>GraphicsEnvironment.isHeadless</code> returns472* <code>true</code>473* @serial474* @see #removeActionListener(ActionListener)475* @see #addActionListener(ActionListener)476* @see java.awt.GraphicsEnvironment#isHeadless477* @see #writeObject(ObjectOutputStream)478*/479private void readObject(ObjectInputStream s)480throws ClassNotFoundException, IOException, HeadlessException481{482GraphicsEnvironment.checkHeadless();483s.defaultReadObject();484485Object keyOrNull;486while(null != (keyOrNull = s.readObject())) {487String key = ((String)keyOrNull).intern();488489if (actionListenerK == key)490addActionListener((ActionListener)(s.readObject()));491492else // skip value for unrecognized key493s.readObject();494}495}496497498/////////////////499// Accessibility support500////////////////501502/**503* Gets the <code>AccessibleContext</code> associated with504* this <code>Button</code>. For buttons, the505* <code>AccessibleContext</code> takes the form of an506* <code>AccessibleAWTButton</code>.507* A new <code>AccessibleAWTButton</code> instance is508* created if necessary.509*510* @return an <code>AccessibleAWTButton</code> that serves as the511* <code>AccessibleContext</code> of this <code>Button</code>512* @beaninfo513* expert: true514* description: The AccessibleContext associated with this Button.515* @since 1.3516*/517public AccessibleContext getAccessibleContext() {518if (accessibleContext == null) {519accessibleContext = new AccessibleAWTButton();520}521return accessibleContext;522}523524/**525* This class implements accessibility support for the526* <code>Button</code> class. It provides an implementation of the527* Java Accessibility API appropriate to button user-interface elements.528* @since 1.3529*/530protected class AccessibleAWTButton extends AccessibleAWTComponent531implements AccessibleAction, AccessibleValue532{533/*534* JDK 1.3 serialVersionUID535*/536private static final long serialVersionUID = -5932203980244017102L;537538/**539* Get the accessible name of this object.540*541* @return the localized name of the object -- can be null if this542* object does not have a name543*/544public String getAccessibleName() {545if (accessibleName != null) {546return accessibleName;547} else {548if (getLabel() == null) {549return super.getAccessibleName();550} else {551return getLabel();552}553}554}555556/**557* Get the AccessibleAction associated with this object. In the558* implementation of the Java Accessibility API for this class,559* return this object, which is responsible for implementing the560* AccessibleAction interface on behalf of itself.561*562* @return this object563*/564public AccessibleAction getAccessibleAction() {565return this;566}567568/**569* Get the AccessibleValue associated with this object. In the570* implementation of the Java Accessibility API for this class,571* return this object, which is responsible for implementing the572* AccessibleValue interface on behalf of itself.573*574* @return this object575*/576public AccessibleValue getAccessibleValue() {577return this;578}579580/**581* Returns the number of Actions available in this object. The582* default behavior of a button is to have one action - toggle583* the button.584*585* @return 1, the number of Actions in this object586*/587public int getAccessibleActionCount() {588return 1;589}590591/**592* Return a description of the specified action of the object.593*594* @param i zero-based index of the actions595*/596public String getAccessibleActionDescription(int i) {597if (i == 0) {598// [[[PENDING: WDW -- need to provide a localized string]]]599return "click";600} else {601return null;602}603}604605/**606* Perform the specified Action on the object607*608* @param i zero-based index of actions609* @return true if the the action was performed; else false.610*/611public boolean doAccessibleAction(int i) {612if (i == 0) {613// Simulate a button click614Toolkit.getEventQueue().postEvent(615new ActionEvent(Button.this,616ActionEvent.ACTION_PERFORMED,617Button.this.getActionCommand()));618return true;619} else {620return false;621}622}623624/**625* Get the value of this object as a Number.626*627* @return An Integer of 0 if this isn't selected or an Integer of 1 if628* this is selected.629* @see javax.swing.AbstractButton#isSelected()630*/631public Number getCurrentAccessibleValue() {632return Integer.valueOf(0);633}634635/**636* Set the value of this object as a Number.637*638* @return True if the value was set.639*/640public boolean setCurrentAccessibleValue(Number n) {641return false;642}643644/**645* Get the minimum value of this object as a Number.646*647* @return An Integer of 0.648*/649public Number getMinimumAccessibleValue() {650return Integer.valueOf(0);651}652653/**654* Get the maximum value of this object as a Number.655*656* @return An Integer of 0.657*/658public Number getMaximumAccessibleValue() {659return Integer.valueOf(0);660}661662/**663* Get the role of this object.664*665* @return an instance of AccessibleRole describing the role of the666* object667* @see AccessibleRole668*/669public AccessibleRole getAccessibleRole() {670return AccessibleRole.PUSH_BUTTON;671}672} // inner class AccessibleAWTButton673674}675676677