Overslaan naar hoofdinhoud

Understanding Components

Openen in ChatGPT
Java API

Voordat je aangepaste componenten in webforJ bouwt, is het belangrijk om de fundamentele architectuur te begrijpen die bepaalt hoe componenten werken. Dit artikel legt de componenthiërarchie, componentidentiteit, levenscyclusconcepten en hoe concerninterfaces componentmogelijkheden bieden uit.

Begrijpen van de componenthiërarchie

webforJ organiseert componenten in een hiërarchie met twee groepen: interne klassen van het framework die je nooit moet uitbreiden, en klassen die specifiek ontworpen zijn voor het bouwen van aangepaste componenten. Dit gedeelte legt uit waarom webforJ compositie boven extensie gebruikt en wat elk niveau van de hiërarchie biedt.

Waarom compositie in plaats van extensie?

In webforJ zijn ingebouwde componenten zoals Button en TextField finale klassen—je kunt ze niet uitbreiden:

// Dit werkt niet in webforJ
public class MyButton extends Button {
// Button is final - kan niet worden uitgebreid
}

webforJ gebruikt compositie boven extensie. In plaats van bestaande componenten uit te breiden, maak je een klasse die Composite uitbreidt en combineert componenten erin. Composite fungeert als een container die een enkele component omhult (de gebonden component genoemd) en stelt je in staat om je eigen componenten en gedrag eraan toe te voegen.

public class SearchBar extends Composite<FlexLayout> {
private final FlexLayout self = getBoundComponent();
private TextField searchField;
private Button searchButton;

public SearchBar() {
searchField = new TextField("Zoeken");
searchButton = new Button("Ga");

self.setDirection(FlexDirection.ROW)
.add(searchField, searchButton);
}
}

Waarom je ingebouwde componenten niet kunt uitbreiden

webforJ-componenten zijn gemarkeerd als final om de integriteit van de onderliggende client-side webcomponent te behouden. Het uitbreiden van webforJ-componentklassen zou controle geven over de onderliggende webcomponent, wat onbedoelde gevolgen kan hebben en de consistentie en voorspelbaarheid van het componentgedrag kan verstoren.

Voor een gedetailleerde uitleg, zie Finale Klassen en Uitbreidingsbeperkingen in de architectuurdocumentatie.

De componenthiërarchie

Klassen voor ontwikkelaars (gebruik deze):

  • Composite
  • ElementComposite
  • ElementCompositeContainer

Interne frameworkklassen (nooit direct uitbreiden):

  • Component
  • DwcComponent
Never extend Component or DwcComponent

Verleng Component of DwcComponent nooit direct. Alle ingebouwde componenten zijn final. Gebruik altijd compositiepatronen met Composite of ElementComposite.

Proberen DwcComponent uit te breiden zal een runtime-exceptie opleveren.

Concerninterfaces

Concerninterfaces zijn Java-interfaces die specifieke mogelijkheden aan je componenten bieden. Elke interface voegt een set gerelateerde methoden toe. Bijvoorbeeld, HasSize voegt methoden toe voor het beheersen van breedte en hoogte, terwijl HasFocus methoden toevoegt voor het beheren van de focusstatus.

Wanneer je een concerninterface op je component implementeert, krijg je toegang tot die mogelijkheden zonder implementatiecode te hoeven schrijven. De interface biedt standaardimplementaties die automatisch werken.

Het implementeren van concerninterfaces geeft je aangepaste componenten dezelfde API's als ingebouwde webforJ-componenten:

// Implementeer HasSize om breedte/hoge methoden automatisch te krijgen
public class SizedCard extends Composite<Div> implements HasSize<SizedCard> {
private final Div self = getBoundComponent();

public SizedCard() {
self.setText("Inhoud kaart");
}

// Geen behoefte om deze te implementeren - je krijgt ze gratis:
// setWidth(), setHeight(), setSize()
}

// Gebruik het zoals elke webforJ-component
SizedCard card = new SizedCard();
card.setWidth("300px")
.setHeight("200px");

De samenstelling stuurt deze oproepen automatisch door naar de onderliggende Div. Geen extra code nodig.

Uiterlijk

Deze interfaces regelen de visuele presentatie van een component, inclusief zijn afmetingen, zichtbaarheid, stijl en thema.

InterfaceBeschrijving
HasSizeBeheert breedte en hoogte, inclusief min- en maxbeperkingen. Extends HasWidth, HasHeight en hun min/max varianten.
HasVisibilityToont of verbergt de component zonder deze uit de lay-out te verwijderen.
HasClassNameBeheert CSS-klassennamen op het root-element van de component.
HasStylePast inline CSS-stijlen toe en verwijdert deze.
HasHorizontalAlignmentBeheert hoe de inhoud horizontaal binnen de component is uitgelijnd.
HasExpanseStelt de groottevariant van de component in met de standaard expanse-tokens (XSMALL tot XLARGE).
HasThemePast een themavariant toe zoals DEFAULT, PRIMARY of DANGER.
HasPrefixAndSuffixVoegt componenten toe aan de prefix- of suffix-slot binnen de component.

Inhoud

Deze interfaces beheren wat een component weergeeft, inclusief tekst, HTML, labels, hints en andere beschrijvende inhoud.

InterfaceBeschrijving
HasTextStelt de platte tekstinhoud van de component in en haalt deze op.
HasHtmlStelt de binnenste HTML van de component in en haalt deze op.
HasLabelVoegt een beschrijvende label toe die aan de component is gekoppeld, gebruikt voor toegankelijkheid.
HasHelperTextToont secundaire hinttekst onder de component.
HasPlaceholderStelt placeholder-tekst in die wordt weergegeven wanneer de component geen waarde heeft.
HasTooltipBevestigt een tooltip die verschijnt bij hover.

Status

Deze interfaces regelen de interactieve status van een component, inclusief of deze is ingeschakeld, bewerkbaar, vereist of gefocust is bij het laden.

InterfaceBeschrijving
HasEnablementZet de component aan of uit.
HasReadOnlyZet de component in een alleen-lezen status waar de waarde zichtbaar is maar niet kan worden gewijzigd.
HasRequiredMerkt de component als vereist, typisch voor formuliervalidatie.
HasAutoFocusVerplaatst automatisch de focus naar de component wanneer de pagina laadt.

Focus

Deze interfaces beheren hoe een component de focus krijgt en hierop reageert.

InterfaceBeschrijving
HasFocusBeheert de focusstatus en of de component focus kan krijgen.
HasFocusStatusControleert of de component momenteel focus heeft. Vereist een round-trip naar de client.
HasHighlightOnFocusBeheert of de inhoud van de component wordt gemarkeerd wanneer deze focus krijgt, en hoe (KEY, MOUSE, KEY_MOUSE, ALL, enzovoorts).

Invoerspecificaties

Deze interfaces definiëren welke waarden een component accepteert, inclusief de huidige waarde, toegestane reeksen, lengtebeperkingen, formatteringsmaskers en lokale specifieke gedragingen.

InterfaceBeschrijving
HasValueHaalt de huidige waarde van de component op en stelt deze in.
HasMinStelt een minimum toegestane waarde in.
HasMaxStelt een maximum toegestane waarde in.
HasStepStelt de stapgrootte in voor numerieke of bereik invoeren.
HasPatternPast een reguliere expressie patroon toe om geaccepteerde invoer te beperken.
HasMinLengthStelt het minimum aantal vereiste karakters in de waarde van de component in.
HasMaxLengthStelt het maximum aantal toegestane karakters in de waarde van de component in.
HasMaskPast een formatmasker toe op de invoer. Gebruikt door gemaskerde veldcomponenten.
HasTypingModeBeheert of getypte karakters worden ingevoegd of bestaande karakters overschrijven (INSERT of OVERWRITE). Gebruikt door gemaskerde velden en TextArea.
HasRestoreValueDefinieert een waarde waar de component naar terugkeert wanneer de gebruiker Escape indrukt of restoreValue() oproept. Gebruikt door gemaskerde velden.
HasLocaleBewaart een per-component locale voor lokale gevoelige formatting. Gebruikt door gemaskerde datum- en tijdvelden.
HasPredictedTextStelt een voorspeld of auto-aanvult tekstwaarde in. Gebruikt door TextArea om inline suggesties te ondersteunen.

Validatie

Deze interfaces voegen client-side validatiegedrag toe, inclusief het markeren van componenten als ongeldig, het weergeven van foutmeldingen en het regelen wanneer validatie wordt uitgevoerd.

InterfaceBeschrijving
HasClientValidationMerkt een component als ongeldig, stelt de foutmelding in en bevestigt een client-side validator.
HasClientAutoValidationBeheert of de component automatisch valideert terwijl de gebruiker typt.
HasClientAutoValidationOnLoadBeheert of de component valideert wanneer deze voor het eerst laadt.
HasClientValidationStyleBeheert hoe validatiemeldingen worden weergegeven: INLINE (onder de component) of POPOVER.

DOM-toegang

Deze interfaces bieden laagdrempelige toegang tot het onderliggende HTML-element van de component en client-side eigenschappen.

InterfaceBeschrijving
HasAttributeLeest en schrijft willekeurige HTML-attributen op het element van de component.
HasPropertyLeest en schrijft DWC-componenteigenschappen direct op het clientelement.

i18n

Deze interface biedt vertaalondersteuning voor componenten die gelokaliseerde tekst moeten weergeven.

InterfaceBeschrijving
HasTranslationBiedt de t() helper-methode voor het oplossen van vertaalkeys naar gelokaliseerde strings met behulp van de huidige locale van de app.
waarschuwing

Als de onderliggende component de interface-mogelijkheid niet ondersteunt, krijg je een runtime-exceptie. Bied in dat geval je eigen implementatie aan.

Voor een complete lijst van beschikbare concerninterfaces, zie de webforJ JavaDoc.

Componentidentificatoren

webforJ-componenten hebben drie verschillende soorten identificatoren die verschillende doeleinden dienen:

  • Server-side component-ID (getComponentId()) - Automatisch toegewezen door het framework voor interne componenttracking. Gebruik dit wanneer je specifieke componenten moet opvragen of aangepaste componentregistraties moet implementeren.
  • Client-side component-ID (getClientComponentId()) - Biedt toegang tot de onderliggende webcomponent vanuit JavaScript. Gebruik dit wanneer je native webcomponentmethoden moet aanroepen of moet integreren met client-side bibliotheken.
  • HTML id attribuut (setAttribute("id", "...")) - Standaard DOM-identificator. Gebruik dit voor CSS-targeting, testautomatiseringseletors en het koppelen van formulierlabels aan invoeren.

Het begrijpen van deze verschillen helpt je de juiste identificator voor je gebruiksgeval te kiezen.

Server-side component-ID

Elke component krijgt automatisch een server-side identificator toegewezen wanneer deze wordt aangemaakt. Deze identificator wordt intern door het framework gebruikt voor het volgen van componenten. Haal het op met getComponentId():

Button button = new Button("Klik op mij");
String serverId = button.getComponentId();

De server-side ID is nuttig wanneer je specifieke componenten binnen een container moet opvragen of aangepaste componenttrackinglogica moet implementeren.

Client-side component-ID

De client-side component-ID biedt toegang tot de onderliggende webcomponent vanuit JavaScript. Dit stelt je in staat om direct met de client-side component te interageren wanneer dat nodig is:

Button btn = new Button("Klik op mij");
btn.onClick(e -> {
OptionDialog.showMessageDialog("De knop is aangeklikt", "Er is een gebeurtenis opgetreden");
});

btn.whenAttached().thenAccept(e -> {
Page.getCurrent().executeJs("objects.get('" + btn.getClientComponentId() + "').click()");
});

Gebruik getClientComponentId() met objects.get() in JavaScript om toegang te krijgen tot de webcomponentinstantie.

important

De client-side component-ID is niet het HTML id attribuut van het DOM-element. Voor het instellen van HTML-ID's voor testen of CSS-targeting, zie Gebruik van Componenten.

Overzicht van de componentlevenscyclus

webforJ beheert de componentlevenscyclus automatisch. Het framework handelt componentcreatie, -bevestiging en -vernietiging af zonder handmatige tussenkomst.

Levenscyclushooks zijn beschikbaar wanneer je ze nodig hebt:

  • onDidCreate(T container) - Wordt aangeroepen nadat de component aan de DOM is gehecht
  • onDidDestroy() - Wordt aangeroepen wanneer de component wordt vernietigd

Deze hooks zijn optioneel. Gebruik ze wanneer je moet:

  • Hulpbronnen opruimen (stoppen met intervallen, verbindingen sluiten)
  • Componenten initialiseren die DOM-hechting vereisen
  • Integreren met client-side JavaScript

Voor de meeste eenvoudige gevallen kun je componenten rechtstreeks in de constructor initialiseren. Gebruik levenscyclushooks zoals onDidCreate() om werk uit te stellen wanneer dat nodig is.