KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > java > awt > Button


1 /*
2  * @(#)Button.java 1.77 04/05/05
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package java.awt;
9
10 import java.awt.peer.ButtonPeer;
11 import java.util.EventListener JavaDoc;
12 import java.awt.event.*;
13 import java.io.ObjectOutputStream JavaDoc;
14 import java.io.ObjectInputStream JavaDoc;
15 import java.io.IOException JavaDoc;
16 import javax.accessibility.*;
17
18 /**
19  * This class creates a labeled button. The application can cause
20  * some action to happen when the button is pushed. This image
21  * depicts three views of a "<code>Quit</code>" button as it appears
22  * under the Solaris operating system:
23  * <p>
24  * <img SRC="doc-files/Button-1.gif" alt="The following context describes the graphic"
25  * ALIGN=center HSPACE=10 VSPACE=7>
26  * <p>
27  * The first view shows the button as it appears normally.
28  * The second view shows the button
29  * when it has input focus. Its outline is darkened to let the
30  * user know that it is an active object. The third view shows the
31  * button when the user clicks the mouse over the button, and thus
32  * requests that an action be performed.
33  * <p>
34  * The gesture of clicking on a button with the mouse
35  * is associated with one instance of <code>ActionEvent</code>,
36  * which is sent out when the mouse is both pressed and released
37  * over the button. If an application is interested in knowing
38  * when the button has been pressed but not released, as a separate
39  * gesture, it can specialize <code>processMouseEvent</code>,
40  * or it can register itself as a listener for mouse events by
41  * calling <code>addMouseListener</code>. Both of these methods are
42  * defined by <code>Component</code>, the abstract superclass of
43  * all components.
44  * <p>
45  * When a button is pressed and released, AWT sends an instance
46  * of <code>ActionEvent</code> to the button, by calling
47  * <code>processEvent</code> on the button. The button's
48  * <code>processEvent</code> method receives all events
49  * for the button; it passes an action event along by
50  * calling its own <code>processActionEvent</code> method.
51  * The latter method passes the action event on to any action
52  * listeners that have registered an interest in action
53  * events generated by this button.
54  * <p>
55  * If an application wants to perform some action based on
56  * a button being pressed and released, it should implement
57  * <code>ActionListener</code> and register the new listener
58  * to receive events from this button, by calling the button's
59  * <code>addActionListener</code> method. The application can
60  * make use of the button's action command as a messaging protocol.
61  *
62  * @version 1.77 05/05/04
63  * @author Sami Shaio
64  * @see java.awt.event.ActionEvent
65  * @see java.awt.event.ActionListener
66  * @see java.awt.Component#processMouseEvent
67  * @see java.awt.Component#addMouseListener
68  * @since JDK1.0
69  */

70 public class Button extends Component JavaDoc implements Accessible {
71
72     /**
73      * The button's label. This value may be null.
74      * @serial
75      * @see getLabel()
76      * @see setLabel()
77      */

78     String JavaDoc label;
79
80     /**
81      * The action to be performed once a button has been
82      * pressed. This value may be null.
83      * @serial
84      * @see getActionCommand()
85      * @see setActionCommand()
86      */

87     String JavaDoc actionCommand;
88
89     transient ActionListener actionListener;
90
91     private static final String JavaDoc base = "button";
92     private static int nameCounter = 0;
93
94     /*
95      * JDK 1.1 serialVersionUID
96      */

97     private static final long serialVersionUID = -8774683716313001058L;
98
99
100     static {
101         /* ensure that the necessary native libraries are loaded */
102     Toolkit.loadLibraries();
103         if (!GraphicsEnvironment.isHeadless()) {
104             initIDs();
105         }
106     }
107
108     /**
109      * Initialize JNI field and method IDs for fields that may be
110      * accessed from C.
111      */

112     private static native void initIDs();
113
114     /**
115      * Constructs a button with an empty string for its label.
116      *
117      * @exception HeadlessException if GraphicsEnvironment.isHeadless()
118      * returns true
119      * @see java.awt.GraphicsEnvironment#isHeadless
120      */

121     public Button() throws HeadlessException JavaDoc {
122     this("");
123     }
124
125     /**
126      * Constructs a button with the specified label.
127      *
128      * @param label a string label for the button, or
129      * <code>null</code> for no label
130      * @exception HeadlessException if GraphicsEnvironment.isHeadless()
131      * returns true
132      * @see java.awt.GraphicsEnvironment#isHeadless
133      */

134     public Button(String JavaDoc label) throws HeadlessException JavaDoc {
135         GraphicsEnvironment.checkHeadless();
136     this.label = label;
137     }
138
139     /**
140      * Construct a name for this component. Called by getName() when the
141      * name is null.
142      */

143     String JavaDoc constructComponentName() {
144         synchronized (getClass()) {
145         return base + nameCounter++;
146     }
147     }
148
149     /**
150      * Creates the peer of the button. The button's peer allows the
151      * application to change the look of the button without changing
152      * its functionality.
153      *
154      * @see java.awt.Toolkit#createButton(java.awt.Button)
155      * @see java.awt.Component#getToolkit()
156      */

157     public void addNotify() {
158         synchronized(getTreeLock()) {
159         if (peer == null)
160             peer = getToolkit().createButton(this);
161         super.addNotify();
162     }
163     }
164
165     /**
166      * Gets the label of this button.
167      *
168      * @return the button's label, or <code>null</code>
169      * if the button has no label.
170      * @see java.awt.Button#setLabel
171      */

172     public String JavaDoc getLabel() {
173     return label;
174     }
175
176     /**
177      * Sets the button's label to be the specified string.
178      *
179      * @param label the new label, or <code>null</code>
180      * if the button has no label.
181      * @see java.awt.Button#getLabel
182      */

183     public void setLabel(String JavaDoc label) {
184         boolean testvalid = false;
185
186     synchronized (this) {
187         if (label != this.label && (this.label == null ||
188                     !this.label.equals(label))) {
189             this.label = label;
190         ButtonPeer peer = (ButtonPeer)this.peer;
191         if (peer != null) {
192             peer.setLabel(label);
193         }
194         testvalid = true;
195         }
196     }
197
198     // This could change the preferred size of the Component.
199
if (testvalid && valid) {
200         invalidate();
201     }
202     }
203
204     /**
205      * Sets the command name for the action event fired
206      * by this button. By default this action command is
207      * set to match the label of the button.
208      *
209      * @param command a string used to set the button's
210      * action command.
211      * If the string is <code>null</code> then the action command
212      * is set to match the label of the button.
213      * @see java.awt.event.ActionEvent
214      * @since JDK1.1
215      */

216     public void setActionCommand(String JavaDoc command) {
217         actionCommand = command;
218     }
219
220     /**
221      * Returns the command name of the action event fired by this button.
222      * If the command name is <code>null</code> (default) then this method
223      * returns the label of the button.
224      */

225     public String JavaDoc getActionCommand() {
226         return (actionCommand == null? label : actionCommand);
227     }
228
229     /**
230      * Adds the specified action listener to receive action events from
231      * this button. Action events occur when a user presses or releases
232      * the mouse over this button.
233      * If l is null, no exception is thrown and no action is performed.
234      *
235      * @param l the action listener
236      * @see #removeActionListener
237      * @see #getActionListeners
238      * @see java.awt.event.ActionListener
239      * @since JDK1.1
240      */

241     public synchronized void addActionListener(ActionListener l) {
242     if (l == null) {
243         return;
244     }
245     actionListener = AWTEventMulticaster.add(actionListener, l);
246         newEventsOnly = true;
247     }
248
249     /**
250      * Removes the specified action listener so that it no longer
251      * receives action events from this button. Action events occur
252      * when a user presses or releases the mouse over this button.
253      * If l is null, no exception is thrown and no action is performed.
254      *
255      * @param l the action listener
256      * @see #addActionListener
257      * @see #getActionListeners
258      * @see java.awt.event.ActionListener
259      * @since JDK1.1
260      */

261     public synchronized void removeActionListener(ActionListener l) {
262     if (l == null) {
263         return;
264     }
265     actionListener = AWTEventMulticaster.remove(actionListener, l);
266     }
267
268     /**
269      * Returns an array of all the action listeners
270      * registered on this button.
271      *
272      * @return all of this button's <code>ActionListener</code>s
273      * or an empty array if no action
274      * listeners are currently registered
275      *
276      * @see #addActionListener
277      * @see #removeActionListener
278      * @see java.awt.event.ActionListener
279      * @since 1.4
280      */

281     public synchronized ActionListener[] getActionListeners() {
282         return (ActionListener[]) (getListeners(ActionListener.class));
283     }
284
285     /**
286      * Returns an array of all the objects currently registered
287      * as <code><em>Foo</em>Listener</code>s
288      * upon this <code>Button</code>.
289      * <code><em>Foo</em>Listener</code>s are registered using the
290      * <code>add<em>Foo</em>Listener</code> method.
291      *
292      * <p>
293      * You can specify the <code>listenerType</code> argument
294      * with a class literal, such as
295      * <code><em>Foo</em>Listener.class</code>.
296      * For example, you can query a
297      * <code>Button</code> <code>b</code>
298      * for its action listeners with the following code:
299      *
300      * <pre>ActionListener[] als = (ActionListener[])(b.getListeners(ActionListener.class));</pre>
301      *
302      * If no such listeners exist, this method returns an empty array.
303      *
304      * @param listenerType the type of listeners requested; this parameter
305      * should specify an interface that descends from
306      * <code>java.util.EventListener</code>
307      * @return an array of all objects registered as
308      * <code><em>Foo</em>Listener</code>s on this button,
309      * or an empty array if no such
310      * listeners have been added
311      * @exception ClassCastException if <code>listenerType</code>
312      * doesn't specify a class or interface that implements
313      * <code>java.util.EventListener</code>
314      *
315      * @see #getActionListeners
316      * @since 1.3
317      */

318     public <T extends EventListener JavaDoc> T[] getListeners(Class JavaDoc<T> listenerType) {
319     EventListener JavaDoc l = null;
320     if (listenerType == ActionListener.class) {
321         l = actionListener;
322     } else {
323         return super.getListeners(listenerType);
324     }
325     return AWTEventMulticaster.getListeners(l, listenerType);
326     }
327
328     // REMIND: remove when filtering is done at lower level
329
boolean eventEnabled(AWTEvent JavaDoc e) {
330         if (e.id == ActionEvent.ACTION_PERFORMED) {
331             if ((eventMask & AWTEvent.ACTION_EVENT_MASK) != 0 ||
332                 actionListener != null) {
333                 return true;
334             }
335             return false;
336         }
337         return super.eventEnabled(e);
338     }
339
340     /**
341      * Processes events on this button. If an event is
342      * an instance of <code>ActionEvent</code>, this method invokes
343      * the <code>processActionEvent</code> method. Otherwise,
344      * it invokes <code>processEvent</code> on the superclass.
345      * <p>Note that if the event parameter is <code>null</code>
346      * the behavior is unspecified and may result in an
347      * exception.
348      *
349      * @param e the event
350      * @see java.awt.event.ActionEvent
351      * @see java.awt.Button#processActionEvent
352      * @since JDK1.1
353      */

354     protected void processEvent(AWTEvent JavaDoc e) {
355         if (e instanceof ActionEvent) {
356             processActionEvent((ActionEvent)e);
357             return;
358         }
359     super.processEvent(e);
360     }
361
362     /**
363      * Processes action events occurring on this button
364      * by dispatching them to any registered
365      * <code>ActionListener</code> objects.
366      * <p>
367      * This method is not called unless action events are
368      * enabled for this button. Action events are enabled
369      * when one of the following occurs:
370      * <p><ul>
371      * <li>An <code>ActionListener</code> object is registered
372      * via <code>addActionListener</code>.
373      * <li>Action events are enabled via <code>enableEvents</code>.
374      * </ul>
375      * <p>Note that if the event parameter is <code>null</code>
376      * the behavior is unspecified and may result in an
377      * exception.
378      *
379      * @param e the action event
380      * @see java.awt.event.ActionListener
381      * @see java.awt.Button#addActionListener
382      * @see java.awt.Component#enableEvents
383      * @since JDK1.1
384      */

385     protected void processActionEvent(ActionEvent e) {
386         ActionListener listener = actionListener;
387         if (listener != null) {
388             listener.actionPerformed(e);
389         }
390     }
391
392     /**
393      * Returns a string representing the state of this <code>Button</code>.
394      * This method is intended to be used only for debugging purposes, and the
395      * content and format of the returned string may vary between
396      * implementations. The returned string may be empty but may not be
397      * <code>null</code>.
398      *
399      * @return the parameter string of this button
400      */

401     protected String JavaDoc paramString() {
402     return super.paramString() + ",label=" + label;
403     }
404
405
406     /* Serialization support.
407      */

408
409     /*
410      * Button Serial Data Version.
411      * @serial
412      */

413     private int buttonSerializedDataVersion = 1;
414
415     /**
416      * Writes default serializable fields to stream. Writes
417      * a list of serializable <code>ActionListeners</code>
418      * as optional data. The non-serializable
419      * <code>ActionListeners</code> are detected and
420      * no attempt is made to serialize them.
421      *
422      * @serialData <code>null</code> terminated sequence of 0 or
423      * more pairs: the pair consists of a <code>String</code>
424      * and an <code>Object</code>; the <code>String</code>
425      * indicates the type of object and is one of the following:
426      * <code>actionListenerK</code> indicating an
427      * <code>ActionListener</code> object
428      *
429      * @param s the <code>ObjectOutputStream</code> to write
430      * @see AWTEventMulticaster#save(ObjectOutputStream, String, EventListener)
431      * @see java.awt.Component#actionListenerK
432      * @see #readObject(ObjectInputStream)
433      */

434     private void writeObject(ObjectOutputStream JavaDoc s)
435       throws IOException JavaDoc
436     {
437       s.defaultWriteObject();
438
439       AWTEventMulticaster.save(s, actionListenerK, actionListener);
440       s.writeObject(null);
441     }
442
443     /**
444      * Reads the <code>ObjectInputStream</code> and if
445      * it isn't <code>null</code> adds a listener to
446      * receive action events fired by the button.
447      * Unrecognized keys or values will be ignored.
448      *
449      * @param s the <code>ObjectInputStream</code> to read
450      * @exception HeadlessException if
451      * <code>GraphicsEnvironment.isHeadless</code> returns
452      * <code>true</code>
453      * @serial
454      * @see #removeActionListener(ActionListener)
455      * @see #addActionListener(ActionListener)
456      * @see java.awt.GraphicsEnvironment#isHeadless
457      * @see #writeObject(ObjectOutputStream)
458      */

459     private void readObject(ObjectInputStream JavaDoc s)
460       throws ClassNotFoundException JavaDoc, IOException JavaDoc, HeadlessException JavaDoc
461     {
462       GraphicsEnvironment.checkHeadless();
463       s.defaultReadObject();
464
465       Object JavaDoc keyOrNull;
466       while(null != (keyOrNull = s.readObject())) {
467     String JavaDoc key = ((String JavaDoc)keyOrNull).intern();
468
469     if (actionListenerK == key)
470       addActionListener((ActionListener)(s.readObject()));
471
472     else // skip value for unrecognized key
473
s.readObject();
474       }
475     }
476
477
478 /////////////////
479
// Accessibility support
480
////////////////
481

482     /**
483      * Gets the <code>AccessibleContext</code> associated with
484      * this <code>Button</code>. For buttons, the
485      * <code>AccessibleContext</code> takes the form of an
486      * <code>AccessibleAWTButton</code>.
487      * A new <code>AccessibleAWTButton</code> instance is
488      * created if necessary.
489      *
490      * @return an <code>AccessibleAWTButton</code> that serves as the
491      * <code>AccessibleContext</code> of this <code>Button</code>
492      * @beaninfo
493      * expert: true
494      * description: The AccessibleContext associated with this Button.
495      */

496     public AccessibleContext getAccessibleContext() {
497         if (accessibleContext == null) {
498             accessibleContext = new AccessibleAWTButton();
499         }
500         return accessibleContext;
501     }
502
503     /**
504      * This class implements accessibility support for the
505      * <code>Button</code> class. It provides an implementation of the
506      * Java Accessibility API appropriate to button user-interface elements.
507      */

508     protected class AccessibleAWTButton extends AccessibleAWTComponent
509         implements AccessibleAction, AccessibleValue
510     {
511         /*
512          * JDK 1.3 serialVersionUID
513          */

514         private static final long serialVersionUID = -5932203980244017102L;
515
516         /**
517          * Get the accessible name of this object.
518          *
519          * @return the localized name of the object -- can be null if this
520          * object does not have a name
521          */

522         public String JavaDoc getAccessibleName() {
523             if (accessibleName != null) {
524                 return accessibleName;
525             } else {
526                 if (getLabel() == null) {
527                     return super.getAccessibleName();
528                 } else {
529                     return getLabel();
530                 }
531             }
532         }
533
534         /**
535          * Get the AccessibleAction associated with this object. In the
536          * implementation of the Java Accessibility API for this class,
537      * return this object, which is responsible for implementing the
538          * AccessibleAction interface on behalf of itself.
539      *
540      * @return this object
541          */

542         public AccessibleAction getAccessibleAction() {
543             return this;
544         }
545
546         /**
547          * Get the AccessibleValue associated with this object. In the
548          * implementation of the Java Accessibility API for this class,
549      * return this object, which is responsible for implementing the
550          * AccessibleValue interface on behalf of itself.
551      *
552      * @return this object
553          */

554         public AccessibleValue getAccessibleValue() {
555             return this;
556         }
557
558         /**
559          * Returns the number of Actions available in this object. The
560          * default behavior of a button is to have one action - toggle
561          * the button.
562          *
563          * @return 1, the number of Actions in this object
564          */

565         public int getAccessibleActionCount() {
566             return 1;
567         }
568     
569         /**
570          * Return a description of the specified action of the object.
571          *
572          * @param i zero-based index of the actions
573          */

574         public String JavaDoc getAccessibleActionDescription(int i) {
575             if (i == 0) {
576                 // [[[PENDING: WDW -- need to provide a localized string]]]
577
return new String JavaDoc("click");
578             } else {
579                 return null;
580             }
581         }
582     
583         /**
584          * Perform the specified Action on the object
585          *
586          * @param i zero-based index of actions
587          * @return true if the the action was performed; else false.
588          */

589         public boolean doAccessibleAction(int i) {
590             if (i == 0) {
591                 // Simulate a button click
592
Toolkit.getEventQueue().postEvent(
593                         new ActionEvent(Button.this,
594                                         ActionEvent.ACTION_PERFORMED,
595                                         Button.this.getActionCommand()));
596                 return true;
597             } else {
598                 return false;
599             }
600         }
601
602         /**
603          * Get the value of this object as a Number.
604          *
605          * @return An Integer of 0 if this isn't selected or an Integer of 1 if
606          * this is selected.
607          * @see javax.swing.AbstractButton#isSelected()
608          */

609         public Number JavaDoc getCurrentAccessibleValue() {
610             return new Integer JavaDoc(0);
611         }
612
613         /**
614          * Set the value of this object as a Number.
615          *
616          * @return True if the value was set.
617          */

618         public boolean setCurrentAccessibleValue(Number JavaDoc n) {
619             return false;
620         }
621
622         /**
623          * Get the minimum value of this object as a Number.
624          *
625          * @return An Integer of 0.
626          */

627         public Number JavaDoc getMinimumAccessibleValue() {
628             return new Integer JavaDoc(0);
629         }
630
631         /**
632          * Get the maximum value of this object as a Number.
633          *
634          * @return An Integer of 0.
635          */

636         public Number JavaDoc getMaximumAccessibleValue() {
637             return new Integer JavaDoc(0);
638         }
639
640         /**
641          * Get the role of this object.
642          *
643          * @return an instance of AccessibleRole describing the role of the
644          * object
645          * @see AccessibleRole
646          */

647         public AccessibleRole getAccessibleRole() {
648             return AccessibleRole.PUSH_BUTTON;
649         }
650     } // inner class AccessibleAWTButton
651

652 }
653
Popular Tags