wiki-convert/wiki-asciidoc/DevFaqAddGlobalContext.asciidoc [259:409]:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
package com.emxsys.projectassistant;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Collection;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.netbeans.api.project.FileOwnerQuery;
import org.netbeans.api.project.Project;
import org.netbeans.api.project.ProjectUtils;
import org.netbeans.api.project.ui.OpenProjects;
import org.netbeans.modules.openide.windows.GlobalActionContextImpl;
import org.openide.explorer.ExplorerManager;
import org.openide.loaders.DataObject;
import org.openide.nodes.Node;
import org.openide.util.ContextGlobalProvider;
import org.openide.util.Lookup;
import org.openide.util.Lookup.Result;
import org.openide.util.Lookup.Template;
import org.openide.util.LookupEvent;
import org.openide.util.LookupListener;
import org.openide.util.lookup.AbstractLookup;
import org.openide.util.lookup.InstanceContent;
import org.openide.util.lookup.ProxyLookup;
import org.openide.util.lookup.ServiceProvider;
import org.openide.windows.TopComponent;
import org.openide.windows.WindowManager;


/**
 * This class proxies the original ContextGlobalProvider and ensures the current project remains in
 * the GlobalContext regardless of the TopComponent selection. The class also ensures that when a
 * child node is selected within the in Projects tab, the parent Project will be in the lookup.
 *
 * To use this class you must edit the Windows System API module dependency: change the dependency
 * to an implementation version so that the org.netbeans.modules.openide.windows package is on the
 * classpath.
 *
 * @see ContextGlobalProvider
 * @see GlobalActionContextImpl
 * @author Bruce Schubert
 */
@ServiceProvider(service = ContextGlobalProvider.class,
                 supersedes = "org.netbeans.modules.openide.windows.GlobalActionContextImpl")
public class GlobalActionContextProxy implements ContextGlobalProvider
{

    /** The native NetBeans global context Lookup provider */
    private final GlobalActionContextImpl globalContextProvider;
    /** Additional content for our proxy lookup */
    private final InstanceContent content;
    /** The primary lookup managed by the platform */
    private Lookup globalContextLookup;
    /** The project lookup managed by resultChanged */
    private Lookup projectLookup;
    /** The actual proxyLookup returned by this class */
    private Lookup proxyLookup;
    /** A lookup result that we listen to for Projects */
    private Result<Project> resultProjects;
    /** Listener for changes resultProjects */
    private final LookupListener resultListener;
    /** Listener for changes on the TopComponent registry */
    private final PropertyChangeListener registryListener;
    /** The last project selected */
    private Project lastProject;
    /** Critical section lock */
    private final Object lock = new Object();
    private static final Logger logger = Logger.getLogger(GlobalActionContextProxy.class.getName());
    public static final String PROJECT_LOGICAL_TAB_ID = "projectTabLogical_tc";
    public static final String PROJECT_FILE_TAB_ID = "projectTab_tc";

    public GlobalActionContextProxy()
    {
        this.content = new InstanceContent();
        
        // The default GlobalContextProvider
        this.globalContextProvider = new GlobalActionContextImpl();
        this.globalContextLookup = this.globalContextProvider.createGlobalContext();

        // Monitor the activation of the Projects Tab TopComponent
        this.registryListener = new RegistryPropertyChangeListener();
        TopComponent.getRegistry().addPropertyChangeListener(this.registryListener);

        // Monitor the existance of a Project in the principle lookup
        this.resultProjects = globalContextLookup.lookupResult(Project.class);
        this.resultListener = new LookupListenerImpl();
        this.resultProjects.addLookupListener(this.resultListener);

        WindowManager.getDefault().invokeWhenUIReady(new Runnable()
        {
            @Override
            public void run()
            {
                // Hack to force the current Project selection when the application starts up
                TopComponent tc = WindowManager.getDefault().findTopComponent(PROJECT_LOGICAL_TAB_ID);
                if (tc != null)
                {
                    tc.requestActive();
                }
            }
        });
    }

    /**
     * Returns a ProxyLookup that adds the current Project instance to the global selection 
     * returned by Utilities.actionsGlobalContext().
     *
     * @return a ProxyLookup that includes the original global context lookup.
     */
    @Override
    public Lookup createGlobalContext()
    {
        if (proxyLookup == null)
        {
            logger.config("Creating a proxy for Utilities.actionsGlobalContext()");
            // Create the two lookups that will make up the proxy
            projectLookup = new AbstractLookup(content);
            proxyLookup = new ProxyLookup(globalContextLookup, projectLookup);
        }
        return proxyLookup;
    }

    /**
     * This class populates the proxy lookup with the currently selected project 
     * found in the Projects tab.
     */
    private class RegistryPropertyChangeListener implements PropertyChangeListener
    {
        private TopComponent projectsTab = null;

        @Override
        public void propertyChange(PropertyChangeEvent event)
        {
            if (event.getPropertyName().equals(TopComponent.Registry.PROP_ACTIVATED_NODES)
                || event.getPropertyName().equals(TopComponent.Registry.PROP_ACTIVATED))
            {
                // Get a reference to the Projects window
                if (projectsTab == null)
                {
                    projectsTab = WindowManager.getDefault().findTopComponent(PROJECT_LOGICAL_TAB_ID);
                    if (projectsTab == null)
                    {
                        logger.severe("propertyChange: cannot find the Projects logical window ("
                                     + PROJECT_LOGICAL_TAB_ID + ")");
                        return;
                    }
                }
                // Look for the current project in the Projects window when activated and handle 
                // special case at startup when lastProject hasn't been initialized.            
                Node[] nodes = null;
                TopComponent activated = TopComponent.getRegistry().getActivated();
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -



wiki-export/wiki-wikimedia/DevFaqAddGlobalContext.mediawiki [233:383]:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
package com.emxsys.projectassistant;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Collection;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.netbeans.api.project.FileOwnerQuery;
import org.netbeans.api.project.Project;
import org.netbeans.api.project.ProjectUtils;
import org.netbeans.api.project.ui.OpenProjects;
import org.netbeans.modules.openide.windows.GlobalActionContextImpl;
import org.openide.explorer.ExplorerManager;
import org.openide.loaders.DataObject;
import org.openide.nodes.Node;
import org.openide.util.ContextGlobalProvider;
import org.openide.util.Lookup;
import org.openide.util.Lookup.Result;
import org.openide.util.Lookup.Template;
import org.openide.util.LookupEvent;
import org.openide.util.LookupListener;
import org.openide.util.lookup.AbstractLookup;
import org.openide.util.lookup.InstanceContent;
import org.openide.util.lookup.ProxyLookup;
import org.openide.util.lookup.ServiceProvider;
import org.openide.windows.TopComponent;
import org.openide.windows.WindowManager;


/**
 * This class proxies the original ContextGlobalProvider and ensures the current project remains in
 * the GlobalContext regardless of the TopComponent selection. The class also ensures that when a
 * child node is selected within the in Projects tab, the parent Project will be in the lookup.
 *
 * To use this class you must edit the Windows System API module dependency: change the dependency
 * to an implementation version so that the org.netbeans.modules.openide.windows package is on the
 * classpath.
 *
 * @see ContextGlobalProvider
 * @see GlobalActionContextImpl
 * @author Bruce Schubert
 */
@ServiceProvider(service = ContextGlobalProvider.class,
                 supersedes = "org.netbeans.modules.openide.windows.GlobalActionContextImpl")
public class GlobalActionContextProxy implements ContextGlobalProvider
{

    /** The native NetBeans global context Lookup provider */
    private final GlobalActionContextImpl globalContextProvider;
    /** Additional content for our proxy lookup */
    private final InstanceContent content;
    /** The primary lookup managed by the platform */
    private Lookup globalContextLookup;
    /** The project lookup managed by resultChanged */
    private Lookup projectLookup;
    /** The actual proxyLookup returned by this class */
    private Lookup proxyLookup;
    /** A lookup result that we listen to for Projects */
    private Result<Project> resultProjects;
    /** Listener for changes resultProjects */
    private final LookupListener resultListener;
    /** Listener for changes on the TopComponent registry */
    private final PropertyChangeListener registryListener;
    /** The last project selected */
    private Project lastProject;
    /** Critical section lock */
    private final Object lock = new Object();
    private static final Logger logger = Logger.getLogger(GlobalActionContextProxy.class.getName());
    public static final String PROJECT_LOGICAL_TAB_ID = "projectTabLogical_tc";
    public static final String PROJECT_FILE_TAB_ID = "projectTab_tc";

    public GlobalActionContextProxy()
    {
        this.content = new InstanceContent();
        
        // The default GlobalContextProvider
        this.globalContextProvider = new GlobalActionContextImpl();
        this.globalContextLookup = this.globalContextProvider.createGlobalContext();

        // Monitor the activation of the Projects Tab TopComponent
        this.registryListener = new RegistryPropertyChangeListener();
        TopComponent.getRegistry().addPropertyChangeListener(this.registryListener);

        // Monitor the existance of a Project in the principle lookup
        this.resultProjects = globalContextLookup.lookupResult(Project.class);
        this.resultListener = new LookupListenerImpl();
        this.resultProjects.addLookupListener(this.resultListener);

        WindowManager.getDefault().invokeWhenUIReady(new Runnable()
        {
            @Override
            public void run()
            {
                // Hack to force the current Project selection when the application starts up
                TopComponent tc = WindowManager.getDefault().findTopComponent(PROJECT_LOGICAL_TAB_ID);
                if (tc != null)
                {
                    tc.requestActive();
                }
            }
        });
    }

    /**
     * Returns a ProxyLookup that adds the current Project instance to the global selection 
     * returned by Utilities.actionsGlobalContext().
     *
     * @return a ProxyLookup that includes the original global context lookup.
     */
    @Override
    public Lookup createGlobalContext()
    {
        if (proxyLookup == null)
        {
            logger.config("Creating a proxy for Utilities.actionsGlobalContext()");
            // Create the two lookups that will make up the proxy
            projectLookup = new AbstractLookup(content);
            proxyLookup = new ProxyLookup(globalContextLookup, projectLookup);
        }
        return proxyLookup;
    }

    /**
     * This class populates the proxy lookup with the currently selected project 
     * found in the Projects tab.
     */
    private class RegistryPropertyChangeListener implements PropertyChangeListener
    {
        private TopComponent projectsTab = null;

        @Override
        public void propertyChange(PropertyChangeEvent event)
        {
            if (event.getPropertyName().equals(TopComponent.Registry.PROP_ACTIVATED_NODES)
                || event.getPropertyName().equals(TopComponent.Registry.PROP_ACTIVATED))
            {
                // Get a reference to the Projects window
                if (projectsTab == null)
                {
                    projectsTab = WindowManager.getDefault().findTopComponent(PROJECT_LOGICAL_TAB_ID);
                    if (projectsTab == null)
                    {
                        logger.severe("propertyChange: cannot find the Projects logical window ("
                                     + PROJECT_LOGICAL_TAB_ID + ")");
                        return;
                    }
                }
                // Look for the current project in the Projects window when activated and handle 
                // special case at startup when lastProject hasn't been initialized.            
                Node[] nodes = null;
                TopComponent activated = TopComponent.getRegistry().getActivated();
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -



