Home > Java, NB Platform, NetBeans > Dynamically show/hide individual toolbars

Dynamically show/hide individual toolbars

In NetBeans you can define your own toolbar configurations (a set of visible/invisible toolbars). DevFaqHideShowToolbar shows you how you can activate a specific toolbar configuration at runtime. But how can I show an individual toolbar dynamically? For example, to show/hide certain toolbar(s) by the visibility of a TopComponent.

An explicit Toolbar API isn’t available in the NetBeans Platform. The class org.openide.awt.ToolbarPool is used to install and update the configured toolbars. With the constructor public ToolbarPool(DataFolder df) an own toolbar configuration at the specified location in the layer.xml (DataFolder) can be created.

But I don’t want create a new toolbar configuration for each TopComponent who should have their own toolbars. The idea is:

  1. Declare the toolbar for the TopComponent at a certain location (!= Toolbars/) in the module’s layer.xml
  2. Register the toolbar in the active toolbar configuration
  3. show the toolbar on TopComponent#componentOpened()
  4. hide the toolbar on TopComponent#componentClosed()

All these steps should be performed dynamically at runtime. How can I achieve this? Let’s go ahead…

Declare the toolbar

<!-- file: layer.xml -->
<filesystem>
   ...
   <folder name="MyModule">
      <folder name="Toolbars">
         <folder name="MyToolbar">
            <attr name="displayName" stringvalue="My Toolbar" />
            <file name="my-action-1.instance">
               ...
            </file>
         </folder>
      </folder>
   </folder>
</filesystem>

Register the toolbar in the active toolbar configuration
Using a shadow entry any custom toolbar is registered once in the default toolbar pool (at Toolbars/):

public static boolean registerToolbar(String toolbarConfigPath) {
   try {
      FileObject fo = FileUtil.getConfigFile(toolbarConfigPath);
      if (fo == null) {
         return false;
      }
      DataFolder df = DataFolder.findFolder(fo);
      DataFolder target = ToolbarPool.getDefault().getFolder();
      FileObject targetFO = target.getPrimaryFile().getFileObject(fo.getNameExt() + ".shadow");

      if (df != null && targetFO == null) {
         DataShadow ds = df.createShadow(target);
         return true;
      }
   } catch (IOException ex) {
      Exceptions.printStackTrace(ex);
   }
   return false;
}

Show/hide the toolbar
For programatically hide and show a toolbar you can write:

Toolbar toolbar = ToolbarPool.getDefault().findToolbar("MyToolbar");
toolbar.getParent().setVisible(false);

The drawback is that the visible state of the toolbar will not be propagated to the toolbar context menu actions.

After debugging I found this solution (or hack):

public static void setToolbarVisible(Toolbar toolbar, boolean visible) {
   try {
      ClassLoader cl = Lookup.getDefault().lookup(ClassLoader.class);
      Class cToolbarConfiguration = cl.loadClass("org.netbeans.core.windows.view.ui.toolbars.ToolbarConfiguration");
      // invoke static ToolbarConfiguration.findConfiguration( String name)
      Object toolbarConfig = cToolbarConfiguration.getMethod("findConfiguration", String.class).
              invoke(cToolbarConfiguration, "Standard");
      // invoke ToolbarConfiguration#setToolbarVisible( Toolbar tb, boolean visible)
      toolbarConfig.getClass().getMethod("setToolbarVisible", Toolbar.class, boolean.class).invoke(toolbarConfig, toolbar, visible);
   } catch (Exception ex) {
      throw new IllegalArgumentException(ex);
   }
}

Link the toolbar together with the TopComponent’s visibility state (simplified):

String toolbarName = "MyToolbar";

public final void componentOpened() {
   ToolbarUtil.registerToolbar("MyModule/Toolbars/" + toolbarName);
   ToolbarUtil.setToolbarVisible(toolbarName, true);
}

public final void componentClosed() {
  ToolbarUtil.setToolbarVisible(toolbarName, false);
}
Advertisements
Categories: Java, NB Platform, NetBeans Tags: ,
  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: