3.5.4.3. BaseAction
BaseAction
is a base class for actions implementation. It is recommended to derive custom actions from it when declarative actions creation functionality is insufficient.
When creating a custom action class, you should implement actionPerform()
method and pass action identifier to the BaseAction
constructor. You can override any property getters: getCaption()
, getDescription()
, getIcon()
, getShortcut()
, isEnabled()
, isVisible()
, isPrimary()
. Standard implementations of these methods return values set by setter methods, except the getCaption()
method. If the action name is not explicitly set by setCaption()
method, it retrieves message using action identifier as key from the the localized message pack corresponding to the action class package. If there is no message with such key, then the key itself, i.e. the action identifier, is returned.
Alternatively, you can use the fluent API for setting properties and providing a lambda expression for handling the action: see withXYZ()
methods.
BaseAction
can change its enabled
and visible
properties depending on user permissions and current context.
BaseAction
is visible if the following conditions are met:
-
setVisible(false)
method was not called; -
there is no
hide
UI permission for this action.
The action is enabled if the following conditions are met:
-
setEnabled(false)
method was not called; -
there are no
hide
or read-only UI permissions for this action; -
isPermitted()
method returns true; -
isApplicable()
method returns true.
Usage examples:
-
Button action:
@Inject private Notifications notifications; @Inject private Button helloBtn; @Subscribe protected void onInit(InitEvent event) { helloBtn.setAction(new BaseAction("hello") { @Override public boolean isPrimary() { return true; } @Override public void actionPerform(Component component) { notifications.create() .withCaption("Hello!") .withType(Notifications.NotificationType.TRAY) .show(); } }); // OR helloBtn.setAction(new BaseAction("hello") .withPrimary(true) .withHandler(e -> notifications.create() .withCaption("Hello!") .withType(Notifications.NotificationType.TRAY) .show())); }
In this example, the
helloBtn
button caption will be set to the string located in the message pack with thehello
key. You can override thegetCaption()
action method to initialize button name in a different way. -
Action of a programmatically created PickerField:
@Inject private UiComponents uiComponents; @Inject private Notifications notifications; @Inject private MessageBundle messageBundle; @Inject private HBoxLayout box; @Subscribe protected void onInit(InitEvent event) { PickerField pickerField = uiComponents.create(PickerField.NAME); pickerField.addAction(new BaseAction("hello") { @Override public String getCaption() { return null; } @Override public String getDescription() { return messageBundle.getMessage("helloDescription"); } @Override public String getIcon() { return "icons/hello.png"; } @Override public void actionPerform(Component component) { notifications.create() .withCaption("Hello!") .withType(Notifications.NotificationType.TRAY) .show(); } }); // OR pickerField.addAction(new BaseAction("hello") .withCaption(null) .withDescription(messageBundle.getMessage("helloDescription")) .withIcon("icons/ok.png") .withHandler(e -> notifications.create() .withCaption("Hello!") .withType(Notifications.NotificationType.TRAY) .show())); box.add(pickerField); }
In this example an anonymous
BaseAction
derived class is used to set the action of the picker field button. The button caption is not displayed, as an icon with a description, which pops up when hovering mouse cursor, is used instead. -
Table action:
@Inject private Notifications notifications; @Inject private Table<Customer> table; @Inject private Security security; @Subscribe protected void onInit(InitEvent event) { table.addAction(new HelloAction()); } private class HelloAction extends BaseAction { public HelloAction() { super("hello"); } @Override public void actionPerform(Component component) { notifications.create() .withCaption("Hello " + table.getSingleSelected()) .withType(Notifications.NotificationType.TRAY) .show(); } @Override protected boolean isPermitted() { return security.isSpecificPermitted("myapp.allow-greeting"); } @Override public boolean isApplicable() { return table != null && table.getSelected().size() == 1; } }
In this example, the
HelloAction
class is declared, and its instance is added to the table’s actions list. The action is enabled for users who havemyapp.allow-greeting
security permission and only when a single table row is selected. The latter is possible because BaseAction’starget
property is automatically assigned to the action when it is added to aListComponent
descendant (Table
orTree
). -
If you need an action, which becomes enabled when one or more table rows are selected, use BaseAction’s descendant -
ItemTrackingAction
, which adds default implementation ofisApplicable()
method:@Inject private Table table; @Inject private Notifications notifications; @Subscribe protected void onInit(InitEvent event) { table.addAction(new ItemTrackingAction("hello") { @Override public void actionPerform(Component component) { notifications.create() .withCaption("Hello " + table.getSelected().iterator().next()) .withType(Notifications.NotificationType.TRAY) .show(); } }); }