Подключаемые фабрики компонентов
Механизм подключаемых фабрик компонентов расширяет процедуру генерации компонентов и позволяет создавать различные поля редактирования в 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;
}
}