Композитный компонент

Композитный компонент — это компонент, состоящий из других компонентов. Как и фрагменты, композитные компоненты позволяют повторно использовать элементы компоновки и логику экранов.

Композитные компоненты рекомендуется использовать в следующих случаях:

  • Функциональность компонента может быть реализована как комбинация существующих визуальных компонентов.
    Если вам нужны какие-либо нестандартные функции, интегрируйте библиотеку JavaScript или создайте веб-компонент с нуля.

  • Компонент относительно прост и не загружает и не сохраняет данные самостоятельно. В противном случае рассмотрите возможность создания фрагмента.

Использование Composite

В приведенном ниже примере компонент ColorComponent создается путем комбинирования компонента ColorPicker, созданного в разделе Использование Element API, и компонента span, который отображает его значение:

import com.vaadin.flow.component.Composite;
import com.vaadin.flow.component.html.Span;
import com.vaadin.flow.component.orderedlayout.FlexComponent;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;

public class ColorComponent extends Composite<HorizontalLayout> { (1)

    private final ColorPicker colorPicker;

    public ColorComponent() {
        colorPicker = new ColorPicker();
        Span valueLabel = new Span(colorPicker.getValue());

        colorPicker.addValueChangeListener(event ->
                valueLabel.setText(event.getValue()));

        getContent().add(colorPicker, valueLabel); (2)
    }

    @Override
    protected HorizontalLayout initContent() { (3)
        HorizontalLayout content = super.initContent();
        content.setAlignItems(FlexComponent.Alignment.CENTER);

        return content;
    }

    public String getValue() { (4)
        return colorPicker.getValue();
    }

    public void setValue(String value) {
        colorPicker.setValue(value);
    }
}
1 Базовый класс Composite параметризован типом корневого компонента.
2 Доступ к корневому компоненту можно получить, используя метод getContent().
3 Метод initContent() вызывается, когда содержимое композитного компонента запрашивается в первый раз. Этот метод должен инициализировать структуру компонента для Composite и вернуть корневой компонент. По умолчанию этот метод использует рефлексию для создания экземпляра компонента на основе generic-типа подкласса.
4 Публичный API композитного компонента, который делегирует вызовы компоненту colorPicker.
composite component
Figure 1. Композитный компонент, добавленный в экран

Использование CustomField

CustomField — это базовый класс для обертывания нескольких компонентов в одно поле. Он предоставляет стандартные функции ввода, такие как надпись, подсказка и валидация. Используйте его для создания собственных компонентов ввода.

Предыдущий пример можно переписать как CustomField:

import com.vaadin.flow.component.customfield.CustomField;
import com.vaadin.flow.component.html.Span;
import com.vaadin.flow.dom.Style;

public class ColorField extends CustomField<String> {

    private final ColorPicker colorPicker;

    public ColorField() {
        colorPicker = new ColorPicker();
        Span valueLabel = new Span(colorPicker.getValue());
        valueLabel.getStyle().setMarginInlineStart("var(--lumo-space-s)");

        colorPicker.addValueChangeListener(event -> {
            valueLabel.setText(event.getValue());
        });

        add(colorPicker, valueLabel);
    }

    @Override
    protected String generateModelValue() {
        return colorPicker.getValue();
    }

    @Override
    protected void setPresentationValue(String presentationValue) {
        colorPicker.setValue(presentationValue);
    }
}

После реализации компонента его можно использовать в экранах, например:

@Subscribe
public void onInit(final InitEvent event) {
    ColorField customField = new ColorField();
    customField.setLabel("Color Field");
    customField.setHelperText("Helper text");
    getContent().add(customField);
}
custom field
Figure 2. Пользовательское поле, добавленное в экран