Containers and Binding Part II

In this section we discuss the use of container hierarchies when dealing with applications that contain mulitple instances and the same command. Creating container hierarchies allow you to segregate commands into distinct namespaces.

Why Do I Need A Container Hierarchy?

CommandContainers are only ever allowed to contain a single instance of any given command (as determined by its Id). So if you ever bind a second instance of any given command to the same container you'll get an IllegalStateException.

This makes sense when you think about it, otherwise how would a container respond to the request to get "command X" if there were two instances?

When Do I Need A Container Hierarchy?

You will always need a heirarchy whenever you have to bind two or more instances of any given command within the one application. Typical examples are:

  • An multi-frame application such as Microsoft Word (with 2 documents open).
  • An application with multiple instances of a component containing commands. E.g. An editor component replicated in multiple tabs.

Containers act as a scope for the commands that bind to them. Typcially you end up with a container structure that corresponds to the component structure of you application. Thus a multiframe application would typically have a container per frame, and a tabbed editor would typically define one container per tab component. This approach allows you to reuse command enabled components without collisions.

Step by Step Example

A Single Editor Component in a Frame

The following diagram shows a typical component binding scenario where a "save" command is bound to an editor component. Since everything is bound to the same container the file and context menus automatically discover and include the save command.

A Simple Editor in a Frame
NOTE: While this example is uses component binding, the exact same principle applies when binding directly to containers.

Adding a Second Editor Instance Without a Hierarchy

Here we add a second editor to the frame (using a JTabbedPane for example). Here the second editor finds the parent container as normal but on adding it an exception is thrown saying the the "save" command is already bound. The diagram illustrates.

Multiple Editor Instances

Adding Child Containers

To overcome this, we give each editor it's own CommandContainer. Now each "save" command will bind to the editor container and not the frame container. As a consequence the frame container can no longer access the "save" commands and the two menus will no longer automatically include it. The following diagram illustrates:

Using Child Containers

Relocating Groups

Since the context menu is specific to each editor, the simplest solution is to move it to the editor as shown in the following diagram. This however still leaves the file menu without access to the save command.

Please Note: The remaining diagrams only shows a single editor instance for clarity.
Using a Locale Context Menu
NOTE: The above diagrams shows the editor container parented by the frame container. This makes commands in the frame container visible to groups in the editor container. This is how container heirarchies are built. The following diagram illustrates.
Container Parents
Thus: groups can always see up the container hierarchy, but do not automatcially see down.

Looking Down the Hierarchy

Now all that is left is to link the file menu with the appropriate save command contained within the editor containers. There are two basic approaches to this:

  1. Use DelegatingCommands.
  2. Use Expansion Points.

Since in this case the relevant save command can be easily determined from the currently focused editor, the simplest solution is to use DelegatingCommands. The following diagram shows the basic approach, but please refer to the delegates documentation for the full details.

Using Delegates