MenuConfig

MenuConfig – это специальный класс, который загружает структуру главного меню на основе файла, указанного в свойстве jmix.ui.menu-config.

Используйте Дизайнер меню Studio для определения структуры меню.

При создании нового проекта в Studio генерируется файл menu.xml, определяющий структуру главного меню приложения.

<menu-config xmlns="http://jmix.io/schema/ui/menu">
    <menu id="application"
          caption="msg://ui.ex2/menu.application"
          description="Application menu items"
          expanded="true"
          icon="VIEW_ACTION"
          insertBefore="administration">
        <item id="User.browse"/>
        <separator/>
        <item screen="sample_CustomerScreen"
              caption="msg://ui.ex2.screen.customer/customerScreen.caption"/>
        <item screen="sample_City.browse" id="cities"/>
    </menu>
</menu-config>

Существует два режима загрузки файлов, которые определяют структуру меню: composite (по умолчанию) и single.

Используйте свойство jmix.ui.composite-menu для переключения между режимами.

Давайте детально рассмотрим файл menu.xml.

menu-config – это корневой XML-элемент. Элементы menu-config образуют древовидную структуру, где элементы menu являются ветвями, а элементы item и separator - листьями.

menu – это вложенный элемент menu-config. Он обладает следующими атрибутами:

  • id - уникальный идентификатор элемента.

  • caption - заголовок элемента меню. Если он не задан, заголовок будет определяться в соответствии с правилом, описанным ниже.

  • description - текст, отображаемый в виде всплывающей подсказки при наведении курсора мыши. Вы можете использовать локализованные сообщения из пакета сообщений.

  • icon - значок элемента menu. Подробнее см. в разделе Значки.

  • insertBefore, insertAfter - определяют, должен ли элемент быть вставлен до или после определенного элемента или пункта меню с указанным идентификатором. Эти атрибуты используются для вставки элемента в соответствующее место в меню, определенном в файлах дополнений. Не используйте атрибуты insertBefore и insertAfter одновременно.

  • stylename - определяет название стиля для пункта меню. Подробнее см. в разделе Темы.

  • expanded - определяет, должен ли элемент menu быть развернут при открытии главного экрана. Значение по умолчанию - false.

Например:

<menu id="application"
      caption="msg://ui.ex2/menu.application"
      description="Application menu items"
      expanded="true"
      icon="VIEW_ACTION"
      insertBefore="administration">
</menu>

Атрибуты Item

item – это вложенный элемент menu. Он обладает следующими атрибутами:

  • id - уникальный идентификатор элемента. Если атрибуты screen, bean, class не определены, id используется для указания на экран с тем же id. Когда пользователь нажимает на пункт меню, на главном экране открывается соответствующий экран.

    <item id="User.browse"/>
  • caption - заголовок элемента item. Если значение не задано, заголовок будет определяться в соответствии с правилом, описанным ниже.

    <item screen="sample_CustomerScreen"
          caption="msg://ui.ex2.screen.customer/customerScreen.caption"/>
  • description - текст, который отображается в виде всплывающей подсказки при наведении курсора мыши. Вы также можете использовать локализованные сообщения из пакета сообщений.

  • screen - идентификатор экрана. Его можно использовать для многократного включения одного экрана в меню. Когда пользователь нажимает на пункт меню, на главном экране открывается соответствующий экран.

    <item screen="sample_City.browse" id="cities"/>
    <item screen="sample_City.browse" id="cities2"/>
  • bean - имя бина. Должен использоваться вместе с beanMethod. Метод бина вызывается, когда пользователь нажимает на пункт меню.

    menu.xml
    <item bean="sample_MenuBean"
          beanMethod="showCityBrowse"
          caption="Show Cities"/>
    MenuBean.java
    @Component("sample_MenuBean")
    public class MenuBean {
        @Autowired
        private ScreenBuilders screenBuilders;
    
        public void showCityBrowse(){
            final Screen frameOwner = AppUI.getCurrent()
                    .getTopLevelWindowNN().getFrameOwner();
            screenBuilders.screen(frameOwner)
                    .withScreenClass(CityBrowse.class)
                    .build()
                    .show();
        }
    }

    Вы можете передать параметры из пункта меню в метод бина, используя вложенный элемент properties. Например:

    menu.xml
    <item bean="sample_MenuBean" beanMethod="openLink"
          id="openBeanWithParams" caption="OpenBeanWithParams">
        <properties>
            <property name="url" value="https://jmix.io"/>
        </properties>
    </item>
    MenuBean.java
    @Component("sample_MenuBean")
    public class MenuBean {
    
        @Autowired
        private ObjectProvider<WebBrowserTools> webBrowserToolsProvider;
    
        public void openLink(Map<String, Object> parameters) {
            String url = (String) parameters.get("url");
            if (url == null) {
                return;
            }
    
            webBrowserToolsProvider.getObject().showWebPage(
                    url, ParamsMap.of("target", "_blank"));
        }
    }
  • class - полное имя класса, который реализует интерфейс MenuItemRunnable. Когда пользователь нажимает на пункт меню, создается экземпляр указанного класса и вызывается его метод.

    menu.xml
    <item class="ui.ex2.app.CustomMenu" id="jmix" caption="Open page"/>
    CustomMenu.java
    public class CustomMenu implements MenuItemRunnable, ApplicationContextAware {
    
        private ApplicationContext applicationContext;
    
        public void openLink(String url) {
            applicationContext.getBean(WebBrowserTools.class)
                    .showWebPage(url, ParamsMap.of("target", "_blank"));
        }
    
        @Override
        public void run(FrameOwner origin, MenuItem menuItem) {
            if (menuItem.getId().equals("jmix")) {
                openLink("https://jmix.io");
            } else {
                openLink("https://google.com");
            }
        }
    
        @Override
        public void setApplicationContext(ApplicationContext applicationContext)
                throws BeansException {
            this.applicationContext = applicationContext;
        }
    }
  • shortcut - сочетание клавиш для данного пункта меню. Возможные модификаторы - ALT, CTRL, SHIFT - разделяются знаком “-”. Например:

    <item screen="sample_City.browse"
          id="cities3"
          shortcut="ALT-C"/>

    Сочетания клавиш также можно настроить в файле application.properties и затем следующим образом использовать в файле menu.xml:

    menu.xml
    <item screen="sample_City.browse"
          id="cities4"
          shortcut="${sample.menu.city}"/>
    application.properties
    sample.menu.city=ALT-CTRL-C
  • Атрибут openMode определяет, как будет открываться экран. Он соответствует перечислению OpenMode со значениями: NEW_TAB, DIALOG, NEW_WINDOW. Значение по умолчанию - NEW_TAB.

    <item screen="sample_City.browse"
          id="cities5"
          openMode="DIALOG"/>
  • icon - значок элемента item. Подробнее см. в Значки.

  • insertBefore, insertAfter - определяют, должен ли элемент быть вставлен до или после определенного элемента или пункта меню с указанным идентификатором.

  • resizable - относится только к режиму открытия окна DIALOG. Управляет возможностью изменения размера окна. Возможные значения − true, false. По умолчанию главное меню не влияет на возможность изменять размер диалоговых окон.

  • stylename - определяет название стиля для пункта меню. Подробнее см. в Темы.

Свойства Item

properties – это вложенный элемент item. Он определяет набор свойств для передачи публичным сеттерам экрана. Каждое свойство определяется в элементе property с атрибутом name, который соответствует методу сеттера. Сеттеры вызываются фреймворком между отправкой AfterInitEvent и BeforeShowEvent.

Атрибуты property:

  • name - название свойства.

  • value - значение property для свойств, не являющихся сущностями.

  • entityClass - класс свойства сущности.

  • entityId - идентификатор свойства сущности.

  • entityFetchPlan - необязательный фетч-план для загрузки свойства сущности.

Например, логическое свойство filterVisible в menu.xml соответствует недействительному методу setFilterVisible(Boolean value) в контроллере экрана:

menu.xml
<item screen="sample_City.browse" id="cities6">
    <properties>
        <property name="filterVisible" value="false"/>
    </properties>
</item>
CityBrowse.java
public void setFilterVisible(Boolean value){
    isFilterVisible = value;
}

Пример со свойством сущности:

<item screen="User.edit" caption="User screen">
    <properties>
        <property name="user"
                  entityClass="ui.ex2.entity.User"
                  entityId="60885987-1b61-4247-94c7-dff348347f93"
                  entityFetchPlan="_base"/>
    </properties>
</item>

Определение заголовка меню

Если атрибут caption не указан, локализованное имя элемента menu или item определяется следующим образом: к идентификатору элемента добавляется префикс menu-config с точкой в конце; результирующая строка используется в качестве ключа для пакета сообщений. Например:

messages.properties
menu-config.User.browse = Users
menu-config.cities = Cities

Если id не задан, заголовок будет сгенерирован на основе имени класса (если установлен атрибут class) или имени бина и имени метода бина (если установлен атрибут bean). Поэтому рекомендуется все же установить атрибут id.