BaseAction
BaseAction
is a base class for action implementation. It is recommended to derive custom actions from it when declarative action creation functionality is insufficient.
When creating a custom action class, you should implement the actionPerform()
method and pass the 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 a message using action identifier as key from the localized message pack corresponding to the action class package. If there is no message with such key, then the key itself, that is, 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 returnstrue
; -
isApplicable()
method returnstrue
; -
all
EnabledRules
(if any) returntrue
.
Usage examples:
Button action
@Autowired
private Notifications notifications;
@Autowired
private Button sayHelloBtn;
@Autowired
private Button sayGoodbyeBtn;
@Subscribe
public void onInit(InitEvent event) {
sayHelloBtn.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();
}
});
sayGoodbyeBtn.setAction(new BaseAction("goodbye")
.withPrimary(true)
.withHandler(e ->
notifications.create()
.withCaption("Goodbye!")
.withType(Notifications.NotificationType.TRAY)
.show()));
}
In this example, the sayHelloBtn
button caption will be set to the string located in the message pack with the hello
key. You can override the getCaption()
action method to initialize the button name differently.
ValuePicker action
Action of a programmatically created ValuePicker
:
@Autowired
protected Notifications notifications;
@Autowired
private UiComponents uiComponents;
@Autowired
private MessageBundle messageBundle;
@Autowired
private VBoxLayout vBox;
@Subscribe
protected void onInit(InitEvent event) {
ValuePicker valueField = uiComponents.create(ValuePicker.NAME);
valueField.addAction(new BaseAction("hello") {
@Override
public String getCaption() {
return null;
}
@Override
public String getDescription() {
return messageBundle.getMessage("helloDescription");
}
@Override
public String getIcon() {
return JmixIcon.HANDSHAKE_O.source();
}
@Override
public void actionPerform(Component component) {
notifications.create()
.withCaption("Hello!")
.withType(Notifications.NotificationType.TRAY)
.show();
}
});
valueField.addAction(new BaseAction("goodbye")
.withCaption(null)
.withDescription(messageBundle.getMessage("goodbyeDescription"))
.withIcon(JmixIcon.HAND_PAPER_O.source())
.withHandler(e ->
notifications.create()
.withCaption("Goodbye!")
.withType(Notifications.NotificationType.TRAY)
.show()));
vBox.add(valueField);
}
In this example, an anonymous BaseAction
derived class is used to set the actions of the value picker buttons. The button’s caption is not displayed, as an icon with a description, which pops up when hovering mouse cursor, is used instead.
Table action
@Autowired
private Table<Customer> customersTable;
@Autowired
private Notifications notifications;
@Subscribe
public void onInit(InitEvent event) {
customersTable.addAction(new AboutSingleAction());
}
private class AboutSingleAction extends BaseAction {
public AboutSingleAction() {
super("aboutSingle");
}
@Nullable
@Override
public String getCaption() {
return "About Single";
}
@Override
public void actionPerform(Component component) {
notifications.create()
.withCaption("Hello " + customersTable.getSingleSelected())
.withType(Notifications.NotificationType.TRAY)
.show();
}
@Override
public boolean isApplicable() {
return customersTable != null && customersTable.getSelected().size() == 1;
}
}
In this example, the AboutSingleAction
class is declared, and its instance is added to the table’s actions list. The action is enabled when a single table row is selected. The latter is possible because BaseAction’s target
property is automatically assigned to the action when it is added to a ListComponent
descendant (Table
or Tree
).
Using ItemTrackingAction
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 of isApplicable()
method:
@Autowired
private Table<Customer> customersTable;
@Autowired
private Notifications notifications;
@Subscribe
public void onInit(InitEvent event) {
customersTable.addAction(new ItemTrackingAction("about") {
@Nullable
@Override
public String getCaption() {
return "About";
}
@Override
public void actionPerform(Component component) {
notifications.create()
.withCaption("Hello " + customersTable.getSelected().iterator().next())
.withType(Notifications.NotificationType.TRAY)
.show();
}
});
}