Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.desktop/share/classes/java/awt/Button.java
41152 views
1
/*
2
* Copyright (c) 1995, 2021, 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
26
package java.awt;
27
28
import java.awt.event.ActionEvent;
29
import java.awt.event.ActionListener;
30
import java.awt.peer.ButtonPeer;
31
import java.beans.BeanProperty;
32
import java.io.IOException;
33
import java.io.ObjectInputStream;
34
import java.io.ObjectOutputStream;
35
import java.io.Serial;
36
import java.util.EventListener;
37
38
import javax.accessibility.Accessible;
39
import javax.accessibility.AccessibleAction;
40
import javax.accessibility.AccessibleContext;
41
import javax.accessibility.AccessibleRole;
42
import javax.accessibility.AccessibleValue;
43
44
/**
45
* This class creates a labeled button. The application can cause
46
* some action to happen when the button is pushed. This image
47
* depicts three views of a "{@code Quit}" button as it appears
48
* under the Solaris operating system:
49
* <p>
50
* <img src="doc-files/Button-1.gif" alt="The following context describes the
51
* graphic" style="margin: 7px 10px;">
52
* <p>
53
* The first view shows the button as it appears normally.
54
* The second view shows the button
55
* when it has input focus. Its outline is darkened to let the
56
* user know that it is an active object. The third view shows the
57
* button when the user clicks the mouse over the button, and thus
58
* requests that an action be performed.
59
* <p>
60
* The gesture of clicking on a button with the mouse
61
* is associated with one instance of {@code ActionEvent},
62
* which is sent out when the mouse is both pressed and released
63
* over the button. If an application is interested in knowing
64
* when the button has been pressed but not released, as a separate
65
* gesture, it can specialize {@code processMouseEvent},
66
* or it can register itself as a listener for mouse events by
67
* calling {@code addMouseListener}. Both of these methods are
68
* defined by {@code Component}, the abstract superclass of
69
* all components.
70
* <p>
71
* When a button is pressed and released, AWT sends an instance
72
* of {@code ActionEvent} to the button, by calling
73
* {@code processEvent} on the button. The button's
74
* {@code processEvent} method receives all events
75
* for the button; it passes an action event along by
76
* calling its own {@code processActionEvent} method.
77
* The latter method passes the action event on to any action
78
* listeners that have registered an interest in action
79
* events generated by this button.
80
* <p>
81
* If an application wants to perform some action based on
82
* a button being pressed and released, it should implement
83
* {@code ActionListener} and register the new listener
84
* to receive events from this button, by calling the button's
85
* {@code addActionListener} method. The application can
86
* make use of the button's action command as a messaging protocol.
87
*
88
* @author Sami Shaio
89
* @see java.awt.event.ActionEvent
90
* @see java.awt.event.ActionListener
91
* @see java.awt.Component#processMouseEvent
92
* @see java.awt.Component#addMouseListener
93
* @since 1.0
94
*/
95
public class Button extends Component implements Accessible {
96
97
/**
98
* The button's label. This value may be null.
99
* @serial
100
* @see #getLabel()
101
* @see #setLabel(String)
102
*/
103
String label;
104
105
/**
106
* The action to be performed once a button has been
107
* pressed. This value may be null.
108
* @serial
109
* @see #getActionCommand()
110
* @see #setActionCommand(String)
111
*/
112
String actionCommand;
113
114
transient ActionListener actionListener;
115
116
private static final String base = "button";
117
private static int nameCounter = 0;
118
119
/**
120
* Use serialVersionUID from JDK 1.1 for interoperability.
121
*/
122
@Serial
123
private static final long serialVersionUID = -8774683716313001058L;
124
125
126
static {
127
/* ensure that the necessary native libraries are loaded */
128
Toolkit.loadLibraries();
129
if (!GraphicsEnvironment.isHeadless()) {
130
initIDs();
131
}
132
}
133
134
/**
135
* Initialize JNI field and method IDs for fields that may be
136
* accessed from C.
137
*/
138
private static native void initIDs();
139
140
/**
141
* Constructs a button with an empty string for its label.
142
*
143
* @exception HeadlessException if GraphicsEnvironment.isHeadless()
144
* returns true
145
* @see java.awt.GraphicsEnvironment#isHeadless
146
*/
147
public Button() throws HeadlessException {
148
this("");
149
}
150
151
/**
152
* Constructs a button with the specified label.
153
*
154
* @param label a string label for the button, or
155
* {@code null} for no label
156
* @exception HeadlessException if GraphicsEnvironment.isHeadless()
157
* returns true
158
* @see java.awt.GraphicsEnvironment#isHeadless
159
*/
160
public Button(String label) throws HeadlessException {
161
GraphicsEnvironment.checkHeadless();
162
this.label = label;
163
}
164
165
/**
166
* Construct a name for this component. Called by getName() when the
167
* name is null.
168
*/
169
String constructComponentName() {
170
synchronized (Button.class) {
171
return base + nameCounter++;
172
}
173
}
174
175
/**
176
* Creates the peer of the button. The button's peer allows the
177
* application to change the look of the button without changing
178
* its functionality.
179
*
180
* @see java.awt.Component#getToolkit()
181
*/
182
public void addNotify() {
183
synchronized(getTreeLock()) {
184
if (peer == null)
185
peer = getComponentFactory().createButton(this);
186
super.addNotify();
187
}
188
}
189
190
/**
191
* Gets the label of this button.
192
*
193
* @return the button's label, or {@code null}
194
* if the button has no label.
195
* @see java.awt.Button#setLabel
196
*/
197
public String getLabel() {
198
return label;
199
}
200
201
/**
202
* Sets the button's label to be the specified string.
203
*
204
* @param label the new label, or {@code null}
205
* if the button has no label.
206
* @see java.awt.Button#getLabel
207
*/
208
public void setLabel(String label) {
209
boolean testvalid = false;
210
211
synchronized (this) {
212
if (label != this.label && (this.label == null ||
213
!this.label.equals(label))) {
214
this.label = label;
215
ButtonPeer peer = (ButtonPeer)this.peer;
216
if (peer != null) {
217
peer.setLabel(label);
218
}
219
testvalid = true;
220
}
221
}
222
223
// This could change the preferred size of the Component.
224
if (testvalid) {
225
invalidateIfValid();
226
}
227
}
228
229
/**
230
* Sets the command name for the action event fired
231
* by this button. By default this action command is
232
* set to match the label of the button.
233
*
234
* @param command a string used to set the button's
235
* action command.
236
* If the string is {@code null} then the action command
237
* is set to match the label of the button.
238
* @see java.awt.event.ActionEvent
239
* @since 1.1
240
*/
241
public void setActionCommand(String command) {
242
actionCommand = command;
243
}
244
245
/**
246
* Returns the command name of the action event fired by this button.
247
* If the command name is {@code null} (default) then this method
248
* returns the label of the button.
249
*
250
* @return the action command name (or label) for this button
251
*/
252
public String getActionCommand() {
253
return (actionCommand == null? label : actionCommand);
254
}
255
256
/**
257
* Adds the specified action listener to receive action events from
258
* this button. Action events occur when a user presses or releases
259
* the mouse over this button.
260
* If l is null, no exception is thrown and no action is performed.
261
* <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
262
* >AWT Threading Issues</a> for details on AWT's threading model.
263
*
264
* @param l the action listener
265
* @see #removeActionListener
266
* @see #getActionListeners
267
* @see java.awt.event.ActionListener
268
* @since 1.1
269
*/
270
public synchronized void addActionListener(ActionListener l) {
271
if (l == null) {
272
return;
273
}
274
actionListener = AWTEventMulticaster.add(actionListener, l);
275
newEventsOnly = true;
276
}
277
278
/**
279
* Removes the specified action listener so that it no longer
280
* receives action events from this button. Action events occur
281
* when a user presses or releases the mouse over this button.
282
* If l is null, no exception is thrown and no action is performed.
283
* <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
284
* >AWT Threading Issues</a> for details on AWT's threading model.
285
*
286
* @param l the action listener
287
* @see #addActionListener
288
* @see #getActionListeners
289
* @see java.awt.event.ActionListener
290
* @since 1.1
291
*/
292
public synchronized void removeActionListener(ActionListener l) {
293
if (l == null) {
294
return;
295
}
296
actionListener = AWTEventMulticaster.remove(actionListener, l);
297
}
298
299
/**
300
* Returns an array of all the action listeners
301
* registered on this button.
302
*
303
* @return all of this button's {@code ActionListener}s
304
* or an empty array if no action
305
* listeners are currently registered
306
*
307
* @see #addActionListener
308
* @see #removeActionListener
309
* @see java.awt.event.ActionListener
310
* @since 1.4
311
*/
312
public synchronized ActionListener[] getActionListeners() {
313
return getListeners(ActionListener.class);
314
}
315
316
/**
317
* Returns an array of all the objects currently registered
318
* as <code><em>Foo</em>Listener</code>s
319
* upon this {@code Button}.
320
* <code><em>Foo</em>Listener</code>s are registered using the
321
* <code>add<em>Foo</em>Listener</code> method.
322
*
323
* <p>
324
* You can specify the {@code listenerType} argument
325
* with a class literal, such as
326
* <code><em>Foo</em>Listener.class</code>.
327
* For example, you can query a
328
* {@code Button b}
329
* for its action listeners with the following code:
330
*
331
* <pre>ActionListener[] als = (ActionListener[])(b.getListeners(ActionListener.class));</pre>
332
*
333
* If no such listeners exist, this method returns an empty array.
334
*
335
* @param listenerType the type of listeners requested; this parameter
336
* should specify an interface that descends from
337
* {@code java.util.EventListener}
338
* @return an array of all objects registered as
339
* <code><em>Foo</em>Listener</code>s on this button,
340
* or an empty array if no such
341
* listeners have been added
342
* @exception ClassCastException if {@code listenerType}
343
* doesn't specify a class or interface that implements
344
* {@code java.util.EventListener}
345
*
346
* @see #getActionListeners
347
* @since 1.3
348
*/
349
public <T extends EventListener> T[] getListeners(Class<T> listenerType) {
350
EventListener l = null;
351
if (listenerType == ActionListener.class) {
352
l = actionListener;
353
} else {
354
return super.getListeners(listenerType);
355
}
356
return AWTEventMulticaster.getListeners(l, listenerType);
357
}
358
359
// REMIND: remove when filtering is done at lower level
360
boolean eventEnabled(AWTEvent e) {
361
if (e.id == ActionEvent.ACTION_PERFORMED) {
362
if ((eventMask & AWTEvent.ACTION_EVENT_MASK) != 0 ||
363
actionListener != null) {
364
return true;
365
}
366
return false;
367
}
368
return super.eventEnabled(e);
369
}
370
371
/**
372
* Processes events on this button. If an event is
373
* an instance of {@code ActionEvent}, this method invokes
374
* the {@code processActionEvent} method. Otherwise,
375
* it invokes {@code processEvent} on the superclass.
376
* <p>Note that if the event parameter is {@code null}
377
* the behavior is unspecified and may result in an
378
* exception.
379
*
380
* @param e the event
381
* @see java.awt.event.ActionEvent
382
* @see java.awt.Button#processActionEvent
383
* @since 1.1
384
*/
385
protected void processEvent(AWTEvent e) {
386
if (e instanceof ActionEvent) {
387
processActionEvent((ActionEvent)e);
388
return;
389
}
390
super.processEvent(e);
391
}
392
393
/**
394
* Processes action events occurring on this button
395
* by dispatching them to any registered
396
* {@code ActionListener} objects.
397
* <p>
398
* This method is not called unless action events are
399
* enabled for this button. Action events are enabled
400
* when one of the following occurs:
401
* <ul>
402
* <li>An {@code ActionListener} object is registered
403
* via {@code addActionListener}.
404
* <li>Action events are enabled via {@code enableEvents}.
405
* </ul>
406
* <p>Note that if the event parameter is {@code null}
407
* the behavior is unspecified and may result in an
408
* exception.
409
*
410
* @param e the action event
411
* @see java.awt.event.ActionListener
412
* @see java.awt.Button#addActionListener
413
* @see java.awt.Component#enableEvents
414
* @since 1.1
415
*/
416
protected void processActionEvent(ActionEvent e) {
417
ActionListener listener = actionListener;
418
if (listener != null) {
419
listener.actionPerformed(e);
420
}
421
}
422
423
/**
424
* Returns a string representing the state of this {@code Button}.
425
* This method is intended to be used only for debugging purposes, and the
426
* content and format of the returned string may vary between
427
* implementations. The returned string may be empty but may not be
428
* {@code null}.
429
*
430
* @return the parameter string of this button
431
*/
432
protected String paramString() {
433
return super.paramString() + ",label=" + label;
434
}
435
436
437
/* Serialization support.
438
*/
439
/**
440
* Serialized data version.
441
* @serial
442
*/
443
private int buttonSerializedDataVersion = 1;
444
445
/**
446
* Writes default serializable fields to stream. Writes
447
* a list of serializable {@code ActionListeners}
448
* as optional data. The non-serializable
449
* {@code ActionListeners} are detected and
450
* no attempt is made to serialize them.
451
*
452
* @serialData {@code null} terminated sequence of 0 or
453
* more pairs: the pair consists of a {@code String}
454
* and an {@code Object}; the {@code String}
455
* indicates the type of object and is one of the following:
456
* {@code actionListenerK} indicating an
457
* {@code ActionListener} object
458
*
459
* @param s the {@code ObjectOutputStream} to write
460
* @throws IOException if an I/O error occurs
461
* @see AWTEventMulticaster#save(ObjectOutputStream, String, EventListener)
462
* @see java.awt.Component#actionListenerK
463
* @see #readObject(ObjectInputStream)
464
*/
465
@Serial
466
private void writeObject(ObjectOutputStream s)
467
throws IOException
468
{
469
s.defaultWriteObject();
470
471
AWTEventMulticaster.save(s, actionListenerK, actionListener);
472
s.writeObject(null);
473
}
474
475
/**
476
* Reads the {@code ObjectInputStream} and if
477
* it isn't {@code null} adds a listener to
478
* receive action events fired by the button.
479
* Unrecognized keys or values will be ignored.
480
*
481
* @param s the {@code ObjectInputStream} to read
482
* @throws ClassNotFoundException if the class of a serialized object could
483
* not be found
484
* @throws IOException if an I/O error occurs
485
* @throws HeadlessException if {@code GraphicsEnvironment.isHeadless()}
486
* returns {@code true}
487
* @serial
488
* @see #removeActionListener(ActionListener)
489
* @see #addActionListener(ActionListener)
490
* @see java.awt.GraphicsEnvironment#isHeadless
491
* @see #writeObject(ObjectOutputStream)
492
*/
493
@Serial
494
private void readObject(ObjectInputStream s)
495
throws ClassNotFoundException, IOException, HeadlessException
496
{
497
GraphicsEnvironment.checkHeadless();
498
s.defaultReadObject();
499
500
Object keyOrNull;
501
while(null != (keyOrNull = s.readObject())) {
502
String key = ((String)keyOrNull).intern();
503
504
if (actionListenerK == key)
505
addActionListener((ActionListener)(s.readObject()));
506
507
else // skip value for unrecognized key
508
s.readObject();
509
}
510
}
511
512
513
/////////////////
514
// Accessibility support
515
////////////////
516
517
/**
518
* Gets the {@code AccessibleContext} associated with
519
* this {@code Button}. For buttons, the
520
* {@code AccessibleContext} takes the form of an
521
* {@code AccessibleAWTButton}.
522
* A new {@code AccessibleAWTButton} instance is
523
* created if necessary.
524
*
525
* @return an {@code AccessibleAWTButton} that serves as the
526
* {@code AccessibleContext} of this {@code Button}
527
* @since 1.3
528
*/
529
@BeanProperty(expert = true, description
530
= "The AccessibleContext associated with this Button.")
531
public AccessibleContext getAccessibleContext() {
532
if (accessibleContext == null) {
533
accessibleContext = new AccessibleAWTButton();
534
}
535
return accessibleContext;
536
}
537
538
/**
539
* This class implements accessibility support for the
540
* {@code Button} class. It provides an implementation of the
541
* Java Accessibility API appropriate to button user-interface elements.
542
* @since 1.3
543
*/
544
protected class AccessibleAWTButton extends AccessibleAWTComponent
545
implements AccessibleAction, AccessibleValue
546
{
547
/**
548
* Use serialVersionUID from JDK 1.3 for interoperability.
549
*/
550
@Serial
551
private static final long serialVersionUID = -5932203980244017102L;
552
553
/**
554
* Constructs an {@code AccessibleAWTButton}.
555
*/
556
protected AccessibleAWTButton() {}
557
558
/**
559
* Get the accessible name of this object.
560
*
561
* @return the localized name of the object -- can be null if this
562
* object does not have a name
563
*/
564
public String getAccessibleName() {
565
if (accessibleName != null) {
566
return accessibleName;
567
} else {
568
if (getLabel() == null) {
569
return super.getAccessibleName();
570
} else {
571
return getLabel();
572
}
573
}
574
}
575
576
/**
577
* Get the AccessibleAction associated with this object. In the
578
* implementation of the Java Accessibility API for this class,
579
* return this object, which is responsible for implementing the
580
* AccessibleAction interface on behalf of itself.
581
*
582
* @return this object
583
*/
584
public AccessibleAction getAccessibleAction() {
585
return this;
586
}
587
588
/**
589
* Get the AccessibleValue associated with this object. In the
590
* implementation of the Java Accessibility API for this class,
591
* return this object, which is responsible for implementing the
592
* AccessibleValue interface on behalf of itself.
593
*
594
* @return this object
595
*/
596
public AccessibleValue getAccessibleValue() {
597
return this;
598
}
599
600
/**
601
* Returns the number of Actions available in this object. The
602
* default behavior of a button is to have one action - toggle
603
* the button.
604
*
605
* @return 1, the number of Actions in this object
606
*/
607
public int getAccessibleActionCount() {
608
return 1;
609
}
610
611
/**
612
* Return a description of the specified action of the object.
613
*
614
* @param i zero-based index of the actions
615
*/
616
public String getAccessibleActionDescription(int i) {
617
if (i == 0) {
618
// [[[PENDING: WDW -- need to provide a localized string]]]
619
return "click";
620
} else {
621
return null;
622
}
623
}
624
625
/**
626
* Perform the specified Action on the object
627
*
628
* @param i zero-based index of actions
629
* @return true if the action was performed; else false.
630
*/
631
public boolean doAccessibleAction(int i) {
632
if (i == 0) {
633
// Simulate a button click
634
Toolkit.getEventQueue().postEvent(
635
new ActionEvent(Button.this,
636
ActionEvent.ACTION_PERFORMED,
637
Button.this.getActionCommand()));
638
return true;
639
} else {
640
return false;
641
}
642
}
643
644
/**
645
* Get the value of this object as a Number.
646
*
647
* @return An Integer of 0 if this isn't selected or an Integer of 1 if
648
* this is selected.
649
* @see javax.swing.AbstractButton#isSelected()
650
*/
651
public Number getCurrentAccessibleValue() {
652
return Integer.valueOf(0);
653
}
654
655
/**
656
* Set the value of this object as a Number.
657
*
658
* @return True if the value was set.
659
*/
660
public boolean setCurrentAccessibleValue(Number n) {
661
return false;
662
}
663
664
/**
665
* Get the minimum value of this object as a Number.
666
*
667
* @return An Integer of 0.
668
*/
669
public Number getMinimumAccessibleValue() {
670
return Integer.valueOf(0);
671
}
672
673
/**
674
* Get the maximum value of this object as a Number.
675
*
676
* @return An Integer of 0.
677
*/
678
public Number getMaximumAccessibleValue() {
679
return Integer.valueOf(0);
680
}
681
682
/**
683
* Get the role of this object.
684
*
685
* @return an instance of AccessibleRole describing the role of the
686
* object
687
* @see AccessibleRole
688
*/
689
public AccessibleRole getAccessibleRole() {
690
return AccessibleRole.PUSH_BUTTON;
691
}
692
} // inner class AccessibleAWTButton
693
694
}
695
696