Sometimes you want an action to be available in specific cases only. In all other cases, you want the action disabled, or perhaps even hidden from the UI.

Such actions are typically located in a pop-up menu. For example, the pop-up menu of the map only shows the Delete action and the Properties action when an object is selected on the map. Otherwise, those actions are not visible in the pop-up menu.

The action itself can indicate to the action bar whether it should be visible or hidden, and whether it should be enabled or disabled. A typical implementation of such an action uses a listener that is notified when the action needs to recalculate its visible and enabled state, and update its state accordingly.

  • The enabled state can be changed using the setEnabled method.

  • The visibility of the action can be changed using the ILcdAction.VISIBLE key.

The example below creates an action that deletes the selected layers from a map. The action is only visible and enabled when layers have been selected:

/**
 * Action which removes the selected layers from the map component
 */
public class DeleteSelectedLayerAction extends ALcdAction {

  private final ILcyLspMapComponent fMapComponent;

  public DeleteSelectedLayerAction(ILcyLspMapComponent aMapComponent) {
    fMapComponent = aMapComponent;

    //set up the initial state of the action
    updateState();

    //Attach a listener to the context to listen for changes in the layer selection
    aMapComponent.addPropertyChangeListener(evt -> {
      if ("selectedLayersAsList".equals(evt.getPropertyName())) {
        updateState();
      }
    });
  }

  @Override
  public void actionPerformed(ActionEvent e) {
    List<ILspLayer> selectedLayers = fMapComponent.getSelectedLayersAsList();
    selectedLayers.forEach(layer -> fMapComponent.getMainView().removeLayer(layer));
  }

  private void updateState() {
    List<ILspLayer> selectedLayers = fMapComponent.getSelectedLayersAsList();

    //We only want to show and enable the action when there are layers selected
    setEnabled(!selectedLayers.isEmpty());
    putValue(ILcdAction.VISIBLE, !selectedLayers.isEmpty());
  }
}

Because an action that works on the current object selection is such a common use case, the API offers ALcdObjectSelectionAction. This action works on the current map selection, and disables itself when no suitable objects are selected. Optionally, the action can make itself invisible when it is not applicable.