Framework for computing enabled/disabled state of an action

$Revision: 1.2 $
Changes: available in CVS
Status: issue 18325


As a part of Action API rewrite a general declarative way how to describe enabled/disabled state of an action is needed. This document states goals for such efford and discusses possible solution.


  • The state of an action (enabled/disabled) has to be computed without any classes loaded into VM
  • It must be easy for a module providing visual objects and actions to combine them together
  • Actions state is based on features or properties of visual object
  • A way to support backward compatiblity


First of all the description of implementation is given, then the format for declarative specification is discussed.
Properties of visual object
The action proposal expects that the state of the system will be accessible thru Lookup containing all selected Nodes and all of their Node.Cookies. Current Actions API encourages use of NodeAction and CookieAction that both react to nodes and cookies provided and can declare which cookies need to be present in order the action is made enabled. The similar approach (but more declarative) is to be used for new action style.

An action can specify dependency on instance of some class being present in the context/lookup. Such class can be instance of a node, cookie, data object and such instance can be either general or provided by the same module. The action can also request number of such objects being present. For example the diff action that compares two files could specify a dependency on org.openide.loaders.DataObject class that must be present exactly twice.

If a module wants to provide an action just for its own object, it can specify a dependency on its own cookie. For example org.netbeans.modules.jarpackager.JarDataObject can be checked by packaging action. For this to work effectively we need to resolve issue 18324.

Fine graning properties
Sometimes a query about implementation class is too general and enabled state depends on smaller attributes. That can be solved by creating enough interfaces instead but it is against our goal to minimize number of classes needed in VM. That is why following additional principle could be choosen.

Each instance of a cookie class can carry additional properties in name-value pairs by either implementing java.util.Map interface or by extending java.beans.FeatureDescriptor. The declarative specification of action then can require properties of some name have some special values. For example:

would specify that we are looking for implementation of EditCookie that also provides implemetnation for getValue (name) method and returns true for getValue ("template") and text/x-java for getValue ("mimeType").

The names and values of properties are private contract between the cookie/instance provider and the action.

No declarative logic
For some actions it is necessary to perform computation checking and do not do any declarative at all. Examples include current public callback actions (CopyAction, CutAction) that still should be replaced by new action framework but have to work in backward compatible way.

The solution is to create a declarative action that will work as all other ones (use ActionMap) but for compatibility reasons call and retrieve its state from the original org.openide.actions.CopyAction.

This could be handy in general (even not encouraged) and that is why there should be a way to specify such behaviour and delegate enabled state queries to some code.

Declarative format
It would be nice to reuse the XML layer attributes format, but specification of classes an action expects and counts their should occur in is more complex and that is why special format will be necessary. Still it should be easy to process so startup is not affected by this. Following example shows the diff action specification:
    <class name="org.openide.loaders.DataObject" count="2" />
and this one the open action declaration:
    <class name="org.openide.cookies.OpenCookie" count="1+" />
and its improvement to support open just on file of java type:
    <class name="org.openide.cookies.OpenCookie" count="1+" />
        <property name="mimeType" value="text/x-java" />
Still it looks desirable to keep the methodvalue and newvalue attributes of XML layer for specification of action to invoke.

Problems of the solution

  • MoveUpAction - ReorderAction is easy but MoveUpAction is dependent on: parent has Index cookie and this node is a child of parent acc. to Index.getNodes and index is >0. Just declaring the enablement check looks unreasonable for any fixed syntax. Not to mention you have to listen for Index.stateChanged events to be told if the situation changes. I think it is hard enough to support such an action when providing a rich Java API, much less fully declaratively.

Send comments and patches to or attach them to issue 18325. Please create the patches to current version of the document.

Project Features

About this Project

openide was started in November 2009, is owned by Antonin Nebuzelsky, and has 92 members.
By use of this website, you agree to the NetBeans Policies and Terms of Use (revision 20160708.bf2ac18). © 2014, Oracle Corporation and/or its affiliates. Sponsored by Oracle logo
Please Confirm