This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

View | Details | Raw Unified | Return to bug 181073
Collapse All | Expand All

(-)a/editor.lib/src/org/netbeans/editor/BaseDocument.java (-7 / +29 lines)
Lines 54-59 Link Here
54
import java.io.IOException;
54
import java.io.IOException;
55
import java.beans.PropertyChangeListener;
55
import java.beans.PropertyChangeListener;
56
import java.beans.PropertyChangeEvent;
56
import java.beans.PropertyChangeEvent;
57
import java.beans.PropertyChangeSupport;
57
import java.util.EventListener;
58
import java.util.EventListener;
58
import java.util.HashMap;
59
import java.util.HashMap;
59
import java.util.HashSet;
60
import java.util.HashSet;
Lines 516-521 Link Here
516
        putProperty(MIME_TYPE_PROP, new MimeTypePropertyEvaluator(this));
517
        putProperty(MIME_TYPE_PROP, new MimeTypePropertyEvaluator(this));
517
        putProperty(VERSION_PROP, new AtomicLong());
518
        putProperty(VERSION_PROP, new AtomicLong());
518
        putProperty(LAST_MODIFICATION_TIMESTAMP_PROP, new AtomicLong());
519
        putProperty(LAST_MODIFICATION_TIMESTAMP_PROP, new AtomicLong());
520
        putProperty(PropertyChangeSupport.class, new PropertyChangeSupport(this));
519
521
520
        lineRootElement = new LineRootElement(this);
522
        lineRootElement = new LineRootElement(this);
521
523
Lines 2315-2320 Link Here
2315
2317
2316
    protected static class LazyPropertyMap extends Hashtable {
2318
    protected static class LazyPropertyMap extends Hashtable {
2317
2319
2320
        private PropertyChangeSupport pcs = null;
2321
2318
        protected LazyPropertyMap(Dictionary dict) {
2322
        protected LazyPropertyMap(Dictionary dict) {
2319
            super(5);
2323
            super(5);
2320
2324
Lines 2335-2348 Link Here
2335
        }
2339
        }
2336
2340
2337
        public @Override Object put(Object key, Object value) {
2341
        public @Override Object put(Object key, Object value) {
2338
            if (key != null) {
2342
             if (key == PropertyChangeSupport.class && value instanceof PropertyChangeSupport) {
2339
                Object val = super.get(key);
2343
                 pcs = (PropertyChangeSupport) value;
2340
                if (val instanceof PropertyHandler) {
2344
             }
2341
                    return ((PropertyHandler) val).setValue(value);
2342
                }
2343
            }
2344
2345
2345
            return super.put(key, value);
2346
             Object old = null;
2347
             boolean usePlainPut = true;
2348
2349
              if (key != null) {
2350
                  Object val = super.get(key);
2351
                  if (val instanceof PropertyHandler) {
2352
                     old = ((PropertyHandler) val).setValue(value);
2353
                     usePlainPut = false;
2354
                  }
2355
              }
2356
2357
             if (usePlainPut) {
2358
                 old = super.put(key, value);
2359
             }
2360
2361
             if (key instanceof String) {
2362
                 if (pcs != null) {
2363
                     pcs.firePropertyChange((String) key, old, value);
2364
                 }
2365
             }
2366
2367
             return old;
2346
        }
2368
        }
2347
    } // End of LazyPropertyMap class
2369
    } // End of LazyPropertyMap class
2348
2370
(-)a/editor.lib/test/unit/src/org/netbeans/editor/BaseDocumentTest.java (-3 / +32 lines)
Lines 27-32 Link Here
27
 */
27
 */
28
package org.netbeans.editor;
28
package org.netbeans.editor;
29
29
30
import java.beans.PropertyChangeEvent;
31
import java.beans.PropertyChangeListener;
32
import java.util.LinkedList;
33
import java.util.List;
30
import javax.swing.text.BadLocationException;
34
import javax.swing.text.BadLocationException;
31
import org.netbeans.junit.NbTestCase;
35
import org.netbeans.junit.NbTestCase;
32
import org.netbeans.lib.editor.util.swing.DocumentUtilities;
36
import org.netbeans.lib.editor.util.swing.DocumentUtilities;
Lines 58-64 Link Here
58
    public void testBreakAtomicLock() throws Exception {
62
    public void testBreakAtomicLock() throws Exception {
59
        final BaseDocument doc = new BaseDocument(false, "text/plain");
63
        final BaseDocument doc = new BaseDocument(false, "text/plain");
60
        doc.runAtomic(new Runnable() {
64
        doc.runAtomic(new Runnable() {
61
            public void run() {
65
            public @Override void run() {
62
                try {
66
                try {
63
                    doc.insertString(0, "test1", null);
67
                    doc.insertString(0, "test1", null);
64
                    doc.breakAtomicLock();
68
                    doc.breakAtomicLock();
Lines 70-76 Link Here
70
        boolean failure = false;
74
        boolean failure = false;
71
        try {
75
        try {
72
            doc.runAtomic(new Runnable() {
76
            doc.runAtomic(new Runnable() {
73
                public void run() {
77
                public @Override void run() {
74
                    throw new IllegalStateException("test");
78
                    throw new IllegalStateException("test");
75
                }
79
                }
76
            });
80
            });
Lines 82-88 Link Here
82
            throw new IllegalStateException("Unexpected");
86
            throw new IllegalStateException("Unexpected");
83
        }
87
        }
84
        doc.runAtomic(new Runnable() {
88
        doc.runAtomic(new Runnable() {
85
            public void run() {
89
            public @Override void run() {
86
                try {
90
                try {
87
                    doc.insertString(0, "test1", null);
91
                    doc.insertString(0, "test1", null);
88
                    doc.insertString(10, "test2", null);
92
                    doc.insertString(10, "test2", null);
Lines 93-96 Link Here
93
        });
97
        });
94
    }
98
    }
95
99
100
    public void testPropertyChangeEvents() {
101
        final List<PropertyChangeEvent> events = new LinkedList<PropertyChangeEvent>();
102
        final BaseDocument doc = new BaseDocument(false, "text/plain");
103
        final PropertyChangeListener l = new PropertyChangeListener() {
104
            public @Override void propertyChange(PropertyChangeEvent evt) {
105
                events.add(evt);
106
            }
107
        };
108
109
        DocumentUtilities.addPropertyChangeListener(doc, l);
110
        assertEquals("No events expected", 0, events.size());
111
112
        doc.putProperty("prop-A", "value-A");
113
        assertEquals("No event fired", 1, events.size());
114
        assertEquals("Wrong property name", "prop-A", events.get(0).getPropertyName());
115
        assertNull("Wrong old property value", events.get(0).getOldValue());
116
        assertEquals("Wrong new property value", "value-A", events.get(0).getNewValue());
117
118
        events.clear();
119
        DocumentUtilities.removePropertyChangeListener(doc, l);
120
        assertEquals("No events expected", 0, events.size());
121
122
        doc.putProperty("prop-B", "value-B");
123
        assertEquals("Expecting no events on removed listener", 0, events.size());
124
    }
96
}
125
}
(-)a/editor.util/apichanges.xml (+15 lines)
Lines 104-109 Link Here
104
104
105
  <changes>
105
  <changes>
106
106
107
    <change id="DocumentUtilities.document-property-listeners">
108
      <summary>Added support for document property listeners</summary>
109
        <version major="1" minor="35"/>
110
        <date day="23" month="2" year="2010"/>
111
        <author login="vstejskal"/>
112
        <compatibility addition="yes" deletion="no" modification="no" binary="compatible" semantic="compatible" />
113
        <description>
114
        <p>
115
            Adding <code>DocumentUtilities.addPropertyChangeListener(Document, PropertyChangeListener)</code>
116
            and <code>DocumentUtilities.removePropertyChangeListener(Document, PropertyChangeListener)</code> in order
117
            to support listening on document property changes.
118
        </p>
119
        </description>
120
    </change>
121
107
    <change id="DocumentUtilities.getDocumentTimestamp-added">
122
    <change id="DocumentUtilities.getDocumentTimestamp-added">
108
      <summary>Added DocumentUtilities.getDocumentTimestamp(Document)</summary>
123
      <summary>Added DocumentUtilities.getDocumentTimestamp(Document)</summary>
109
        <version major="1" minor="34"/>
124
        <version major="1" minor="34"/>
(-)a/editor.util/manifest.mf (-1 / +1 lines)
Lines 2-5 Link Here
2
OpenIDE-Module: org.netbeans.modules.editor.util/1
2
OpenIDE-Module: org.netbeans.modules.editor.util/1
3
OpenIDE-Module-Localizing-Bundle: org/netbeans/lib/editor/util/Bundle.properties
3
OpenIDE-Module-Localizing-Bundle: org/netbeans/lib/editor/util/Bundle.properties
4
AutoUpdate-Show-In-Client: false
4
AutoUpdate-Show-In-Client: false
5
OpenIDE-Module-Specification-Version: 1.34
5
OpenIDE-Module-Specification-Version: 1.35
(-)a/editor.util/src/org/netbeans/lib/editor/util/swing/DocumentUtilities.java (+41 lines)
Lines 41-46 Link Here
41
41
42
package org.netbeans.lib.editor.util.swing;
42
package org.netbeans.lib.editor.util.swing;
43
43
44
import java.beans.PropertyChangeListener;
45
import java.beans.PropertyChangeSupport;
44
import java.lang.reflect.Field;
46
import java.lang.reflect.Field;
45
import java.util.Map;
47
import java.util.Map;
46
import java.util.concurrent.atomic.AtomicLong;
48
import java.util.concurrent.atomic.AtomicLong;
Lines 898-901 Link Here
898
        Object version = doc.getProperty(LAST_MODIFICATION_TIMESTAMP_PROP);
900
        Object version = doc.getProperty(LAST_MODIFICATION_TIMESTAMP_PROP);
899
        return version instanceof AtomicLong ? ((AtomicLong) version).get() : 0;
901
        return version instanceof AtomicLong ? ((AtomicLong) version).get() : 0;
900
    }
902
    }
903
904
    /**
905
     * Adds <code>PropertyChangeListener</code> to a document.
906
     *
907
     * <p>In general, document properties are key-value pairs where both the key
908
     * and the value can be any <code>Object</code>. Contrary to that <code>PropertyChangeListener</code>s
909
     * can only handle named properties that can have an arbitrary value, but have <code>String</code> names.
910
     * Therefore the listenera attached to a document will only ever recieve document
911
     * properties, which keys are of <code>java.lang.String</code> type.
912
     *
913
     * <p>Additionally, the list of document properties that clients can listen on
914
     * is not part of this contract.
915
     *
916
     * @param doc The document to add the listener to.
917
     * @param l The listener to add to the document.
918
     *
919
     * @since 1.35
920
     */
921
    public static void addPropertyChangeListener(Document doc, PropertyChangeListener l) {
922
        PropertyChangeSupport pcs = (PropertyChangeSupport) doc.getProperty(PropertyChangeSupport.class);
923
        if (pcs != null) {
924
            pcs.addPropertyChangeListener(l);
925
        }
926
    }
927
928
    /**
929
     * Removes <code>PropertyChangeListener</code> from a document.
930
     *
931
     * @param doc The document to remove the listener from.
932
     * @param l The listener to remove from the document.
933
     *
934
     * @since 1.35
935
     */
936
    public static void removePropertyChangeListener(Document doc, PropertyChangeListener l) {
937
        PropertyChangeSupport pcs = (PropertyChangeSupport) doc.getProperty(PropertyChangeSupport.class);
938
        if (pcs != null) {
939
            pcs.removePropertyChangeListener(l);
940
        }
941
    }
901
}
942
}

Return to bug 181073