Custom Corporate Menu Bar for NetBeans Platform Applications

Today let's create a highly customized menu bar in our NetBeans Platform application:

What's special in the above screenshot is that the menu bar has an image, the menu items are set to the right, and the toolbar is gone. That's all. But the effect is quite nice and professional for corporate applications.

Get to the above point as follows:

  1. The key to everything is "netbeans.winsys.menu_bar.path"  which is a NetBeans property pointing to a folder in the central registry where a custom menu bar can optionally be registered. You can set the above via -J-D or via System.setProperty in your Installer:
    public class Installer extends ModuleInstall {
    
        @Override
        public void restored() {
            System.setProperty("netbeans.winsys.menu_bar.path", "LookAndFeel/MenuBar.instance");
        }
    
    }
  2. And here is the registered custom menu bar referred to above:
    <folder name="LookAndFeel">
        <file name="MenuBar.instance">
            <attr name="instanceOf" stringvalue="org.openide.awt.MenuBar"/>
            <attr name="instanceCreate" newvalue="org.menu.bar.MyMenuBar"/>
        </file>
    </folder>
  3. So I have a package named "org.menu.bar", where "MyMenuBar" is registered. A lot of the code below comes from this interview with Tonny Kohar. Here's my custom menu bar:
    public class MyMenuBar extends JMenuBar {
    
        //Load content from Menu folder and populate the custom menubar,
        //refer to the interview with Tonny Kohar:
        
        public MyMenuBar() {
            //Let the menus appear from the right:
            add(Box.createHorizontalGlue());
            //Now we'll get the "Menu" folder and process its content: 
            FileObject menuFolder = FileUtil.getConfigFile("Menu");
            FileObject[] menuKids = menuFolder.getChildren();
            for (FileObject menuKid : FileUtil.getOrder(Arrays.asList(menuKids), true)) {
                JMenu m = new JMenu(menuKid.getName());
                if (m != null) {
                    add(m);
                }
                buildPopup(menuKid, m);
            }
            setPreferredSize(new Dimension(50, 50));
        }
    
        private void buildPopup(FileObject fo, JComponent comp) {
    
            DataFolder df = DataFolder.findFolder(fo);
            DataObject[] childs = df.getChildren();
            DataObject dob;
            Object instanceObj;
            for (int i = 0; i < childs.length; i++) {
                dob = childs[i];
                if (dob.getPrimaryFile().isFolder()) {
                    FileObject childFo = childs[i].getPrimaryFile();
                    JMenu menu = new JMenu();
                    Mnemonics.setLocalizedText(menu, dob.getNodeDelegate().getDisplayName());
                    comp.add(menu);
                    buildPopup(childFo, menu);
                } else {
                    //Cookie or Lookup API discovery:
                    InstanceCookie ck = (InstanceCookie) dob.getCookie(InstanceCookie.class);
                    try {
                        instanceObj = ck.instanceCreate();
                    } catch (Exception ex) {
                        instanceObj = null;
                        ErrorManager.getDefault().notify(ErrorManager.EXCEPTION, ex);
                    }
                    if (instanceObj == null) {
                        continue;
                    }
                    if (instanceObj instanceof JSeparator) {
                        comp.add((JSeparator) instanceObj);
                    } else if (instanceObj instanceof BooleanStateAction) {
                        JCheckBoxMenuItem menuItem = new JCheckBoxMenuItem();
                        Actions.connect(menuItem, (BooleanStateAction) instanceObj, true);
                    } else if (instanceObj instanceof Action) {
                        final Action a = (Action) instanceObj;
                        String name = (String) a.getValue(Action.NAME);
                        String cutAmpersand = Actions.cutAmpersand(name);
                        JMenuItem menuItem = new JMenuItem();
                        menuItem.setAction(new AbstractAction(cutAmpersand) {
                            @Override
                            public void actionPerformed(ActionEvent e) {
                                a.actionPerformed(e);
                            }
                        });
                        //Should be like this, but somehow didn't work in this case:
                        //Actions.connect(menuItem, (Action) instanceObj, false);
                        comp.add(menuItem);
                    }
                }
            }
    
        }
        
        //Paint the banner image into the menu bar:
    
        private final Paint bannerPaint = makeBannerPaint();
    
        @Override
        protected void paintComponent(Graphics g) {
            Graphics2D g2 = (Graphics2D) g;
            g2.setPaint(bannerPaint);
            g2.fillRect(0, 0, getWidth(), getHeight());
        }
    
        private Paint makeBannerPaint() {
            //Pointing to an image in org/menu/bar:
            BufferedImage img = (BufferedImage) ImageUtilities.loadImage("org/menu/bar/banner.jpg");
            return new TexturePaint(img, new Rectangle(0, 0, img.getWidth(), img.getHeight()));
        }
        
    }

  4. Finally, in the layer, hide the toolbar:
    <file name="Toolbars_hidden"/>

That's it, now you have a nice corporate menu bar.

Comments:

Excelent feature! thank you Geertjan, I definitly will try it this weekend.

Posted by Xavier Callejas on July 08, 2011 at 01:50 AM PDT #

Thanks Geertjan, that's a really nice feature!
Do you know if it's possible to do the same thing for the toolbar (eg. use a custom image as background)?

Posted by Matt on July 08, 2011 at 05:10 AM PDT #

Hello,
I am building project module in netbeans rcp. when I am trying to add dependencies it is compulsory to add Project API and Project UI API but when I go into the properties of the module to add dependencies apis for Project and Project UI are no available to add.

any help is highly appreciated towards fixing the issue.

Sincerely,
Usunix

Posted by Unix on March 20, 2013 at 05:38 AM PDT #

Nice tutorial.
Sir, I have a question.
JButton mnemonic does not work in Netbeans plateform application.
Have you any solution?

Posted by guest on February 12, 2014 at 04:23 AM PST #

Post a Comment:
  • HTML Syntax: NOT allowed
About

Geertjan Wielenga (@geertjanw) is a Principal Product Manager in the Oracle Developer Tools group living & working in Amsterdam. He is a Java technology enthusiast, evangelist, trainer, speaker, and writer. He blogs here daily.

The focus of this blog is mostly on NetBeans (a development tool primarily for Java programmers), with an occasional reference to NetBeans, and sometimes diverging to topics relating to NetBeans. And then there are days when NetBeans is mentioned, just for a change.

Search

Archives
« April 2014
SunMonTueWedThuFriSat
  
12
13
14
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today