Sunteți pe pagina 1din 3

Exemplu de componenta custom: Spinner

Descriere: spinner-ul ne permite sa introducem valori intr-un text field, fie prin tiparire directe
fie prin doua butoane de incrementare decrementare. Vom considera doar posibilitatea
introducerii valorilor numerice. Convertorul standard de intregi va manipula si erorile de
conversie.
Tagul custom va suporta urmatoarele atribute: binding, id, minimum, maximum, rendered,
size, value (obligatoriu si admite atat string cat si EL.
Vom adopta urmatoarea conventie: clasa ce procesea!a atributele tag-ului va avea sufixul Tag
si se va numi SpinnerTag, iar clasa componenta ce contine starea, renderi!ea!a interfata
utili!ator si procesea!a intrarea ca avea prefixul UI si se va numi UISpinner.
Clasa component va extinde UIInput.
Completari teoretice:
Clasa abstracta UIComponent gestionea!a urmatoarele categorii de date:
o Lista componentelor descendente, care poate fi vida
o "n map de compomente facet. #acet-urile sunt similare componentelor
descendente, dar fiecare facet are o c$eie.
o "n map de atribute.
o "n map de calue expressions
o % colectie de listeneri
Componenta noastra nu are descendenti deci vom renderi!a totul in encodeBegin(). Toate
cele trei parti specifice ale spinner-ului se vor renderi!a prin tag-uri <input>, in care type va
avea valoarea text sau submit.
&enderi!area pentru textfield este:
writerstart!lement("input"# t%is)&
writerwrite'ttribute("name"# clientId# "clientId")&
(b)ect v * get+alue()&
i, (v -* null)
writerwrite'ttribute("value"# vtoString()# "value")&
Integer size * (Integer) get'ttributes()get("size")&
i, (size -* null) writerwrite'ttribute("size"# size# "size")&
writerend!lement("input")&
writer este un obiect .esponse/riter, care cuprinde metodele pentru scrierea marca'elor.
"ltimul parametru al metodelor start!lement() si write'ttribute() sunt folosite pentru
tool suport. Trebuie sa trimitem obiectul componenta renderi!at sau numele atributului, sau
null, daca iesirea nu corespunde direct unui atribut al componentei.
%btinerea starii curente a spinner-ului se face prin metode specifice: get+alue(), metoda
mostenita din UIInput, pentru a obtine valoarea cu care setam atributul value si
get'ttributes()get("size") pentru setarea atributului size.
Descrierea procesului de decodare
(entru inceput serverul trimite bro)serului un formular *T+L. ,poi, bro)serul trimite
inapoi o cerere (%-T ce consta din perec$i nume.valoare. Cererea (%-T cuprinde singurele
date pe care serverul le poate utili!a pentru a interpreta actiunile user-ului din bro)ser.
/n ca!ul spinner-ului, decodarea unei cereri *TT( determina cautarea numelui parametrilor
cererii ce se potrivesc /D-ului client si procesea!a valorile asociate.
public void decode(0acesContext context) 1
2ap re3uest2ap *
contextget!xternalContext()get.e3uest4arameter2ap()&
String clientId * getClientId(context)&
int increment&
i, (re3uest2apcontains5ey(clientId 6 2(.!)) increment * 7&
else i, (re3uest2apcontains5ey(clientId 6 8!SS)) increment * 97&
else increment * :&
try 1
int submitted+alue
* IntegerparseInt((String) re3uest2apget(clientId))&
int new+alue * getIncremented+alue(submitted+alue# increment)&
setSubmitted+alue("" 6 new+alue)&
set+alid(true)&
;
catc%(<umber0ormat!xception ex) 1
== let t%e converter ta>e care o, bad input# but we still %ave
== to set t%e submitted value or t%e converter won?t %ave
== any input to deal wit%
setSubmitted+alue((String) re3uest2apget(clientId))&
;
;
+etoda de decodare cauta printre parametri cererii pentru a determina care dintre butoanele
spinner-ului a determinat cererea, daca a fost vreunul. Daca parametrul numit clientIdless
exista, unde clientId este /D-ul clientului spinnerului pe care il decodam, atunci stim ca
butonul de decrementare a fost activat. Daca metoda de decodare gaseste parametrul numit
clientIdmore, atunci butonul de incrementare a fost activat. Daca niciun parametru nu
exista atunci cererea nu a fost initiata de spinner si valoarea de incrementat este !ero.
Valoarea trebuie totusi updatata pentru ca este posibil ca utili!atorul sa fi editat o valoare.
%bservatie: daca avem mai multe spinnere in aceeasi pagina fiecare isi decodea!a propria
cerere pe ba!a /D-ului de client unic.
Dupa obtinerea valorii de incrementare metoda apelea!a metoda setSubmitted+alue().
,ceasta inmaga!inea!a valorile trimise in componenta. ,poi, conform ciclului de viata 0-#,
valorile trimise vor fi convertite si validate de 0-#.
Vom folosi convertori 0-# standard pentru a converti string-urile la Integer si vice versa.
Vom defini aceasta in constructorul clasei:
public UISpinner() 1
setConverter(new IntegerConverter())& == to convert t%e submitted value
set.endererType(null)& == t%is component renders itsel,
;
Daca sunt intalnite valori invalide, metoda decode() le va prinde in clau!a
<umber0ormat!xception. /n locul raportarii unei erori, va seta valorile trimise la cele
introduse de utili!ator. ,poi, in ciclu de viata 0-# convertorul va incerca sa converteasca
valorile si va genera un mesa' de eroare pentru intrare gresita.
Implementarea custom component tag-ului
-copul fisierului tld este acela de a specifica numele clasei tag $andler si atributele tag-ului.
%bservatie: putem folosi tag-ul uri pentru a identifica biblioteca tag-ului. ,ceasta valoare
poate fi referita de directiva taglib-ului.
%bservatie: ma'oritatea definitiilor de atribute din fisierul TLD contin un element de,erred9
value. ,ceasta inseamna ca este definit de o expresie valoare, adica un string constant sau un
string @1;. Elementul type din interiorul elementului anterior specifica tipul 0ava al
expresiei valoare.
,lte atribute sunt specificate prin expresii metoda. -pre exemplu:
<attribute>
<name>action8istener<=name>
<de,erred9met%od>
<met%od9signature>
void action8istener()avax,acesevent'ction!vent)
<=met%od9signature>
<=de,erred9met%od>
<=attribute>
,tributul id este, de obicei definit de o expresie valoare runtime. -pre exemplu:
<attribute>
<description>T%e client id o, t%is component<=description>
<name>id<=name>
<rtexprvalue>true<=rtexprvalue>
<=attribute>
Clasa tag-ului componenta are urmatoarele responsabilitati:
/dentificarea tipului componenta
/dentificarea tipului renderului
#urni!area de setter-/ atributelor tag-ului. ,cestia sunt utili!ati in procesarea paginii
0-#
-tocarea valorilor atributelor tagului in componenta tagului
Eliberarea resurselor, care este necesara pentru ca implementarea 0-# poate tine in
cac$e obiecte tag $andler si apoi sa le reutili!e!e. Daca un tag $andler este reutili!at el
nu trebuie sa foloseasca setarile unui tag anterior.

S-ar putea să vă placă și