3.5.5.1. Декларативное создание действий
В XML-дескрипторе экрана для любого компонента, реализующего интерфейс Component.ActionsHolder
, в том числе для всего экрана или фрейма, может быть задан набор действий. Делается это в элементе actions
, который содержит вложенные элементы action
.
Элемент action
может иметь следующие атрибуты:
-
id
− идентификатор, должен быть уникален в рамках данного компонентаActionsHolder
. -
type
- задает тип действия. Если данный атрибут установлен, фреймворк находит класс, имеющий аннотацию@ActionType
с таким же значением, и использует его для инстанциирования действия. Если тип не задан, фреймворк создает экземпляр класса BaseAction. Раздел Стандартные действия описывает типы действий, предоставляемые фреймворком, раздел Собственные типы действий объясняет, как создавать собственные типы действий. -
caption
- название действия. -
description
- описание действия. -
enable
- признак доступности действия (true
/false
). -
icon
- значок действия.
-
primary
- атрибут, определяющий подсветку кнопок, обеспечивающих выполнение этого действия (true
/false
). Если выбраноtrue
, для подсветки будет использован особый стиль.В теме
hover
подсветка доступна по умолчанию; для её активации в темеhalo
установите значениеtrue
для переменной стиля$cuba-highlight-primary-action
.Следующие действия являются
primary
по умолчанию, если не установлено иное:create
у табличных компонентов иlookupSelectAction
в экранах выбора. -
shortcut
- комбинация клавиш для вызова.Комбинации можно жёстко задавать в XML-дескрипторе. Возможные модификаторы -
ALT
,CTRL
,SHIFT
- отделяются символом "-". Например:<action id="create" shortcut="ALT-N"/>
Для большей гибкости можно использовать готовые псевдонимы комбинаций из списка ниже, к примеру:
<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
Кроме того, есть возможность задавать комбинацию с помощью полного имени интерфейса
Config
и имени метода, возвращающего нужную комбинацию:<action id="remove" shortcut="${com.haulmont.cuba.client.ClientConfig#getTableRemoveShortcut}"/>
-
-
visible
- признак видимости действия (true
/false
).
Рассмотрим примеры декларативного объявления действий.
-
Объявление действий на уровне экрана:
<window> <actions> <action id="sayHello" caption="msg://sayHello" shortcut="ALT-T"/> </actions> <layout> <button action="sayHello"/> </layout> </window>
// controller @Inject private Notifications notifications; @Subscribe("sayHello") protected void onSayHelloActionPerformed(Action.ActionPerformedEvent event) { notifications.create() .withCaption("Hello") .withType(Notifications.NotificationType.HUMANIZED) .show(); }
Здесь объявляется действие с идентификатором
sayHello
и названием из пакета сообщений. С этим действием связывается кнопка, заголовок которой будет установлен в название действия. Контроллер экрана подписан на событие действияActionPerformedEvent
, так что методonSayHelloActionPerformed()
будет вызван при нажатии на кнопку, а также при нажатии комбинации клавиш ALT-T.
Обратите внимание, что действия, объявленные на уровне экрана, не обновляют своё состояние. Это значит, если действие имеет установленный |
-
Объявление действий для PopupButton:
<popupButton id="sayBtn" caption="Say"> <actions> <action id="hello" caption="Say Hello"/> <action id="goodbye" caption="Say Goodbye"/> </actions> </popupButton>
// controller @Inject private Notifications notifications; private void showNotification(String message) { notifications.create() .withCaption(message) .withType(NotificationType.HUMANIZED) .show(); } @Subscribe("sayBtn.hello") private void onSayBtnHelloActionPerformed(Action.ActionPerformedEvent event) { notifications.create() .withCaption("Hello") .show(); } @Subscribe("sayBtn.goodbye") private void onSayBtnGoodbyeActionPerformed(Action.ActionPerformedEvent event) { notifications.create() .withCaption("Hello") .show(); }
-
Объявление действий для Table:
<groupTable id="customersTable" width="100%" dataContainer="customersDc"> <actions> <action id="create" type="create"/> <action id="edit" type="edit"/> <action id="remove" type="remove"/> <action id="copy" caption="Copy" icon="COPY" trackSelection="true"/> </actions> <columns> <!-- --> </columns> <rowsCount/> <buttonsPanel alwaysVisible="true"> <!-- --> <button action="customersTable.copy"/> </buttonsPanel> </groupTable>
// controller @Subscribe("customersTable.copy") protected void onCustomersTableCopyActionPerformed(Action.ActionPerformedEvent event) { // ... }
Здесь помимо стандартных действий таблицы
create
,edit
иremove
объявлено действиеcopy
. Для этого действия указан также атрибутtrackSelection="true"
, в результате чего действие и связанная с ним кнопка становятся недоступными, если в таблице не выбрана ни одна строка. Это удобно, если действие предназначено для выполнения над текущей выбранной строкой таблицы. -
Объявление действий для PickerField:
<pickerField id="userPickerField" dataContainer="customerDc" property="user"> <actions> <action id="lookup" type="picker_lookup"/> <action id="show" description="Show user" icon="USER"/> </actions> </pickerField>
// controller @Subscribe("userPickerField.show") protected void onUserPickerFieldShowActionPerformed(Action.ActionPerformedEvent event) { // }
В данном примере для компонента
PickerField
объявлено стандартное действиеpicker_lookup
и дополнительное действиеshow
. Так как в кнопкахPickerField
, отображающих действия, используются значки, а не надписи, атрибутcaption
явно установлен в пустую строку, иначе названием действия и заголовком кнопки стал бы идентификатор действия. Атрибутdescription
позволяет отображать всплывающую подсказку при наведении мыши на кнопку действия.
Ссылки на любые декларативно объявленные действия можно получить в контроллере экрана либо непосредственно путем инжекции, либо из компонентов, реализующих интерфейс Component.ActionsHolder
. Это может понадобиться для программной установки свойств действия. Например:
@Named("customersTable.copy")
private Action customersTableCopy;
@Inject
private PickerField<User> userPickerField;
@Subscribe
protected void onBeforeShow(BeforeShowEvent event) {
customersTableCopy.setEnabled(false);
userPickerField.getActionNN("show").setEnabled(false);
}