Over a million developers have joined DZone.

How to Create a Tabbed Toolbar on the NetBeans Platform

· Java Zone

Discover how powerful static code analysis and ergonomic design make development not only productive but also an enjoyable experience, brought to you in partnership with JetBrains

One of the many enviable features of the Maltego client, the NetBeans Platform app that is part of some very powerful intelligence gathering software, is its really cool tabbed toolbar:

Take note of the "Investigate" and "Manage" tabs in the toolbar. Pretty neat. Maybe you want something just like that in your own NetBeans Platform application? In the case of Maltego, the tabbed toolbar is the ribbon bar from the Flamingo Library that is installed by the OfficeLAF. The Flamingo ribbon bars can have multiple tabs, which explains how Maltego ends up with a tabbed toolbar.

However, what if you don't want to use OfficeLAF and you don't want to use Flamingo? I asked Chris Bohme, the lead developer behind Maltego, and he sent me the code that results in the toolbar used in this small sample application on the NetBeans Platform:

Let's first look at the general steps taken to achieve the above result and then look at the actual code, so that you can create your own tabbed toolbar right away. These instructions come directly from the details sent me by Chris:

  1. Tell the Window System to hide the main toolbar.
  2. Install a new toolbar component into the layered pane of the main frame on layer 0.
  3. Provide a custom layout for the root pane that respects the toolbar component's preferred height and positions the content pane accordingly.

So, how to do all of the above? The steps below describe everything involved here.

Hiding the Main Toolbar

In your ModuleInstall class, within the "restored()" method, add this line:

System.setProperty("netbeans.winsys.no_toolbars", "true");

Note: More properties just like that are listed in the Window System API javadoc.

Hurray now you have no toolbar anymore. Next, we need to create our own.

Adding a Custom Main Toolbar

Our custom main toolbar will be a JTabbedPane (since, after all, we want tabs in our toolbar). The definition of the JTabbedPane is provided below by the "DefaultToolbarComponentProvider" class. We need to make sure that the main toolbar is a singleton, so we expose a public "getDefault()" method, which only provides an instance of our main toolbar if none already exists.

public abstract class ToolbarComponentProvider {

    public abstract JComponent createToolbar();

    public static ToolbarComponentProvider getDefault() {
        ToolbarComponentProvider provider = Lookup.getDefault().lookup(ToolbarComponentProvider.class);
        if (provider == null) {
            provider = new DefaultToolbarComponentProvider();
        }
        return provider;
    }

    private static class DefaultToolbarComponentProvider extends ToolbarComponentProvider {
        @Override
        public JComponent createToolbar() {
            JTabbedPane pane = new JTabbedPane();
            JPanel panel1 = new JPanel(new FlowLayout(FlowLayout.LEFT, 15, 5));
            panel1.add(new JButton("Button 1"));
            panel1.add(new JButton("Button 2"));
            pane.add("Tab 1", panel1);
            pane.add("Tab 2", new JPanel());
            pane.setPreferredSize(new Dimension(100, 70));
            return pane;
        }
    }

}

The next thing we need to be concerned about is the layout of the root pane. The root pane's layout should respect the toolbar component's preferred height, while it should also position the content pane accordingly. The entire definition of the related layout adjustment can be found by clicking on this link:

MyRootPaneLayout.java

Now that we have access to our JTabbedPane, and we have a new layout for fitting it into the root pane, let's hook everything into our application. Below the statement that hides the toolbars, i.e., still in the "restored()" method, add this:

//This would be too late:
//WindowManager.getDefault().invokeWhenUIReady(new Runnable() {});
//Therefore use this:
SwingUtilities.invokeLater(new Runnable() {
@Override
    public void run() {
//Get the main window of the NetBeans Platform:
        JFrame frame = (JFrame) WindowManager.getDefault().getMainWindow();
//Get our custom main toolbar:
        JComponent toolbar = ToolbarComponentProvider.getDefault().createToolbar();
//Set the new layout of our root pane:
        frame.getRootPane().setLayout(new MyRootPaneLayout(toolbar));
//Install a new toolbar component into the layered pane
//of the main frame on layer 0:
        toolbar.putClientProperty(JLayeredPane.LAYER_PROPERTY, 0);
        frame.getRootPane().getLayeredPane().add(toolbar, 0);
    }
});

That's it. You now have a tabbed toolbar. Thanks Chris!

Note: A disadvantage to this approach is that the toolbar buttons in the layer file do not land in your new custom toolbar. So, if you want your toolbar to be extensible (which is not something you necessarily want, of course), you would need to provide code for reading the layer entries and populating the toolbar accordingly.

Learn more about Kotlin, a new programming language designed to solve problems that software developers face every day brought to you in partnership with JetBrains.

Topics:

The best of DZone straight to your inbox.

SEE AN EXAMPLE
Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.
Subscribe

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}