配置

添加小部件

默认情况下,该扩展组件没有预定义的小部件。按照下列步骤创建小部件:

  1. 使用 Studio 创建一个新 fragment。在 Jmix 工具窗口中,点击 New → Screen,然后选择 Screen Fragment 模板。设置界面描述和控制器的名称。

  2. 在界面控制器中,添加 @DashboardWidget 注解。

下面是一个展示公司 logo 的简单小部件:

LogoWidget.java
@UiController("sample_Logo")
@UiDescriptor("logo-widget.xml")
@DashboardWidget(name = "Logo")
public class LogoWidget extends ScreenFragment {
}
logo-widget.xml
<fragment xmlns="http://jmix.io/schema/ui/fragment">
    <layout>
        <image>
            <resource>
                <classpath path="dashboards/ex1/screen/widgets/image/jmix-logo.png"/>
            </resource>
        </image>
    </layout>
</fragment>

小部件更新

RefreshableWidget 接口支持对一个小部件进行不定时刷新。如果小部件实现了 RefreshableWidget 接口,在每次仪表盘更新事件触发时,都会调用其 refresh() 方法。

下面示例中,小部件展示一个随机的小笑话。刷新频率在创建仪表盘时,使用 仪表盘编辑器 设置。

RandomJokeWidget.java
@UiController("sample_RandomJokeWidget")
@UiDescriptor("random-joke-widget.xml")
@DashboardWidget(name = "Random Joke")
public class RandomJokeWidget extends ScreenFragment implements RefreshableWidget {

    @Autowired
    private TextArea<String> randomJoke;

    @Subscribe
    private void onAfterInit(AfterInitEvent event) {
        randomJoke.setValue(getNewJoke());
    }

    @Override
    public void refresh(DashboardEvent dashboardEvent) {
        randomJoke.setValue(getNewJoke());
    }

    private String getNewJoke() {
        String host = "icanhazdadjoke.com";
        String url = "https://" + host;
        RestTemplate restTemplate = new RestTemplate();
        HttpHeaders headers = new HttpHeaders();
        headers.set("Accept", "text/plain");
        headers.set("User-Agent", "CubaDashboardDemoApp");
        headers.set("Cache-Control", "no-cache");
        headers.set("Host", host);
        HttpEntity<String> request = new HttpEntity<>("", headers);

        ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.GET, request, String.class);
        return response.getBody();

    }
}

小部件参数

如果希望类成员变量作为小部件参数使用,需要为其添加 @WindowParam@WidgetParam 注解。

扩展插件提供 参数编辑器 对话框,支持创建参数并传递给小部件。

我们看看如何在代码中访问参数。下面的小部件展示一个图片,图片保存在一个类成员变量中:

ArtWidget.java
@UiController("sample_ArtWidget")
@UiDescriptor("art-widget.xml")
@DashboardWidget(name = "Pokemon Art")
public class ArtWidget extends ScreenFragment {

    public static final String INIT_POKEMON = "Cubone"; (1)

    @Autowired
    private InstanceContainer<Pet> petDc; (2)

    @Autowired
    private DataManager dataManager;

    @WindowParam
    @WidgetParam
    protected Pet pet; (3)

    @WindowParam
    protected Widget widget; (4)

    @Subscribe
    public void onInit(InitEvent event) {
        if (pet == null || pet.getPicture() == null) { (5)
            pet = dataManager.loadValue("select s from sample_Pet s where " +
                            "s.name = :name", Pet.class)
                    .parameter("name", INIT_POKEMON)
                    .one();
        }
        petDc.setItem(pet); (6)
        widget.setCaption(pet.getName()); (7)
    }
}
1 包含实体 name 字段的常量。没有为小部件设置参数时,默认使用该值。
2 注入实体实例数据容器,容器中包含一个带有图片属性的实体。
3 Pet 类型的类成员变量。其名称需要与参数编辑器中的 alias 字段相同。
4 注入小部件本身,为其设置新标题。
5 如果参数未设置,则使用 name 等于常量的实体。
6 将实体放入实例容器中。
7 设置小部件的标题。

小部件的界面描述可以是这样:

art-widget.xml
<fragment xmlns="http://jmix.io/schema/ui/fragment">
    <data>
        <instance id="petDc" class="dashboards.ex1.entity.Pet">
            <fetchPlan extends="_base"/>
            <loader id="petDl"/>
        </instance>
    </data>
    <layout>
        <image id="pokemonImage"
               dataContainer="petDc"
               property="picture"/>
    </layout>
</fragment>

自定义小部件编辑器

可以根据需要自定义 小部件编辑器 对话框。

下面的示例中,为自定义小部件编辑器添加一个 EntityPicker 组件。组件中选择的实体将作为参数在小部件中使用。

首先,使用 Studio 创建一个空的界面 fragment:在 Jmix 工具窗口,点击 New → Screen 然后选择 Screen Fragment 模板。设置界面描述和控制器的名称。

界面描述如下:

pokemon-widget-editor.xml
<fragment xmlns="http://jmix.io/schema/ui/fragment">
    <layout expand="hBox">
        <hbox id="hBox" width="AUTO" spacing="true" expand="pokemonPicker">
            <label value="msg://dashboards.ex1.screen.widget/pokemonToShow.caption"/>
            <entityPicker id="pokemonPicker"
                          metaClass="sample_Pet"
                          property="name"
                          required="true"/>
        </hbox>
    </layout>
</fragment>

编辑器的控制器如下:

PokemonWidgetEditor.java
@UiController("sample_PokemonWidgetEditor")
@UiDescriptor("pokemon-widget-editor.xml")
public class PokemonWidgetEditor extends ScreenFragment {

    @Autowired
    private EntityPicker<Pet> pokemonPicker;

    @WindowParam
    @WidgetParam
    protected Pet pet; (1)

    @Subscribe("pokemonPicker") (2)
    public void onPokemonPickerValueChange(HasValue.ValueChangeEvent<String> event) {
        pet = pokemonPicker.getValue(); (3)
    }

}
1 定义作为小部件参数的字段。Defines a field that is used as a widget parameter.
2 订阅 ValueChangeEvent
3 将选择的值设置为小部件参数。

然后,需要在小部件中定义自定义编辑器。

PokemonWidget.java
@UiController("sample_PokemonWidget")
@UiDescriptor("pokemon-widget.xml")
@DashboardWidget(name = "Pokemon Widget", editFragmentId = "sample_PokemonWidgetEditor") (1)
public class PokemonWidget extends ScreenFragment {

    @Autowired
    private InstanceContainer<Pet> petDc;

    @WindowParam
    @WidgetParam
    protected Pet pet; (2)

    @Subscribe
    public void onInit(InitEvent event) {
        petDc.setItem(pet);
    }
}
1 自定义小部件编辑器的 id 在 @DashboardWidget 注解定义。
2 小部件参数从编辑器传入。

创建的编辑器界面如下:

widget custom

预定义角色

该扩展组件提供下列预定义角色:

  • dashboards-admin - 允许用户创建和编辑仪表盘和小部件模板。

  • dashboards-view - 允许用户查看嵌入的仪表盘。

  • dashboards-browse - 允许用户查看可用的仪表盘列表。