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 103235
Collapse All | Expand All

(-)lib2/apichanges.xml (+13 lines)
Lines 82-87 Link Here
82
82
83
    <changes>
83
    <changes>
84
84
85
        <change id="added-EditorRegistry">
86
            <summary>EditorRegistry added</summary>
87
            <version major="1" minor="4"/>
88
            <date day="4" month="6" year="2007"/>
89
            <author login="mmetelka"/>
90
            <compatibility binary="compatible" source="compatible" semantic="compatible" addition="yes"/>
91
            <description>
92
                The <code>EditorRegistry</code> allows to get focused and last focused text component
93
                and list of all registered components and it allows to listen for currently focused
94
                component and changes of documents in it.
95
            </description>
96
        </change>
97
85
        <change id="removed-AttributesUtilities">
98
        <change id="removed-AttributesUtilities">
86
            <summary>AttributesUtilities removed</summary>
99
            <summary>AttributesUtilities removed</summary>
87
            <version major="1" minor="3"/>
100
            <version major="1" minor="3"/>
(-)lib2/nbproject/project.xml (+1 lines)
Lines 111-116 Link Here
111
                </test-type>
111
                </test-type>
112
            </test-dependencies>
112
            </test-dependencies>
113
            <public-packages>
113
            <public-packages>
114
                <package>org.netbeans.api.editor</package>
114
                <package>org.netbeans.spi.editor.highlighting</package>
115
                <package>org.netbeans.spi.editor.highlighting</package>
115
                <package>org.netbeans.spi.editor.highlighting.support</package>
116
                <package>org.netbeans.spi.editor.highlighting.support</package>
116
            </public-packages>
117
            </public-packages>
(-)lib2/src/org/netbeans/api/editor/EditorRegistry.java (+363 lines)
Added Link Here
1
/*
2
 * The contents of this file are subject to the terms of the Common Development
3
 * and Distribution License (the License). You may not use this file except in
4
 * compliance with the License.
5
 *
6
 * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7
 * or http://www.netbeans.org/cddl.txt.
8
 *
9
 * When distributing Covered Code, include this CDDL Header Notice in each file
10
 * and include the License file at http://www.netbeans.org/cddl.txt.
11
 * If applicable, add the following below the CDDL Header, with the fields
12
 * enclosed by brackets [] replaced by your own identifying information:
13
 * "Portions Copyrighted [year] [name of copyright owner]"
14
 *
15
 * The Original Software is NetBeans. The Initial Developer of the Original
16
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17
 * Microsystems, Inc. All Rights Reserved.
18
 */
19
20
package org.netbeans.api.editor;
21
22
import java.awt.Component;
23
import java.awt.event.FocusEvent;
24
import java.awt.event.FocusListener;
25
import java.beans.PropertyChangeEvent;
26
import java.beans.PropertyChangeListener;
27
import java.beans.PropertyChangeSupport;
28
import java.lang.ref.WeakReference;
29
import java.util.ArrayList;
30
import java.util.Collections;
31
import java.util.List;
32
import java.util.logging.Level;
33
import java.util.logging.Logger;
34
import javax.swing.text.Document;
35
import javax.swing.text.JTextComponent;
36
import org.netbeans.lib.editor.util.ArrayUtilities;
37
38
/**
39
 * Registry maintaining {@link JTextComponent}s in most-recently-used order.
40
 * <br/>
41
 * The particular text component needs to register itself first (to avoid dealing
42
 * with all the JTextFields etc.). Then the registry will attach
43
 * a focus listener to the text component and once the component gains
44
 * the focus it will move to the head of the components list.
45
 * <br/>
46
 * The registry will also fire a change in case a document property
47
 * of the focused component changes (by calling component.setDocument()).
48
 *
49
 * @author Miloslav Metelka
50
 */
51
public class EditorRegistry {
52
    
53
    // -J-Dorg.netbeans.api.editor.EditorRegistry.level=FINEST
54
    private static final Logger LOG = Logger.getLogger(EditorRegistry.class.getName());
55
56
    /**
57
     * Fired when focus was delivered to a registered text component.
58
     * <br/>
59
     * The focused component will become the first in the components list.
60
     * <br/>
61
     * The {@link PropertyEvent#getOldValue()} will be the a component
62
     * losing the focus {@link FocusEvent#getOppositeComponent()}.
63
     * The {@link PropertyEvent#getNewValue()} will be the text component gaining the focus.
64
     */
65
    public static final String FOCUS_GAINED_PROPERTY = "focusGained";
66
    
67
    /**
68
     * Fired when a registered focused component has lost the focus.
69
     * <br/>
70
     * The focused component will remain the first in the components list.
71
     * <br/>
72
     * The {@link PropertyEvent#getOldValue()} will be the text component
73
     * losing the focus and the {@link PropertyEvent#getNewValue()}
74
     * will be the component gaining the focus {@link FocusEvent#getOppositeComponent()}.
75
     */
76
    public static final String FOCUS_LOST_PROPERTY = "focusLost";
77
    
78
    /**
79
     * Fired when document property of the focused component changes
80
     * i.e. someone has called {@link JTextComponent#setDocument(Document)}.
81
     * <br/>
82
     * The {@link PropertyEvent#getOldValue()} will be the original document
83
     * of the focused text component and the {@link PropertyEvent#getNewValue()}
84
     * will be the new document set to the focused text component.
85
     */
86
    public static final String FOCUSED_DOCUMENT_PROPERTY = "focusedDocument";
87
88
    /**
89
     * Double linked list of weak references to text components.
90
     */
91
    private static Item textComponentRefs;
92
    
93
    private static final PropertyChangeSupport pcs = new PropertyChangeSupport(EditorRegistry.class);
94
95
96
    /**
97
     * Return last focused text component (from the ones included in the registry).
98
     * <br/>
99
     * It may or may not currently have a focus.
100
     * 
101
     * @return last focused text component or null if no text components
102
     *  were registered yet.
103
     */
104
    public static synchronized JTextComponent lastFocusedComponent() {
105
        return firstValidComponent();
106
    }
107
    
108
    /**
109
     * Return the last focused component if it currently has a focus
110
     * or return null if none of the registered components currently have the focus.
111
     * <br/>
112
     * @return focused component or null if none of the registered components
113
     *  is currently focused.
114
     */
115
    public static synchronized JTextComponent focusedComponent() {
116
        JTextComponent c = firstValidComponent();
117
        return (c != null && c.isFocusOwner()) ? c : null;
118
    }
119
    
120
    /**
121
     * Get list of all components present in the registry starting with the most active
122
     * and ending with least active component.
123
     * <br/>
124
     * The list is a snapshot of the current state and it may be modified
125
     * by the caller if desired.
126
     * 
127
     * @return non-null list containing all the registered components in MRU order.
128
     */
129
    public static synchronized List<JTextComponent> componentList() {
130
        List<JTextComponent> l;
131
        JTextComponent c = firstValidComponent();
132
        if (c != null) {
133
            l = new ArrayList<JTextComponent>();
134
            l.add(c);
135
            // Add remaining ones (eliminate empty items)
136
            Item item = textComponentRefs.next;
137
            while (item != null) {
138
                c = item.get();
139
                if (c != null) {
140
                    l.add(c);
141
                    item = item.next;
142
                } else
143
                    item = removeItem(item);
144
            }
145
146
        } else // No valid items
147
            l = Collections.emptyList();
148
        return l;
149
    }
150
    
151
    /**
152
     * Add a given text component to the registry. The registry will weakly
153
     * reference the given component for its whole lifetime
154
     * until it will be garbage collected.
155
     * 
156
     * @param c non-null text component to be registered.
157
     */
158
    public static synchronized void register(JTextComponent c) {
159
        assert (c != null);
160
        if (c.getClientProperty(Item.class) == null) { // Not registered yet
161
            Item item = new Item(c);
162
            c.putClientProperty(Item.class, item);
163
            c.addFocusListener(FocusL.INSTANCE);
164
            // Add to end of list
165
            if (textComponentRefs == null)
166
                textComponentRefs = item;
167
            else {
168
                Item i = textComponentRefs;
169
                while (i.next != null)
170
                    i = i.next;
171
                i.next = item;
172
                item.previous = i;
173
            }
174
            if (LOG.isLoggable(Level.FINE)) {
175
                LOG.log(Level.FINE, "REGISTERED new component as last item:\n" + dumpItemList());
176
            }
177
178
            // If focused (rare since usually registered early when not focused yet)
179
            if (c.isFocusOwner()) {
180
                focusGained(c, null); // opposite could eventually be got from Focus Manager
181
            }
182
        }
183
    }
184
    
185
    /**
186
     * Add a property change listener for either of the following properties:
187
     * <ul>
188
     *   <li>{@link #FOCUS_GAINED_PROPERTY}</li>
189
     *   <li>{@link #FOCUS_LOST_PROPERTY}</li>
190
     *   <li>{@link #FOCUSED_DOCUMENT_PROPERTY}</li>
191
     * </ul>.
192
     * <br/>
193
     * All the firing should occur in AWT thread only
194
     * (assuming the JTextComponent.setDocument() is done properly in AWT).
195
     * 
196
     * @param l non-null listener to add.
197
     */
198
    public static void addPropertyChangeListener(PropertyChangeListener l) {
199
        pcs.addPropertyChangeListener(l);
200
    }
201
    
202
    public static void removePropertyChangeListener(PropertyChangeListener l) {
203
        pcs.removePropertyChangeListener(l);
204
    }
205
    
206
    static synchronized void focusGained(JTextComponent c, Component origFocused) {
207
        Item item = (Item)c.getClientProperty(Item.class);
208
        assert (item != null) : "Not registered!"; // NOI18N
209
        assert (item.next != null || item.previous != null || textComponentRefs == item)
210
                : "Already released!"; // NOI18N
211
        moveToHead(item);
212
        c.addPropertyChangeListener(PropertyDocL.INSTANCE);
213
        if (LOG.isLoggable(Level.FINE)) {
214
            LOG.log(Level.FINE, FOCUS_GAINED_PROPERTY + ": " + dumpComponent(c) + '\n');
215
        }
216
        firePropertyChange(FOCUS_GAINED_PROPERTY, origFocused, c);
217
    }
218
    
219
    static void focusLost(JTextComponent c, Component newFocused) {
220
        c.removePropertyChangeListener(PropertyDocL.INSTANCE);
221
        if (LOG.isLoggable(Level.FINE)) {
222
            LOG.log(Level.FINE, FOCUS_LOST_PROPERTY + ": " + dumpComponent(c) + '\n');
223
        }
224
        firePropertyChange(FOCUS_LOST_PROPERTY, c, newFocused);
225
    }
226
    
227
    static void focusedDocumentChange(JTextComponent c, Document oldDoc, Document newDoc) {
228
        if (LOG.isLoggable(Level.FINE)) {
229
            LOG.log(Level.FINE, FOCUSED_DOCUMENT_PROPERTY + ": " + dumpComponent(c)
230
                    + "\n    OLDDoc=" + oldDoc + "\n    NEWDoc=" + newDoc + '\n');
231
        }
232
        firePropertyChange(FOCUSED_DOCUMENT_PROPERTY, oldDoc, newDoc);
233
    }
234
    
235
    private static JTextComponent firstValidComponent() {
236
        JTextComponent c = null;
237
        while (textComponentRefs != null && (c = textComponentRefs.get()) == null) {
238
            removeItem(textComponentRefs);
239
        }
240
        return c;
241
    }
242
    
243
    /**
244
     * Remove given entry and return a next one.
245
     */
246
    private static Item removeItem(Item item) {
247
        Item next = item.next;
248
        if (item.previous == null) { // Head
249
            assert (textComponentRefs == item);
250
            textComponentRefs = next;
251
        } else { // Not head
252
            item.previous.next = next;
253
        }
254
        if (next != null)
255
            next.previous = item.previous;
256
        item.next = item.previous = null;
257
        return next;
258
    }
259
    
260
    private static void moveToHead(Item item) {
261
        if (LOG.isLoggable(Level.FINEST)) { // Debugging
262
            isItemInList(item);
263
        }
264
        removeItem(item);
265
        item.next = textComponentRefs;
266
        if (textComponentRefs != null)
267
            textComponentRefs.previous = item;
268
        textComponentRefs = item;
269
        if (LOG.isLoggable(Level.FINEST)) { // Debugging
270
            isItemInList(item);
271
            checkItemListConsistency();
272
        }
273
    }
274
    
275
    private static void firePropertyChange(String propertyName, Object oldValue, Object newValue) {
276
        pcs.firePropertyChange(propertyName, oldValue, newValue);
277
    }
278
    
279
    private static boolean isItemInList(Item item) {
280
        Item i = textComponentRefs;
281
        while (i != null) {
282
            if (i == item)
283
                return true;
284
            i = i.next;
285
        }
286
        return false;
287
    }
288
    
289
    private static void checkItemListConsistency() {
290
        Item item = textComponentRefs;
291
        Item previous = null;
292
        while (item != null) {
293
            assert item.previous == previous;
294
            previous = item;
295
            item = item.next;
296
        }
297
        if (previous != null)
298
            assert previous.next == null;
299
    }
300
301
    private static String dumpItemList() {
302
        StringBuilder sb = new StringBuilder();
303
        int i = 0;
304
        Item item = textComponentRefs;
305
        while (item != null) {
306
            ArrayUtilities.appendBracketedIndex(sb, i, 1);
307
            sb.append(dumpComponent(item.get()));
308
            sb.append('\n');
309
            item = item.next;
310
            i++;
311
        }
312
        sb.append('\n'); // One extra delimiting newline
313
        return sb.toString();
314
    }
315
    
316
    private static String dumpComponent(JTextComponent c) {
317
        return "c[IHC=" + System.identityHashCode(c)
318
                + "]=" + c;
319
    }
320
    
321
    /**
322
     * Item of a single linked list of text component references.
323
     */
324
    private static final class Item extends WeakReference<JTextComponent> {
325
        
326
        Item(JTextComponent c) {
327
            super(c);
328
        }
329
        
330
        Item next;
331
        
332
        Item previous;
333
334
    }
335
    
336
    private static final class FocusL implements FocusListener {
337
        
338
        static final FocusL INSTANCE = new FocusL();
339
340
        public void focusGained(FocusEvent e) {
341
            EditorRegistry.focusGained((JTextComponent)e.getSource(), e.getOppositeComponent());
342
            
343
        }
344
345
        public void focusLost(FocusEvent e) {
346
            EditorRegistry.focusLost((JTextComponent)e.getSource(), e.getOppositeComponent());
347
        }
348
        
349
    }
350
    
351
    private static final class PropertyDocL implements PropertyChangeListener {
352
        
353
        static final PropertyDocL INSTANCE = new PropertyDocL();
354
355
        public void propertyChange(PropertyChangeEvent evt) {
356
            if ("document".equals(evt.getPropertyName())) {
357
                focusedDocumentChange((JTextComponent)evt.getSource(), (Document)evt.getOldValue(), (Document)evt.getNewValue());
358
            }
359
        }
360
361
    }
362
363
}
(-)lib2/test/unit/src/org/netbeans/api/editor/EditorRegistryTest.java (+146 lines)
Added Link Here
1
/*
2
 * The contents of this file are subject to the terms of the Common Development
3
 * and Distribution License (the License). You may not use this file except in
4
 * compliance with the License.
5
 *
6
 * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7
 * or http://www.netbeans.org/cddl.txt.
8
 *
9
 * When distributing Covered Code, include this CDDL Header Notice in each file
10
 * and include the License file at http://www.netbeans.org/cddl.txt.
11
 * If applicable, add the following below the CDDL Header, with the fields
12
 * enclosed by brackets [] replaced by your own identifying information:
13
 * "Portions Copyrighted [year] [name of copyright owner]"
14
 *
15
 * The Original Software is NetBeans. The Initial Developer of the Original
16
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17
 * Microsystems, Inc. All Rights Reserved.
18
 */
19
20
package org.netbeans.api.editor;
21
22
import java.beans.PropertyChangeEvent;
23
import java.beans.PropertyChangeListener;
24
import java.util.List;
25
import javax.swing.JEditorPane;
26
import javax.swing.text.Document;
27
import javax.swing.text.JTextComponent;
28
import org.netbeans.junit.NbTestCase;
29
30
/**
31
 * Tests of editor registry.
32
 *
33
 * @author Miloslav Metelka
34
 */
35
public class EditorRegistryTest extends NbTestCase {
36
    
37
    public EditorRegistryTest(String name) {
38
        super(name);
39
    }
40
    
41
    public void testRegistry() throws Exception {
42
        // Start listening
43
        EditorRegistry.addPropertyChangeListener(EditorRegistryListener.INSTANCE);
44
45
        // Test registration
46
        JTextComponent c1 = new JEditorPane();
47
        EditorRegistry.register(c1);
48
        JTextComponent c2 = new JEditorPane();
49
        EditorRegistry.register(c2);
50
        List<JTextComponent> jtcList = EditorRegistry.componentList();
51
        assertSame(2, jtcList.size());
52
        assertSame(c1, jtcList.get(0));
53
        assertSame(c2, jtcList.get(1));
54
        
55
        // Ignore repetitive registration
56
        EditorRegistry.register(c2);
57
        EditorRegistry.register(c2);
58
        assertSame(2, EditorRegistry.componentList().size());
59
        
60
        // Extra component
61
        JTextComponent c3 = new JEditorPane();
62
        EditorRegistry.register(c3);
63
        assertSame(3, EditorRegistry.componentList().size());
64
        
65
        // Simulate focusGained
66
        EditorRegistry.focusGained(c3, null);
67
        assertSame(1, EditorRegistryListener.INSTANCE.firedCount);
68
        assertSame(c3, EditorRegistryListener.INSTANCE.newValue);
69
        assertSame(null, EditorRegistryListener.INSTANCE.oldValue);
70
        EditorRegistryListener.INSTANCE.reset(); // Reset to 0
71
72
        jtcList = EditorRegistry.componentList();
73
        assertSame(3, jtcList.size());
74
        assertSame(c3, jtcList.get(0));
75
76
        // Simulate document change of focused component
77
        Document oldDoc = c3.getDocument();
78
        Document newDoc = c3.getUI().getEditorKit(c3).createDefaultDocument();
79
        c3.setDocument(newDoc);
80
        assertSame(1, EditorRegistryListener.INSTANCE.firedCount);
81
        assertSame(newDoc, EditorRegistryListener.INSTANCE.newValue);
82
        assertSame(oldDoc, EditorRegistryListener.INSTANCE.oldValue);
83
        EditorRegistryListener.INSTANCE.reset(); // Reset to 0
84
        oldDoc = null;
85
        newDoc = null;
86
87
        // Simulate focusLost
88
        EditorRegistry.focusLost(c3, null);
89
        assertSame(1, EditorRegistryListener.INSTANCE.firedCount);
90
        assertSame(null, EditorRegistryListener.INSTANCE.newValue);
91
        assertSame(c3, EditorRegistryListener.INSTANCE.oldValue);
92
        EditorRegistryListener.INSTANCE.reset(); // Reset to 0
93
94
        EditorRegistry.focusGained(c1, null);
95
        assertSame(1, EditorRegistryListener.INSTANCE.firedCount);
96
        assertSame(c1, EditorRegistryListener.INSTANCE.newValue);
97
        assertSame(null, EditorRegistryListener.INSTANCE.oldValue);
98
        EditorRegistryListener.INSTANCE.reset(); // Reset to 0
99
        
100
        // Partial GC: c3
101
        c3 = null;
102
        jtcList = null;
103
        System.gc();
104
        assertSame(2, EditorRegistry.componentList().size());
105
        
106
        // Test full GC
107
        jtcList = null;
108
        c1 = null;
109
        c2 = null;
110
        c3 = null;
111
        EditorRegistryListener.INSTANCE.reset();
112
        System.gc();
113
        assertSame(0, EditorRegistry.componentList().size());
114
115
        
116
    }
117
    
118
    private static final class EditorRegistryListener implements PropertyChangeListener {
119
        
120
        static final EditorRegistryListener INSTANCE = new EditorRegistryListener();
121
        
122
        int firedCount;
123
        
124
        String propertyName;
125
        
126
        Object oldValue;
127
        
128
        Object newValue;
129
        
130
        public void propertyChange(PropertyChangeEvent evt) {
131
            firedCount++;
132
            propertyName = evt.getPropertyName();
133
            oldValue = evt.getOldValue();
134
            newValue = evt.getNewValue();
135
        }
136
        
137
        public void reset() {
138
            firedCount = 0;
139
            propertyName = null;
140
            oldValue = null;
141
            newValue = null;
142
        }
143
144
    }
145
146
}
(-)completion/nbproject/project.xml (-4 / +13 lines)
Lines 40-46 Link Here
40
                    </run-dependency>
40
                    </run-dependency>
41
                </dependency>
41
                </dependency>
42
                <dependency>
42
                <dependency>
43
                    <code-name-base>org.netbeans.modules.editor.util</code-name-base>
43
                    <code-name-base>org.netbeans.modules.editor.lib2</code-name-base>
44
                    <build-prerequisite/>
44
                    <build-prerequisite/>
45
                    <compile-dependency/>
45
                    <compile-dependency/>
46
                    <run-dependency>
46
                    <run-dependency>
Lines 55-67 Link Here
55
                    <run-dependency>
55
                    <run-dependency>
56
                        <release-version>1</release-version>
56
                        <release-version>1</release-version>
57
                    </run-dependency>
57
                    </run-dependency>
58
                </dependency>                
58
                </dependency>
59
                <dependency>
59
                <dependency>
60
                    <code-name-base>org.openide.util</code-name-base>
60
                    <code-name-base>org.netbeans.modules.editor.util</code-name-base>
61
                    <build-prerequisite/>
61
                    <build-prerequisite/>
62
                    <compile-dependency/>
62
                    <compile-dependency/>
63
                    <run-dependency>
63
                    <run-dependency>
64
                        <specification-version>6.2</specification-version>
64
                        <release-version>1</release-version>
65
                        <specification-version>1.3</specification-version>
65
                    </run-dependency>
66
                    </run-dependency>
66
                </dependency>
67
                </dependency>
67
                <dependency>
68
                <dependency>
Lines 74-79 Link Here
74
                </dependency>
75
                </dependency>
75
                <dependency>
76
                <dependency>
76
                    <code-name-base>org.openide.modules</code-name-base>
77
                    <code-name-base>org.openide.modules</code-name-base>
78
                    <build-prerequisite/>
79
                    <compile-dependency/>
80
                    <run-dependency>
81
                        <specification-version>6.2</specification-version>
82
                    </run-dependency>
83
                </dependency>
84
                <dependency>
85
                    <code-name-base>org.openide.util</code-name-base>
77
                    <build-prerequisite/>
86
                    <build-prerequisite/>
78
                    <compile-dependency/>
87
                    <compile-dependency/>
79
                    <run-dependency>
88
                    <run-dependency>
(-)completion/src/org/netbeans/modules/editor/completion/CompletionImpl.java (-8 / +9 lines)
Lines 21-26 Link Here
21
21
22
import java.awt.*;
22
import java.awt.*;
23
import java.awt.event.*;
23
import java.awt.event.*;
24
import java.beans.PropertyChangeEvent;
25
import java.beans.PropertyChangeListener;
24
import java.lang.ref.WeakReference;
26
import java.lang.ref.WeakReference;
25
import java.util.ArrayList;
27
import java.util.ArrayList;
26
import java.util.Collection;
28
import java.util.Collection;
Lines 34-44 Link Here
34
import javax.swing.*;
36
import javax.swing.*;
35
import javax.swing.event.ListSelectionListener;
37
import javax.swing.event.ListSelectionListener;
36
import javax.swing.event.CaretListener;
38
import javax.swing.event.CaretListener;
37
import javax.swing.event.ChangeListener;
38
import javax.swing.event.DocumentListener;
39
import javax.swing.event.DocumentListener;
39
import javax.swing.plaf.TextUI;
40
import javax.swing.plaf.TextUI;
40
import javax.swing.text.*;
41
import javax.swing.text.*;
41
42
43
import org.netbeans.api.editor.EditorRegistry;
42
import org.netbeans.api.editor.mimelookup.MimeLookup;
44
import org.netbeans.api.editor.mimelookup.MimeLookup;
43
import org.netbeans.api.editor.mimelookup.MimePath;
45
import org.netbeans.api.editor.mimelookup.MimePath;
44
import org.netbeans.editor.BaseDocument;
46
import org.netbeans.editor.BaseDocument;
Lines 48-54 Link Here
48
import org.netbeans.editor.SettingsNames;
50
import org.netbeans.editor.SettingsNames;
49
import org.netbeans.lib.editor.util.swing.DocumentUtilities;
51
import org.netbeans.lib.editor.util.swing.DocumentUtilities;
50
import org.netbeans.lib.editor.util.swing.DocumentListenerPriority;
52
import org.netbeans.lib.editor.util.swing.DocumentListenerPriority;
51
import org.netbeans.editor.Registry;
52
import org.netbeans.editor.Utilities;
53
import org.netbeans.editor.Utilities;
53
import org.netbeans.editor.ext.ExtKit;
54
import org.netbeans.editor.ext.ExtKit;
54
import org.netbeans.spi.editor.completion.*;
55
import org.netbeans.spi.editor.completion.*;
Lines 72-78 Link Here
72
 */
73
 */
73
74
74
public class CompletionImpl extends MouseAdapter implements DocumentListener,
75
public class CompletionImpl extends MouseAdapter implements DocumentListener,
75
CaretListener, KeyListener, FocusListener, ListSelectionListener, ChangeListener, SettingsChangeListener {
76
CaretListener, KeyListener, FocusListener, ListSelectionListener, PropertyChangeListener, SettingsChangeListener {
76
    
77
    
77
    private static final boolean debug = Boolean.getBoolean("org.netbeans.modules.editor.completion.debug");
78
    private static final boolean debug = Boolean.getBoolean("org.netbeans.modules.editor.completion.debug");
78
    private static final boolean alphaSort = Boolean.getBoolean("org.netbeans.modules.editor.completion.alphabeticalSort"); // [TODO] create an option
79
    private static final boolean alphaSort = Boolean.getBoolean("org.netbeans.modules.editor.completion.alphabeticalSort"); // [TODO] create an option
Lines 176-182 Link Here
176
    private boolean pleaseWaitDisplayed = false;
177
    private boolean pleaseWaitDisplayed = false;
177
    
178
    
178
    private CompletionImpl() {
179
    private CompletionImpl() {
179
        Registry.addChangeListener(this);
180
        EditorRegistry.addPropertyChangeListener(this);
180
        completionAutoPopupTimer = new Timer(0, new ActionListener() {
181
        completionAutoPopupTimer = new Timer(0, new ActionListener() {
181
            public void actionPerformed(ActionEvent e) {
182
            public void actionPerformed(ActionEvent e) {
182
                Result localCompletionResult;
183
                Result localCompletionResult;
Lines 361-371 Link Here
361
    /**
362
    /**
362
     * Expected to be called from the AWT only.
363
     * Expected to be called from the AWT only.
363
     */
364
     */
364
    public void stateChanged(javax.swing.event.ChangeEvent e) {
365
    public void propertyChange(PropertyChangeEvent e) {
365
        assert (SwingUtilities.isEventDispatchThread()); // expected in AWT only
366
        assert (SwingUtilities.isEventDispatchThread()); // expected in AWT only
366
367
367
        boolean cancel = false;
368
        boolean cancel = false;
368
        JTextComponent component = Registry.getMostActiveComponent();
369
        JTextComponent component = EditorRegistry.lastFocusedComponent();
369
        if (component != getActiveComponent()) {
370
        if (component != getActiveComponent()) {
370
            activeProviders = getCompletionProvidersForComponent(component);
371
            activeProviders = getCompletionProvidersForComponent(component);
371
            if (debug) {
372
            if (debug) {
Lines 401-408 Link Here
401
            installKeybindings();
402
            installKeybindings();
402
            cancel = true;
403
            cancel = true;
403
        }
404
        }
404
        Document document = Registry.getMostActiveDocument();
405
        Document document = component.getDocument();
405
        if (component != null && document == component.getDocument() && document != getActiveDocument()) {
406
        if (component != null && document != getActiveDocument()) {
406
            activeProviders = getCompletionProvidersForComponent(component);
407
            activeProviders = getCompletionProvidersForComponent(component);
407
            if (debug) {
408
            if (debug) {
408
                StringBuffer sb = new StringBuffer("Completion PROVIDERS:\n"); // NOI18N
409
                StringBuffer sb = new StringBuffer("Completion PROVIDERS:\n"); // NOI18N

Return to bug 103235