KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > javax > swing > ActionPropertyChangeListener


1 /*
2  * @(#)ActionPropertyChangeListener.java 1.15 06/02/09
3  *
4  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7 package javax.swing;
8
9 import java.beans.PropertyChangeEvent JavaDoc;
10 import java.beans.PropertyChangeListener JavaDoc;
11 import java.io.*;
12 import java.lang.ref.WeakReference JavaDoc;
13 import java.lang.ref.ReferenceQueue JavaDoc;
14
15 /**
16  * A package-private PropertyChangeListener which listens for
17  * property changes on an Action and updates the properties
18  * of an ActionEvent source.
19  * <p>
20  * Subclasses must override the actionPropertyChanged method,
21  * which is invoked from the propertyChange method as long as
22  * the target is still valid.
23  * </p>
24  * <p>
25  * WARNING WARNING WARNING WARNING WARNING WARNING:<br>
26  * Do NOT create an annonymous inner class that extends this! If you do
27  * a strong reference will be held to the containing class, which in most
28  * cases defeats the purpose of this class.
29  *
30  * @param T the type of JComponent the underlying Action is attached to
31  *
32  * @version 1.15 02/09/06
33  * @author Georges Saab
34  * @see AbstractButton
35  */

36 abstract class ActionPropertyChangeListener<T extends JComponent JavaDoc>
37         implements PropertyChangeListener JavaDoc, Serializable {
38     private static ReferenceQueue JavaDoc<JComponent JavaDoc> queue;
39
40     // WeakReference's aren't serializable.
41
private transient OwnedWeakReference<T> target;
42     // The Component's that reference an Action do so through a strong
43
// reference, so that there is no need to check for serialized.
44
private Action JavaDoc action;
45
46     private static ReferenceQueue JavaDoc<JComponent JavaDoc> getQueue() {
47         synchronized(ActionPropertyChangeListener JavaDoc.class) {
48             if (queue == null) {
49                 queue = new ReferenceQueue JavaDoc<JComponent JavaDoc>();
50             }
51         }
52         return queue;
53     }
54
55     public ActionPropertyChangeListener(T c, Action JavaDoc a) {
56     super();
57     setTarget(c);
58     this.action = a;
59     }
60
61     /**
62      * PropertyChangeListener method. If the target has been gc'ed this
63      * will remove the <code>PropertyChangeListener</code> from the Action,
64      * otherwise this will invoke actionPropertyChanged.
65      */

66     public final void propertyChange(PropertyChangeEvent JavaDoc e) {
67         T target = getTarget();
68         if (target == null) {
69             getAction().removePropertyChangeListener(this);
70         } else {
71             actionPropertyChanged(target, getAction(), e);
72         }
73     }
74
75     /**
76      * Invoked when a property changes on the Action and the target
77      * still exists.
78      */

79     protected abstract void actionPropertyChanged(T target, Action JavaDoc action,
80                                                   PropertyChangeEvent JavaDoc e);
81     
82     private void setTarget(T c) {
83         ReferenceQueue JavaDoc<JComponent JavaDoc> queue = getQueue();
84     // Check to see whether any old buttons have
85
// been enqueued for GC. If so, look up their
86
// PCL instance and remove it from its Action.
87
OwnedWeakReference r;
88         while ((r = (OwnedWeakReference)queue.poll()) != null) {
89             ActionPropertyChangeListener JavaDoc oldPCL = r.getOwner();
90         Action JavaDoc oldAction = oldPCL.getAction();
91         if (oldAction!=null) {
92             oldAction.removePropertyChangeListener(oldPCL);
93         }
94     }
95         this.target = new OwnedWeakReference<T>(c, queue, this);
96     }
97     
98     public T getTarget() {
99         if (target == null) {
100             // Will only happen if serialized and real target was null
101
return null;
102         }
103         return this.target.get();
104     }
105
106     public Action JavaDoc getAction() {
107       return action;
108     }
109
110     private void writeObject(ObjectOutputStream s) throws IOException {
111         s.defaultWriteObject();
112         s.writeObject(getTarget());
113     }
114
115     @SuppressWarnings JavaDoc("unchecked")
116     private void readObject(ObjectInputStream s)
117                      throws IOException, ClassNotFoundException JavaDoc {
118         s.defaultReadObject();
119         T target = (T)s.readObject();
120         if (target != null) {
121             setTarget(target);
122         }
123     }
124
125
126     private static class OwnedWeakReference<U extends JComponent JavaDoc> extends
127                               WeakReference JavaDoc<U> {
128         private ActionPropertyChangeListener JavaDoc owner;
129
130         OwnedWeakReference(U target, ReferenceQueue JavaDoc<? super U> queue,
131                            ActionPropertyChangeListener JavaDoc owner) {
132         super(target, queue);
133         this.owner = owner;
134     }
135
136         public ActionPropertyChangeListener JavaDoc getOwner() {
137         return owner;
138     }
139     }
140 }
141
Popular Tags