ViewAction
ViewAction – это действие с коллекцией, предназначенное для просмотра и редактирования экземпляров сущности. Оно открывает экран редактирования таким же образом, как EditAction, но делает все поля ввода нередактируемыми и запрещает действия, реализующие интерфейс ReadOnlyAwareScreen. Если необходимо дать пользователю возможность переключить экран в режим редактирования, добавьте в экран кнопку и свяжите ее с предопределенным действием enableEditing:
<hbox id="editActions" spacing="true">
    <button id="commitAndCloseBtn" action="windowCommitAndClose"/>
    <button id="closeBtn" action="windowClose"/>
    <button action="enableEditing"/> (1)
</hbox>
| 1 | Эта кнопка отображается только тогда, когда экран находится в режиме "только для чтения". | 
Заголовок действия enableEditing можно переопределить в главном пакете сообщений, используя ключ actions.EnableEditing, или непосредственно в экране путем указания атрибута caption у соответствующей кнопки.
Действие реализовано классом io.jmix.ui.action.list.ViewAction и объявляется в XML с помощью атрибута type="view". Общие свойства действий можно конфигурировать с помощью атрибутов элемента action, подробнее см. раздел Декларативные действия. Ниже рассматриваются параметры, специфичные для класса ViewAction.
Параметры
Следующие параметры можно установить и в XML, и в Java:
- 
openMode- режим открытия экрана редактирования, задаваемый значением перечисленияOpenMode:NEW_TAB,DIALOG, и т.д. По умолчанию экран открывается в режимеTHIS_TAB. - 
screenId- строковый идентификатор экрана редактирования. По умолчанию используется экран, аннотированный@PrimaryEditorScreen, или имеющий идентификатор вида<entity_name>.edit, напримерdemo_Customer.edit. - 
screenClass- класс Java экрана редактирования. Данный параметр имеет более высокий приоритет,screenId. 
Например, если необходимо открыть определенный экран редактирования в режиме диалога, действие можно сконфигурировать в XML следующим образом:
<action id="view" type="view">
    <properties>
        <property name="openMode" value="DIALOG"/>
        <property name="screenClass" value="ui.ex1.screen.entity.customer.CustomerEdit"/>
    </properties>
</action>
В качестве альтернативы, действие можно инжектировать в контроллер экрана и сконфигурировать, используя сеттеры:
@Named("custTable.view")
private ViewAction<Customer> viewAction;
@Subscribe
public void onInit(InitEvent event) {
    viewAction.setOpenMode(OpenMode.DIALOG);
    viewAction.setScreenClass(CustomerEdit.class);
}
Обработчики
Далее рассматриваются параметры, которые можно сконфигурировать только программно в Java. Для генерации корректно аннотированных методов для этих параметров используйте Studio.
screenOptionsSupplier
Это обработчик, возвращающий объект ScreenOptions для передачи в открываемый экран редактирования. Например:
@Install(to = "custTable.view", subject = "screenOptionsSupplier")
private ScreenOptions custTableViewScreenOptionsSupplier() {
    return new MapScreenOptions(ParamsMap.of("someParameter", 10));
}
Возвращаемый объект ScreenOptions будет доступен в InitEvent открываемого экрана.
screenConfigurer
Это обработчик, принимающий экран редактирования для его конфигурации перед открытием. Например:
@Install(to = "custTable.view", subject = "screenConfigurer")
private void custTableViewScreenConfigurer(Screen screen) {
    ((CustomerEdit) screen).setSomeParameter(10);
}
Обратите внимание, что конфигуратор экрана вступает в действие, когда экран уже инициализирован, но еще не показан, то есть после InitEvent и AfterInitEvent, и до BeforeShowEvent.
transformation
Это обработчик, вызываемый после того, как сущность выбрана и прошла валидацию в экране редактирования. Он принимает выбранную сущность и может быть использован для того, чтобы преобразовать закоммиченную сущность (если было выполнено действие enableEditing) перед ее установкой в целевой контейнер данных. Например:
@Install(to = "custTable.view", subject = "transformation")
private Customer custTableViewTransformation(Customer customer) {
    return reloadCustomer(customer);
}
afterCommitHandler
Это обработчик, вызываемый после коммита редактируемого экземпляра сущности в экране редактирования, если пользователь переключил экран в режим редактирования используя действие enableEditing, упомянутое выше. Принимает сохраненный в БД экземпляр сущности. Например:
@Install(to = "custTable.view", subject = "afterCommitHandler")
private void custTableViewAfterCommitHandler(Customer customer) {
    System.out.println("Updated " + customer);
}
afterCloseHandler
Это обработчик, вызываемый после закрытия экрана редактирования. Принимает AfterCloseEvent. Например:
@Install(to = "custTable.view", subject = "afterCloseHandler")
private void custTableViewAfterCloseHandler(AfterCloseEvent afterCloseEvent) {
    if (afterCloseEvent.closedWith(StandardOutcome.COMMIT)) {
        System.out.println("Enabled editing and then committed");
    }
}
Использование ActionPerformedEvent
Для того чтобы произвести какие-либо проверки, или взаимодействовать с пользователем перед выполнением действия, необходимо подписаться на событие ActionPerformedEvent действия и в нужный момент вызвать метод execute(). Действие будет вызвано со всеми параметрами, которые были для него заданы. В примере ниже перед выполнением действия отображается диалог подтверждения:
@Autowired
private ScreenBuilders screenBuilders;
@Subscribe("custTable.view")
public void onCustTableView(Action.ActionPerformedEvent event) {
    CustomerEdit customerEdit = screenBuilders.editor(custTable)
            .withOpenMode(OpenMode.DIALOG)
            .withScreenClass(CustomerEdit.class)
            .withAfterCloseListener(afterScreenCloseEvent -> {
                if (afterScreenCloseEvent.closedWith(StandardOutcome.COMMIT)) {
                    Customer committedCustomer = (afterScreenCloseEvent.getSource()).getEditedEntity();
                    System.out.println("Updated " + committedCustomer);
                }
            })
            .build();
    customerEdit.setReadOnly(true);
    customerEdit.show();
}