| # GUI Commands User Guide ## Version 2.1 |
| # Container Properties Container properties are a mechanism that allows you to pass objects around your commands and groups in a loosely coupled manner. Once a command or group is bound to a container it has access to all the properties defined within the container hierarchy. Containers will request the property from their parent if it's not locally defined. ## Standard Properties There are a number of standard properties are used to provide common infrastructure required by the library. These are: DelegateMediator - Used by DelegatingCommands to track the currently active set of delegates. GlassPaneStrategy - Used by SwingWorkerCommands to activate the glasspane. UndoContext - Used by the Undo and Redo Commands to determine the current undo state.
       CommandContainer container = new CommandContainer();
       // set the delegate mediator
       container.setDelegateMediator(new FocusTrackingDelegateMediator(myFrame));

       // set the glass pane strategy
       container.setGlassPaneStrategy(new DefaultGlassPaneStrategy());

       // set the undo context
       container.setUndoContext(new UndoContext());
## User Defined Properties You can also define your own properties using `putProperty(String, Object)` and access them from commands and groups as required.
       container.putProperty("my-custom-component", myCustomComponent);
## Accessing Container Properties Container properties can be accessed from commands using the convenience `getContainerProperty(...)` method. This method will check that the container isn't null as would be the case if the command wasn't bound. You can also call `getCommandContainer()` and invoke `getProperty()` if you need to ensure the container has been bound. The following example shows accessing a container property during command execution.
       public void handleExecute()
       {
          // get the property
          Object propertyValue = getContainerProperty("myProperty");

          // and use it...
          ...
       }
## Monitoring Container Properties The situation is a little more complex if you need to add listeners to a container property to monitor its state. Container properties are only available once commands are bound and as such listeners must be updated in any of the following cases: After binding or unbinding After changes to the container hierarchy. After changes to the containers properties. To simplify monitoring of container properties both commands and groups allow you to add `ContainerPropertyListener`s. These are conceptually very similar to Java bean PropertyChangeListeners, but they are notified in all the cases listed above. Unlike PropertyChangeListeners, ContainerPropertyListeners: Only provide the new property value. May be invoked more than once with the same value. The following shows a typical example of monitoring a container property:
       public class MyCommand extends ActionCommand
       {
          // Our model which is stored as a container property.
          private Model model;

          // Our model listener.
          private ModelListener modelListener = ...;

          /**
           * Create our command and add our property listener
           */
          public MyCommand()
          {
             super("my-command");

             // Add a container property listener to monitor the
             // "model" property of our container.
             addContainerPropertyListener("model",
                                          new ContainerPropertyListener()
             {
                public void propertyChanged(ContainerPropertyEvent e)
                {
                   // update our model reference
                   setModel((Model) e.getNewValue())
                }
             }

             updateState();
          }

          /**
           * Configure our model
           */
          public void setModel(Model model)
          {
             if (this.model != null)
             {
                // remove the listener from the old model
                this.model.removeModelListener(modelListener);
             }

             this.model = model;

             if (this.model != null)
             {
                // and listen to the new model
                this.model.addModelListener(modelListener);
             }

             // update our state to reflect the new model
             updateState();
          }

          private void updateState()
          {
             // we're only enabled if the model is configured and ok
             setEnabled(model != null && model.isInSuitableState());
          }

       }