Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.desktop/share/classes/javax/swing/AbstractAction.java
41153 views
1
/*
2
* Copyright (c) 1997, 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 javax.swing;
27
28
import java.beans.PropertyChangeEvent;
29
import java.beans.PropertyChangeListener;
30
import java.io.IOException;
31
import java.io.ObjectInputStream;
32
import java.io.ObjectOutputStream;
33
import java.io.Serial;
34
import java.io.Serializable;
35
import java.security.AccessController;
36
37
import javax.swing.event.SwingPropertyChangeSupport;
38
39
import sun.security.action.GetPropertyAction;
40
41
/**
42
* This class provides default implementations for the JFC <code>Action</code>
43
* interface. Standard behaviors like the get and set methods for
44
* <code>Action</code> object properties (icon, text, and enabled) are defined
45
* here. The developer need only subclass this abstract class and
46
* define the <code>actionPerformed</code> method.
47
* <p>
48
* <strong>Warning:</strong>
49
* Serialized objects of this class will not be compatible with
50
* future Swing releases. The current serialization support is
51
* appropriate for short term storage or RMI between applications running
52
* the same version of Swing. As of 1.4, support for long term storage
53
* of all JavaBeans
54
* has been added to the <code>java.beans</code> package.
55
* Please see {@link java.beans.XMLEncoder}.
56
*
57
* @author Georges Saab
58
* @see Action
59
* @since 1.2
60
*/
61
@SuppressWarnings("serial") // Same-version serialization only
62
public abstract class AbstractAction implements Action, Cloneable, Serializable
63
{
64
/**
65
* Whether or not actions should reconfigure all properties on null.
66
*/
67
private static Boolean RECONFIGURE_ON_NULL;
68
69
/**
70
* Specifies whether action is enabled; the default is true.
71
*/
72
protected boolean enabled = true;
73
74
75
/**
76
* Contains the array of key bindings.
77
*/
78
private transient ArrayTable arrayTable;
79
80
/**
81
* Whether or not to reconfigure all action properties from the
82
* specified event.
83
*/
84
@SuppressWarnings("removal")
85
static boolean shouldReconfigure(PropertyChangeEvent e) {
86
if (e.getPropertyName() == null) {
87
synchronized(AbstractAction.class) {
88
if (RECONFIGURE_ON_NULL == null) {
89
RECONFIGURE_ON_NULL = Boolean.valueOf(
90
AccessController.doPrivileged(new GetPropertyAction(
91
"swing.actions.reconfigureOnNull", "false")));
92
}
93
return RECONFIGURE_ON_NULL;
94
}
95
}
96
return false;
97
}
98
99
/**
100
* Sets the enabled state of a component from an Action.
101
*
102
* @param c the Component to set the enabled state on
103
* @param a the Action to set the enabled state from, may be null
104
*/
105
static void setEnabledFromAction(JComponent c, Action a) {
106
c.setEnabled((a != null) ? a.isEnabled() : true);
107
}
108
109
/**
110
* Sets the tooltip text of a component from an Action.
111
*
112
* @param c the Component to set the tooltip text on
113
* @param a the Action to set the tooltip text from, may be null
114
*/
115
static void setToolTipTextFromAction(JComponent c, Action a) {
116
c.setToolTipText(a != null ?
117
(String)a.getValue(Action.SHORT_DESCRIPTION) : null);
118
}
119
120
static boolean hasSelectedKey(Action a) {
121
return (a != null && a.getValue(Action.SELECTED_KEY) != null);
122
}
123
124
static boolean isSelected(Action a) {
125
return Boolean.TRUE.equals(a.getValue(Action.SELECTED_KEY));
126
}
127
128
129
130
/**
131
* Creates an {@code Action}.
132
*/
133
public AbstractAction() {
134
}
135
136
/**
137
* Creates an {@code Action} with the specified name.
138
*
139
* @param name the name ({@code Action.NAME}) for the action; a
140
* value of {@code null} is ignored
141
*/
142
public AbstractAction(String name) {
143
putValue(Action.NAME, name);
144
}
145
146
/**
147
* Creates an {@code Action} with the specified name and small icon.
148
*
149
* @param name the name ({@code Action.NAME}) for the action; a
150
* value of {@code null} is ignored
151
* @param icon the small icon ({@code Action.SMALL_ICON}) for the action; a
152
* value of {@code null} is ignored
153
*/
154
public AbstractAction(String name, Icon icon) {
155
this(name);
156
putValue(Action.SMALL_ICON, icon);
157
}
158
159
/**
160
* Gets the <code>Object</code> associated with the specified key.
161
*
162
* @param key a string containing the specified <code>key</code>
163
* @return the binding <code>Object</code> stored with this key; if there
164
* are no keys, it will return <code>null</code>
165
* @see Action#getValue
166
*/
167
public Object getValue(String key) {
168
if (key == "enabled") {
169
return enabled;
170
}
171
if (arrayTable == null) {
172
return null;
173
}
174
return arrayTable.get(key);
175
}
176
177
/**
178
* Sets the <code>Value</code> associated with the specified key.
179
*
180
* @param key the <code>String</code> that identifies the stored object
181
* @param newValue the <code>Object</code> to store using this key
182
* @see Action#putValue
183
*/
184
public void putValue(String key, Object newValue) {
185
Object oldValue = null;
186
if (key == "enabled") {
187
// Treat putValue("enabled") the same way as a call to setEnabled.
188
// If we don't do this it means the two may get out of sync, and a
189
// bogus property change notification would be sent.
190
//
191
// To avoid dependencies between putValue & setEnabled this
192
// directly changes enabled. If we instead called setEnabled
193
// to change enabled, it would be possible for stack
194
// overflow in the case where a developer implemented setEnabled
195
// in terms of putValue.
196
if (newValue == null || !(newValue instanceof Boolean)) {
197
newValue = false;
198
}
199
oldValue = enabled;
200
enabled = (Boolean)newValue;
201
} else {
202
if (arrayTable == null) {
203
arrayTable = new ArrayTable();
204
}
205
if (arrayTable.containsKey(key))
206
oldValue = arrayTable.get(key);
207
// Remove the entry for key if newValue is null
208
// else put in the newValue for key.
209
if (newValue == null) {
210
arrayTable.remove(key);
211
} else {
212
arrayTable.put(key,newValue);
213
}
214
}
215
firePropertyChange(key, oldValue, newValue);
216
}
217
218
/**
219
* Returns true if the action is enabled.
220
*
221
* @return true if the action is enabled, false otherwise
222
* @see Action#isEnabled
223
*/
224
public boolean isEnabled() {
225
return enabled;
226
}
227
228
/**
229
* Sets whether the {@code Action} is enabled. The default is {@code true}.
230
*
231
* @param newValue {@code true} to enable the action, {@code false} to
232
* disable it
233
* @see Action#setEnabled
234
*/
235
public void setEnabled(boolean newValue) {
236
boolean oldValue = this.enabled;
237
238
if (oldValue != newValue) {
239
this.enabled = newValue;
240
firePropertyChange("enabled",
241
Boolean.valueOf(oldValue), Boolean.valueOf(newValue));
242
}
243
}
244
245
246
/**
247
* Returns an array of <code>Object</code>s which are keys for
248
* which values have been set for this <code>AbstractAction</code>,
249
* or <code>null</code> if no keys have values set.
250
* @return an array of key objects, or <code>null</code> if no
251
* keys have values set
252
* @since 1.3
253
*/
254
public Object[] getKeys() {
255
if (arrayTable == null) {
256
return null;
257
}
258
Object[] keys = new Object[arrayTable.size()];
259
arrayTable.getKeys(keys);
260
return keys;
261
}
262
263
/**
264
* If any <code>PropertyChangeListeners</code> have been registered, the
265
* <code>changeSupport</code> field describes them.
266
*/
267
protected SwingPropertyChangeSupport changeSupport;
268
269
/**
270
* Supports reporting bound property changes. This method can be called
271
* when a bound property has changed and it will send the appropriate
272
* <code>PropertyChangeEvent</code> to any registered
273
* <code>PropertyChangeListeners</code>.
274
*
275
* @param propertyName the name of the property that has changed
276
* @param oldValue the old value of the property
277
* @param newValue the new value of the property
278
*/
279
protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) {
280
if (changeSupport == null ||
281
(oldValue != null && newValue != null && oldValue.equals(newValue))) {
282
return;
283
}
284
changeSupport.firePropertyChange(propertyName, oldValue, newValue);
285
}
286
287
288
/**
289
* Adds a <code>PropertyChangeListener</code> to the listener list.
290
* The listener is registered for all properties.
291
* <p>
292
* A <code>PropertyChangeEvent</code> will get fired in response to setting
293
* a bound property, e.g. <code>setFont</code>, <code>setBackground</code>,
294
* or <code>setForeground</code>.
295
* Note that if the current component is inheriting its foreground,
296
* background, or font from its container, then no event will be
297
* fired in response to a change in the inherited property.
298
*
299
* @param listener The <code>PropertyChangeListener</code> to be added
300
*
301
* @see Action#addPropertyChangeListener
302
*/
303
public synchronized void addPropertyChangeListener(PropertyChangeListener listener) {
304
if (changeSupport == null) {
305
changeSupport = new SwingPropertyChangeSupport(this);
306
}
307
changeSupport.addPropertyChangeListener(listener);
308
}
309
310
311
/**
312
* Removes a <code>PropertyChangeListener</code> from the listener list.
313
* This removes a <code>PropertyChangeListener</code> that was registered
314
* for all properties.
315
*
316
* @param listener the <code>PropertyChangeListener</code> to be removed
317
*
318
* @see Action#removePropertyChangeListener
319
*/
320
public synchronized void removePropertyChangeListener(PropertyChangeListener listener) {
321
if (changeSupport == null) {
322
return;
323
}
324
changeSupport.removePropertyChangeListener(listener);
325
}
326
327
328
/**
329
* Returns an array of all the <code>PropertyChangeListener</code>s added
330
* to this AbstractAction with addPropertyChangeListener().
331
*
332
* @return all of the <code>PropertyChangeListener</code>s added or an empty
333
* array if no listeners have been added
334
* @since 1.4
335
*/
336
public synchronized PropertyChangeListener[] getPropertyChangeListeners() {
337
if (changeSupport == null) {
338
return new PropertyChangeListener[0];
339
}
340
return changeSupport.getPropertyChangeListeners();
341
}
342
343
344
/**
345
* Clones the abstract action. This gives the clone
346
* its own copy of the key/value list,
347
* which is not handled for you by <code>Object.clone()</code>.
348
**/
349
350
protected Object clone() throws CloneNotSupportedException {
351
AbstractAction newAction = (AbstractAction)super.clone();
352
synchronized(this) {
353
if (arrayTable != null) {
354
newAction.arrayTable = (ArrayTable)arrayTable.clone();
355
}
356
}
357
return newAction;
358
}
359
360
@Serial
361
private void writeObject(ObjectOutputStream s) throws IOException {
362
// Store the default fields
363
s.defaultWriteObject();
364
365
// And the keys
366
ArrayTable.writeArrayTable(s, arrayTable);
367
}
368
369
@Serial
370
private void readObject(ObjectInputStream s) throws ClassNotFoundException,
371
IOException {
372
s.defaultReadObject();
373
for (int counter = s.readInt() - 1; counter >= 0; counter--) {
374
putValue((String)s.readObject(), s.readObject());
375
}
376
}
377
}
378
379