You may have seen menu items with check boxes in MPS and wondered how you can create your own.

Each menu item in IDEA platform applications must be defined through an action. MPS provides DSL constructs in the plugin language for defining basic actions. However, if you want your action to have a check box you cannot use the provided constructs and have to resort to coding the action in plain Java.

For an action to get a check box, it must extend class com.intellij.openapi.actionSystem.ToggleAction. The action class must provide implementations for the two methods, isSelected(AnActionEvent) and setSelected(AnActionEvent).

Here is what a simple implementation might look like:

public class ToggleActionExample extends ToggleAction { 
   
  public static Set<Integer> selectedStates = new HashSet<>(); 
   
  private final int state; 

  public ToggleActionExample(int state) { 
    super("Toggle State " + state); 
    this.state = state; 
  } 
   
  @Override 
  public boolean isSelected(@NotNull() AnActionEvent event) { 
    selectedStates.contains(state); 
  } 
  @Override 
  public void setSelected(@NotNull() AnActionEvent event, boolean b) { 
    if (b) { 
      selectedStates.add(state); 
    } else { 
      selectedStates.remove(state); 
    } 
  } 
}

To add actions to a menu we need to add them to an action group. Although we have defined our action in plain Java, we can still make use of the plugin language to build a group out of our Java actions and add it to another group to have it show up.

The DSL constructs provided by MPS only support adding simple actions defined using the plugin language but there is also an “escape hatch” into plain Java. When defining the contents of the group we can choose from three options: build, element list, and update. The build and update options let us use Java code to build our group. In the code of the build or update method we can use the this pointer to access Java methods on the action group object that we are building:

And this is what the resulting menu looks like:

If you are interested, check out the sample project on GitHub.