Source Code Cross Referenced for EditorRegistry.java in  » IDE-Netbeans » editor » org » netbeans » api » editor » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » IDE Netbeans » editor » org.netbeans.api.editor 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003:         *
004:         * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005:         *
006:         * The contents of this file are subject to the terms of either the GNU
007:         * General Public License Version 2 only ("GPL") or the Common
008:         * Development and Distribution License("CDDL") (collectively, the
009:         * "License"). You may not use this file except in compliance with the
010:         * License. You can obtain a copy of the License at
011:         * http://www.netbeans.org/cddl-gplv2.html
012:         * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013:         * specific language governing permissions and limitations under the
014:         * License.  When distributing the software, include this License Header
015:         * Notice in each file and include the License file at
016:         * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
017:         * particular file as subject to the "Classpath" exception as provided
018:         * by Sun in the GPL Version 2 section of the License file that
019:         * accompanied this code. If applicable, add the following below the
020:         * License Header, with the fields enclosed by brackets [] replaced by
021:         * your own identifying information:
022:         * "Portions Copyrighted [year] [name of copyright owner]"
023:         *
024:         * Contributor(s):
025:         *
026:         * The Original Software is NetBeans. The Initial Developer of the Original
027:         * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
028:         * Microsystems, Inc. All Rights Reserved.
029:         *
030:         * If you wish your version of this file to be governed by only the CDDL
031:         * or only the GPL Version 2, indicate your decision by adding
032:         * "[Contributor] elects to include this software in this distribution
033:         * under the [CDDL or GPL Version 2] license." If you do not indicate a
034:         * single choice of license, a recipient has the option to distribute
035:         * your version of this file under either the CDDL, the GPL Version 2 or
036:         * to extend the choice of license to its licensees as provided above.
037:         * However, if you add GPL Version 2 code and therefore, elected the GPL
038:         * Version 2 license, then the option applies only if the new code is
039:         * made subject to such option by the copyright holder.
040:         */
041:
042:        package org.netbeans.api.editor;
043:
044:        import java.awt.Component;
045:        import java.awt.event.ActionEvent;
046:        import java.awt.event.ActionListener;
047:        import java.awt.event.FocusEvent;
048:        import java.awt.event.FocusListener;
049:        import java.beans.PropertyChangeEvent;
050:        import java.beans.PropertyChangeListener;
051:        import java.beans.PropertyChangeSupport;
052:        import java.lang.ref.WeakReference;
053:        import java.util.ArrayList;
054:        import java.util.Collections;
055:        import java.util.List;
056:        import java.util.logging.Level;
057:        import java.util.logging.Logger;
058:        import javax.swing.JComponent;
059:        import javax.swing.SwingUtilities;
060:        import javax.swing.Timer;
061:        import javax.swing.event.AncestorEvent;
062:        import javax.swing.event.AncestorListener;
063:        import javax.swing.text.Document;
064:        import javax.swing.text.JTextComponent;
065:        import org.netbeans.lib.editor.util.ArrayUtilities;
066:        import org.netbeans.modules.editor.lib2.EditorApiPackageAccessor;
067:
068:        /**
069:         * Registry maintaining {@link JTextComponent}s in most-recently-used order.
070:         * <br/>
071:         * The particular text component needs to register itself first (to avoid dealing
072:         * with all the JTextFields etc.). Then the registry will attach
073:         * a focus listener to the text component and once the component gains
074:         * the focus it will move to the head of the components list.
075:         * <br/>
076:         * The registry will also fire a change in case a document property
077:         * of the focused component changes (by calling component.setDocument()).
078:         *
079:         * @author Miloslav Metelka
080:         */
081:        public final class EditorRegistry {
082:
083:            private EditorRegistry() {
084:                // No instances
085:            }
086:
087:            static {
088:                EditorApiPackageAccessor.register(new PackageAccessor());
089:            }
090:
091:            // -J-Dorg.netbeans.api.editor.EditorRegistry.level=FINEST
092:            private static final Logger LOG = Logger
093:                    .getLogger(EditorRegistry.class.getName());
094:
095:            /**
096:             * Fired when focus was delivered to a registered text component.
097:             * <br/>
098:             * The focused component will become the first in the components list.
099:             * <br/>
100:             * The {@link java.beans.PropertyChangeEvent#getOldValue()} will be a component
101:             * losing the focus {@link FocusEvent#getOppositeComponent()}.
102:             * The {@link java.beans.PropertyChangeEvent#getNewValue()} will be the text component gaining the focus.
103:             */
104:            public static final String FOCUS_GAINED_PROPERTY = "focusGained";
105:
106:            /**
107:             * Fired when a registered focused component has lost the focus.
108:             * <br/>
109:             * The focused component will remain the first in the components list.
110:             * <br/>
111:             * The {@link java.beans.PropertyChangeEvent#getOldValue()} will be the text component
112:             * losing the focus and the {@link java.beans.PropertyChangeEvent#getNewValue()}
113:             * will be the component gaining the focus {@link FocusEvent#getOppositeComponent()}.
114:             */
115:            public static final String FOCUS_LOST_PROPERTY = "focusLost";
116:
117:            /**
118:             * Fired when document property of the focused component changes
119:             * i.e. someone has called {@link JTextComponent#setDocument(Document)}.
120:             * <br/>
121:             * The {@link java.beans.PropertyChangeEvent#getOldValue()} will be the original document
122:             * of the focused text component and the {@link java.beans.PropertyChangeEvent#getNewValue()}
123:             * will be the new document set to the focused text component.
124:             */
125:            public static final String FOCUSED_DOCUMENT_PROPERTY = "focusedDocument";
126:
127:            /**
128:             * Fired when the last focused component (returned previously from {@link #lastFocusedComponent()})
129:             * was removed from component hierarchy (so it's likely that the component will be released completely
130:             * and garbage-collected).
131:             * <br/>
132:             * Such component will no longer be returned from {@link #componentList()}
133:             * or {@link #lastFocusedComponent()}.
134:             * <br/>
135:             * The {@link java.beans.PropertyChangeEvent#getOldValue()} will be the removed
136:             * last focused component and the {@link java.beans.PropertyChangeEvent#getNewValue()}
137:             * will be the component that would currently be returned from {@link #lastFocusedComponent()}.
138:             * <br/>
139:             * If {@link java.beans.PropertyChangeEvent#getNewValue()} returns <code>null</code>
140:             * then there are no longer any registered components
141:             * ({@link #componentList()} would return empty list). If the client
142:             * holds per-last-focused-component data it should clear them.
143:             */
144:            public static final String LAST_FOCUSED_REMOVED_PROPERTY = "lastFocusedRemoved";
145:
146:            /**
147:             * Double linked list of weak references to text components.
148:             */
149:            private static Item items;
150:
151:            private static final PropertyChangeSupport pcs = new PropertyChangeSupport(
152:                    EditorRegistry.class);
153:
154:            private static Class ignoredAncestorClass;
155:
156:            /**
157:             * Return last focused text component (from the ones included in the registry).
158:             * <br/>
159:             * It may or may not currently have a focus.
160:             * 
161:             * @return last focused text component or null if no text components
162:             *  were registered yet or all the registered components were closed.
163:             */
164:            public static synchronized JTextComponent lastFocusedComponent() {
165:                return firstValidComponent();
166:            }
167:
168:            /**
169:             * Return the last focused component if it currently has a focus
170:             * or return null if none of the registered components currently have the focus.
171:             * <br/>
172:             * @return focused component or null if none of the registered components
173:             *  is currently focused.
174:             */
175:            public static synchronized JTextComponent focusedComponent() {
176:                JTextComponent c = firstValidComponent();
177:                return (c != null && c.isFocusOwner()) ? c : null;
178:            }
179:
180:            /**
181:             * Get list of all components present in the registry starting with the most active
182:             * and ending with least active component.
183:             * <br/>
184:             * The list is a snapshot of the current state and it may be modified
185:             * by the caller if desired.
186:             * 
187:             * @return non-null list containing all the registered components in MRU order.
188:             */
189:            public static synchronized List<? extends JTextComponent> componentList() {
190:                List<JTextComponent> l;
191:                JTextComponent c = firstValidComponent();
192:                if (c != null) {
193:                    l = new ArrayList<JTextComponent>();
194:                    l.add(c);
195:                    // Add remaining ones (eliminate empty items)
196:                    Item item = items.next;
197:                    while (item != null) {
198:                        c = item.get();
199:                        if (c != null) {
200:                            l.add(c);
201:                            item = item.next;
202:                        } else
203:                            item = removeFromItemList(item);
204:                    }
205:
206:                } else
207:                    // No valid items
208:                    l = Collections.emptyList();
209:                return l;
210:            }
211:
212:            /**
213:             * Add a property change listener for either of the following properties:
214:             * <ul>
215:             *   <li>{@link #FOCUS_GAINED_PROPERTY}</li>
216:             *   <li>{@link #FOCUS_LOST_PROPERTY}</li>
217:             *   <li>{@link #FOCUSED_DOCUMENT_PROPERTY}</li>
218:             * </ul>.
219:             * <br/>
220:             * All the firing should occur in AWT thread only
221:             * (assuming the JTextComponent.setDocument() is done properly in AWT).
222:             * 
223:             * @param l non-null listener to add.
224:             */
225:            public static void addPropertyChangeListener(
226:                    PropertyChangeListener l) {
227:                pcs.addPropertyChangeListener(l);
228:            }
229:
230:            public static void removePropertyChangeListener(
231:                    PropertyChangeListener l) {
232:                pcs.removePropertyChangeListener(l);
233:            }
234:
235:            /**
236:             * Add a given text component to the registry. The registry will weakly
237:             * reference the given component for its whole lifetime
238:             * until it will be garbage collected.
239:             * 
240:             * @param c non-null text component to be registered.
241:             */
242:            static synchronized void register(JTextComponent c) {
243:                assert (c != null);
244:                if (item(c) == null) { // Not registered yet
245:                    Item item = new Item(c);
246:                    c.putClientProperty(Item.class, item);
247:                    c.addFocusListener(FocusL.INSTANCE);
248:                    c.addAncestorListener(AncestorL.INSTANCE);
249:                    if (LOG.isLoggable(Level.FINE)) {
250:                        LOG.log(Level.FINE, "EditorRegistry.register(): "
251:                                + dumpComponent(c) + '\n');
252:                    }
253:                    // By default do not add the component to be last in the item list
254:                    // at this point since e.g. the component from warmup task(s) would show up
255:                    // in the item list and they would never be removed
256:                    // since they have no ancestor and they do not become focused ever.
257:                    if (c.isFocusOwner()) { // If the focus owner then simulate the focus was gained
258:                        focusGained(c, null); // opposite could eventually be got from Focus Manager
259:                    } else if (c.isDisplayable()) { // Simulate that addNotify() was called
260:                        itemMadeDisplayable(item);
261:                    }
262:                }
263:            }
264:
265:            static synchronized void setIgnoredAncestorClass(
266:                    Class ignoredAncestorClass) {
267:                EditorRegistry.ignoredAncestorClass = ignoredAncestorClass;
268:            }
269:
270:            static synchronized void notifyClose(JComponent c) {
271:                // Go through the present items and remove those that have the "c" as parent.
272:                Item item = items;
273:                while (item != null) {
274:                    JTextComponent textComponent = item.get();
275:                    if (textComponent == null
276:                            || (item.ignoreAncestorChange && c
277:                                    .isAncestorOf(textComponent))) {
278:                        // Explicitly call focusLost() before physical removal from the registry.
279:                        // In practice this notification happens first before focusLost() from focus listener.
280:                        if (textComponent != null) {
281:                            focusLost(textComponent, null); // Checks if the component is focused and does nothing otherwise
282:                            item = removeFromRegistry(item);
283:                        } else { // Null text component - just remove the item
284:                            item = removeFromItemList(item);
285:                        }
286:                    } else {
287:                        item = item.next;
288:                    }
289:                }
290:            }
291:
292:            static synchronized void focusGained(JTextComponent c,
293:                    Component origFocused) {
294:                Item item = item(c);
295:                assert (item != null) : "Not registered!"; // NOI18N
296:
297:                // Move the item to head of the list
298:                removeFromItemList(item);
299:                addToItemListAsFirst(item);
300:                item.focused = true;
301:
302:                c.addPropertyChangeListener(PropertyDocL.INSTANCE);
303:                if (LOG.isLoggable(Level.FINE)) {
304:                    LOG.log(Level.FINE, FOCUS_GAINED_PROPERTY + ": "
305:                            + dumpComponent(c) + '\n');
306:                    logItemListFinest();
307:                }
308:                firePropertyChange(FOCUS_GAINED_PROPERTY, origFocused, c);
309:            }
310:
311:            static void focusLost(JTextComponent c, Component newFocused) {
312:                Item item = item(c);
313:                assert (item != null) : "Not registered!"; // NOI18N
314:                // For explicit close notifications: in practice the closing comes first before focus lost.
315:                if (item.focused) {
316:                    item.focused = false;
317:                    if (!item.ignoreAncestorChange
318:                            && firstValidComponent() != c) {
319:                        throw new IllegalStateException(
320:                                "Invalid ordering of focusLost()");
321:                    }
322:                    c.removePropertyChangeListener(PropertyDocL.INSTANCE);
323:                    if (LOG.isLoggable(Level.FINE)) {
324:                        LOG.log(Level.FINE, FOCUS_LOST_PROPERTY + ": "
325:                                + dumpComponent(c) + '\n');
326:                        logItemListFinest();
327:                    }
328:                    firePropertyChange(FOCUS_LOST_PROPERTY, c, newFocused);
329:                }
330:            }
331:
332:            static void itemMadeDisplayable(Item item) {
333:                // If the component was removed from the component hierarchy and then
334:                // returned back to the hierarchy it will be readded to the end of the component list.
335:                // If the item is not removed yet then the addAsLast() will do nothing.
336:                addToItemListAsLast(item);
337:                JTextComponent c = item.get();
338:                if (c == null)
339:                    throw new IllegalStateException(
340:                            "Component should be non-null");
341:
342:                // Remember whether component should not be removed from registry upon removeNotify()
343:                item.ignoreAncestorChange = (SwingUtilities.getAncestorOfClass(
344:                        ignoredAncestorClass, c) != null);
345:                if (LOG.isLoggable(Level.FINER)) {
346:                    LOG.fine("ancestorAdded: " + dumpComponent(item.get())
347:                            + '\n');
348:                    logItemListFinest();
349:                }
350:            }
351:
352:            static void focusedDocumentChange(JTextComponent c,
353:                    Document oldDoc, Document newDoc) {
354:                if (LOG.isLoggable(Level.FINE)) {
355:                    LOG.log(Level.FINE, FOCUSED_DOCUMENT_PROPERTY + ": "
356:                            + dumpComponent(c) + "\n    OLDDoc=" + oldDoc
357:                            + "\n    NEWDoc=" + newDoc + '\n');
358:                }
359:                firePropertyChange(FOCUSED_DOCUMENT_PROPERTY, oldDoc, newDoc);
360:            }
361:
362:            private static JTextComponent firstValidComponent() {
363:                JTextComponent c = null;
364:                while (items != null && (c = items.get()) == null) {
365:                    removeFromItemList(items);
366:                }
367:                return c;
368:            }
369:
370:            static Item item(JComponent c) {
371:                return (Item) c.getClientProperty(Item.class);
372:
373:            }
374:
375:            private static void addToItemListAsLast(Item item) {
376:                if (item.linked)
377:                    return;
378:                item.linked = true;
379:                if (items == null) {
380:                    items = item;
381:                } else {
382:                    Item i = items;
383:                    while (i.next != null)
384:                        i = i.next;
385:                    i.next = item;
386:                    item.previous = i;
387:                }
388:                // Assuming item.next == null (done in removeItem() too).
389:                if (LOG.isLoggable(Level.FINEST)) { // Consistency checking
390:                    checkItemListConsistency();
391:                }
392:            }
393:
394:            private static void addToItemListAsFirst(Item item) {
395:                if (item.linked)
396:                    return;
397:                item.linked = true;
398:                item.next = items;
399:                if (items != null)
400:                    items.previous = item;
401:                items = item;
402:                if (LOG.isLoggable(Level.FINEST)) { // Consistency checking
403:                    checkItemListConsistency();
404:                }
405:            }
406:
407:            /**
408:             * Remove given entry and return a next one.
409:             */
410:            private static Item removeFromItemList(Item item) {
411:                if (!item.linked)
412:                    return null;
413:                item.linked = false;
414:                Item next = item.next;
415:                if (item.previous == null) { // Head
416:                    assert (items == item);
417:                    items = next;
418:                } else { // Not head
419:                    item.previous.next = next;
420:                }
421:                if (next != null)
422:                    next.previous = item.previous;
423:                item.next = item.previous = null;
424:                if (LOG.isLoggable(Level.FINEST)) { // Consistency checking
425:                    checkItemListConsistency();
426:                }
427:                return next;
428:            }
429:
430:            /**
431:             * Remove the given item from registry and return the next one.
432:             * 
433:             * @param item item to remove.
434:             * @return next item in registry.
435:             */
436:            static Item removeFromRegistry(Item item) {
437:                boolean lastFocused = (items == item);
438:                // Remove component from item chain
439:                JTextComponent component = item.get();
440:                item = removeFromItemList(item);
441:                if (component != null) {
442:                    if (LOG.isLoggable(Level.FINEST)) {
443:                        LOG.fine("Component removed: "
444:                                + dumpComponent(component) + '\n');
445:                        logItemListFinest();
446:                    }
447:                    if (lastFocused) {
448:                        firePropertyChange(LAST_FOCUSED_REMOVED_PROPERTY,
449:                                component, lastFocusedComponent());
450:                        if (LOG.isLoggable(Level.FINE)) {
451:                            LOG.fine("Fired LAST_FOCUSED_REMOVED_PROPERTY for "
452:                                    + dumpComponent(component) + '\n');
453:                        }
454:                    }
455:                }
456:                return item;
457:            }
458:
459:            static void checkItemListConsistency() {
460:                Item item = items;
461:                Item previous = null;
462:                while (item != null) {
463:                    if (!item.linked)
464:                        throw new IllegalStateException("item=" + item
465:                                + " is in list but item.linked is false.");
466:                    if (item.previous != previous)
467:                        throw new IllegalStateException(
468:                                "Invalid previous of item=" + item);
469:                    if (item.ignoreAncestorChange
470:                            && (item.runningTimer != null))
471:                        throw new IllegalStateException("item=" + item
472:                                + " has running timer.");
473:                    if (item.focused && item != items)
474:                        throw new IllegalStateException(
475:                                "Non-first component has focused flag.");
476:
477:                    previous = item;
478:                    item = item.next;
479:                }
480:            }
481:
482:            static void firePropertyChange(String propertyName,
483:                    Object oldValue, Object newValue) {
484:                pcs.firePropertyChange(propertyName, oldValue, newValue);
485:            }
486:
487:            static void logItemListFinest() {
488:                if (LOG.isLoggable(Level.FINEST)) {
489:                    LOG.finest(dumpItemList());
490:                }
491:            }
492:
493:            private static String dumpItemList() {
494:                StringBuilder sb = new StringBuilder(256);
495:                sb.append("---------- EditorRegistry Dump START ----------\n");
496:                int i = 0;
497:                Item item = items;
498:                while (item != null) {
499:                    ArrayUtilities.appendBracketedIndex(sb, i, 1);
500:                    sb.append(' ');
501:                    if (item.focused)
502:                        sb.append("Focused, ");
503:                    if (item.ignoreAncestorChange)
504:                        sb.append("IgnoreAncestorChange, ");
505:                    sb.append(dumpComponent(item.get()));
506:                    sb.append('\n');
507:                    item = item.next;
508:                    i++;
509:                }
510:                sb.append("---------- EditorRegistry Dump END ----------\n");
511:                return sb.toString();
512:            }
513:
514:            static String dumpComponent(JComponent c) {
515:                Object streamDesc = null;
516:                if (c instanceof  JTextComponent) {
517:                    Document doc = ((JTextComponent) c).getDocument();
518:                    if (doc != null) {
519:                        streamDesc = doc
520:                                .getProperty(Document.StreamDescriptionProperty);
521:                    }
522:                }
523:                return "component[IHC=" + System.identityHashCode(c) + "]:"
524:                        + ((streamDesc != null) ? streamDesc : c);
525:            }
526:
527:            /**
528:             * Item of a single linked list of text component references.
529:             */
530:            private static final class Item extends
531:                    WeakReference<JTextComponent> {
532:
533:                Item(JTextComponent c) {
534:                    super (c);
535:                }
536:
537:                /**
538:                 * Whether the item is contained in the item list - used for quicker checking
539:                 * than checking next/last vars (and possibly items var).
540:                 */
541:                boolean linked;
542:
543:                /**
544:                 * Whether this item is currently treated as focused.
545:                 */
546:                boolean focused;
547:
548:                /**
549:                 * Next item in items double linked list.
550:                 */
551:                Item next;
552:
553:                /**
554:                 * Previous item in items double linked list.
555:                 */
556:                Item previous;
557:
558:                /**
559:                 * Whether component should not be removed from registry upon removeNotify()
560:                 * since TabbedAdapter in NB winsys removes the component upon tab switching.
561:                 */
562:                boolean ignoreAncestorChange;
563:
564:                /**
565:                 * Timer for removal of component from registry after removeNotify() was called on component.
566:                 */
567:                Timer runningTimer;
568:
569:                @Override
570:                public String toString() {
571:                    return "component=" + get() + ", linked=" + linked
572:                            + ", hasPrevious=" + (previous != null)
573:                            + ", hasNext=" + (next != null)
574:                            + ", ignoreAncestorChange=" + ignoreAncestorChange
575:                            + ", hasTimer=" + (runningTimer != null);
576:                }
577:
578:            }
579:
580:            private static final class FocusL implements  FocusListener {
581:
582:                static final FocusL INSTANCE = new FocusL();
583:
584:                public void focusGained(FocusEvent e) {
585:                    EditorRegistry.focusGained((JTextComponent) e.getSource(),
586:                            e.getOppositeComponent());
587:
588:                }
589:
590:                public void focusLost(FocusEvent e) {
591:                    EditorRegistry.focusLost((JTextComponent) e.getSource(), e
592:                            .getOppositeComponent());
593:                }
594:
595:            }
596:
597:            private static final class PropertyDocL implements 
598:                    PropertyChangeListener {
599:
600:                static final PropertyDocL INSTANCE = new PropertyDocL();
601:
602:                public void propertyChange(PropertyChangeEvent evt) {
603:                    if ("document".equals(evt.getPropertyName())) {
604:                        focusedDocumentChange((JTextComponent) evt.getSource(),
605:                                (Document) evt.getOldValue(), (Document) evt
606:                                        .getNewValue());
607:                    }
608:                }
609:
610:            }
611:
612:            private static final class AncestorL implements  AncestorListener {
613:
614:                static final AncestorL INSTANCE = new AncestorL();
615:
616:                private static final int BEFORE_REMOVE_DELAY = 2000; // 2000ms delay
617:
618:                public void ancestorAdded(AncestorEvent event) {
619:                    Item item = item(event.getComponent());
620:                    if (item.runningTimer != null) {
621:                        item.runningTimer.stop();
622:                        item.runningTimer = null;
623:                    }
624:                    itemMadeDisplayable(item);
625:                }
626:
627:                public void ancestorMoved(AncestorEvent event) {
628:                }
629:
630:                public void ancestorRemoved(AncestorEvent event) {
631:                    final JComponent component = event.getComponent();
632:                    Item item = item(component);
633:                    // In case the ancestor has class of certain type
634:                    // the ancestor removal is not significant and the registry expects
635:                    // that the closing of the component will be notified explicitly.
636:                    if (LOG.isLoggable(Level.FINER)) {
637:                        LOG.fine("ancestorRemoved for "
638:                                + dumpComponent(component)
639:                                + "; ignoreAncestorChange="
640:                                + item.ignoreAncestorChange + '\n');
641:                    }
642:                    if (!item.ignoreAncestorChange) {
643:                        // Only start timer when ancestor changes are not ignored.
644:                        item.runningTimer = new Timer(BEFORE_REMOVE_DELAY,
645:                                new ActionListener() {
646:                                    public void actionPerformed(ActionEvent e) {
647:                                        Item item = item(component);
648:                                        item.runningTimer.stop();
649:                                        item.runningTimer = null;
650:                                        removeFromRegistry(item);
651:                                    }
652:                                });
653:                        item.runningTimer.start();
654:                    }
655:                }
656:
657:            }
658:
659:            private static final class PackageAccessor extends
660:                    EditorApiPackageAccessor {
661:
662:                @Override
663:                public void register(JTextComponent c) {
664:                    EditorRegistry.register(c);
665:                }
666:
667:                @Override
668:                public void setIgnoredAncestorClass(Class ignoredAncestorClass) {
669:                    EditorRegistry
670:                            .setIgnoredAncestorClass(ignoredAncestorClass);
671:                }
672:
673:                @Override
674:                public void notifyClose(JComponent c) {
675:                    EditorRegistry.notifyClose(c);
676:                }
677:
678:            }
679:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.