There’s a hoard of tutorials on the Internet showing you how to make menus in Java, and they’re just fine, however I always wonder to myself whether they’re the best solution to the common problem of having hundreds of lines of code just to create a menu, so I decided to try out some alternative approaches.

In this tutorial I’ll show you an example from my own project generating menu items dynamically, from any format you wish.

Representing The Data

First of all you need a format to represent the menu items.  For this example I’m using dots by themselves to represent separators, and I’m ending items with a colon to represent them as a menu.  All of these items are contained in one String array, and each element represents an entire menu.  Thus, the format will look like:

{"File: New . Menu-Item Another-Menu-Item . Other-Items", "Tools: Draw . Fill . Editing-Tools"}

This example is extremely basic and there are far better ways of doing it, but for the purpose of this tutorial I’ll keep it simple by not using multi-dimensional arrays, or extracting values from files etc.

Pulling The Data Out

Next we will need to iterate over the list of elements and choose what goes where. You’ll also need to use a small regular expression to split the data by whatever format you choose.  Spaces separate elements in my data representation therefore I use \\s+.


for(String menuElement : menuItems)
{
   String[] splitMenuItems = menuElement.split(”\\s+”);

   menu = new JMenu(splitMenuItems[0].substring(0, splitMenuItems[0].length() - 1));
   menu.addActionListener(this);
   menuBar.add(menu);

   for(String menuItemElement : splitMenuItems)
   {
      if(!menuItemElement.endsWith(”:”) && !menuItemElement.equals(”.”))
      {
         menuItem = new JMenuItem(menuItemElement.replace(’-', ‘ ‘));
         menuItem.setActionCommand(menuItemElement);
         menuItem.addActionListener(this);
         menu.add(menuItem);
      }
      else if(menuItemElement.equals(”.”))
      {
         menu.addSeparator();
      }
   }
}

 Here I use a nested for loop to first iterate over each element in the String array, and each time I do I then split the String into its individual elements and place them into a String array of their own.  A root menu is represented by a proceeding ":" character, so  splitMenuItems[0].substring(0, splitMenuItems[0].length() - 1) takes out the colon at the end of "File:".

In the next nested for loop I ignore elements ending with the ":" character because due to the String split, it naturally includes the first element which is "File:" - you can choose to remove this element if you wish, whatever suits you really.  I also ignore the "." character and if that character does occur the statement will then go over to the else if statement where it will add a separator for every dot found.

Because the menu items are delimited by spaces I needed to handle menu item text with spaces in it.  To do so I merely used "-" characters to represent spaces.  Underscores may have been better as you may actually use hyphens in your menu items.  When one is found I just simply replace it with a space character.

But What About Key Mnemonics?

Key mnemonics allow you to hit a key on your keyboard and that menu item open up.  You may think that this option isn’t as customisable, but it just means there’s a little more work to do.  Obviously we can represent the data in any form we want, and thus to enable key mnemonics simple change the format of the data.  For example, {"File:_69 New . Close . Exit"} - here we can use an underscore to separate mnemonics and then give the integer value of the VK constant which you can then add to setMnemonic(int).

Simple, huh?

(Please note that this code was developed in accordance with my university and thus is copyrighted. You may freely use this code as long as you give a link back here, or at least put my name in your code somewhere. Thanks! :))


Rss Commenti

No Comments

No comments yet.

Post a comment

You must be logged in to post a comment.