Composite Components
El componente Composite combina componentes existentes de webforJ en componentes reutilizables y autónomos con comportamiento personalizado. Úsalo para envolver componentes internos de webforJ en unidades de lógica empresarial reutilizables, reutilizar patrones de componentes en toda tu aplicación y combinar múltiples componentes sin exponer los detalles de implementación.
Un componente Composite tiene una fuerte asociación con un componente vinculado subyacente. 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 tipo segura
- ElementCompositeContainer: Para componentes web que aceptan contenido en ranuras
The webforj-creating-components skill can wrap web components, JS libraries, or compositions as reusable webforJ components. After installing the webforJ AI plugin, ask your assistant:
- "Wrap this Custom Element library as webforJ components."
- "Compose these webforJ components into a reusable card."
- "Integrate this plain JavaScript library as a webforJ component."
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 sostiene 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 hijos 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 directamente Component o DwcComponent. Siempre utiliza patrones de composición con Composite para construir componentes personalizados.
Sobrepasa 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 requiera 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("Correo electrónico");
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 manejo del ciclo de vida para los 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 hijos, 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 específicos adicionales de configuración o limpieza, puedes necesitar 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 adjuntos DOM
refreshInterval = new Interval(5.0, event -> updateData());
refreshInterval.start();
}
@Override
protected void onDidDestroy() {
// Limpia 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 ítem es un componente Composite que consiste en un RadioButton estilizado como un interruptor y un Div con texto:
Mostrar Código
- CompositeView.java
- composite.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
- AnalyticsCardCompositeView.java
- analyticscomposite.css