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 是 menu-config 的内部元素。具有下列属性:
-
id- 元素的唯一标识符。 -
caption-menu元素的标题。如果未设置,则会用 下面 介绍的规则确定标题。 -
description- 鼠标悬停时展示的提示文字。可以使用 消息包 中的本地化消息。 -
icon-menu元素的图标。参阅 图标 章节了解详情。 -
insertBefore、insertAfter- 将当前菜单放在某个特定元素或指定了 id 的菜单项之前或之后。这些属性用来将一个菜单项放置于 扩展组件 中定义菜单中的合适位置。不要同时使用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指向同名界面。当用户点击时,会在 主界面 打开相应的界面。<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- bean 名称。必须与beanMethod一起使用。当用户点击时,执行 bean 方法。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 内部元素可以从菜单项传递参数至 bean 方法。示例:
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.javapublic 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.propertiessample.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- 将当前菜单放在某个特定元素或指定了 id 的菜单项之前或之后。 -
resizable- 仅在以DIALOG模式打开界面有效。控制弹窗是否可改变大小。可设置为true或false。默认情况下,主菜单对窗口是否可以改变大小没有限制。 -
stylename- 定义菜单项的样式名。参阅 主题 了解详情。
item 的元素
properties 是 item 的内部元素。用于定义传递给界面公共 setter 的一组属性参数。每个属性参数在 property 元素内使用 name 属性定义,名称对应于一个 setter 方法。框架在界面的 AfterInitEvent 和 BeforeShowEvent 事件之间调用 setter。
property 属性:
-
name- 属性名称。 -
value- 非实体属性的属性值。 -
entityClass- 实体属性的类。 -
entityId- 实体属性的 id。 -
entityFetchPlan- 可选参数,设置用于加载实体属性的 fetch plan。
例如,menu.xml 中的 filterVisible 布尔属性对应界面控制器中的 void setFilterVisible(Boolean value) 方法:
<item screen="sample_City.browse" id="cities6">
<properties>
<property name="filterVisible" value="false"/>
</properties>
</item>
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 作为前缀,再加上元素的 id,中间以 “.” 分隔。形成的字符串作为 消息包 的键值。示例:
menu-config.User.browse = Users
menu-config.cities = Cities
如果 id 未设置,则标题会使用类名(如果设置了 class 属性)或 bean 名称及方法(如果设置了 bean 属性)生成。因此,我们推荐最好设置 id 属性。