4.5.4.1. Declarative Creation of Actions

You can specify a set of actions in an XML screen descriptor for any component that implements the Component.ActionsHolder interface, including the entire screen or frame. This is done in the actions element, which contains nested action elements.

The action element can have the following attributes:

  • id − identifier, which should be unique within the ActionsHolder component.

  • caption – action name.

  • description – action description.

  • enable – accessibility flag (true / false).

  • icon – action icon.

  • invoke - name of the controller method to be invoked. The method should be public void, and either not have arguments or have one argument of the Component type. If the method has a Component argument, then an instance of the visual component that launches this action will be passed to it when invoked.

  • shortcut - keyboard shortcut for invocation.

    Shortcut values can be hard-coded in the XML descriptor. Possible modifiers, ALT, CTRL, SHIFT, are separated by the "-" character. For example:

    <action id="create" shortcut="ALT-N"/>

    To avoid the hard code, you can use the predefined shortcut aliases from the list below, for example:

    <action id="edit" shortcut="${TABLE_EDIT_SHORTCUT}"/>
    • TABLE_EDIT_SHORTCUT

    • COMMIT_SHORTCUT

    • CLOSE_SHORTCUT

    • FILTER_APPLY_SHORTCUT

    • FILTER_SELECT_SHORTCUT

    • NEXT_TAB_SHORTCUT

    • PREVIOUS_TAB_SHORTCUT

    • PICKER_LOOKUP_SHORTCUT

    • PICKER_OPEN_SHORTCUT

    • PICKER_CLEAR_SHORTCUT

    Another option is to use the full qualified name of the Config interface and method which returns shortcut:

    <action id="remove" shortcut="${com.haulmont.cuba.client.ClientConfig#getTableRemoveShortcut}"/>
  • visible – visibility flag (true / false).

The examples of declaration are provided below.

  • Declaring actions at the screen level:

    <window ...>
        <dsContext/>
    
        <actions>
            <action id="sayHelloAction" caption="msg://sayHello" shortcut="ALT-T" invoke="sayHello"/>
        </actions>
    
        <layout>
            <button action="sayHelloAction"/>
        </layout>
    </window>
    // controller
    
    public void sayHello(Component component) {
        showNotification("Hello!", NotificationType.TRAY);
    }

    In the example above, an action with sayHelloAction identifier and a name from message pack is declared. This action is bound with a button, which caption will be set to the action name. The action will invoke the sayHello() controller method when clicking on the button, or when pressing the ALT-T shortcut if at that moment the screen has input focus.

  • Declaring actions for PopupButton:

    <popupButton caption="Say something">
        <actions>
            <action id="helloAction" caption="Say hello" invoke="sayHello"/>
            <action id="goodbyeAction" caption="Say goodbye" invoke="sayGoodbye"/>
        </actions>
    </popupButton>
  • Declaring actions for Table:

    <table id="usersTable" width="100%">
        <actions>
            <action id="create"/>
            <action id="edit"/>
            <action id="copy" caption="msg://copy" icon="icons/copy.png"
                    invoke="copy" trackSelection="true"/>
            <action id="changePassw" caption="msg://changePassw" icon="icons/change-pass.png"
                    invoke="changePassword" trackSelection="true"/>
        </actions>
        <buttonsPanel>
            <button action="usersTable.create"/>
            <button action="usersTable.edit"/>
            <button action="usersTable.copy"/>
            <button action="usersTable.changePassw"/>
        </buttonsPanel>
        <rowsCount/>
        <columns>
            <column id="login"/>
            ...
        </columns>
        <rows datasource="usersDs"/>
    </table>

    In this example copy and changePassw actions are declared in addition to create and edit standard actions of the table. These actions invoke corresponding methods of the controller. In addition, the trackSelection="true" attribute is specified for them, which means that the action and corresponding button become disabled if no row is selected in the table. It is useful if the action is intended to be executed over a currently selected table row.

    An optional openType attribute can be specified for create and edit actions to define edit screen opening mode, as described for the setOpenType() method of the CreateAction class.

  • Declaring PickerField actions:

    <pickerField id="colourField" datasource="carDs" property="colour">
        <actions>
            <action id="lookup"/>
            <action id="show" icon="icons/show.png"
                    invoke="showColour" caption="" description="Show colour"/>
        </actions>
    </pickerField>

    In the example above, the standard lookup action and an additional show action invoking the showColour() method of the controller, are declared for the PickerField component. Since PickerField buttons that display actions use icons instead of captions, the caption attribute is explicitly set to an empty string, otherwise action name and button caption would be set to the action identifier. The description attribute allows you to display a tooltip when hovering over the action button.

You can obtain references to any declared actions in the screen controller either directly by injection, or from components that implement the Component.ActionsHolder interface. This can be useful to set action properties programmatically. For example:

@Named("carsTable.create")
private CreateAction createAction;

@Named("carsTable.copy")
private Action copyAction;

@Inject
private PickerField colourField;

@Override
public void init(Map<String, Object> params) {
    Map<String, Object> values = new HashMap<>();
    values.put("type", CarType.PASSENGER);
    createAction.setInitialValues(values);

    copyAction.setEnabled(false);

    Action showAction = colourField.getAction("show");
    showAction.setEnabled(false);
}