Eine Command
                       Action teilt eine Action in den beschreiben Anteil wie
                    Label Text, Tooltip Text oder Icon, und die Business Logik auf.
                    Ein ICommand stellt dabei die Business Logik
                    dar. Diese hat drei Aspekte:
                  
         
Enabled Checking prüft, ob die Aktion ausführbar ist.
Execution führt die eigentliche Aktion aus
Exception Handling behandelt Ausnahmen
                    Die Schnittstelle ICommand wird häufig selbst
                    implementiert, um die Business Logik abzubilden. Diese hat die
                    folgenden Methoden:
                  
         
    ICommandExecutor getCommandExecutor();
    IExceptionHandler getExceptionHandler();
    
    IEnabledChecker getEnabledChecker();
                    Dabei kann jede der Methoden null
                    zurückliefern, wenn der jeweilige Aspekt nicht unterstützt wird
                    (einen Enabled Checker oder Exception Handler anzubieten, ohne
                    einen Executor zu haben ist allerdings nicht unbedingt
                    sinnvoll).
                  
         
                         Die Schnittstelle ICommandExecutor hat die
                         folgende Methode:
                       
            
    void execute(IExecutionContext executionContext) throws Exception;
                         Diese wird aufgerufen, wenn der Command ausgeführt werden
                         soll. Die Schnittstelle IExecutionContext
                         liefert dabei die folgenden Methoden:
                       
            
    IAction getAction();
    
    IWidget getSource();
    
    <VALUE_TYPE> VALUE_TYPE getValue(final ITypedKey<VALUE_TYPE> key);Damit kann man eine Referenz auf die auslösende Action, das Widget, für welches die Action ausgeführt wurde, und weitere Properties erhalten. Über die ausführende Action kann man sich Beispielsweise das Action Label und Icon beschaffen, um diese etwa in einem Dialog anzuzeigen. Das folgende Beispiel soll das verdeutlichen:
  1  public final class ExampleExecutor implements ICommandExecutor {
  2  
  3      @Override
  4      public void execute(final IExecutionContext executionContext) throws Exception {
  5          final IAction action = executionContext.getAction();
  6          final String title = action.getText();
  7          final IImageConstant icon = action.getIcon();
  8          final String message = "Execution was successful";
  9          MessagePane.showInfo(title, icon, message);
 10      }
 11  
 12  }
                         Das dies ein häufiger Anwendungsfall ist, unterstützt die
                         Accessor Klasse MessagePane auch das
                         direkte Übergeben des executionContext. Die
                         folgende Implementierung hat daher den gleichen Effekt:
                       
            
  1  public final class ExampleExecutor implements ICommandExecutor {
  2  
  3      @Override
  4      public void execute(final IExecutionContext executionContext) throws Exception {
  5          final String message = "Execution was successful";
  6          MessagePane.showInfo(executionContext, message);
  7      }
  8  
  9  }
                         Die Schnittstelle IExceptionHandler hat die
                         folgende Methode:
                       
            
    void handleException(
        IExecutionContext executionContext, 
        final Exception exception) throws Exception;
                         Auch hier wird der IExecutionContext der
                         auslösenden Action übergeben. Zudem bekommt man die
                         aufgetretene Exception übergeben. Wenn man diese nicht selbst
                         behandeln kann, kann man sie erneut werfen. Sie wird dann als
                         nächstes vom Exception Handler der
                         Action behandelt,
                         falls ein solcher existiert.
                       
            
                         Die Schnittstelle IEnabledChecker liefert
                         die folgenden Methoden:
                       
            
    IEnabledState getEnabledState();
    
    void addChangeListener(IChangeListener listener);
    void removeChangeListener(IChangeListener listener);
                         Die Methode getEnabledState() liefert die
                         Information, ob die Aktion ausführbar ist. Immer wenn sich der
                         EnabledState ändert, müssen die registrierten Listener darüber
                         informiert werden.
                       
            
                         Die Schnittstelle IEnabledState hat die
                         folgenden Methoden:
                       
            
    boolean isEnabled();
    String getReason();
                         Das bedeutet, es wird nicht nur die Information geliefert, ob
                         eine Aktion ausführbar ist, sondern auch der Grund warum
                         nicht. Die Methode getReason() sollte einen
                         internationalisierten String zurückliefern, welche dem Nutzer
                         Auskunft darüber gibt, warum die Aktion nicht ausführbar ist.
                         Beispiele sind:
                       
            
Speichern - „Es gibt keine Änderungen“
Speichern - „Es existiert bereits ein Datensatz mit gleicher Artikelnummer“
Undo - „Es gibt keine Änderungen“
Nachricht versenden - „Die Nachricht hat keinen Betreff“
Löschen - „Fehlendes Recht“
                         Es ist jedoch auch erlaubt null oder einen
                         Leerstring zurück zu liefern.
                       
            
                         Die Default Implementierung der
                         Command Action
                         tauscht, wenn der
                         EnabledState disabled und der
                         reason nicht leer ist,
                         das Tooltip des gebundenen
                         MenuItem, Button oder ToolbarButton
                         gegen den reason
                               Text aus.
                       
            
Dies hat sich in großen und komplexen Enterprise Anwendungen als äußerst nützlich herausgestellt und wurde von Kunden mehrfach gelobt. So wurde sogar die Aussage getätigt, das man dieses Feature in vielen anderen Applikationen vermisse, seit dem man mit dieser Applikation arbeiten würde.
Wenn man bei Google den Text „why is that button greyed out in“ eingibt, liefert einem die Autovervollständigung unzählige Fortführungen dieses Satzes, woraus sich vermuten lässt, dass sich Nutzer diese Frage häufig zu stellen scheinen. Da der Entwickler den Grund für das Ausgrauen in der Regel kennt, wäre es doch auch hilfreich, diesen an den Nutzer weiter zu geben, um die Usability zu erhöhen.
                         Die Klasse EnabledState liefert folgende
                         statische Methode zur Erzeugung eines
                         disabled State:
                       
            
    public static EnabledState disabled(final String reason) {...}Sowie die folgenden Konstanten:
    public static final EnabledState ENABLED = new EnabledState();
    public static final EnabledState DISABLED = new EnabledState(false, null);
                         Das folgende Beispiel demonstriert die Implementierung eines
                         IEnabledChecker:
                       
            
  1  public final class ModifiedEnabledChecker extends AbstractEnabledChecker {
  2  
  3      private final IInputComponent<?> inputComponent;
  4  
  5      private ModifiedEnabledChecker(final IInputComponent<?> inputComponent) {
  6          this.inputComponent = inputComponent;
  7  
  8          inputComponent.addInputListener(new IInputListener() {
  9              @Override
 10              public void inputChanged() {
 11                  fireEnabledStateChanged();
 12              }
 13          });
 14      }
 15  
 16      @Override
 17      public IEnabledState getEnabledState() {
 18          if (!inputComponent.hasModifications()) {
 19              return EnabledState.disabled("There is no modification");
 20          }
 21          else {
 22              return EnabledState.ENABLED;
 23          }
 24      }
 25  
 26  }
                         Dieser erlaubt die Ausführung nur, wenn die referenzierte
                         Input
                            Component Modifikationen hat. Für die Implementierung
                         wird von der abstrakten Klasse
                         AbstractEnabledChecker abgeleitet. Dadurch
                         spart man sich die Implementierung Methoden
                         addChangeListener() und
                         removeChangeListener(). Um Änderungen
                         anzuzeigen muss nur die Methode
                         fireEnabledStateChanged() aufgerufen werden
                         (Zeile 11).
                       
            
                         Mit Hilfe der Klasse EnabledChecker könnte
                         man das gleiche wie oben auch so erreichen:
                       
            
  1      final EnabledChecker enabledChecker = new EnabledChecker();
  2  
  3      inputComponent.addInputListener(new IInputListener() {
  4          @Override
  5          public void inputChanged() {
  6              if (!inputComponent.hasModifications()) {
  7                  enabledChecker.setDisabled("There is no modification");
  8              }
  9              else {
 10                  enabledChecker.setEnabled();
 11              }
 12          }
 13      });Je nach Anwendungsfall kann die eine oder andere Variante besser geeignet sein.