// 
//     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.
//

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

=== How do I identify the "main project"?

[source,java]
----

Project mainProject = org.netbeans.api.project.ui.OpenProjects.getDefault().getMainProject();
----

For this, you need to declare dependencies on Project UI API, Project API and File System API.

As an example usage of the above line of code, here is an action that display a JOptionPane containing the path to the main project, if a project is selected:

[source,java]
----

public final class ShowMainProjectAction extends CookieAction {

    protected void performAction(Node[] activatedNodes) {
        String projectPath = OpenProjects.getDefault().getMainProject().getProjectDirectory().getPath();
        JOptionPane.showMessageDialog(null, projectPath);
    }

    protected int mode() {
        return CookieAction.MODE_EXACTLY_ONE;
    }

    public String getName() {
        return NbBundle.getMessage(ShowMainProjectAction.class, "CTL_ShowMainProjectAction");
    }

    protected Class[] cookieClasses() {
        return new Class[]{Project.class};
    }

    @Override
    protected void initialize() {
        super.initialize();
        // see org.openide.util.actions.SystemAction.iconResource() Javadoc for more details
        putValue("noIconInMenu", Boolean.TRUE);
    }

    public HelpCtx getHelpCtx() {
        return HelpCtx.DEFAULT_HELP;
    }

    @Override
    protected boolean asynchronous() {
        return false;
    }
}
----

=== 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/DevFaqIdentifyMain[http://wiki.netbeans.org/DevFaqIdentifyMain] , 
that was last modified by NetBeans user Admin 
on 2009-11-06T15:46:33Z.


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