KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > help > internal > workingset > PropertyChange


1 /*******************************************************************************
2  * Copyright (c) 2000, 2004 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Common Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/cpl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.help.internal.workingset;
12
13 import java.util.*;
14
15 /**
16  * Utility classes copied from the org.eclipse.core.runtime.Preferences class.
17  */

18 public class PropertyChange {
19
20     /**
21      * Listener for property changes.
22      * <p>
23      * Usage:
24      *
25      * <pre>
26      *
27      *
28      *
29      *
30      *
31      * Preferences.IPropertyChangeListener listener =
32      * new Preferences.IPropertyChangeListener() {
33      * public void propertyChange(Preferences.PropertyChangeEvent event) {
34      * ... // code to deal with occurrence of property change
35      * }
36      * };
37      * emitter.addPropertyChangeListener(listener);
38      * ...
39      * emitter.removePropertyChangeListener(listener);
40      *
41      *
42      *
43      *
44      *
45      * </pre>
46      *
47      * </p>
48      */

49     public interface IPropertyChangeListener extends EventListener {
50
51         /**
52          * Notification that a property has changed.
53          * <p>
54          * This method gets called when the observed object fires a property
55          * change event.
56          * </p>
57          *
58          * @param event
59          * the property change event object describing which property
60          * changed and how
61          */

62         public void propertyChange(PropertyChangeEvent event);
63     }
64
65     /**
66      * An event object describing a change to a named property.
67      * <p>
68      * The preferences object reports property change events for internal state
69      * changes that may be of interest to external parties. A special listener
70      * interface (<code>Preferences.IPropertyChangeListener</code>) is
71      * defined for this purpose. Listeners are registered via the
72      * <code>Preferences.addPropertyChangeListener</code> method.
73      * </p>
74      * <p>
75      * Clients cannot instantiate or subclass this class.
76      * </p>
77      *
78      * @see WorkingSetManager#addPropertyChangeListener
79      * @see PropertyChange.IPropertyChangeListener
80      */

81     public static class PropertyChangeEvent extends EventObject {
82
83         /**
84          * The name of the changed property.
85          */

86         private String JavaDoc propertyName;
87
88         /**
89          * The old value of the changed property, or <code>null</code> if not
90          * known or not relevant.
91          */

92         private Object JavaDoc oldValue;
93
94         /**
95          * The new value of the changed property, or <code>null</code> if not
96          * known or not relevant.
97          */

98         private Object JavaDoc newValue;
99
100         /**
101          * Creates a new property change event.
102          *
103          * @param source
104          * the object whose property has changed
105          * @param property
106          * the property that has changed (must not be
107          * <code>null</code>)
108          * @param oldValue
109          * the old value of the property, or <code>null</code> if
110          * none
111          * @param newValue
112          * the new value of the property, or <code>null</code> if
113          * none
114          */

115         PropertyChangeEvent(Object JavaDoc source, String JavaDoc property, Object JavaDoc oldValue,
116                 Object JavaDoc newValue) {
117
118             super(source);
119             if (property == null) {
120                 throw new IllegalArgumentException JavaDoc();
121             }
122             this.propertyName = property;
123             this.oldValue = oldValue;
124             this.newValue = newValue;
125         }
126
127         /**
128          * Returns the name of the property that changed.
129          * <p>
130          * Warning: there is no guarantee that the property name returned is a
131          * constant string. Callers must compare property names using
132          * <code>equals</code>, not ==.
133          * </p>
134          *
135          * @return the name of the property that changed
136          */

137         public String JavaDoc getProperty() {
138             return propertyName;
139         }
140
141         /**
142          * Returns the new value of the property.
143          *
144          * @return the new value, or <code>null</code> if not known or not
145          * relevant
146          */

147         public Object JavaDoc getNewValue() {
148             return newValue;
149         }
150
151         /**
152          * Returns the old value of the property.
153          *
154          * @return the old value, or <code>null</code> if not known or not
155          * relevant
156          */

157         public Object JavaDoc getOldValue() {
158             return oldValue;
159         }
160     }
161
162     /**
163      * Internal class is used to maintain a list of listeners. It is a fairly
164      * lightweight object, occupying minimal space when no listeners are
165      * registered.
166      * <p>
167      * Note that the <code>add</code> method checks for and eliminates
168      * duplicates based on identity (not equality). Likewise, the
169      * <code>remove</code> method compares based on identity.
170      * </p>
171      * <p>
172      * Use the <code>getListeners</code> method when notifying listeners. Note
173      * that no garbage is created if no listeners are registered. The
174      * recommended code sequence for notifying all registered listeners of say,
175      * <code>FooListener.eventHappened</code>, is:
176      *
177      * <pre>
178      * Object[] listeners = myListenerList.getListeners();
179      * for (int i = 0; i &lt; listeners.length; ++i) {
180      * ((FooListener) listeners[i]).eventHappened(event);
181      * }
182      * </pre>
183      *
184      * </p>
185      */

186     public static class ListenerList {
187         /**
188          * The initial capacity of the list. Always >= 1.
189          */

190         private int capacity;
191
192         /**
193          * The current number of listeners. Maintains invariant: 0 <= size <=
194          * listeners.length.
195          */

196         private int size;
197
198         /**
199          * The list of listeners. Initially <code>null</code> but initialized
200          * to an array of size capacity the first time a listener is added.
201          * Maintains invariant: listeners != null IFF size != 0
202          */

203         private Object JavaDoc[] listeners = null;
204
205         /**
206          * The empty array singleton instance, returned by getListeners() when
207          * size == 0.
208          */

209         private static final Object JavaDoc[] EmptyArray = new Object JavaDoc[0];
210
211         /**
212          * Creates a listener list with an initial capacity of 3.
213          */

214         public ListenerList() {
215             this(3);
216         }
217
218         /**
219          * Creates a listener list with the given initial capacity.
220          *
221          * @param capacity
222          * the number of listeners which this list can initially
223          * accept without growing its internal representation; must
224          * be at least 1
225          */

226         public ListenerList(int capacity) {
227             if (capacity < 1) {
228                 throw new IllegalArgumentException JavaDoc();
229             }
230             this.capacity = capacity;
231         }
232
233         /**
234          * Adds the given listener to this list. Has no effect if an identical
235          * listener is already registered.
236          *
237          * @param listener
238          * the listener
239          */

240         public void add(Object JavaDoc listener) {
241             if (listener == null) {
242                 throw new IllegalArgumentException JavaDoc();
243             }
244             if (size == 0) {
245                 listeners = new Object JavaDoc[capacity];
246             } else {
247                 // check for duplicates using identity
248
for (int i = 0; i < size; ++i) {
249                     if (listeners[i] == listener) {
250                         return;
251                     }
252                 }
253                 // grow array if necessary
254
if (size == listeners.length) {
255                     System.arraycopy(listeners, 0,
256                             listeners = new Object JavaDoc[size * 2 + 1], 0, size);
257                 }
258             }
259             listeners[size++] = listener;
260         }
261
262         /**
263          * Returns an array containing all the registered listeners. The
264          * resulting array is unaffected by subsequent adds or removes. If there
265          * are no listeners registered, the result is an empty array singleton
266          * instance (no garbage is created). Use this method when notifying
267          * listeners, so that any modifications to the listener list during the
268          * notification will have no effect on the notification itself.
269          *
270          * @return the list of registered listeners
271          */

272         public Object JavaDoc[] getListeners() {
273             if (size == 0)
274                 return EmptyArray;
275             Object JavaDoc[] result = new Object JavaDoc[size];
276             System.arraycopy(listeners, 0, result, 0, size);
277             return result;
278         }
279
280         /**
281          * Returns whether this listener list is empty.
282          *
283          * @return <code>true</code> if there are no registered listeners, and
284          * <code>false</code> otherwise
285          */

286         public boolean isEmpty() {
287             return size == 0;
288         }
289
290         /**
291          * Removes the given listener from this list. Has no effect if an
292          * identical listener was not already registered.
293          *
294          * @param listener
295          * the listener
296          */

297         public void remove(Object JavaDoc listener) {
298             if (listener == null) {
299                 throw new IllegalArgumentException JavaDoc();
300             }
301             for (int i = 0; i < size; ++i) {
302                 if (listeners[i] == listener) {
303                     if (size == 1) {
304                         listeners = null;
305                         size = 0;
306                     } else {
307                         System.arraycopy(listeners, i + 1, listeners, i, --size
308                                 - i);
309                         listeners[size] = null;
310                     }
311                     return;
312                 }
313             }
314         }
315
316         /**
317          * Returns the number of registered listeners.
318          *
319          * @return the number of registered listeners
320          */

321         public int size() {
322             return size;
323         }
324     }
325 }
326
Popular Tags