Composite Components
El componente Composite combina componentes existentes de webforJ en componentes reutilizables y auto-contenidos con un comportamiento personalizado. Úsalo para envolver componentes internos de webforJ en unidades de lógica de negocio reutilizables, reutilizar patrones de componentes en toda tu aplicación y combinar múltiples componentes sin exponer detalles de implementación.
Un componente Composite tiene una fuerte asociación con un componente subyacente vinculado. Esto te da control sobre qué métodos y propiedades pueden acceder los usuarios, a diferencia de la herencia tradicional donde todo está expuesto.
Si necesitas integrar componentes web de otra fuente, utiliza alternativas especializadas:
- ElementComposite: Para componentes web con gestión de propiedades segura por tipo
- ElementCompositeContainer: Para componentes web que aceptan contenido con huecos
Uso
Para definir un componente Composite, extiende la clase Composite y especifica el tipo de componente que gestiona. Este se convierte en tu componente vinculado, que es el contenedor raíz que mantiene tu estructura interna:
public class BasicComposite extends Composite<FlexLayout> {
private final FlexLayout self = getBoundComponent();
public BasicComposite() {
// Accede al componente vinculado para configurarlo
self.setDirection(FlexDirection.COLUMN)
.setSpacing("3px")
.add(new TextField(), new Button("Enviar"));
}
}
El método getBoundComponent() proporciona acceso a tu componente subyacente, permitiéndote configurar sus propiedades, agregar componentes secundarios y gestionar su comportamiento directamente.
El componente vinculado puede ser cualquier componente de webforJ o componente de elemento HTML. Para diseños flexibles, considera usar FlexLayout o Div como tu componente vinculado.
Nunca extiendas Component o DwcComponent directamente. Siempre utiliza patrones de composición con Composite para construir componentes personalizados.
Sobrescribe initBoundComponent() cuando necesites mayor flexibilidad en la creación y gestión del componente vinculado, como usar constructores parametrizados en lugar del constructor por defecto sin argumentos. Usa este patrón cuando el componente vinculado requiere que se pasen componentes a su constructor en lugar de agregarlos después.
public class CustomFormLayout extends Composite<FlexLayout> {
private TextField nameField;
private TextField emailField;
private Button submitButton;
@Override
protected FlexLayout initBoundComponent() {
nameField = new TextField("Nombre");
emailField = new TextField("Email");
submitButton = new Button("Enviar");
FlexLayout layout = new FlexLayout(nameField, emailField, submitButton);
layout.setDirection(FlexDirection.COLUMN);
layout.setSpacing("10px");
return layout;
}
}
Ciclo de vida del componente
webforJ gestiona automáticamente todo el ciclo de vida para componentes Composite. Al usar el método getBoundComponent(), la mayoría del comportamiento personalizado se puede manejar en el constructor, incluyendo la adición de componentes secundarios, la configuración de propiedades, la configuración básica del diseño y el registro de eventos.
public class UserDashboard extends Composite<FlexLayout> {
private final FlexLayout self = getBoundComponent();
private TextField searchField;
private Button searchButton;
private Div resultsContainer;
public UserDashboard() {
initializeComponents();
setupLayout();
configureEvents();
}
private void initializeComponents() {
searchField = new TextField("Buscar usuarios...");
searchButton = new Button("Buscar");
resultsContainer = new Div();
}
private void setupLayout() {
FlexLayout searchRow = new FlexLayout(searchField, searchButton);
searchRow.setAlignment(FlexAlignment.CENTER);
searchRow.setSpacing("8px");
getBoundComponent()
.setDirection(FlexDirection.COLUMN)
.add(searchRow, resultsContainer);
}
private void configureEvents() {
searchButton.onClick(event -> performSearch());
}
private void performSearch() {
// Lógica de búsqueda aquí
}
}
Si tienes requisitos de configuración o limpieza adicionales, es posible que necesites usar los ganchos de ciclo de vida opcionales onDidCreate() y onDidDestroy():
public class DataVisualizationPanel extends Composite<Div> {
private Interval refreshInterval;
@Override
protected void onDidCreate(Div container) {
// Inicializa componentes que requieren adjunción en el DOM
refreshInterval = new Interval(5.0, event -> updateData());
refreshInterval.start();
}
@Override
protected void onDidDestroy() {
// Limpieza de recursos
if (refreshInterval != null) {
refreshInterval.stop();
}
}
private void updateData() {
// Lógica de actualización de datos
}
}
Si necesitas realizar acciones después de que el componente esté adjunto al DOM, utiliza el método whenAttached():
public class InteractiveMap extends Composite<Div> {
public InteractiveMap() {
setupMapContainer();
whenAttached().thenAccept(component -> {
initializeMapLibrary();
loadMapData();
});
}
}
Ejemplo de componente Composite
El siguiente ejemplo demuestra una aplicación Todo donde cada elemento es un componente Composite que consiste en un RadioButton estilizado como un interruptor y un Div con texto:
Mostrar Código
- Java
- CSS
Ejemplo: Agrupación de componentes
A veces puedes querer usar un Composite para agrupar componentes relacionados en una sola unidad, incluso cuando la reutilización no es la principal preocupación:
Mostrar Código
- Java
- CSS