3.5.3.4.2. Программное создание компонентов данных
Компоненты данных можно создавать и использовать программно.
В следующем примере мы создадим экран редактирования с тем же данными и визуальными компонентами, которые мы определяли декларативно в предыдущем примере, на чистой Java без XML-дескриптора.
package com.company.sales.web.order;
import com.company.sales.entity.Customer;
import com.company.sales.entity.Order;
import com.company.sales.entity.OrderLine;
import com.haulmont.cuba.core.global.View;
import com.haulmont.cuba.gui.UiComponents;
import com.haulmont.cuba.gui.components.*;
import com.haulmont.cuba.gui.components.data.options.ContainerOptions;
import com.haulmont.cuba.gui.components.data.table.ContainerTableItems;
import com.haulmont.cuba.gui.components.data.value.ContainerValueSource;
import com.haulmont.cuba.gui.model.*;
import com.haulmont.cuba.gui.screen.PrimaryEditorScreen;
import com.haulmont.cuba.gui.screen.StandardEditor;
import com.haulmont.cuba.gui.screen.Subscribe;
import com.haulmont.cuba.gui.screen.UiController;
import javax.inject.Inject;
import java.sql.Date;
@UiController("sales_Order.edit")
public class OrderEdit extends StandardEditor<Order> {
@Inject
private DataComponents dataComponents; (1)
@Inject
private UiComponents uiComponents;
private InstanceContainer<Order> orderDc;
private CollectionPropertyContainer<OrderLine> linesDc;
private CollectionContainer<Customer> customersDc;
private InstanceLoader<Order> orderDl;
private CollectionLoader<Customer> customersDl;
@Subscribe
protected void onInit(InitEvent event) {
createDataComponents();
createUiComponents();
}
private void createDataComponents() {
DataContext dataContext = dataComponents.createDataContext();
getScreenData().setDataContext(dataContext); (2)
orderDc = dataComponents.createInstanceContainer(Order.class);
orderDl = dataComponents.createInstanceLoader();
orderDl.setContainer(orderDc); (3)
orderDl.setDataContext(dataContext); (4)
orderDl.setView("order-edit");
linesDc = dataComponents.createCollectionContainer(
OrderLine.class, orderDc, "lines"); (5)
customersDc = dataComponents.createCollectionContainer(Customer.class);
customersDl = dataComponents.createCollectionLoader();
customersDl.setContainer(customersDc);
customersDl.setDataContext(dataContext);
customersDl.setQuery("select e from sales_Customer e"); (6)
customersDl.setView(View.MINIMAL);
}
private void createUiComponents() {
DateField<Date> dateField = uiComponents.create(DateField.TYPE_DATE);
getWindow().add(dateField);
dateField.setValueSource(new ContainerValueSource<>(orderDc, "date")); (7)
Form form = uiComponents.create(Form.class);
getWindow().add(form);
LookupPickerField<Customer> customerField = uiComponents.create(LookupField.of(Customer.class));
form.add(customerField);
customerField.setValueSource(new ContainerValueSource<>(orderDc, "customer"));
customerField.setOptions(new ContainerOptions<>(customersDc)); (8)
TextField<Integer> amountField = uiComponents.create(TextField.TYPE_INTEGER);
amountField.setValueSource(new ContainerValueSource<>(orderDc, "amount"));
Table<OrderLine> table = uiComponents.create(Table.of(OrderLine.class));
getWindow().add(table);
getWindow().expand(table);
table.setItems(new ContainerTableItems<>(linesDc)); (9)
Button okButton = uiComponents.create(Button.class);
okButton.setAction(getWindow().getActionNN(WINDOW_COMMIT_AND_CLOSE));
getWindow().add(okButton);
Button cancelButton = uiComponents.create(Button.class);
cancelButton.setAction(getWindow().getActionNN(WINDOW_CLOSE));
getWindow().add(cancelButton);
}
@Override
protected InstanceContainer<Order> getEditedEntityContainer() { (10)
return orderDc;
}
@Subscribe
protected void onBeforeShow(BeforeShowEvent event) { (11)
orderDl.load();
customersDl.load();
}
}
1 | DataComponents - это фабрика для создания компонентов данных. |
2 | Регистрируем в экране экземпляр DataContext , чтобы обеспечить работу стандартного действия commit. |
3 | Загрузчик orderDl загружает данные в контейнер orderDc . |
4 | Загрузчик orderDl помещает загруженные сущности в data context для отслеживания изменений. |
5 | linesDc создаётся как контейнер свойства. |
6 | Определяем запрос для загрузчика customersDl . |
7 | ContainerValueSource используется для связи одиночных полей с контейнерами данных. |
8 | ContainerOptions предоставляет список опций для полей выбора. |
9 | ContainerTableItems используется для связи таблиц с контейнерами. |
10 | Переопределяем getEditedEntityContainer() , чтобы указать контейнер, вместо аннотации @EditedEntityContainer . |
11 | Загружаем данные перед отображением экрана. Идентификатор редактируемой сущности будет автоматически передан в загрузчик orderDl . |