Подключаемые фабрики компонентов
Механизм подключаемых фабрик компонентов расширяет процедуру генерации компонентов и позволяет создавать различные поля редактирования в Form, Table и DataGrid. Это означает, что компоненты приложения или сам ваш проект могут предоставлять собственные стратегии, которые будут создавать нестандартные компоненты и/или поддерживать кастомные типы данных.
Точкой входа в данный механизм является метод UiComponentsGenerator.generate(ComponentGenerationContext). Сначала он пытается найти все реализации интерфейса ComponentGenerationStrategy. Если как минимум одна реализация существует, то он обходит все реализации в соответствии с интерфейсом org.springframework.core.Ordered и возвращает первый созданный не нулевой компонент.
Реализации интерфейса ComponentGenerationStrategy используются при создании UI компонентов. Проект может содержать любое количество таких стратегий.
ComponentGenerationContext – класс, содержащий следующую информацию, которая может быть использована при создании компонента:
-
metaClass- задает сущность, для которой создается компонент. -
property- задает атрибут сущности, для которой создается компонент. -
valueSource- источник данных, который может быть связан с компонентом. -
options- источник данных, который может быть связан с компонентом для показа опций. -
xmlDescriptor- XML-дескриптор с дополнительной информацией, в случае, если компонент объявлен в XML-дескрипторе. -
targetClass- целевой класс, для которого должен быть создан компонент, напримерForm,Table,DataGrid.
Существуют две встроенные стратегии:
-
DefaultComponentGenerationStrategyиспользуется для создания компонентов в соответствии с переданным объектомComponentGenerationContext. Имеет значениеorderравноеJmixOrder.LOWEST_PLATFORM_PRECEDENCE(1000). Более высокие значения интерпретируются как имеющие более низкий приоритет; самое низкое значение имеет самый высокий приоритет; одинаковые значенияorderприведут к произвольным позициям сортировки для затронутых объектов. -
CustomDatatypesComponentGenerationStrategyпредназначена для генерации поля по умолчанию в соответствии с datatype, для которого не создали поле другие стратегии генерации. Например, если datatype является кастомным и не соответствует ни одному типу, для которого создает поляDefaultComponentGenerationStrategy. Имеет значениеorderравноеInteger.MAX_VALUE(0x7fffffff).
Пример ниже показывает, как заменить стандартную генерацию поля в компоненте Form для определенного атрибута некоторой сущности.
@org.springframework.stereotype.Component("sample_SalesComponentGenerationStrategy")
public class SalesComponentGenerationStrategy implements ComponentGenerationStrategy, Ordered {
@Inject
private UiComponents uiComponents;
@Inject
private Metadata metadata;
@Nullable
@Override
public Component createComponent(ComponentGenerationContext context) {
String property = context.getProperty();
MetaClass orderMetaClass = metadata.getClass(Order.class);
if (orderMetaClass.equals(context.getMetaClass())
&& "date".equals(property) (1)
&& context.getClass() != null
&& Form.class.isAssignableFrom(context.getClass())) { (2)
DatePicker<Date> datePicker = uiComponents.create(DatePicker.TYPE_DATE); (3)
ValueSource valueSource = context.getValueSource();
if (valueSource != null) {
datePicker.setValueSource(valueSource); (4)
}
return datePicker;
}
return null;
}
@Override
public int getOrder() {
return 50; (5)
}
}
| 1 | Проверяет конкретное поле сущности Order. |
| 2 | Проверяет, что компонент создан для компонента Form. |
| 3 | Создает конкретный компонент DatePicker. |
| 4 | Привязывает компонент к источнику данных. |
| 5 | Возвращает значение order этого объекта. |
Пример ниже показывает, как определить ComponentGenerationStrategy для некоторого datatype.
@Order(100)
@org.springframework.stereotype.Component("sample_ColorComponentGenerationStrategy")
public class ColorComponentGenerationStrategy implements ComponentGenerationStrategy {
@Inject
private UiComponents uiComponents;
@Nullable
@Override
public Component createComponent(ComponentGenerationContext context) {
String property = context.getProperty();
MetaPropertyPath mpp = context.getMetaClass().getPropertyPath(property);
if (mpp != null) {
Range mppRange = mpp.getRange();
if (mppRange.isDatatype()
&& (Datatype) mppRange.asDatatype() instanceof ColorDatatype) {
ColorPicker colorPicker = uiComponents.create(ColorPicker.class);
colorPicker.setDefaultCaptionEnabled(true);
ValueSource valueSource = context.getValueSource();
if (valueSource != null) {
colorPicker.setValueSource(valueSource);
}
return colorPicker;
}
}
return null;
}
}