Archive

Posts Tagged ‘Toolbar’

Toolbar buttons with label

2012-04-16 8 comments

As default, any action in a NetBeans toolbar is displayed with an icon only. If you want to show also a label for a desired action you have to implement a Presenter.TOOLBAR. If you don’t want do this for each action, register a custom org.openide.awt.Actions.ButtonActionConnector like this:

/**
 * @see org.openide.awt.Actions#connect(AbstractButton, Action)
 */
@ServiceProvider(service = ButtonActionConnector.class, position = 100)
public class MyButtonActionConnector implements ButtonActionConnector {

   @Override
   public boolean connect(AbstractButton button, Action action) {
      String text = (String)action.getValue("menuText"); // NOI18N
      if (text != null) {
         button.setAction(action);
         button.setText(Actions.cutAmpersand(text));
         String desc = (String)action.getValue(Action.SHORT_DESCRIPTION);
         if (desc != null) {
            button.setToolTipText(desc);
         } else {
            button.setToolTipText((String)action.getValue(Action.NAME));
         }
         return true;
      }
      return false;
   }

   @Override
   public boolean connect(JMenuItem item, Action action, boolean popup) {
      return false; // use default implementation
   }
}

If the property menuText is set, the the button is configured with icon and text. The basic use of the menuText Property is (copied from @ActionRegistration‘s javadoc):

Provides the JMenuItem text if one wants to use other than the name of the action returned by ActionRegistration.displayName().

With the custom ButtonActionConnector this property is “extended” to show a toolbar button text if supplied.

Provide a value for the @ActionRegistration’s menuText Attribute for the desired action(s):

@ActionRegistration(displayName = "#CTL_PwdChangeAction",
                    menuText = "#CTL_PwdChangeAction",
                    iconBase = "resources/key.png")
@ActionReference(path = "Toolbars/User")
@Messages("CTL_PwdChangeAction=Change Password…")
public final class PwdChangeAction implements ActionListener {
   ...
}

Result:

or

Tested with NetBeans 7.1.1 (see comments)

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);
}
Categories: Java, NB Platform, NetBeans Tags: ,

Custom Toolbar Configuration

2010-08-19 6 comments

In my first NetBeans Platform post I show you how you can change the default toolbar configuration of your NetBeans Platform application:

  • Change the default toolbar icon size to 16px
  • Right aligned toolbar
  • Non-floating toolbar
  • Create your own set of Toolbar configuration

After reading this article about general toolbar configurations and some investigation in the NetBeans Platform source code I found the solution for the items above. The improved DTD for toolbar configuration (version 1.1) introduced with NetBeans V6.7 allows you to use the new attributes “align” and “dragable”, e.g.:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configuration PUBLIC "-//NetBeans IDE//DTD toolbar 1.1//EN"
 "http://www.netbeans.org/dtds/toolbar1_1.dtd">
<Configuration>
   <Row>
      <Toolbar name="File" visible="true" />
      <Toolbar name="Clipboard" visible="false"/>
      <Toolbar name="UndoRedo" visible="false"/>
      <Toolbar name="Memory" visible="true" draggable="false" align="right"/>
      <Toolbar name="Picture" visible="true" draggable="false" align="right"/>
   </Row>
</Configuration>

Overwrite the default toolbar configuration in the layer.xml:

<!-- http://wiki.netbeans.org/DevFaqHideShowToolbar -->
<!-- http://blogs.sun.com/geertjan/entry/toolbar_configurations -->
<folder name="Toolbars">
   <file name="MyToolbars.xml" url="res/MyToolbars.xml">
      <attr name="position" intvalue="100"/>
   </file>
</folder>

A NetBeans Platform application comes with the two toolbar sets:

  • Default
  • Debugging

In the example configuration above I created a new one named “MyToolbars”.

Now I want “MyToolbars” as my default toolbar configuration. Additionally I need to have 16px icons as default.
To achieve this, write a custom Window Manager Properties file:

<!-- File: res/windowManager.xml -->

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE windowmanager PUBLIC
          "-//NetBeans//DTD Window Manager Properties 2.1//EN"
          "http://www.netbeans.org/dtds/windowmanager-properties2_1.dtd">

<windowmanager version="2.1">
   <main-window> 
      <joined-properties centered-horizontally="true" centered-vertically="true"
                           relative-width="0.9" relative-height="0.9" />
      <separated-properties centered-horizontally="true" relative-y="0.1"
                           relative-width="0.8" relative-height="0.08" />
   </main-window>
   <editor-area state="joined">
      <constraints>
         <path orientation="horizontal" number="60" weight="0.7" />
         <path orientation="vertical" number="40" weight="0.7" />
         <path orientation="horizontal" number="40" weight="0.7" />
      </constraints>
      <relative-bounds x="33" y="24" width="42" height="44"/>
   </editor-area>
   <screen width="1280" height="1024" />
   <active-mode name="explorer" />
   <maximized-mode name="" />
   <toolbar configuration="MyToolbars" preferred-icon-size="16" />
</windowmanager>

… and registered in the layer.xml:

<folder name="Windows2">          
   <file name="WindowManager.wswmgr" url="res/windowManager.xml" />
</folder>
Categories: NB Platform Tags: ,