History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/javax/swing/AbstractAction.java (1 of 18352 files). Show all

Unified · Split

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