Creating a dynamic menu

In stage 1 of SimplyHTML the menu consisting of menu bar, menus and menu items had been hard coded in method constructMenu. This part would always have to be changed when the menu changes or is extended by additional functions. In stage 2 of the application we therefore add functionality to build a menu dynamically controlled by parameters from a resource file.

Connect actions dynamically

Certainly actions triggered by menu selections still have to be coded also because they contain the actual functionality in most cases. But how actions are connected to menu items or other GUI elements does not have to be hard coded and therefore actions are included in the change towards a dynamic menu.

Advantage

By having functions to dynamically construct and control a menu, the code does not have to be changed again once a new menu is to be added or changes in the menu structure occur.

Menus and menu items can be added simply by making an entry in the resource file.

How to automate the menu construction

Each action has a name which we use as unique key, such as new, open, save, etc. In class FrmMain's constructor a commands Hashtable is created with all actions of SimplyHTML and their action commands ( new, save, etc.). With method getAction, an action can be fetched by its command name.

Method createMenuBar

To create the menu bar a menu bar definition string from the resource file is read having the key for each menu delimited by blanks (e.g. file edit help). The keys are in the order as menus shall appear in the menu bar.

Method createMenu

To create menus a menu definition string from the resource file is read having the action key for each menu item delimited by blanks. The keys are in the order as items shall appear in respective menu.

Method createMenuItem

Menu items are created with the key to 'their' action (new, save, etc.) as the action command. The key also serves to get the label for the menu item: In the resource file all menu labels are named fileLabel, newLabel, saveLabel, etc. so they can be read automatically and stored with the menu item.

Consistent state handling over components

Menu items always should reflect if their action is available at a certain point in time during execution of an application. Actions in turn should only be available if it makes sense at that point in time. Action close for instance should only be enabled, if there are documents open, that can be closed.

Listeners for interaction between menus, menu items and actions

A reference between menus, menu items and actions is created in several ways to ensure this behaviour:

- The menu item is connected to a PropertyChangeListener and registered with the action belonging to that menu item to automatically update the state of the menu item according to the state of the action.
- The action in turn is registered with the menu item as an ActionListener so that the action can execute its actionPerformed method whenever the menu item fires the action command.
- Finally with each menu a MenuListener is registered that updates the action state of each item in respective menu whenever it is about to be displayed. This ensures that always the actions are in the correct state. (In later stages, this has to be refined by updating controls other than menus if such are connected to actions in addition.)