// 
//     Licensed to the Apache Software Foundation (ASF) under one
//     or more contributor license agreements.  See the NOTICE file
//     distributed with this work for additional information
//     regarding copyright ownership.  The ASF licenses this file
//     to you under the Apache License, Version 2.0 (the
//     "License"); you may not use this file except in compliance
//     with the License.  You may obtain a copy of the License at
// 
//       http://www.apache.org/licenses/LICENSE-2.0
// 
//     Unless required by applicable law or agreed to in writing,
//     software distributed under the License is distributed on an
//     "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
//     KIND, either express or implied.  See the License for the
//     specific language governing permissions and limitations
//     under the License.
//

= DevFaqAppLifecycleHooks
:jbake-type: wiki
:jbake-tags: wiki, devfaq, needsreview
:jbake-status: published
:keywords: Apache NetBeans wiki DevFaqAppLifecycleHooks
:description: Apache NetBeans wiki DevFaqAppLifecycleHooks
:toc: left
:toc-title:
:syntax: true

==== What are some of the hooks in the application's lifecycle I can plug into?

One major difference between developing a Platform application and a monolithic Java application is that there is no `main` method.  This sometimes leaves developers wondering where they can insert their own code.  This FAQ entry describes some places where this is possible.

Although a bit drastic for most cases, you can
replace the main class used to start NetBeans
(link:DevFaqPlatformAppAuthStrategies.asciidoc[DevFaqPlatformAppAuthStrategies])
with your own class and then delegate back to NetBeans' normal main class.
This offers you a hook early in the startup sequence without having to modify the launchers or shell scripts.

Any module may provide a link:http://bits.netbeans.org/dev/javadoc/org-openide-modules/org/openide/modules/ModuleInstall.html[ModuleInstall] implementation.  The `validate` method will be called before your module is even loaded, so it is the first module-level hook available in the startup sequence.  Note that many services and classes offered by the platform are unlikely to be initialized at this point.

A short time afterwards, the `restored` method will be called on each `ModuleInstall` class.
More services and classes will be initialized at this point than with the `validate` method, but the GUI will probably not yet be realized.
You can post some code to be executed when the UI is fully loaded like this:

[source,java]
----

@Override public void restored() {
    WindowManager.getDefault().invokeWhenUIReady(new Runnable() {
        public void run() {
            // any code here will be run with the UI is available
            SomeTopComponent.findInstance().open();
        }
    });
}
----

The `ModuleInstall` class offers two methods which let you plug into the exit sequence.
The `closing` method is called first and requires that you return a boolean value.
If `true`, then your module agrees to be closed,
but if `false`, then you will prevent the exit sequence from continuing.
The `close` method is called after all `ModuleInstall` classes return `true` from the `closing` method
and is the final hook in which modules can participate in the application's lifecycle.

Note that providing a `ModuleInstall` class will increase total startup time a little,
even if you have taken care to execute any long-running tasks from its methods in a background thread.
It is always preferable to register objects declaratively,
and/or run procedural code when it is first needed rather than eagerly.

Another major class in platform development is the link:http://bits.netbeans.org/dev/javadoc/org-openide-windows/org/openide/windows/TopComponent.html[TopComponent] class.
It offers several methods which allow you to hook into its lifecycle.

Here are some events you can hook into for when a `TopComponent` is opened:

* `JComponent.addNotify`
* `TopComponent.componentOpened`
* `TopComponent.componentShowing`
* `TopComponent.componentActivated`

When you set focus on a `TopComponent`, the `componentActivated` method is called.
Likewise, the `componentDeactivated` method is called when focus is moved away from that `TopComponent`.

Here are some events you can hook into for when a `TopComponent` is closed:

* `TopComponent.canClose`
* `JComponent.removeNotify`
* `TopComponent.componentHidden`
* `TopComponent.componentDeactivated`
* `TopComponent.componentClosed`

(The exact sequence in which the opening/closing hooks are invoked is not documented or guaranteed to remain constant.)

Note that you can return `false` from `TopComponent.canClose` to prevent the `TopComponent` from being closed at all.

Applies to: NetBeans 6.5 and later

==== Further reading

You can get more details along with code examples link:http://wiki.netbeans.org/BookNBPlatformCookbookCH01#Module_Installer[here].

=== Apache Migration Information

The content in this page was kindly donated by Oracle Corp. to the
Apache Software Foundation.

This page was exported from link:http://wiki.netbeans.org/DevFaqAppLifecycleHooks[http://wiki.netbeans.org/DevFaqAppLifecycleHooks] , 
that was last modified by NetBeans user Javydreamercsw 
on 2012-07-31T13:15:59Z.


*NOTE:* This document was automatically converted to the AsciiDoc format on 2018-02-07, and needs to be reviewed.
