Source Code Cross Referenced for TopComponent.java in  » IDE-Netbeans » openide » org » openide » windows » 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 » openide » org.openide.windows 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
0003:         *
0004:         * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
0005:         *
0006:         * The contents of this file are subject to the terms of either the GNU
0007:         * General Public License Version 2 only ("GPL") or the Common
0008:         * Development and Distribution License("CDDL") (collectively, the
0009:         * "License"). You may not use this file except in compliance with the
0010:         * License. You can obtain a copy of the License at
0011:         * http://www.netbeans.org/cddl-gplv2.html
0012:         * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
0013:         * specific language governing permissions and limitations under the
0014:         * License.  When distributing the software, include this License Header
0015:         * Notice in each file and include the License file at
0016:         * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
0017:         * particular file as subject to the "Classpath" exception as provided
0018:         * by Sun in the GPL Version 2 section of the License file that
0019:         * accompanied this code. If applicable, add the following below the
0020:         * License Header, with the fields enclosed by brackets [] replaced by
0021:         * your own identifying information:
0022:         * "Portions Copyrighted [year] [name of copyright owner]"
0023:         *
0024:         * Contributor(s):
0025:         *
0026:         * The Original Software is NetBeans. The Initial Developer of the Original
0027:         * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
0028:         * Microsystems, Inc. All Rights Reserved.
0029:         *
0030:         * If you wish your version of this file to be governed by only the CDDL
0031:         * or only the GPL Version 2, indicate your decision by adding
0032:         * "[Contributor] elects to include this software in this distribution
0033:         * under the [CDDL or GPL Version 2] license." If you do not indicate a
0034:         * single choice of license, a recipient has the option to distribute
0035:         * your version of this file under either the CDDL, the GPL Version 2 or
0036:         * to extend the choice of license to its licensees as provided above.
0037:         * However, if you add GPL Version 2 code and therefore, elected the GPL
0038:         * Version 2 license, then the option applies only if the new code is
0039:         * made subject to such option by the copyright holder.
0040:         */
0041:
0042:        package org.openide.windows;
0043:
0044:        import java.awt.EventQueue;
0045:        import java.awt.Image;
0046:        import java.awt.Toolkit;
0047:        import java.awt.event.ActionEvent;
0048:        import java.awt.event.ActionListener;
0049:        import java.awt.event.KeyEvent;
0050:        import java.beans.PropertyChangeEvent;
0051:        import java.beans.PropertyChangeListener;
0052:        import java.io.Externalizable;
0053:        import java.io.IOException;
0054:        import java.io.ObjectInput;
0055:        import java.io.ObjectInputStream;
0056:        import java.io.ObjectOutput;
0057:        import java.io.ObjectOutputStream;
0058:        import java.io.ObjectStreamException;
0059:        import java.io.Serializable;
0060:        import java.lang.ref.Reference;
0061:        import java.lang.ref.WeakReference;
0062:        import java.lang.reflect.InvocationTargetException;
0063:        import java.lang.reflect.Method;
0064:        import java.util.ArrayList;
0065:        import java.util.Arrays;
0066:        import java.util.Collection;
0067:        import java.util.List;
0068:        import java.util.Set;
0069:        import java.util.logging.Level;
0070:        import java.util.logging.LogRecord;
0071:        import java.util.logging.Logger;
0072:        import javax.accessibility.Accessible;
0073:        import javax.accessibility.AccessibleContext;
0074:        import javax.accessibility.AccessibleRole;
0075:        import javax.swing.AbstractAction;
0076:        import javax.swing.Action;
0077:        import javax.swing.ActionMap;
0078:        import javax.swing.JComponent;
0079:        import javax.swing.KeyStroke;
0080:        import javax.swing.SwingUtilities;
0081:        import javax.swing.Timer;
0082:        import javax.swing.plaf.basic.BasicHTML;
0083:        import javax.swing.text.Keymap;
0084:        import org.openide.awt.UndoRedo;
0085:        import org.openide.nodes.Node;
0086:        import org.openide.nodes.NodeAdapter;
0087:        import org.openide.nodes.NodeListener;
0088:        import org.openide.util.ContextAwareAction;
0089:        import org.openide.util.HelpCtx;
0090:        import org.openide.util.Lookup;
0091:        import org.openide.util.NbBundle;
0092:        import org.openide.util.Utilities;
0093:        import org.openide.util.WeakListeners;
0094:        import org.openide.util.WeakSet;
0095:        import org.openide.util.actions.SystemAction;
0096:
0097:        /**
0098:         * Embeddable visual component to be displayed in NetBeans.
0099:         * This is the basic unit of display--windows should not be
0100:         * created directly, but rather use this class.
0101:         * A top component may correspond to a single window, but may also
0102:         * be a tab (e.g.) in a window. It may be docked or undocked,
0103:         * have selected nodes, supply actions, etc.
0104:         *
0105:         * Important serialization note: Serialization of this TopComponent is designed
0106:         * in a way that it's not desired to override writeReplace method. If you would
0107:         * like to resolve to something, please implement readResolve() method directly
0108:         * on your top component.
0109:         *
0110:         * @author Jaroslav Tulach, Petr Hamernik, Jan Jancura
0111:         */
0112:        public class TopComponent extends JComponent implements  Externalizable,
0113:                Accessible, HelpCtx.Provider, Lookup.Provider {
0114:            /** UI logger to notify about invocation of an action */
0115:            private static Logger UILOG = Logger
0116:                    .getLogger("org.netbeans.ui.actions"); // NOI18N
0117:            /** generated Serialized Version UID */
0118:            static final long serialVersionUID = -3022538025284122942L;
0119:            /** top component logger */
0120:            static final Logger LOG = Logger.getLogger(TopComponent.class
0121:                    .getName());
0122:
0123:            /** Behavior in which a top component closed (by the user) in one workspace
0124:             * will be removed from <em>every</em> workspace.
0125:             * Also, {@link #close} is called.
0126:             * This is appropriate for top components such as Editor panes which
0127:             * the user expects to really close (and prompt to save) when closed
0128:             * in any
0129:             * @deprecated Do not use. It is redundant since workspaces are not supported anymore. */
0130:            @Deprecated
0131:            public static final int CLOSE_EACH = 0;
0132:
0133:            /** Behavior in which a top component closed (by the user) in one workspace
0134:             * may be left in other workspaces.
0135:             * Only when the last remaining manifestation in any workspace is closed
0136:             * will the object be deleted using {@link #close}.
0137:             * Appropriate for components containing no user data, for which closing
0138:             * the component is only likely to result from the user's wanting to remove
0139:             * it from active view (on the current workspace).
0140:             * @deprecated Do not use. It is redundant since workspaces are not supported anymore. */
0141:            @Deprecated
0142:            public static final int CLOSE_LAST = 1;
0143:
0144:            /** Persistence type of TopComponent instance. TopComponent is persistent. */
0145:            public static final int PERSISTENCE_ALWAYS = 0;
0146:
0147:            /** Persistence type of TopComponent instance. TopComponent is persistent only when
0148:             * it is opened in Mode. */
0149:            public static final int PERSISTENCE_ONLY_OPENED = 1;
0150:
0151:            /** Persistence type of TopComponent instance. TopComponent is not persistent. */
0152:            public static final int PERSISTENCE_NEVER = 2;
0153:
0154:            /** a lock for operations in default impl of getLookup */
0155:            private static Object defaultLookupLock = new Object();
0156:
0157:            /** Classes that have been warned about overriding preferredID() */
0158:            private static final Set<Class> warnedTCPIClasses = new WeakSet<Class>();
0159:
0160:            /** Used to print warning about getPersistenceType */
0161:            private static final Set<Class> warnedClasses = new WeakSet<Class>();
0162:
0163:            /** reference to Lookup with default implementation for the
0164:             * component or the lookup associated with the component itself
0165:             */
0166:            private Object defaultLookupRef;
0167:
0168:            /** Holds support for sync with node display name or null */
0169:            private NodeName nodeName;
0170:
0171:            // Do not use, deprecated.
0172:
0173:            /** constant for desired close operation */
0174:            private int closeOperation = CLOSE_LAST;
0175:
0176:            /** Icon of this <code>TopComponent</code> */
0177:            private transient Image icon;
0178:
0179:            /** Activated nodes of this <code>TopComponent</code>. */
0180:            private transient Node[] activatedNodes;
0181:
0182:            /** Localized display name of this <code>TopComponent</code>. */
0183:            private transient String displayName;
0184:
0185:            /** Holds localized display name of this <code>TopComponent</code> in html syntax,
0186:             * or null if not needed */
0187:            private String htmlDisplayName;
0188:
0189:            /** identification of serialization version
0190:             * Used in CloneableTopComponent readObject method.
0191:             */
0192:            short serialVersion = 1;
0193:            private AttentionGetter attentionGetter = null;
0194:
0195:            /** Create a top component.
0196:             */
0197:            public TopComponent() {
0198:                this ((Lookup) null);
0199:            }
0200:
0201:            /** Creates a top component for a provided lookup that will delegate
0202:             * take and synchronize activated nodes and ActionMap from a provided
0203:             * lookup. The lookup will also be returned from {@link #getLookup} method,
0204:             * if not overriden.
0205:             *
0206:             * @param lookup the lookup to associate with
0207:             * @since 4.19
0208:             */
0209:            public TopComponent(Lookup lookup) {
0210:                if (lookup != null) {
0211:                    setLookup(lookup, true);
0212:                }
0213:
0214:                enableEvents(java.awt.AWTEvent.KEY_EVENT_MASK);
0215:
0216:                // #27731 TopComponent itself shouldn't get the focus.
0217:                // XXX What to do in case nothing in TopComponent is focusable?
0218:                setFocusable(false);
0219:                initActionMap(lookup);
0220:            }
0221:
0222:            // It is necessary so the old actions (clone and close from org.openide.actions package) remain working.
0223:
0224:            /** Initialized <code>ActionMap</code> of this <code>TopComponent</code>.
0225:             * @since 4.13 */
0226:            private void initActionMap(Lookup lookup) {
0227:                ActionMap inner = null;
0228:                if (lookup != null) {
0229:                    inner = lookup.lookup(ActionMap.class);
0230:                }
0231:                if (inner == null) {
0232:                    inner = new ActionMap();
0233:                }
0234:
0235:                DelegateActionMap am = new DelegateActionMap(this , inner);
0236:
0237:                if (this  instanceof  TopComponent.Cloneable) {
0238:                    am.put("cloneWindow", // NOI18N
0239:                            new CloneWindowAction(am));
0240:                }
0241:
0242:                am.put("closeWindow", // NOI18N
0243:                        new CloseWindowAction(am));
0244:
0245:                setActionMap(am);
0246:            }
0247:
0248:            /** Getter for class that allows obtaining of information about components.
0249:             * It allows to find out which component is selected, which nodes are
0250:             * currently or has been activated and list of all components.
0251:             *
0252:             * @return the registry of components
0253:             */
0254:            public static final Registry getRegistry() {
0255:                return WindowManager.getDefault().getRegistry();
0256:            }
0257:
0258:            /** Get the set of activated nodes in this component.
0259:             * @return the activated nodes for this component or <code>null</code>, <code>null</code>
0260:             *         means such component does not change {@link Registry#getActivatedNodes()} just
0261:             *         {@link Registry#getCurrentNodes()} when this component gets activated */
0262:            public final Node[] getActivatedNodes() {
0263:                return activatedNodes;
0264:            }
0265:
0266:            /** Set the set of activated nodes in this component.
0267:             * @param activatedNodes activated nodes for this component
0268:             */
0269:            public final void setActivatedNodes(Node[] activatedNodes) {
0270:                assert multiviewActivatedNodes();
0271:                setActivatedNodesImpl(activatedNodes);
0272:            }
0273:
0274:            private boolean multiviewActivatedNodes() {
0275:                if ("org.netbeans.core.multiview.MultiViewTopComponent"
0276:                        .equals(this .getClass().getName())
0277:                        || //NOI18N
0278:                        "org.netbeans.core.multiview.MultiViewCloneableTopComponent"
0279:                                .equals(this .getClass().getName())) { //NOI18N
0280:                    LOG
0281:                            .info("Warning: You should not call setActivatedNodes()"
0282:                                    + //NOI18N
0283:                                    " on the multiview topcomponents. Instead please manipulate the lookup of the embedded MultiViewElements."
0284:                                    + //NOI18N
0285:                                    " For details, please see http://www.netbeans.org/issues/show_bug.cgi?id=67257");//NOI18N
0286:                }
0287:                return true;
0288:            }
0289:
0290:            private void setActivatedNodesImpl(Node[] activatedNodes) {
0291:                boolean l = LOG.isLoggable(Level.FINER);
0292:
0293:                if (Arrays.equals(this .activatedNodes, activatedNodes)) {
0294:                    if (l) {
0295:                        LOG.finer("No change to activatedNodes for " + this ); // NOI18N
0296:                    }
0297:                    return;
0298:                }
0299:
0300:                Lookup lookup = getLookup(false);
0301:
0302:                if (lookup instanceof  DefaultTopComponentLookup) {
0303:                    if (l) {
0304:                        LOG.finer("Updating lookup " + lookup + " for " + this ); // NOI18N
0305:                    }
0306:                    ((DefaultTopComponentLookup) lookup)
0307:                            .updateLookups(activatedNodes);
0308:                }
0309:
0310:                Node[] old = this .activatedNodes;
0311:                this .activatedNodes = activatedNodes;
0312:
0313:                if (l) {
0314:                    LOG.finer("activatedNodes changed: "
0315:                            + (activatedNodes == null ? "" : Arrays.asList(
0316:                                    activatedNodes).toString())); // NOI18N
0317:                }
0318:                // notify all that are interested...
0319:                WindowManager.getDefault().topComponentActivatedNodesChanged(
0320:                        this , this .activatedNodes);
0321:
0322:                if (l) {
0323:                    LOG.finer("window manager notified: " + this ); // NOI18N
0324:                }
0325:
0326:                firePropertyChange("activatedNodes", old, this .activatedNodes); // NOI18N
0327:
0328:                if (l) {
0329:                    LOG.finer("listeners notified: " + this ); // NOI18N
0330:                }
0331:            }
0332:
0333:            /**
0334:             * Overwrite when you want to change default persistence type. Default
0335:             * persistence type is PERSISTENCE_ALWAYS.
0336:             * Return value should be constant over a given TC's lifetime.
0337:             * @return one of P_X constants
0338:             * @since 4.20
0339:             */
0340:            public int getPersistenceType() {
0341:                //First check for 'PersistenceType' client property for compatibility.
0342:                if (warnedClasses.add(getClass())
0343:                        && !TopComponent.class.equals(getClass())) {
0344:                    Logger
0345:                            .getAnonymousLogger()
0346:                            .warning(
0347:                                    "Note - " // NOI18N
0348:                                            + getClass().getName()
0349:                                            + " ought to override getPersistenceType()" // NOI18N
0350:                                            + " rather than using the client property or accepting the default."); // NOI18N
0351:                }
0352:
0353:                String propValue = (String) getClientProperty("PersistenceType"); // NOI18N
0354:
0355:                if (propValue == null) {
0356:                    return PERSISTENCE_ALWAYS;
0357:                } else if ("Never".equals(propValue)) { // NOI18N
0358:
0359:                    return PERSISTENCE_NEVER;
0360:                } else if ("OnlyOpened".equals(propValue)) { // NOI18N
0361:
0362:                    return PERSISTENCE_ONLY_OPENED;
0363:                } else {
0364:                    return PERSISTENCE_ALWAYS;
0365:                }
0366:            }
0367:
0368:            /** Get the undo/redo support for this component.
0369:             * The default implementation returns a dummy support that cannot
0370:             * undo anything.
0371:             *
0372:             * @return undoable edit for this component
0373:             */
0374:            public UndoRedo getUndoRedo() {
0375:                return UndoRedo.NONE;
0376:            }
0377:
0378:            /** Shows this <code>TopComponent</code>.
0379:             * <em>Note:</em> This method only makes it visible, but does not
0380:             * activates it.
0381:             * @see #requestActive */
0382:            public void open() {
0383:                open(null);
0384:            }
0385:
0386:            /** Shows this <code>TopComponent</code> in current workspace.
0387:             * <em>Node:</em> Currently workspaces are not supported. The method has the same effect
0388:             * like {@link #open()}.
0389:             * @deprecated Use {@link #open()} instead. */
0390:            @Deprecated
0391:            public void open(Workspace workspace) {
0392:                WindowManager.getDefault().topComponentOpen(this );
0393:            }
0394:
0395:            /** Opens TopComponent at given position in the mode. TopComponent is inserted at given
0396:             * position, positions of already opened TopComponents in the same mode are
0397:             * incremented.
0398:             * 
0399:             * <ul>
0400:             *    <li>Does no operation if this TopComponent is already opened.</li>
0401:             *    <li>For position value less then 0, TopComponent is opened at position 0, the very first one.</li>
0402:             *    <li>For position value greater then count of opened TopComponents in the mode,
0403:             *          TopComponent is opened at last position</li>
0404:             * </ul>
0405:             * 
0406:             * @param position Index of the requested position.
0407:             * @since 6.15
0408:             */
0409:            public final void openAtTabPosition(int position) {
0410:                WindowManager.getDefault().topComponentOpenAtTabPosition(this ,
0411:                        position);
0412:            }
0413:
0414:            /** Gives position index of opened TopComponent in the mode.
0415:             * 
0416:             * For closed TopComponents, position value less then zero is returned.
0417:             * 
0418:             * @return Index of position.
0419:             * @since 6.15
0420:             */
0421:            public final int getTabPosition() {
0422:                return WindowManager.getDefault().topComponentGetTabPosition(
0423:                        this );
0424:            }
0425:
0426:            /** Indicates whether this <code>TopComponent</code> is opened.
0427:             * @return true if given top component is opened, false otherwise */
0428:            public final boolean isOpened() {
0429:                return isOpened(null);
0430:            }
0431:
0432:            /** Indicates whether this <code>TopComponent</code> is opened in current workspace.
0433:             * <em>Node:</em> Currently workspaces are not supported. The method has the same effect
0434:             * like {@link #isOpened()}.
0435:             * @deprecated Use {@link #isOpened()} instead. */
0436:            @Deprecated
0437:            public final boolean isOpened(Workspace workspace) {
0438:                return WindowManager.getDefault().topComponentIsOpened(this );
0439:            }
0440:
0441:            /** Closes this <code>TopComponent</code>.
0442:             * @return true if top component was succesfully closed, false if
0443:             * top component for some reason refused to close. */
0444:            public final boolean close() {
0445:                return close(null);
0446:            }
0447:
0448:            /** Closes this <code>TopComponent</code> in current workspace.
0449:             * <em>Node:</em> Currently workspaces are not supported. The method has the same effect
0450:             * like {@link #close()}.
0451:             * @deprecated Use {@link #close()} instead. */
0452:            @Deprecated
0453:            public final boolean close(Workspace workspace) {
0454:                if (!isOpened()) {
0455:                    return true;
0456:                }
0457:
0458:                if (canClose()) {
0459:                    WindowManager.getDefault().topComponentClose(this );
0460:
0461:                    return true;
0462:                } else {
0463:                    return false;
0464:                }
0465:            }
0466:
0467:            /** This method is called when this <code>TopComponent</code> is about to close.
0468:             * Allows subclasses to decide if <code>TopComponent</code> is ready to close.
0469:             * @since 4.13 */
0470:            public boolean canClose() {
0471:                if (!isOpened()) {
0472:                    return false;
0473:                }
0474:
0475:                return canClose(null, true);
0476:            }
0477:
0478:            /** This method is called when top component is about to close.
0479:             * Allows subclasses to decide if top component is ready for closing
0480:             * or not.<br>
0481:             * Default implementation always return true.
0482:             *
0483:             * @param workspace the workspace on which we are about to close or
0484:             *                  null which means that component will be closed
0485:             *                  on all workspaces where it is opened (CLOSE_EACH mode)
0486:             * @param last true if this is last workspace where top component is
0487:             *             opened, false otherwise. If close operation is set to
0488:             *             CLOSE_EACH, then this param is always true
0489:             * @return true if top component is ready to close, false otherwise.
0490:             * @deprecated Do not use anymore. Use {@link #canClose()} instead.
0491:             * Both parameters are redundant since workspaces are not supported anymore. */
0492:            @Deprecated
0493:            public boolean canClose(Workspace workspace, boolean last) {
0494:                return true;
0495:            }
0496:
0497:            /** Called only when top component was closed on all workspaces before and
0498:             * now is opened for the first time on some workspace. The intent is to
0499:             * provide subclasses information about TopComponent's life cycle across
0500:             * all existing workspaces.
0501:             * Subclasses will usually perform initializing tasks here.
0502:             * @deprecated Use {@link #componentOpened} instead. */
0503:            @Deprecated
0504:            protected void openNotify() {
0505:            }
0506:
0507:            /** Called only when top component was closed so that now it is closed
0508:             * on all workspaces in the system. The intent is to provide subclasses
0509:             * information about TopComponent's life cycle across workspaces.
0510:             * Subclasses will usually perform cleaning tasks here.
0511:             * @deprecated Use {@link #componentClosed} instead.
0512:             */
0513:            @Deprecated
0514:            protected void closeNotify() {
0515:            }
0516:
0517:            /** Gets the system actions which will appear in the popup menu of this component.
0518:             * @return array of system actions for this component
0519:             * @deprecated Use {@link #getActions()} instead.
0520:             */
0521:            @Deprecated
0522:            public SystemAction[] getSystemActions() {
0523:                return new SystemAction[0];
0524:            }
0525:
0526:            /** Gets the actions which will appear in the popup menu of this component.
0527:             * <p>Subclasses are encouraged to override this method to specify
0528:             * their own sets of actions.
0529:             * <p>Remember to call the super method when overriding and add your actions
0530:             * to the superclass' ones (in some order),
0531:             * because the default implementation provides support for standard
0532:             * component actions like save, close, and clone.
0533:             * @return array of actions for this component
0534:             * @since 3.32
0535:             */
0536:            public javax.swing.Action[] getActions() {
0537:                Action[] actions = WindowManager.getDefault()
0538:                        .topComponentDefaultActions(this );
0539:
0540:                SystemAction[] sysActions = getSystemActions();
0541:
0542:                // If there are some sys actions (i.e. the subclass overrided the defautl impl) add them.
0543:                if (sysActions.length > 0) {
0544:                    List<Action> acs = new ArrayList<Action>(Arrays
0545:                            .asList(actions));
0546:                    acs.addAll(Arrays.asList(sysActions));
0547:
0548:                    return acs.toArray(new Action[0]);
0549:                } else {
0550:                    return actions;
0551:                }
0552:            }
0553:
0554:            /** Set the close mode for the component.
0555:             * @param closeOperation one of {@link #CLOSE_EACH} or {@link #CLOSE_LAST}
0556:             * @throws IllegalArgumentException if an unrecognized close mode was supplied
0557:             * @see #close()
0558:             * @deprecated Do not use. It is redundant since workspaces are not supported anymore. */
0559:            @Deprecated
0560:            public final void setCloseOperation(final int closeOperation) {
0561:                if ((closeOperation != CLOSE_EACH)
0562:                        && (closeOperation != CLOSE_LAST)) {
0563:                    throw new IllegalArgumentException(NbBundle.getBundle(
0564:                            TopComponent.class).getString(
0565:                            "EXC_UnknownOperation"));
0566:                }
0567:
0568:                if (this .closeOperation == closeOperation) {
0569:                    return;
0570:                }
0571:
0572:                this .closeOperation = closeOperation;
0573:                firePropertyChange("closeOperation", null, null); // NOI18N
0574:            }
0575:
0576:            /** Get the current close mode for this component.
0577:             * @return one of {@link #CLOSE_EACH} or {@link #CLOSE_LAST}
0578:             * @deprecated Do not use. It is redundant since workspaces are not supported anymore. */
0579:            @Deprecated
0580:            public final int getCloseOperation() {
0581:                return closeOperation;
0582:            }
0583:
0584:            /**
0585:             * Subclasses are encouraged to override this method to provide preferred value
0586:             * for unique TopComponent ID returned by {@link org.openide.windows.WindowManager#findTopComponentID}.
0587:             *
0588:             * Returned value should be a String, preferably describing semantics of
0589:             * TopComponent subclass, such as "PieChartViewer" or "HtmlEditor" etc.
0590:             * Value is then used by window system as prefix value for creating unique
0591:             * TopComponent ID.
0592:             *
0593:             * Returned String value should be preferably unique, but need not be.
0594:             * @since 4.13
0595:             */
0596:            protected String preferredID() {
0597:                Class clazz = getClass();
0598:
0599:                if (getPersistenceType() != PERSISTENCE_NEVER
0600:                        && warnedTCPIClasses.add(clazz)) {
0601:                    Logger.getAnonymousLogger().warning(
0602:                            clazz.getName() + " should override preferredID()" //NOI18N
0603:                    );
0604:                }
0605:
0606:                String name = getName();
0607:
0608:                // fix for #47021 and #47115
0609:                if (name == null) {
0610:                    int ind = clazz.getName().lastIndexOf('.');
0611:                    name = (ind == -1) ? clazz.getName() : clazz.getName()
0612:                            .substring(ind + 1);
0613:                }
0614:
0615:                return name;
0616:            }
0617:
0618:            /** Called only when top component was closed on all workspaces before and
0619:             * now is opened for the first time on some workspace. The intent is to
0620:             * provide subclasses information about TopComponent's life cycle across
0621:             * all existing workspaces.
0622:             * Subclasses will usually perform initializing tasks here.
0623:             * @since 2.18 */
0624:            protected void componentOpened() {
0625:                openNotify();
0626:            }
0627:
0628:            /** Called only when top component was closed so that now it is closed
0629:             * on all workspaces in the system. The intent is to provide subclasses
0630:             * information about TopComponent's life cycle across workspaces.
0631:             * Subclasses will usually perform cleaning tasks here.
0632:             * @since 2.18 */
0633:            protected void componentClosed() {
0634:                closeNotify();
0635:            }
0636:
0637:            /** Called when <code>TopComponent</code> is about to be shown.
0638:             * Shown here means the component is selected or resides in it own cell
0639:             * in container in its <code>Mode</code>. The container is visible and not minimized.
0640:             * <p><em>Note:</em> component
0641:             * is considered to be shown, even its container window
0642:             * is overlapped by another window.</p>
0643:             * @since 2.18 */
0644:            protected void componentShowing() {
0645:            }
0646:
0647:            /** Called when <code>TopComponent</code> was hidden. <em>Nore</em>:
0648:             * <p><em>Note:</em> Beside typical situations when component is hidden,
0649:             * it is considered to be hidden even in that case
0650:             * the component is in <code>Mode</code> container hierarchy,
0651:             * the cointainer is visible, not minimized,
0652:             * but the component is neither selected nor in its own cell,
0653:             * i.e. it has it's own tab, but is not the selected one.
0654:             * @since 2.18 */
0655:            protected void componentHidden() {
0656:            }
0657:
0658:            /** Called when this component is activated.
0659:             * This happens when the parent window of this component gets focus
0660:             * (and this component is the preferred one in it), <em>or</em> when
0661:             * this component is selected in its window (and its window was already focussed).
0662:             * Remember to call the super method.
0663:             * The default implementation does nothing.
0664:             */
0665:            protected void componentActivated() {
0666:            }
0667:
0668:            /** Called when this component is deactivated.
0669:             * This happens when the parent window of this component loses focus
0670:             * (and this component is the preferred one in the parent),
0671:             * <em>or</em> when this component loses preference in the parent window
0672:             * (and the parent window is focussed).
0673:             * Remember to call the super method.
0674:             * The default implementation does nothing.
0675:             */
0676:            protected void componentDeactivated() {
0677:            }
0678:
0679:            /** Request focus for the window holding this top component.
0680:             * Also makes the component preferred in that window.
0681:             * The component will <em>not</em> be automatically {@link #open opened} first
0682:             * if it is not already.
0683:             * <p>Subclasses should override this method to transfer focus to desired
0684:             * focusable component. <code>TopComponent</code> itself is not focusable.
0685:             * See for example {@link org.openide.text.CloneableEditor#requestFocus}.
0686:             * @deprecated Use {@link #requestActive} instead to make TopComponent active
0687:             * in window system not only focused. This method should have been preserved
0688:             * for focus management only but not activation of <code>TopComponent</code> inside
0689:             * window system.
0690:             */
0691:            @Deprecated
0692:            @Override
0693:            public void requestFocus() {
0694:                if (isFocusable()) {
0695:                    //Issue 44304 - output window is focusable when empty, need some
0696:                    //way to give it focus
0697:                    super .requestFocus();
0698:                }
0699:            }
0700:
0701:            /** Request focus for the top component inside focused window.
0702:             * Also makes the component preferred in that window.
0703:             * The component will <em>not</em> be automatically {@link #open opened} first
0704:             * if it is not already.
0705:             * <p>Subclasses should override this method to transfer focus to desired
0706:             * focusable component. <code>TopComponent</code> itself is not focusable.
0707:             * See for example {@link org.openide.text.CloneableEditor#requestFocusInWindow}.
0708:             * @deprecated Use {@link #requestActive} instead to make TopComponent active
0709:             * in window system not only focused. This method should have been preserved
0710:             * for focus management only but not activation of <code>TopComponent</code> inside
0711:             * window system.
0712:             */
0713:            @Deprecated
0714:            @Override
0715:            public boolean requestFocusInWindow() {
0716:                if (isFocusable()) {
0717:                    return super .requestFocusInWindow();
0718:                } else {
0719:                    return false;
0720:                }
0721:            }
0722:
0723:            /** Activates this <code>TopComponent<code> if it is opened.
0724:             * @since 4.13 */
0725:            public void requestActive() {
0726:                WindowManager.getDefault().topComponentRequestActive(this );
0727:            }
0728:
0729:            /**
0730:             * Attempts to bring the parent <code>Window</code> or <code>Frame</code>
0731:             * of this <code>TopComponent<code> to front of other windows.
0732:             * @since 5.8
0733:             */
0734:            public void toFront() {
0735:                WindowManager.getDefault().topComponentToFront(this );
0736:            }
0737:
0738:            /** Selects this <code>TopComponent</code>, if it is opened, but does not activate it
0739:             * unless it is in active mode already. */
0740:            public void requestVisible() {
0741:                WindowManager.getDefault().topComponentRequestVisible(this );
0742:                org.netbeans.modules.openide.windows.GlobalActionContextImpl
0743:                        .blickActionMap(getActionMap());
0744:            }
0745:
0746:            /**
0747:             * Cause this TopComponent's tab to flash or otherwise draw attention to
0748:             * itself.  This method is thread-safe.
0749:             * <p>
0750:             * It will remain flashing until either <code>cancelRequestAttention</code>
0751:             * is called, the component becomes selected or its activated state changes,
0752:             * unless the <code>brief</code> argument is true, in which case it will stop
0753:             * after a few second.
0754:             * @param brief True if the tab should blink a few times and stop
0755:             * @since 5.1
0756:             */
0757:            public final void requestAttention(final boolean brief) {
0758:                //Reentrancy issues - always invoke later
0759:                EventQueue.invokeLater(new Runnable() {
0760:                    public void run() {
0761:                        if ((attentionGetter != null) && !brief) {
0762:                            attentionGetter.kill();
0763:                        } else if (!brief) {
0764:                            WindowManager.getDefault()
0765:                                    .topComponentRequestAttention(
0766:                                            TopComponent.this );
0767:                        } else if (attentionGetter != null) {
0768:                            attentionGetter.reset();
0769:                        } else {
0770:                            attentionGetter = new AttentionGetter();
0771:                        }
0772:                    }
0773:                });
0774:            }
0775:
0776:            /**
0777:             * Cause this TopComponent's tab to stop flashing if it was flashing.
0778:             * @since 5.1
0779:             */
0780:            public final void cancelRequestAttention() {
0781:                //Reentrancy issues - always invoke later
0782:                EventQueue.invokeLater(new Runnable() {
0783:                    public void run() {
0784:                        if (attentionGetter != null) {
0785:                            attentionGetter.stop();
0786:                        } else {
0787:                            WindowManager.getDefault()
0788:                                    .topComponentCancelRequestAttention(
0789:                                            TopComponent.this );
0790:                        }
0791:                    }
0792:                });
0793:            }
0794:
0795:            /** Set the name of this top component.
0796:             * The default implementation just notifies the window manager.
0797:             * @param name the new display name
0798:             */
0799:            public void setName(final String name) {
0800:                String old = getName();
0801:
0802:                if ((name != null) && (name.equals(old))) {
0803:                    return;
0804:                }
0805:
0806:                super .setName(name);
0807:                firePropertyChange("name", old, name); // NOI18N
0808:
0809:                // XXX When displayName is null, it is used the name.
0810:                WindowManager.getDefault().topComponentDisplayNameChanged(this ,
0811:                        name);
0812:            }
0813:
0814:            /** Sets localized display name of this <code>TopComponent</code>.
0815:             * @param displayName localized display name which is set
0816:             * @since 4.13 */
0817:            public void setDisplayName(String displayName) {
0818:                String old = this .displayName;
0819:
0820:                if ((displayName == old)
0821:                        || ((displayName != null) && displayName.equals(old))) {
0822:                    return;
0823:                }
0824:
0825:                // warning if display name contains html tags
0826:                if (BasicHTML.isHTMLString(displayName)) {
0827:                    Logger
0828:                            .getAnonymousLogger()
0829:                            .warning(
0830:                                    "Call of "
0831:                                            + getClass().getName()
0832:                                            + ".setDisplayName(\""
0833:                                            + displayName
0834:                                            + "\")"
0835:                                            + " shouldn't contain any HTML tags. Please use "
0836:                                            + getClass().getName()
0837:                                            + ".setHtmlDisplayName(String)"
0838:                                            + "for such purpose. For details please see http://www.netbeans.org/issues/show_bug.cgi?id=66777.");
0839:                }
0840:
0841:                this .displayName = displayName;
0842:                firePropertyChange("displayName", old, displayName); // NOI18N
0843:
0844:                WindowManager.getDefault().topComponentDisplayNameChanged(this ,
0845:                        displayName);
0846:            }
0847:
0848:            /** Gets localized display name of this <code>TopComponent</code>.
0849:             * @return localized display name or <code>null</code> if there is none
0850:             * @since 4.13 */
0851:            public String getDisplayName() {
0852:                return displayName;
0853:            }
0854:
0855:            /** Sets localized html display name of this <code>TopComponent</code>.
0856:             * Hmtl name usually contains basic html tags for text coloring and style.
0857:             * Html name may be null if not needed.
0858:             * Must apparently begin with <code>&lt;html&gt;</code>.
0859:             *
0860:             * @param htmlDisplayName localized html display name which is set
0861:             *
0862:             * @since 6.4
0863:             */
0864:            public void setHtmlDisplayName(String htmlDisplayName) {
0865:                String old = this .htmlDisplayName;
0866:
0867:                if ((htmlDisplayName == old)
0868:                        || ((htmlDisplayName != null) && htmlDisplayName
0869:                                .equals(old))) {
0870:                    return;
0871:                }
0872:
0873:                this .htmlDisplayName = htmlDisplayName;
0874:                firePropertyChange("htmlDisplayName", old, htmlDisplayName); // NOI18N
0875:
0876:                WindowManager.getDefault().topComponentHtmlDisplayNameChanged(
0877:                        this , htmlDisplayName);
0878:            }
0879:
0880:            /** Gets localized display name of this <code>TopComponent</code> with added
0881:             * html tags for text coloring and/or font style. May return null.
0882:             * Must apparently begin with <code>&lt;html&gt;</code>.
0883:             *
0884:             * @return localized html display name or <code>null</code> if there is none
0885:             *
0886:             * @since 6.4
0887:             */
0888:            public String getHtmlDisplayName() {
0889:                return htmlDisplayName;
0890:            }
0891:
0892:            /** Sets toolTip for this <code>TopComponent</code>, adds notification
0893:             * about the change to its <code>WindowManager.TopComponentManager</code>. */
0894:            public void setToolTipText(String toolTip) {
0895:                if ((toolTip != null) && toolTip.equals(getToolTipText())) {
0896:                    return;
0897:                }
0898:
0899:                super .setToolTipText(toolTip);
0900:
0901:                // XXX #19428. Container updates name and tooltip in the same handler.
0902:                WindowManager.getDefault().topComponentToolTipChanged(this ,
0903:                        toolTip);
0904:            }
0905:
0906:            /** Set the icon of this top component.
0907:             * The icon will be used for
0908:             * the component's representation on the screen, e.g. in a multiwindow's tab.
0909:             * The default implementation just notifies the window manager.
0910:             * @param icon New components' icon.
0911:             */
0912:            public void setIcon(final Image icon) {
0913:                if (icon == this .icon) {
0914:                    return;
0915:                }
0916:
0917:                Image old = this .icon;
0918:                this .icon = icon;
0919:
0920:                WindowManager.getDefault().topComponentIconChanged(this ,
0921:                        this .icon); // TEMP
0922:
0923:                firePropertyChange("icon", old, icon); // NOI18N
0924:            }
0925:
0926:            /** @return The icon of the top component */
0927:            public Image getIcon() {
0928:                return icon;
0929:            }
0930:
0931:            /** Get the help context for this component.
0932:             * Subclasses should generally override this to return specific help.
0933:             * @return the help context
0934:             */
0935:            public HelpCtx getHelpCtx() {
0936:                return new HelpCtx(TopComponent.class); // XXX #63303
0937:            }
0938:
0939:            /** Allows top component to specify list of modes into which can be docked
0940:             * by end user. Subclasses should override this method if they want to
0941:             * alter docking policy of top component. <p>
0942:             * So for example, by returning empty list, top component refuses
0943:             * to be docked anywhere. <p>
0944:             * Default implementation allows docking anywhere by returning
0945:             * input list unchanged.
0946:             *
0947:             * @param modes list of {@link Mode} which represent all modes of current
0948:             * workspace, can contain nulls. Items are structured in logical groups
0949:             * separated by null entries. <p>
0950:             * Input array also contains special constant modes for docking
0951:             * into newly created frames. Their names are "SingleNewMode",
0952:             * "MultiNewMode", "SplitNewMode", can be used for their
0953:             * recognition. Please note that names and existence of special modes
0954:             * can change in future releases.
0955:             *
0956:             * @return list of {@link Mode} which are available for dock, can contain nulls
0957:             * @since 2.14
0958:             */
0959:            public List<Mode> availableModes(List<Mode> modes) {
0960:                return modes;
0961:            }
0962:
0963:            /** Overrides superclass method, adds possible additional handling of global keystrokes
0964:             * in case this <code>TopComoponent</code> is ancestor of focused component. */
0965:            protected boolean processKeyBinding(KeyStroke ks, KeyEvent e,
0966:                    int condition, boolean pressed) {
0967:                boolean ret = super 
0968:                        .processKeyBinding(ks, e, condition, pressed);
0969:
0970:                // XXX #30189 Reason of overriding: to process global shortcut.
0971:                if ((JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT == condition)
0972:                        && (ret == false) && !e.isConsumed()) { // NOI18N
0973:
0974:                    Keymap km = Lookup.getDefault().lookup(Keymap.class);
0975:                    Action action = (km != null) ? km.getAction(ks) : null;
0976:
0977:                    if (action == null) {
0978:                        return false;
0979:                    }
0980:
0981:                    // If necessary create context aware instance.
0982:                    if (action instanceof  ContextAwareAction) {
0983:                        Action delegate = ((ContextAwareAction) action)
0984:                                .createContextAwareInstance(getLookup());
0985:                        if (delegate.isEnabled() || getActivatedNodes() != null)
0986:                            action = delegate;
0987:                        //else 
0988:                        //  use the global instance which might be enabled if it can survive focus changes
0989:
0990:                    } else if (SwingUtilities.getWindowAncestor(e
0991:                            .getComponent()) instanceof  java.awt.Dialog) {
0992:                        // #30303 For 'old type' actions check the transmodal flag,
0993:                        // if invoked in dialog. See ShorcutAndMenuKeyEventProcessor in core.
0994:                        Object value = action
0995:                                .getValue("OpenIDE-Transmodal-Action"); // NOI18N
0996:
0997:                        if (!Boolean.TRUE.equals(value)) {
0998:                            return false;
0999:                        }
1000:                    }
1001:
1002:                    if (action.isEnabled()) {
1003:                        LogRecord rec = new LogRecord(Level.FINER,
1004:                                "UI_ACTION_KEY_PRESS"); // NOI18N
1005:                        rec.setParameters(new Object[] { ks, ks.toString(),
1006:                                action.toString(), action.getClass().getName(),
1007:                                action.getValue(Action.NAME) });
1008:                        rec.setResourceBundle(NbBundle
1009:                                .getBundle(TopComponent.class));
1010:                        rec.setLoggerName(UILOG.getName());
1011:                        UILOG.log(rec);
1012:
1013:                        ActionEvent ev = new ActionEvent(this ,
1014:                                ActionEvent.ACTION_PERFORMED, Utilities
1015:                                        .keyToString(ks));
1016:                        action.actionPerformed(ev);
1017:                    } else {
1018:                        Toolkit.getDefaultToolkit().beep();
1019:                    }
1020:
1021:                    return true;
1022:                } else {
1023:                    return ret;
1024:                }
1025:            }
1026:
1027:            /** Serialize this top component.
1028:             * Subclasses wishing to store state must call the super method, then write to the stream.
1029:             * @param out the stream to serialize to
1030:             */
1031:            public void writeExternal(ObjectOutput out) throws IOException {
1032:                out.writeObject(new Short(serialVersion));
1033:                out.writeInt(closeOperation);
1034:                out.writeObject(getName());
1035:                out.writeObject(getToolTipText());
1036:
1037:                if (getDisplayName() != null) {
1038:                    out.writeObject(getDisplayName());
1039:                }
1040:
1041:                Node n = (nodeName == null) ? null : nodeName.getNode();
1042:                Node.Handle h = (n == null) ? null : n.getHandle();
1043:                out.writeObject(h);
1044:            }
1045:
1046:            /** Deserialize this top component.
1047:             * Subclasses wishing to store state must call the super method, then read from the stream.
1048:             * @param in the stream to deserialize from
1049:             */
1050:            public void readExternal(ObjectInput in) throws IOException,
1051:                    ClassNotFoundException {
1052:                Object firstObject = in.readObject();
1053:
1054:                if (firstObject instanceof  Integer) {
1055:                    // backward compatibility read
1056:                    serialVersion = 0;
1057:
1058:                    closeOperation = ((Integer) firstObject).intValue();
1059:
1060:                    // BCR: this is backward compatibility read and is likely not needed
1061:                    // BCR: anymore. So let's just ignore the read of the data object
1062:                    // BCR:     DataObject obj = (DataObject)in.readObject();
1063:                    in.readObject();
1064:
1065:                    super .setName((String) in.readObject());
1066:                    setToolTipText((String) in.readObject());
1067:
1068:                    // initialize the connection to a data object
1069:
1070:                    /* BCR: Remove this as we ignore the DataObject
1071:                                if (obj != null) {
1072:                                    nodeName = new NodeName (this);
1073:                                    nodeName.attach (obj.getNodeDelegate ());
1074:                                }
1075:                     */
1076:                } else {
1077:                    // new serialization
1078:                    serialVersion = ((Short) firstObject).shortValue();
1079:
1080:                    closeOperation = in.readInt();
1081:                    super .setName((String) in.readObject());
1082:                    setToolTipText((String) in.readObject());
1083:
1084:                    Object obj = in.readObject();
1085:
1086:                    if (obj instanceof  String) {
1087:                        setDisplayName((String) obj);
1088:                        obj = in.readObject();
1089:                    }
1090:
1091:                    Node.Handle h = (Node.Handle) obj;
1092:
1093:                    if (h != null) {
1094:                        Node n = h.getNode();
1095:                        NodeName.connect(this , n);
1096:                    }
1097:                }
1098:
1099:                if ((closeOperation != CLOSE_EACH)
1100:                        && (closeOperation != CLOSE_LAST)) {
1101:                    throw new IOException("invalid closeOperation: "
1102:                            + closeOperation); // NOI18N
1103:                }
1104:            }
1105:
1106:            /** Delegates instance of replacer class to be serialized instead
1107:             * of top component itself. Replacer class calls writeExternal and
1108:             * constructor, readExternal and readResolve methods properly, so
1109:            8 any top component can behave like any other externalizable object.
1110:             * Subclasses can override this method to perform their
1111:             * serialization differentrly */
1112:            protected Object writeReplace() throws ObjectStreamException {
1113:                return new Replacer(this );
1114:            }
1115:
1116:            /* Read accessible context
1117:             * @return - accessible context
1118:             */
1119:            public AccessibleContext getAccessibleContext() {
1120:                if (accessibleContext == null) {
1121:                    accessibleContext = new JComponent.AccessibleJComponent() {
1122:                        public AccessibleRole getAccessibleRole() {
1123:                            return AccessibleRole.PANEL;
1124:                        }
1125:
1126:                        public String getAccessibleName() {
1127:                            if (accessibleName != null) {
1128:                                return accessibleName;
1129:                            }
1130:
1131:                            return getName();
1132:                        }
1133:
1134:                        /* Fix for 19344: Null accessible decription of all TopComponents on JDK1.4 */
1135:                        public String getToolTipText() {
1136:                            return TopComponent.this .getToolTipText();
1137:                        }
1138:                    };
1139:                }
1140:
1141:                return accessibleContext;
1142:            }
1143:
1144:            /** Gets lookup which represents context of this component. By default
1145:             * the lookup delegates to result of <code>getActivatedNodes</code>
1146:             * method and result of this component <code>ActionMap</code> delegate.
1147:             * 
1148:             * If you override the method in your subclass, the default activatedNodes<->lookup synchronization
1149:             * will not be performed. That can influence functionality that relies on activated Nodes being present 
1150:             * in the TopComponent's lookup. If you want to preserve the synchronization, use <code>associateLookup</code>
1151:             * instead.
1152:             *
1153:             * @return a lookup with designates context of this component
1154:             * @see org.openide.util.ContextAwareAction
1155:             * @see org.openide.util.Utilities#actionsToPopup(Action[], Lookup)
1156:             * @since 3.29
1157:             */
1158:            public Lookup getLookup() {
1159:                return getLookup(true);
1160:            }
1161:
1162:            /**
1163:             * @param init should a lookup be initialized if it is not?
1164:             * @return lookup or null
1165:             */
1166:            private Lookup getLookup(boolean init) {
1167:                synchronized (defaultLookupLock) {
1168:                    if (defaultLookupRef instanceof  Lookup) {
1169:                        return (Lookup) defaultLookupRef;
1170:                    }
1171:
1172:                    if (defaultLookupRef instanceof  Object[]) {
1173:                        return (Lookup) ((Object[]) defaultLookupRef)[0];
1174:                    }
1175:
1176:                    if (defaultLookupRef instanceof  java.lang.ref.Reference) {
1177:                        Object l = ((java.lang.ref.Reference) defaultLookupRef)
1178:                                .get();
1179:
1180:                        if (l instanceof  Lookup) {
1181:                            return (Lookup) l;
1182:                        }
1183:                    }
1184:
1185:                    if (!init) {
1186:                        return null;
1187:                    }
1188:
1189:                    Lookup lookup = new DefaultTopComponentLookup(this ); // Lookup of activated nodes and action map
1190:                    defaultLookupRef = new java.lang.ref.WeakReference<Lookup>(
1191:                            lookup);
1192:
1193:                    return lookup;
1194:                }
1195:            }
1196:
1197:            /** Associates the provided lookup with the component. So it will
1198:             * be returned from {@link #getLookup} method.
1199:             *
1200:             * @param lookup the lookup to associate
1201:             * @exception IllegalStateException if there already is a lookup registered
1202:             *   with this component
1203:             * @since 4.23
1204:             */
1205:            protected final void associateLookup(Lookup lookup) {
1206:                setLookup(lookup, true);
1207:            }
1208:
1209:            /** Associates the provided lookup with the component. So it will
1210:             * be returned from {@link #getLookup} method.
1211:             *
1212:             * @param lookup the lookup to associate
1213:             * @param sync synchronize return value of {@link #getActivatedNodes} with the
1214:             *   content of lookup?
1215:             * @exception IllegalStateException if there already is a lookup registered
1216:             *   with this component
1217:             */
1218:            final void setLookup(Lookup lookup, boolean sync) {
1219:                synchronized (defaultLookupLock) {
1220:                    if (defaultLookupRef != null) {
1221:                        throw new IllegalStateException("Trying to set lookup "
1222:                                + lookup + " but there already is "
1223:                                + defaultLookupRef + " for component: " + this ); // NOI18N
1224:                    }
1225:
1226:                    defaultLookupRef = lookup;
1227:
1228:                    if (sync) {
1229:                        defaultLookupRef = new Object[] { defaultLookupRef,
1230:                                new SynchronizeNodes(lookup) };
1231:                    }
1232:                    if (LOG.isLoggable(Level.FINE)) {
1233:                        LOG.fine("setLookup with " + lookup + " and sync: "
1234:                                + sync + " on " + this ); // NOI18N
1235:                    }
1236:                }
1237:            }
1238:
1239:            private void attachNodeName(NodeName nodeName) {
1240:                this .nodeName = nodeName;
1241:            }
1242:
1243:            /** Each top component that wishes to be cloned should implement
1244:             * this interface, so CloneAction can check it and call the cloneComponent
1245:             * method.
1246:             */
1247:            public static interface Cloneable {
1248:                /** Creates a clone of this component
1249:                 * @return cloned component.
1250:                 */
1251:                public TopComponent cloneComponent();
1252:            }
1253:
1254:            /** Registry of all top components.
1255:             * There is one instance that can be obtained via {@link TopComponent#getRegistry}
1256:             * and it permits listening to the currently selected element, and to
1257:             * the activated nodes assigned to it.
1258:             */
1259:            public static interface Registry {
1260:                /** Name of property for the set of opened components. */
1261:                public static final String PROP_OPENED = "opened"; // NOI18N
1262:
1263:                /** Name of property for the selected top component. */
1264:                public static final String PROP_ACTIVATED = "activated"; // NOI18N
1265:
1266:                /** Name of property for currently selected nodes. */
1267:                public static final String PROP_CURRENT_NODES = "currentNodes"; // NOI18N
1268:
1269:                /** Name of property for lastly activated nodes. */
1270:                public static final String PROP_ACTIVATED_NODES = "activatedNodes"; // NOI18N
1271:
1272:                /** Name of property for listening to TopComponents opened through open() call,
1273:                 * either by user or programmatically.
1274:                 * Fired property change event returns opened TopComponent from its getNewValue()
1275:                 */
1276:                public static final String PROP_TC_OPENED = "tcOpened"; // NOI18N
1277:
1278:                /** Name of property for listening to TopComponents closed through close() call,
1279:                 * either by user or programmatically.
1280:                 * Fired property change event returns closed TopComponent from its getNewValue().
1281:                 */
1282:                public static final String PROP_TC_CLOSED = "tcClosed"; // NOI18N
1283:
1284:                /** Get reference to a set of all opened componets in the system.
1285:                 *
1286:                 * @return live read-only set of {@link TopComponent}s
1287:                 */
1288:                public Set<TopComponent> getOpened();
1289:
1290:                /** Get the currently selected element.
1291:                 * @return the selected top component, or <CODE>null</CODE> if there is none
1292:                 */
1293:                public TopComponent getActivated();
1294:
1295:                /** Getter for the currently selected nodes.
1296:                 * @return array of nodes or null if no component activated or it returns
1297:                 *   null from getActivatedNodes ().
1298:                 */
1299:                public Node[] getCurrentNodes();
1300:
1301:                /** Getter for the lastly activated nodes. Comparing
1302:                 * to previous method it always remembers the selected nodes
1303:                 * of the last component that had ones.
1304:                 *
1305:                 * @return array of nodes (not null)
1306:                 */
1307:                public Node[] getActivatedNodes();
1308:
1309:                /** Add a property change listener.
1310:                 * @param l the listener to add
1311:                 */
1312:                public void addPropertyChangeListener(PropertyChangeListener l);
1313:
1314:                /** Remove a property change listener.
1315:                 * @param l the listener to remove
1316:                 */
1317:                public void removePropertyChangeListener(
1318:                        PropertyChangeListener l);
1319:            }
1320:
1321:            private class AttentionGetter implements  ActionListener {
1322:                Timer timer = null;
1323:
1324:                public AttentionGetter() {
1325:                    reset();
1326:                }
1327:
1328:                public void reset() {
1329:                    assert EventQueue.isDispatchThread();
1330:
1331:                    if (timer != null) {
1332:                        timer.stop();
1333:                    }
1334:
1335:                    start();
1336:                    timer = new Timer(3500, this );
1337:                    timer.setRepeats(false);
1338:                    timer.start();
1339:                }
1340:
1341:                private void start() {
1342:                    WindowManager.getDefault().topComponentRequestAttention(
1343:                            TopComponent.this );
1344:                }
1345:
1346:                public void kill() {
1347:                    timer.stop();
1348:                    attentionGetter = null;
1349:                }
1350:
1351:                private void stop() {
1352:                    if (timer != null) {
1353:                        timer.stop();
1354:                    }
1355:
1356:                    attentionGetter = null;
1357:                    WindowManager.getDefault()
1358:                            .topComponentCancelRequestAttention(
1359:                                    TopComponent.this );
1360:                    attentionGetter = null;
1361:                }
1362:
1363:                public void actionPerformed(ActionEvent ae) {
1364:                    stop();
1365:                }
1366:            }
1367:
1368:            /** This class provides the connection between the node name and
1369:             * a name of the component.
1370:             *
1371:             * @deprecated Please do not use. This support class does nothing much
1372:             * useful. If you need to synchronize display name of your TopComponent
1373:             * with some Node's display name, we recommend you to do it manually in
1374:             * your client's code.
1375:             */
1376:            @Deprecated
1377:            public static class NodeName extends NodeAdapter {
1378:                /** asociation with top component */
1379:                private TopComponent top;
1380:
1381:                /** weak ref to node we are attached to or null */
1382:                private Reference node;
1383:
1384:                /** Listener to node, used for weak listening */
1385:                private NodeListener nodeL;
1386:
1387:                /** Connects a top component and a node. The name of
1388:                 * component will be updated as the name of the node
1389:                 * changes.
1390:                 *
1391:                 * @param top top compoonent to modify its name
1392:                 * @param n node to take name from
1393:                 *
1394:                 * @since 4.3
1395:                 */
1396:                public static void connect(TopComponent top, Node n) {
1397:                    new NodeName(top).attach(n);
1398:                }
1399:
1400:                /** Constructs new name adapter that
1401:                 * can be attached to any node and will listen on changes
1402:                 * of its display name and modify the name of the component.
1403:                 *
1404:                 * @param top top component to modify its name
1405:                 * 
1406:                 * @deprecated Please do not use, public just by an accident.
1407:                 */
1408:                @Deprecated
1409:                public NodeName(TopComponent top) {
1410:                    this .top = top;
1411:                }
1412:
1413:                /** Listens to Node.PROP_DISPLAY_NAME.
1414:                 *
1415:                 * @deprecated Please do not use, public just by an accident.
1416:                 */
1417:                @Deprecated
1418:                public void propertyChange(PropertyChangeEvent ev) {
1419:                    if (ev.getPropertyName().equals(Node.PROP_DISPLAY_NAME)) {
1420:                        Node n = (Node) node.get();
1421:                        if (n != null) {
1422:                            top.setName(n.getDisplayName());
1423:                        }
1424:                    }
1425:                }
1426:
1427:                /** Attaches itself to a given node.
1428:                 */
1429:                private void attach(Node n) {
1430:                    synchronized (top) {
1431:                        node = new WeakReference<Node>(n);
1432:                        nodeL = WeakListeners.create(NodeListener.class, this ,
1433:                                n);
1434:                        n.addNodeListener(nodeL);
1435:                        top.attachNodeName(this );
1436:                        top.setActivatedNodes(new Node[] { n });
1437:                        top.setName(n.getDisplayName());
1438:                    }
1439:                }
1440:
1441:                private Node getNode() {
1442:                    return (Node) node.get();
1443:                }
1444:
1445:            } // end of NodeName
1446:
1447:            /** Instance of this class is serialized instead of TopComponent itself.
1448:             * Emulates behaviour of serialization of externalizable objects
1449:             * to keep TopComponent serialization compatible with previous versions. */
1450:            private static final class Replacer implements  Serializable {
1451:                /** SUID */
1452:                static final long serialVersionUID = -8897067133215740572L;
1453:
1454:                /** Asociation with top component which is to be serialized using
1455:                 * this replacer */
1456:                transient TopComponent tc;
1457:
1458:                public Replacer(TopComponent tc) {
1459:                    this .tc = tc;
1460:                }
1461:
1462:                private void writeObject(ObjectOutputStream oos)
1463:                        throws IOException, ClassNotFoundException {
1464:                    // write the name of the top component first
1465:                    oos.writeObject(tc.getClass().getName());
1466:
1467:                    // and now let top component to serialize itself
1468:                    tc.writeExternal(oos);
1469:                }
1470:
1471:                private void readObject(ObjectInputStream ois)
1472:                        throws IOException, ClassNotFoundException {
1473:                    // read the name of top component's class, instantiate it
1474:                    // and read its attributes from the stream
1475:                    String name = (String) ois.readObject();
1476:                    name = org.openide.util.Utilities.translate(name);
1477:
1478:                    try {
1479:                        ClassLoader loader = Lookup.getDefault().lookup(
1480:                                ClassLoader.class);
1481:
1482:                        if (loader == null) {
1483:                            loader = getClass().getClassLoader();
1484:                        }
1485:
1486:                        Class tcClass = Class.forName(name, true, loader);
1487:
1488:                        // instantiate class event if it has protected or private
1489:                        // default constructor
1490:                        java.lang.reflect.Constructor con = tcClass
1491:                                .getDeclaredConstructor(new Class[0]);
1492:                        con.setAccessible(true);
1493:
1494:                        try {
1495:                            tc = (TopComponent) con.newInstance(new Object[0]);
1496:                        } finally {
1497:                            con.setAccessible(false);
1498:                        }
1499:
1500:                        tc.readExternal(ois);
1501:
1502:                        // call readResolve() if present and use resolved value
1503:                        Method resolveMethod = findReadResolveMethod(tcClass);
1504:
1505:                        if (resolveMethod != null) {
1506:                            // check exceptions clause
1507:                            Class[] result = resolveMethod.getExceptionTypes();
1508:
1509:                            if ((result.length == 1)
1510:                                    && ObjectStreamException.class
1511:                                            .equals(result[0])) {
1512:                                // returned value type
1513:                                if (Object.class.equals(resolveMethod
1514:                                        .getReturnType())) {
1515:                                    // make readResolve accessible (it can have any access modifier)
1516:                                    resolveMethod.setAccessible(true);
1517:
1518:                                    // invoke resolve method and accept its result
1519:                                    try {
1520:                                        TopComponent unresolvedTc = tc;
1521:                                        tc = (TopComponent) resolveMethod
1522:                                                .invoke(tc);
1523:
1524:                                        if (tc == null) {
1525:                                            throw new java.io.InvalidObjectException(
1526:                                                    "TopComponent.readResolve() cannot return null." // NOI18N
1527:                                                            + " See http://www.netbeans.org/issues/show_bug.cgi?id=27849 for more info." // NOI18N
1528:                                                            + " TopComponent:"
1529:                                                            + unresolvedTc); // NOI18N
1530:                                        }
1531:                                    } finally {
1532:                                        resolveMethod.setAccessible(false);
1533:                                    }
1534:                                }
1535:                            }
1536:                        }
1537:                    } catch (Exception exc) {
1538:                        Throwable th = exc;
1539:
1540:                        // Extract target exception.
1541:                        if (th instanceof  InvocationTargetException) {
1542:                            th = ((InvocationTargetException) th)
1543:                                    .getTargetException();
1544:                        }
1545:
1546:                        // IOException throw directly.
1547:                        if (th instanceof  IOException) {
1548:                            throw (IOException) th;
1549:                        }
1550:
1551:                        // All others wrap into IOException.
1552:                        throw (IOException) new IOException(th.toString())
1553:                                .initCause(th);
1554:                    }
1555:                }
1556:
1557:                /** Resolve to original top component instance */
1558:                private Object readResolve() throws ObjectStreamException {
1559:                    return tc;
1560:                }
1561:
1562:                /** Tries to find readResolve method in given class. Finds
1563:                 * both public and non-public occurences of the method and
1564:                 * searches also in superclasses */
1565:                private static Method findReadResolveMethod(Class clazz) {
1566:                    Method result = null;
1567:                    Class[] params = new Class[0];
1568:
1569:                    // first try public occurences
1570:                    try {
1571:                        result = clazz.getMethod("readResolve", params); // NOI18N
1572:                    } catch (NoSuchMethodException exc) {
1573:                        // public readResolve does not exist
1574:                        // now try non-public occurences; search also in superclasses
1575:                        for (Class i = clazz; (i != null)
1576:                                && (i != TopComponent.class); i = i
1577:                                .getSuperclass()) { // perf: TC and its superclasses do not have readResolve method
1578:
1579:                            try {
1580:                                result = i.getDeclaredMethod("readResolve",
1581:                                        params); // NOI18N
1582:
1583:                                // get out of cycle if method found
1584:                                break;
1585:                            } catch (NoSuchMethodException exc2) {
1586:                                // readResolve does not exist in current class
1587:                            }
1588:                        }
1589:                    }
1590:
1591:                    return result;
1592:                }
1593:            }
1594:
1595:            // end of Replacer inner class
1596:
1597:            /** Synchronization between Lookup and getActivatedNodes
1598:             */
1599:            private class SynchronizeNodes implements 
1600:                    org.openide.util.LookupListener, Runnable {
1601:                private Lookup.Result<Node> res;
1602:
1603:                public SynchronizeNodes(Lookup l) {
1604:                    res = l.lookup(new Lookup.Template<Node>(Node.class));
1605:                    res.addLookupListener(this );
1606:                    resultChanged(null);
1607:                }
1608:
1609:                public void resultChanged(org.openide.util.LookupEvent ev) {
1610:                    boolean l = LOG.isLoggable(Level.FINE);
1611:                    if (l) {
1612:                        LOG.fine("lookup changed for " + TopComponent.this 
1613:                                + " is visible: "
1614:                                + TopComponent.this .isVisible()); // NOI18N
1615:                    }
1616:                    if (TopComponent.this .isVisible()
1617:                            && EventQueue.isDispatchThread()) {
1618:                        // run immediatelly
1619:                        run();
1620:                    } else {
1621:                        // replan
1622:                        EventQueue.invokeLater(this );
1623:                    }
1624:                    if (l) {
1625:                        LOG.fine("lookup changed exit " + TopComponent.this ); // NOI18N
1626:                    }
1627:                }
1628:
1629:                public void run() {
1630:                    boolean l = LOG.isLoggable(Level.FINE);
1631:
1632:                    Collection<? extends Node> nodes = res.allInstances();
1633:
1634:                    if (l) {
1635:                        LOG.fine("setting nodes for " + TopComponent.this 
1636:                                + " to " + nodes); // NOI18N
1637:                    }
1638:                    setActivatedNodesImpl(nodes.toArray(new Node[0]));
1639:                    if (l) {
1640:                        LOG.fine("setting nodes done for " + TopComponent.this 
1641:                                + " to " + nodes); // NOI18N
1642:                    }
1643:                }
1644:            } // end of SynchronizeNodes
1645:
1646:            private static class CloneWindowAction extends AbstractAction {
1647:                DelegateActionMap am;
1648:
1649:                public CloneWindowAction(DelegateActionMap am) {
1650:                    this .am = am;
1651:                }
1652:
1653:                public void actionPerformed(ActionEvent evt) {
1654:                    TopComponent.Cloneable self = (TopComponent.Cloneable) am
1655:                            .getComponent();
1656:                    if (self != null) {
1657:                        TopComponent cloned = self.cloneComponent();
1658:                        cloned.open();
1659:                        cloned.requestActive();
1660:                    }
1661:                }
1662:            } // end of CloneWindowAction
1663:
1664:            private static class CloseWindowAction extends AbstractAction {
1665:                DelegateActionMap am;
1666:
1667:                public CloseWindowAction(DelegateActionMap am) {
1668:                    this .am = am;
1669:                }
1670:
1671:                public void actionPerformed(ActionEvent evt) {
1672:                    TopComponent self = (TopComponent) am.getComponent();
1673:                    if (self != null) {
1674:                        self.close();
1675:                    }
1676:                }
1677:            } // end of CloseWindowAction
1678:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.