X

Geertjan's Blog

  • December 22, 2011

Singleton/Non-Singleton TopComponent via Annotations

Geertjan Wielenga
Product Manager

This is a TopComponent with the annotations created by the New Window wizard:

import org.openide.awt.ActionID;
import org.openide.awt.ActionReference;
import org.openide.util.NbBundle;
import org.openide.windows.TopComponent;
@TopComponent.Description(preferredID = "MySingletonTopComponent",
persistenceType = TopComponent.PERSISTENCE_ALWAYS)
@TopComponent.Registration(mode = "editor", openAtStartup = true)
@ActionID(category = "Window", id = "org.test.module.MySingletonTopComponent")
@ActionReference(path = "Menu/Window")
@TopComponent.OpenActionRegistration(displayName = "#CTL_MySingletonAction",
preferredID = "MySingletonTopComponent")
@NbBundle.Messages({
    "CTL_MySingletonAction=MySingleton",
    "CTL_MySingletonTopComponent=MySingleton Window",
    "HINT_MySingletonTopComponent=This is a MySingleton window"
})
public class MySingletonTopComponent extends TopComponent {
     public MySingletonTopComponent() {
        setName(Bundle.CTL_MySingletonTopComponent());
        setToolTipText(Bundle.HINT_MySingletonTopComponent());
    }
}

However, I don't always want a singleton. So, if you change the annotations slightly, you have a non-singleton. All I did was remove the "preferredID" from the @TopComponent.OpenActionRegistration annotation (i.e., the bit you see in bold above) and now I can open multiple instances of the TopComponent below:

import org.openide.awt.ActionID;
import org.openide.awt.ActionReference;
import org.openide.util.NbBundle.Messages;
import org.openide.windows.TopComponent;
@TopComponent.Description(preferredID = "MyInstanceTopComponent",
persistenceType = TopComponent.PERSISTENCE_ALWAYS)
@TopComponent.Registration(mode = "editor", openAtStartup = true)
@ActionID(category = "Window", id = "org.test.module.MyInstanceTopComponent")
@ActionReference(path = "Menu/Window")
@TopComponent.OpenActionRegistration(displayName = "#CTL_MyInstanceTopComponentAction")
@Messages({
    "CTL_MyInstanceTopComponentAction=MyInstance",
    "CTL_MyInstanceTopComponent=MyInstance Window",
    "HINT_MyInstanceTopComponent=This is a MyInstance window"
})
public final class MyInstanceTopComponent extends TopComponent {
    public MyInstanceTopComponent() {
        setName(Bundle.CTL_MyInstanceTopComponent());
        setToolTipText(Bundle.HINT_MyInstanceTopComponent());
    }
}

Probably it means that the Action is unable to find the existing instance of the TopComponent, since it doesn't know its ID, and therefore creates a new one.

Join the discussion

Comments ( 7 )
  • Jesse Glick Thursday, December 22, 2011

    The annotations are only intended for singleton TCs. For non-singletons, they do not really buy you anything - you can always create a fresh TC of your custom type using its constructor and just call open() on it.


  • Geertjan Friday, December 23, 2011

    So all the @TopComponent.* annotations apply to singletons only? Then how does one dock a non-singleton window into a mode at startup? Via dockInto on a mode?


  • DrAhmedJava Thursday, January 5, 2012

    and what about hiding menus using annotation instead of xml layer file?


  • Mvek Tuesday, February 21, 2012

    Interesting, removing that attribute in annotation, have not helped me. Still the Windows menu entry opened only one instance. But of course, creating new action and creating and opening new instance of Top Componenet by open() method helps.


  • Alberto Tuesday, September 11, 2012

    I am afraid this is working for the reference action with path Menu/Window, but by removing preferredID, any ContextAware action launched for instance from a Node, won't create a new instance, unless you instanciate the TopComponent itself. Doing so, you are force to include the dependency between different modules.

    Is there any way to make it works from actions without adding the module dependency (invoking via WindowManager.getDefault.findInstace(TOP_COMPONENT_ID))?

    Thanks in advance.


  • Awais Monday, November 17, 2014

    On JButton actionlistener, this is my code

    TopComponent tcToOpen = WindowManager.getDefault().findTopComponent("MyFormsTopComponent"); tcToOpen.open();

    tcToOpen.requestActive();

    I want to open new Instance of the same TopComponent everytime I click on JButton.


  • Awais Tuesday, November 18, 2014

    How to open multiple instances of the TopComponent on button click


Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.