Re: Creating window groups on Netbeans Platform with Annotations

Javier Ortiz <[email protected]>
Newsgroups gmane.comp.java.netbeans.modules.openide.devel
Message-ID <CAP3=pbP+PVtZRNBOFTHYGXOpC0m_51=CaYwC-2uMtQ=E-ODHsQ@mail.gmail.com>
Here's my solution in case someone else runs into this question:

Here's how I was able to make it work for anyone stumbling on this question:

I created a class and registered as a service based on this code
<http://www.smartcode.ch/netbeans-hide-show-topcomponent/>:

/**
 * Based on code from: http://www.smartcode.ch/netbeans-hide-show-topcomponent/
 *
 * @author Javier A. Ortiz Bultrón [email protected]
 */import java.util.HashMap;import java.util.Map;import
java.util.Set;import org.openide.util.Lookup;import
org.openide.util.lookup.ServiceProvider;import
org.openide.windows.Mode;import
org.openide.windows.TopComponent;import
org.openide.windows.WindowManager;
@ServiceProvider(service = ViewManager.class)public class ViewManager {

    private final Map<TopComponent, Mode> hiddenComponents;

    public ViewManager() {
        hiddenComponents = new HashMap<>();
    }

    public synchronized void showTopComponent(Class<? extends
TopComponent> topComponentClass) {

        for (Map.Entry<TopComponent, Mode> hiddenComponentEntry :
hiddenComponents.entrySet()) {
            TopComponent hiddenComponent = hiddenComponentEntry.getKey();

            if (hiddenComponent.getClass().equals(topComponentClass)) {
                Mode mode = hiddenComponentEntry.getValue();

WindowManager.getDefault().findMode(mode.getName()).dockInto(hiddenComponent);
                hiddenComponent.open();
                hiddenComponents.remove(hiddenComponent);
                break;
            }

        }
    }

    public synchronized void hideTopComponent(Class<? extends
TopComponent> topComponentClass) {

        Set<TopComponent> shownTopComponents =
WindowManager.getDefault().getRegistry().getOpened();

        for (TopComponent shownTopComponent : shownTopComponents) {
            if (shownTopComponent.getClass().equals(topComponentClass)) {
                Mode mode =
WindowManager.getDefault().findMode(shownTopComponent);

                hiddenComponents.put(shownTopComponent, mode);
                shownTopComponent.close();
            }
        }
    }

    public synchronized void showAll() {
        for (TopComponent tc : hiddenComponents.keySet()) {
            showTopComponent(tc.getClass());
        }
    }

    /**
     * Load a screen role.
     *
     * @param role Role to load.
     */
    public static void loadRole(String role) {
        //Open all components
        Lookup.getDefault().lookup(ViewManager.class).showAll();
        //Change role (this closes the ones not in this role)
        WindowManager.getDefault().setRole(role);
    }}

Then in a module installer I do this:

@Override
    public void restored() {
        WindowManager.getDefault().invokeWhenUIReady(() -> {
            /**
             * All windows start opened. Populated the ViewManager. It is
             * important to configure all TopComponents with:
             * persistenceType = TopComponent.PERSISTENCE_NEVER or
TopComponent.PERSISTENCE_ONLY_OPENED
             * and openAtStartup = true
             */
            ViewManager manager = Lookup.getDefault().lookup(ViewManager.class);
            WindowManager.getDefault().getRegistry().getOpened().stream()
                    .forEach((tc) -> {
                        manager.hideTopComponent(tc.getClass());
                    });
            manager.loadRole(Tool.LOBBY);
        });
    }

The trick, as documented in the Installer code, is to mark all modules to
open at start up and with the right persistence type.

This will open all windows on the application start, hide them (while
registering them on the ViewManager) and then open the specified role.

Roles, as documented here
<http://bits.netbeans.org/dev/javadoc/org-openide-windows/org/openide/windows/WindowManager.html#setRole-java.lang.String->,
do the following:

The default implementation of this method does the following:

   1. Hide the main window.
   2. Save the current window layout of the current role.
   3. Load new window layout from the given role.
   4. Show the main window.

Another option would be overriding the WindowManager itself to do all of
this but I found it to be way too invasive and dangerous as some methods
are protected so it's not possible to wrap the WindowsManagerImpl (the
default). Also is impossible to just extend WindowsManagerImpl as this it's
package is private.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.