Migration to CUBA 7 API: Required Components Migration

Please note that your entire codebase should work on the new version of the framework only with minor changes listed in the release notes, i.e. you don’t need to migrate existing screens on the new API, but if you want, the following guide may be helpful.

Table of Contents

Migration to CUBA 7 API: Screens
Migration to CUBA 7 API: Browser / Lookup Screens
Migration to CUBA 7 API: Editor Screens
Migration to CUBA 7 API: Required Components Migration
Migration to CUBA 7 API: Optional Components Migration

The invoke attribute

XML elements such as <button> and <action> have the invoke attribute, which must be replaced by the corresponding component subscription, e.g.

Before
XML

...
<actions>
	<action id="someAction"
			caption="Click Me!"
			invoke="someAction"/>
</actions>
...
<button caption="Say Hello!"
		description="Click Me!"
		invoke="sayHello"/>
...

Controller

public void someAction() {
	...
}

public void sayHello() {
	...
}

After
XML

...
<actions>
	<action id="someAction"
			caption="Click Me!"/>
</actions>
...
<button id="helloButton"
		caption="Say Hello!"
		description="Click Me!"/>
...

Controller

@Subscribe("someAction")
protected void onSomeActionActionPerformed(Action.ActionPerformedEvent event) {
	...
}

@Subscribe("helloButton")
protected void onHelloButtonClick(Button.ClickEvent event) {
	...
}

Bulk Editing

Replace the bulkEditor component with the bulkEdit action.

Before

<buttonsPanel>
	<bulkEditor for="customersTable"/>
</buttonsPanel>

After

...
<actions>
	<action id="bulkEdit" type="bulkEdit"/>
</actions>
...
<buttonsPanel>
	<button id="bulkEditButton"
			action="customersTable.bulkEdit"/>
</buttonsPanel>
...

CollectionContainer Add/Remove items

In order to mutate CollectionContainer items (similar to CollectionDatasource addItem() / removeItem()), the getMutableItems() method must be used.

getMutableItems() - returns a mutable list of entities stored in the container. All list changes caused by the add(), addAll(), remove(), removeAll(), set(), clear() methods produce CollectionChangeEvent, so subscribed visual components will update accordingly.

Before

customersDs.addItem(newCustomer);

After

customersDc.getMutableItems().add(newCustomer);

Component type parameters

It is highly recommended to set type parameter for UI components explicitly, even default type parameter should be set. For example:

@Inject
protected LookupField<User> userField;
@Inject
protected TextField<Long> countField;
@Inject
protected Label<String> defaultTypedLabel;

Create/Edit actions with OpenType.DIALOG

Standard actions ignore the openType attribute which is taken into account by legacy actions.

For the new API, you need to subscribe on ActionPerformedEvent and provide a custom implementation, e.g.

@UiController("sales_Product.browse")
@UiDescriptor("product-browse.xml")
@LookupComponent("productsTable")
@LoadDataBeforeShow
public class ProductBrowse extends StandardLookup<Product> {
    @Inject
    private GroupTable<Product> productsTable;

    @Inject
    private ScreenBuilders screenBuilders;

    @Subscribe("productsTable.create")
    private void onProductsTableCreate(Action.ActionPerformedEvent event) {
        screenBuilders.editor(Product.class, this)
                .newEntity()
                .withLaunchMode(OpenMode.DIALOG)
                .build()
                .show();
    }

    @Subscribe("productsTable.edit")
    private void onProductsTableEdit(Action.ActionPerformedEvent event) {
        screenBuilders.editor(productsTable)
                .withLaunchMode(OpenMode.DIALOG)
                .build()
                .show();
    }
}

The easiest way is to set forceDialog="true" for the <dialogMode/> element of an editor screen.

<dialogMode height="600" 
            width="800"
            forceDialog="true"/>

The third possible approach is to implement custom Create/Edit actions that can be used independently of the standard ones.

This demo project illustrates the above dialog-actions.zip (81.7 KB).

DialogCreateAction and DialogEditAction are custom actions and both are used in the product-browse.xml:

@ActionType(DialogCreateAction.ID)
public class DialogCreateAction extends CreateAction {

    public static final String ID = "create_dialog";

    public DialogCreateAction() {
        this(ID);
    }

    public DialogCreateAction(String id) {
        super(id);
    }

    @SuppressWarnings("unchecked")
    @Override
    public void actionPerform(Component component) {
        // if standard behaviour
        if (!hasSubscriptions(ActionPerformedEvent.class)) {
            Screen editor = screenBuilders.editor(target)
                    .newEntity()
                    .withOpenMode(OpenMode.DIALOG)
                    .build();
            editor.show();
        } else {
            super.actionPerform(component);
        }
    }
}
@ActionType(DialogEditAction.ID)
public class DialogEditAction extends EditAction {

    public static final String ID = "edit_dialog";

    public DialogEditAction() {
        super(ID);
    }

    public DialogEditAction(String id) {
        super(id);
    }

    @SuppressWarnings("unchecked")
    @Override
    public void actionPerform(Component component) {
        // if standard behaviour
        if (!hasSubscriptions(ActionPerformedEvent.class)) {
            Entity editedEntity = target.getSingleSelected();
            Screen editor = screenBuilders.editor(target)
                    .editEntity(editedEntity)
                    .withOpenMode(OpenMode.DIALOG)
                    .build();
            editor.show();
        } else {
            super.actionPerform(component);
        }
    }
}
<actions>
    <action id="create" type="create_dialog"/>
    <action id="edit" type="edit_dialog"/>
...
</actions>

Similarly to screens, the actions base package must be registered in the web-springs.xml

<gui:actions base-packages="com.company.demo.gui.actions"/>

Query parameters

Using Screen Parameters in Loaders
Dependencies Between Data Components

5 Likes

how to set “includeProperties” for bulkEditAction?

Hi,

In order to set includeProperties you need to use the com.haulmont.cuba.gui.BulkEditors bean directly.

GuiDevelopmentException: BulkEditor component can be used only in legacy screens based on AbstractWindow

It’s com.haulmont.cuba.gui.BulkEditors, not com.haulmont.cuba.gui.components.BulkEditor. You can find the example of it’s programmatic usage in the doc.

For cuba7, we don’t need migrate existing screens. How about for future releases of cuba?