001: /*
002: * Sun Public License Notice
003: *
004: * The contents of this file are subject to the Sun Public License
005: * Version 1.0 (the "License"). You may not use this file except in
006: * compliance with the License. A copy of the License is available at
007: * http://www.sun.com/
008: *
009: * The Original Code is NetBeans. The Initial Developer of the Original
010: * Code is Sun Microsystems, Inc. Portions Copyright 1997-2000 Sun
011: * Microsystems, Inc. All Rights Reserved.
012: */
013:
014: package org.netbeans.editor;
015:
016: import java.beans.PropertyChangeEvent;
017: import java.beans.PropertyChangeListener;
018: import java.lang.ref.WeakReference;
019: import java.util.ArrayList;
020:
021: /**
022: * Similair functionality as PropertyChangeSupport but holds only weak
023: * references to listener classes
024: *
025: * @author Miloslav Metelka
026: * @version 1.00
027: */
028:
029: public class WeakPropertyChangeSupport {
030:
031: private transient ArrayList listeners = new ArrayList();
032:
033: private transient ArrayList interestNames = new ArrayList();
034:
035: /**
036: * Add weak listener to listen to change of any property. The caller must
037: * hold the listener object in some instance variable to prevent it from
038: * being garbage collected.
039: */
040: public synchronized void addPropertyChangeListener(
041: PropertyChangeListener l) {
042: addLImpl(null, l);
043: }
044:
045: /**
046: * Add weak listener to listen to change of the specified property. The
047: * caller must hold the listener object in some instance variable to prevent
048: * it from being garbage collected.
049: */
050: public synchronized void addPropertyChangeListener(
051: String propertyName, PropertyChangeListener l) {
052: addLImpl(propertyName, l);
053: }
054:
055: /** Remove listener for changes in properties */
056: public synchronized void removePropertyChangeListener(
057: PropertyChangeListener l) {
058: int cnt = listeners.size();
059: for (int i = 0; i < cnt; i++) {
060: Object o = ((WeakReference) listeners.get(i)).get();
061: if (o == null || o == l) { // remove null references and the
062: // required one
063: listeners.remove(i);
064: interestNames.remove(i);
065: i--;
066: cnt--;
067: }
068: }
069: }
070:
071: public void firePropertyChange(Object source, String propertyName,
072: Object oldValue, Object newValue) {
073: if (oldValue != null && newValue != null
074: && oldValue.equals(newValue)) {
075: return;
076: }
077: PropertyChangeListener la[];
078: String isa[];
079: int cnt;
080: synchronized (this ) {
081: cnt = listeners.size();
082: la = new PropertyChangeListener[cnt];
083: for (int i = 0; i < cnt; i++) {
084: PropertyChangeListener l = (PropertyChangeListener) ((WeakReference) listeners
085: .get(i)).get();
086: if (l == null) { // remove null references
087: listeners.remove(i);
088: interestNames.remove(i);
089: i--;
090: cnt--;
091: } else {
092: la[i] = l;
093: }
094: }
095: isa = (String[]) interestNames.toArray(new String[cnt]);
096: }
097:
098: // now create and fire the event
099: PropertyChangeEvent evt = new PropertyChangeEvent(source,
100: propertyName, oldValue, newValue);
101: for (int i = 0; i < cnt; i++) {
102: if (isa[i] == null || propertyName == null
103: || isa[i].equals(propertyName)) {
104: la[i].propertyChange(evt);
105: }
106: }
107: }
108:
109: private void addLImpl(String sn, PropertyChangeListener l) {
110: listeners.add(new WeakReference(l));
111: interestNames.add(sn);
112: }
113:
114: }
|