Im folgenden soll die Verwendung von Command Actions noch einmal anhand eines Beispiels verdeutlicht werden. Die folgenden Abbildung zeigen vorab fertige Ergebnis:
In dem Textfeld wurde der Text „Hello World“ durch den Benutzer eingegeben. Dadurch ist der Save Button neben dem Text Feld sowie in der Toolbar aktiviert. Zudem befindet sich die Action auch noch im File Menu (nicht auf dem Screenshot sichtbar).
Nachdem die Save Action ausgelöst wurde, ist das folgende zu sehen:
Ein Dialog erscheint, dass die Aktion ausgeführt wurde. Wird dieser geschlossen und öffnet man das File Menu, sieht man das folgende:
                    Der Tooltip zu der Save Action im File Menü zeigt den Grund für
                    die Deaktivierung im Tooltip. Die Save Action soll genau dann
                    enabled sein, wenn der Text im Textfeld sich
                    seit dem letzten Speichern geändert hat.
                  
         
Der folgende Code zeigt die Implementierung (das vollständige Snipped inklusive Imports befindet sich hier):
  1  public final class CommandActionSnipped implements IApplication {
  2  
  3      @Override
  4      public void start(final IApplicationLifecycle lifecycle) {
  5  
  6          //create a root frame
  7          final IFrameBluePrint frameBp = BPF.frame();
  8          frameBp.setSize(new Dimension(400, 300)).setTitle("Command actions");
  9          final IFrame frame = Toolkit.createRootFrame(frameBp, lifecycle);
 10  
 11          //Create the menu bar
 12          final IMenuBarModel menuBar = frame.getMenuBarModel();
 13  
 14          //Use a border layout
 15          frame.setLayout(BorderLayout.builder().gap(0).build());
 16  
 17          //add a toolbar to the top
 18          final IToolBarModel toolBar = frame.add(BPF.toolBar(), BorderLayout.TOP).getModel();
 19  
 20          //add a composite to the center
 21          final IComposite composite = frame.add(BPF.composite().setBorder(), BorderLayout.CENTER);
 22          composite.setLayout(new MigLayoutDescriptor("[grow][]", "[]"));
 23  
 24          //add a input field and save button to the composite
 25          final IInputField<String> inputField = composite.add(BPF.inputFieldString(), "growx");
 26          final IButton saveButton = composite.add(BPF.button());
 27  
 28          //create save action 
 29          final IAction saveAction = createSaveAction(inputField);
 30  
 31          //create a menu and add save action
 32          final MenuModel menu = new MenuModel("File");
 33          menu.addAction(saveAction);
 34  
 35          //add the menu to the menu bar
 36          menuBar.addMenu(menu);
 37  
 38          //add the action to the toolbar
 39          toolBar.addAction(saveAction);
 40  
 41          //bind the action to the save button
 42          saveButton.setAction(saveAction);
 43  
 44          //set the root frame visible
 45          frame.setVisible(true);
 46      }
 47  
 48      private static IAction createSaveAction(final IInputComponent<String> inputComponent) {
 49          final IActionBuilder builder = Action.builder();
 50          builder.setText("Save");
 51          builder.setToolTipText("Saves the text");
 52          builder.setAccelerator(VirtualKey.S, Modifier.CTRL);
 53          builder.setIcon(IconsSmall.DISK);
 54  
 55          //save command implements ICommandExecutor and IEnabledChecker,
 56          //so set them both
 57          final SaveCommand saveCommand = new SaveCommand(inputComponent);
 58          builder.setCommand(saveCommand, saveCommand);
 59  
 60          return builder.build();
 61      }
 62  
 63      private static final class SaveCommand 
 64          extends AbstractEnabledChecker implements ICommandExecutor, IEnabledChecker {
 65  
 66          private final IInputComponent<?> inputComponent;
 67  
 68          private SaveCommand(final IInputComponent<?> inputComponent) {
 69              this.inputComponent = inputComponent;
 70  
 71              inputComponent.addInputListener(new IInputListener() {
 72                  @Override
 73                  public void inputChanged() {
 74                      fireEnabledStateChanged();
 75                  }
 76              });
 77          }
 78  
 79          @Override
 80          public void execute(final IExecutionContext executionContext) throws Exception {
 81              inputComponent.resetModificationState();
 82              fireEnabledStateChanged();
 83              final String message = "'" + inputComponent.getValue() + "' saved!";
 84              MessagePane.showInfo(executionContext, message);
 85          }
 86  
 87          @Override
 88          public IEnabledState getEnabledState() {
 89              if (!inputComponent.hasModifications()) {
 90                  return EnabledState.disabled("No changes to save");
 91              }
 92              else {
 93                  return EnabledState.ENABLED;
 94              }
 95          }
 96  
 97      }
 98  
 99  }
                    Die Klasse SaveCommand implementiert sowohl
                    die Schnittstelle ICommandExecutor als auch
                    IEnabledChecker. Dies ist im Beispiel
                    einfacher, da sich nach dem Zurücksetzen des Modification State
                    in Zeile 81 auch der EnabledState ändert. In Zeile 82 werden
                    daher die registrierten Listener darüber informiert. Es ist bei
                    diesem Vorgehen zu beachten, dass in Zeile 58 die
                    saveCommand Instanz doppelt angegeben wird,
                    einmal als ICommandExecutor und einmal als
                    IEnabledChecker.
                  
         
                    Beide Schnittstellen in einer Klasse zu implementieren ist nicht
                    ungewöhnlich. In manchem Fällen lassen sich aber auch
                    IEnabledChecker für unterschiedliche Actions
                    wiederverwenden, was eine Trennung der Implementierung nahelegt.