Sunteți pe pagina 1din 168

www.cartiaz.

ro Carti si articole online gratuite de la A la Z

Introducere
Scurt istoric
Limbajul Java mpreun cu mediul su de dezvoltare i execuie au fost proiectate pentru a
rezolva o parte dintre problemele actuale ale programrii. Proiectul Java a pornit cu scopul declarat de
a dezvolta un software performant pentru aparatele electronice de larg consum. Aceste echipamente se
definesc ca: mici, portabile, distribuite i lucrnd n timp real. De la aceste aparate, ne-am obinuit s
cerem fiabilitate i uurin n exploatare.
Limbajul luat iniial n considerare a fost C++. Din pcate, atunci cnd s-a ncercat crearea unui
mediu de execuie care s respecte toate aceste condiii s-a observat c o serie de trsturi ale C++ sunt
incompatibile cu necesitile declarate. n principal, problema vine din faptul c C++ este prea
complicat, folosete mult prea multe convenii i are nc prea multe elemente de definiie lsate la
latitudinea celor care scriu compilatoare pentru o platform sau alta.
n aceste condiii, firma Sun a pornit proiectarea unui nou limbaj de programare asemntor cu
C++ dar mult mai flexibil, mai simplu i mai portabil. Aa s-a nscut Java. Printele noului limbaj a
fost James Gostling care este cunoscut ca autor al editorului emacs i al sistemului de ferestre grafice
NeWS. Proiectul a nceput nc din 1990 dar Sun a fcut public specificaia noului limbaj abia n 1995
la SunWorld n San Francisco.
Numele iniial al limbajului a fost Oak, numele unui copac care crete n faa biroului lui James
Gostling. Ulterior, s-a descoperit c numele fusese deja folosit n trecut pentru un alt limbaj de
programare aa c a fost abandonat i nlocuit cu Java, spre deliciul programatorilor care iubesc
cafenelele i aromele exotice.

Ce este Java?
n primul rnd, Java ncearc s rmn un limbaj simplu de folosit chiar i de ctre
programatorii neprofesioniti, programatori care doresc s se concentreze asupra aplicaiilor n
principal i abia apoi asupra tehnicilor de implementare a acestora. Aceast trstur poate fi
considerat ca o reacie direct la complexitatea considerabil a limbajului C++.
Au fost ndeprtate din Java aspectele cele mai derutante din C++ precum suprancrcarea
operatorilor i motenirea multipl. A fost introdus un colector automat de gunoaie care s rezolve
problema dealocrii memoriei n mod uniform, fr intervenia programatorului. Colectorul de gunoaie
nu este o trstur nou, dar implementarea acestuia n Java este fcut inteligent i eficient folosind un
fir separat de execuie, pentru c Java are ncorporate faciliti de execuie pe mai multe fire de

www.cartiaz.ro Carti si articole online gratuite de la A la Z


execuie. Astfel, colectarea gunoaielor se face de obicei n timp ce un alt fir ateapt o operaie de
intrare-ieire sau pe un semafor.
Limbajul Java este independent de arhitectura calculatorului pe care lucreaz i foarte portabil.
n loc s genereze cod nativ pentru o platform sau alta, compilatorul Java genereaz o secven de
instruciuni ale unei maini virtuale Java (numit bytecod). Execuia aplicaiilor Java este interpretat.
Singura parte din mediul de execuie Java care trebuie portat de pe o arhitectur pe alta este mediul de
execuie cuprinznd interpretorul i o parte din bibliotecile standard care depind de sistem. n acest fel,
aplicaii Java compilate pe o arhitectur SPARC de exemplu, pot fi rulate fr recompilare pe un sistem
bazat pe procesoare Intel.
Una dintre principalele probleme ale limbajelor interpretate este viteza de execuie, considerabil
sczut fa de cea a limbajelor compilate. Dac nu v mulumete viteza de execuie a unei astfel de
aplicaii, putei cere mediului de execuie Java s genereze automat, plecnd de la codul mainii
virtuale, codul specific mainii pe care lucrai, obinndu-se astfel un executabil nativ care poate rula la
vitez maxim. De obicei ns, n Java se compileaz doar acele pri ale programului mari
consumatoare de timp, restul rmnnd interpretate pentru a nu se pierde flexibilitatea. Mediul de
execuie nsui este scris n C, ceea ce l face extrem de portabil.
Interpretorul Java este gndit s lucreze pe maini mici, precum ar fi procesoarele cu care sunt
dotate aparatele casnice. Interpretorul plus bibliotecile standard cu legare dinamic nu depesc 300
Koctei. Chiar mpreun cu interfaa grafic totul rmne mult sub 1 Moctet.
Limbajul Java este n totalitate orientat obiect. Cu el se pot crea clase de obiecte i instane ale
acestora, se pot ncapsula informaiile, se pot moteni variabilele i metodele de la o clas la alta, etc.
Singura trstur specific limbajelor orientate obiect care lipsete este motenirea multipl, dar pentru
a suplini aceast lips, Java ofer o facilitate mai simpl, numit interfa, care permite definirea unui
anumit comportament pentru o clas de obiecte, altul dect cel definit de clasa de baz. n Java orice
element este un obiect, n afar de datele primare. Din Java lipsesc funciile i variabilele globale. Ne
rmn desigur metodele i variabilele statice ale claselor.
Java este distribuit, avnd implementate biblioteci pentru lucrul n reea care ne ofer TCP/IP,
URL i ncrcarea resurselor din reea. Aplicaiile Java pot accesa foarte uor reeaua, folosindu-se de
apelurile ctre un set standard de clase.
Java este robust. n Java legarea funciilor se face n timpul execuiei i informaiile de
compilare sunt disponibile pn n momentul rulrii aplicaiei. Acest mod de lucru face ca sistemul s
poat determina n orice moment neconcordana dintre tipul referit la compilare i cel referit n timpul
execuiei evitndu-se astfel posibile intruziuni ruvoitoare n sistem prin intermediul unor referine
falsificate. n acelai timp, Java detecteaz referinele nule dac acestea sunt folosite n operaii de
acces. Indicii n tablourile Java sunt verificai permanent n timpul execuiei i tablourile nu se pot
parcurge prin intermediul unor pointeri aa cum se ntmpl n C/C++. De altfel, pointerii lipsesc
complet din limbajul Java, mpreun cu ntreaga lor aritmetic, eliminndu-se astfel una din
principalele surse de erori. n plus, eliberarea memoriei ocupate de obiecte i tablouri se face automat,
prin mecanismul de colectare de gunoaie, evitndu-se astfel ncercrile de eliberare multipl a unei
zone de memorie.
Java este un limbaj cu securitate ridicat. El verific la fiecare ncrcare codul prin mecanisme
de CRC i prin verificarea operaiilor disponibile pentru fiecare set de obiecte. Robusteea este i ea o
trstur de securitate. La un al doilea nivel, Java are incorporate faciliti de protecie a obiectelor din
sistem la scriere i/sau citire. Variabilele protejate ntr-un obiect Java nu pot fi accesate fr a avea

www.cartiaz.ro Carti si articole online gratuite de la A la Z


drepturile necesare, verificarea fiind fcut n timpul execuiei. n plus, mediul de execuie Java poate fi
configurat pentru a proteja reeaua local, fiierele i celelalte resurse ale calculatorului pe care ruleaz
o aplicaie Java.
Limbajul Java are inclus suportul nativ pentru aplicaii care lucreaz cu mai multe fire de
execuie, inclusiv primitive de sincronizare ntre firele de execuie. Acest suport este independent de
sistemul de operare, dar poate fi conectat, pentru o performan mai bun, la facilitile sistemului dac
acestea exist.
Java este dinamic. Bibliotecile de clase n Java pot fi reutilizate cu foarte mare uurin.
Cunoscuta problem a fragilitii superclasei este rezolvat mai bine dect n C++. Acolo, dac o
superclas este modificat, trebuie recompilate toate subclasele acesteia pentru c obiectele au o alt
structur n memorie. n Java aceast problem este rezolvat prin legarea trzie variabilelor, doar la
execuie. Regsirea variabilelor se face prin nume i nu printr-un deplasament fix. Dac superclasa nu a
ters o parte dintre vechile variabile i metode, ea va putea fi refolosit fr s fie necesar
recompilarea subclaselor acesteia. Se elimin astfel necesitatea actualizrii aplicaiilor, generat de
apariia unei noi versiuni de bibliotec aa cum se ntmpl, de exemplu, cu MFC-ul Microsoft (i toate
celelalte ierarhii C++).

Reprezentarea informaiilor cu obiecte


Obiecte
Informaiile pe care le reprezentm n memoria calculatorului sunt rareori att de simple precum
culorile sau literele. n general, dorim s reprezentm informaii complexe, care s descrie obiectele
fizice care ne nconjoar sau noiunile cu care operm zilnic, n interiorul crora culoarea sau o
secven de litere reprezint doar o mic parte. Aceste obiecte fizice sau noiuni din lumea real
trebuiesc reprezentate n memoria calculatorului n aa fel nct informaiile specifice lor s fie pstrate
la un loc i s se poat prelucra ca un tot unitar. S nu uitm ns c, la nivelul cel mai de jos,
informaia ataat acestor obiecte continu s fie tratat de ctre compilator ca un ir de numere binare,
singurele informaii reprezentabile direct n memoria calculatoarelor actuale.
Putem s extindem cerinele noastre mai departe, spunnd c, atunci cnd analizm un obiect
fizic sau o noiune pentru a le reprezenta n calculator, trebuie s analizm nu numai proprietile
acestora dar i modul n care acestea pot fi utilizate i care sunt operaiile care pot fi executate asupra
lor sau cu ajutorul lor. Uneori, setul de operaii specifice unui obiect mpreun cu modul n care acesta
reacioneaz la stimuli exteriori se numete comportamentul obiectului.
De exemplu, dac dorim s construim un obiect care reprezint o minge de form sferic n
spaiu, este necesar s definim trei numere care s reprezinte coordonatele x, y i z relativ la un sistem
de axe dat, precum i o valoare pentru raza sferei. Aceste valori numerice vor face parte din setul de
proprieti ale obiectului minge. Dac mai trziu vom dori s construim o operaie care s reprezinte
mutarea n spaiu a obiectului minge, este suficient s ne folosim de operaiile cu numere pentru a
modifica valorile coordonatelor x, y i z.
Desigur, obiectul minge este insuficient descris prin aceste coordonate i, pentru a simula n
calculator obiectul real este nevoie de multe proprieti suplimentare precum i de multe operaii n
plus. Dar, dac problema pe care o avem de rezolvat nu necesit aceste proprieti i operaii, este
preferabil s nu le definim n obiectul folosit pentru reprezentare. Rezultatul direct al acestui mod de

www.cartiaz.ro Carti si articole online gratuite de la A la Z


abordare este acela c vom putea defini acelai obiect real n mai multe feluri pentru a-l reprezenta n
memoria intern. Modul de definire depinde de problema de rezolvat i de programatorul care a gndit
reprezentarea. De altfel, aceste diferene de percepie ale unui obiect real exist i ntre diveri
observatori umani.
Din punctul de vedere al programrii, un obiect este o reprezentare n memoria calculatorului a
proprietilor i comportamentului unei noiuni sau ale unui obiect real.

Figura 1 Modelul de reprezentare al unui obiect n memorie. Stratul exterior reprezint doar operaiile care ofer
calea de a interaciona cu proprietile obiectului i nu are corespondent direct n zona de memorie ocupat de obiect.

ncapsularea informaiilor n interiorul obiectelor


Exist situaii n care accesul din exterior la proprietile unui obiect poate s pun probleme
acestuia. Din aceste motive, este preferabil s lsm modificarea acestor parametri n sarcina exclusiv
a unor operaii definite de ctre obiect, operaii care vor verifica noile valori nainte de a le schimba n
interiorul obiectului. n lipsa acestui filtru, putem s stricm coerena valorilor memorate n interiorul
unui obiect, fcndu-l inutilizabil.
Din acest punct de vedere, putem privi obiectul ca pe un set de valori care formeaz miezul
obiectului i un set de operaii care mbrac aceste valori, protejndu-le. Vom spune c proprietile
obiectului sunt ncapsulate n interiorul acestora. Mai mult, obiectul ncapsuleaz i modul de
funcionare a operaiilor lui specifice, din exterior neputndu-se observa dect modul de apelare a
acestor operaii i rezultatele apelurilor. Cu alte cuvinte, procesul de ncapsulare este procesul de
ascundere a detaliilor neimportante sau sensibile de construcie a obiectului.
Dar nu numai proprietile unui obiect trebuiesc protejate ci i operaiile definite de ctre acesta.
Unele dintre operaiile definite pentru un obiect sunt periculos de lsat la dispoziia oricui. Este
preferabil s putem controla foarte exact cine ce operaii poate apela pentru un anumit obiect.
Aceast protejare i ncapsulare a proprietilor i operaiilor ce se pot executa cu ajutorul unui
obiect are i o alt consecin i anume aceea c utilizatorul obiectului respectiv este independent de
detaliile constructive ale obiectului respectiv. Structura intern a obiectului poate fi astfel schimbat i
perfecionat n timp fr ca funcionalitatea de baz s fie afectat.

www.cartiaz.ro Carti si articole online gratuite de la A la Z

Clase de obiecte
n lumea real se pot identifica uor familii de obiecte. Este greu s descriem ntr-un limbaj de
programare fiecare minge din lume dar, pentru a putea folosi orice minge din lume, este suficient s
descriem o singur dat care sunt proprietile unei mingi n general, precum i operaiile care pot fi
executate cu aceasta. Aceasta nu nseamn c toate obiectele minge din lume sunt identice. Diferena
dintre ele se afl reprezentat n primul rnd n valorile proprietilor lor care difer de la un obiect de
acelai fel la altul. De exemplu, n fiecare obiect minge vom avea un numr natural care reprezint
culoarea mingii. Acest numr poate s difere de la o minge la alta exact aa cum, n realitate, culoarea
difer de la o minge la alta. La fel coordonatele poziiei mingii la un moment dat sau raza mingii
precum i materialul din care este confecionat au valori care variaz de la o minge la alta.
Cu alte cuvinte, fiecare minge din lume are acelai set de proprieti, dar valorile acestora pot s
difere de la o minge la alta. Modelul de reprezentare n memorie a unui obiect este ntotdeauna acelai,
dar valorile memorate n locaiile corespunztoare proprietilor sunt n general diferite.
n ceea ce privete operaiile, acestea sunt ntotdeauna aceleai dar rezultatul aplicrii lor poate
s difere n funcie de valorile proprietilor obiectului asupra cruia au fost aplicate. De exemplu,
atunci cnd aruncm o minge spre pmnt ea va ricoa din acesta ridicndu-se din nou n aer. nlimea
la care se va ridica ns, este dependent de dimensiunile i materialul din care a fost confecionat
mingea. Cu alte cuvinte, noua poziie n spaiu se va calcula printr-o operaie care va ine cont de
valorile memorate n interiorul obiectului. Se poate ntmpla chiar ca operaia s hotrasc faptul c
mingea va strpunge podeaua n loc s fie respins de ctre aceasta.
S mai observm c operaiile nu depind numai de proprietile obiectului ci i de unele valori
exterioare acestuia. Atunci cnd aruncm o minge spre pmnt, nlimea la care va ricoa aceasta
depinde i de viteza cu care a fost aruncat mingea. Aceast vitez este un parametru al operaiei de
aruncare. Nu are nici un rost s transmitem ca parametrii ai unei operaii valorile proprietilor unui
obiect pentru c acestea sunt ntotdeauna disponibile operaiei. Nici o operaie nu se poate aplica asupra
unui obiect fr s tim exact care este obiectul respectiv i ce proprieti are acesta. Este absurd s ne
gndim la ce nlime se va ridica o minge n general, fr s facem presupuneri asupra valorilor
proprietilor acesteia. S mai observm ns c, dac toate mingile ar avea aceleai valori pentru
proprietile implicate n operaia descris mai sus, am putea s calculm nlimea de ricoeu n
general, fr s fim dependeni de o anumit minge.
n concluzie, putem spune c obiectele cu care lucrm fac parte ntotdeauna dintr-o
familie mai mare de obiecte cu proprieti i comportament similar. Aceste familii de obiecte le
vom numi n continuare clase de obiecte sau concepte n timp ce obiectele aparinnd unei anumite
clase le vom numi instane ale clasei de obiecte respective. Putem vorbi despre clasa de obiecte minge
i despre instanele acesteia, mulimea tuturor obiectelor minge care exist n lume. Fiecare instan a
clasei minge are un loc bine precizat n spaiu i n timp, un material i o culoare. Aceste proprieti
difer de la o instan la alta, dar fiecare instan a aceleiai clase va avea ntotdeauna aceleai
proprieti i aceleai operaii vor putea fi aplicate asupra ei. n continuare vom numi variabile aceste
proprieti ale unei clase de obiecte i vom numi metode operaiile definite pentru o anumit clas de
obiecte.
Pentru a clarifica, s mai relum nc o dat: O clas de obiecte este o descriere a
proprietilor i operaiilor specifice unui nou tip de obiecte reprezentabile n memorie. O
instan a unei clase de obiecte este un obiect de memorie care respect descrierea clasei. O

www.cartiaz.ro Carti si articole online gratuite de la A la Z


variabil a unei clase de obiecte este o proprietate a clasei respective care poate lua valori diferite
n instane diferite ale clasei. O metod a unei clase este descrierea unei operaii specifice clasei
respective.
S mai precizm faptul c, spre deosebire de variabilele unei clase, metodele acesteia sunt
memorate o singur dat pentru toate obiectele. Comportarea diferit a acestora este dat de faptul c
ele depind de valorile variabilelor.
O categorie aparte a claselor de obiecte este categoria acelor clase care reprezint concepte care
nu se pot instania n mod direct, adic nu putem construi instane ale clasei respective, de obicei pentru
c nu avem destule informaii pentru a le putea construi. De exemplu, conceptul de om nu se poate
instania n mod direct pentru c nu putem construi un om despre care nu tim exact dac este brbat
sau femeie. Putem n schimb instania conceptul de brbat i conceptul de femeie care sunt nite
subconcepte ale conceptului om.
Clasele abstracte, neinstaniabile, servesc n general pentru definirea unor proprieti sau
operaii comune ale mai multor clase i pentru a putea generaliza operaiile referitoare la
acestea. Putem, de exemplu s definim n cadrul clasei de obiecte om modul n care acesta se
alimenteaz ca fiind independent de apartenena la conceptul de brbat sau femeie. Aceast definiie va
fi valabil la amndou subconceptele definite mai sus. n schimb, nu putem dect cel mult s precizm
faptul c un om trebuie s aib un comportament social. Descrierea exact a acestui comportament
trebuie fcut n cadrul conceptului de brbat i a celui de femeie. Oricum, este interesant faptul c,
indiferent care ar fi clasa acestuia, putem s ne bazm pe faptul c acesta va avea definit un
comportament social, specific clasei lui.
Cele dou metode despre care am vorbit mai sus, definite la nivelul unui superconcept, sunt
profund diferite din punctul de vedere al subconceptelor acestuia. n timp ce metoda de alimentaie este
definit exact i amndou subconceptele pot s o foloseasc fr probleme, metoda de comportament
social este doar o metod abstract, care trebuie s existe, dar despre care nu se tie exact cum trebuie
definit.
Fiecare dintre subconcepte trebuie s-i defineasc propriul su comportament social pentru a
putea deveni instaniabil. Dac o clas de obiecte are cel puin o metod abstract, ea devine n
ntregime o clas abstract i nu poate fi instaniat, adic nu putem crea instane ale unei clase de
obiecte abstracte.
Altfel spus, o clas abstract de obiecte este o clas pentru care nu s-au precizat suficient
de clar toate metodele astfel nct s poat fi folosit n mod direct.

Derivarea claselor de obiecte


O alt proprietate interesant a claselor de obiecte este aceea de ierarhizare. Practic, ori de cte
ori definim o nou clas de obiecte care s reprezinte un anumit concept, specificm clasa de obiecte
care reprezint conceptul original din care provine noul concept mpreun cu diferenele pe care le
aduce noul concept derivat fa de cel original. Aceast operaie de definire a unei noi clase de
obiecte pe baza uneia deja existente o vom numi derivare. Conceptul mai general se va numi
superconcept iar conceptul derivat din acesta se va numi subconcept. n acelai mod, clasa original
se va numi superclas a noii clase n timp ce noua clas de obiecte se va numi subclas a clasei
derivate.

www.cartiaz.ro Carti si articole online gratuite de la A la Z


Uneori, n loc de derivare se folosete termenul de extindere. Termenul vine de la faptul c o
subclas i extinde superclasa cu noi variabile i metode.
n spiritul acestei ierarhizri, putem presupune c toate clasele de obiecte sunt derivate dintr-o
clas iniial, s-i spunem clasa de obiecte generice, n care putem defini proprietile i operaiile
comune tuturor obiectelor precum ar fi testul de egalitate dintre dou instane, duplicarea instanelor
sau aflarea clasei de care aparine o anumit instan.
Ierarhizarea se poate extinde pe mai multe nivele, sub form arborescent, n fiecare punct
nodal al structurii arborescente rezultate aflndu-se clase de obiecte. Desigur, clasele de obiecte de pe
orice nivel pot avea instane proprii, cu condiia s nu fie clase abstracte, imposibil de instaniat.

Figura 2 O ierarhie de clase de obiecte n care clasele sunt reprezentate n cmpuri eliptice iar instanele acestora n
cmpuri dreptunghiulare. Clasele abstracte de obiecte au elipsa dublat.

Desigur, este foarte dificil s construim o ierarhie de clase de obiecte complet, care s conin
clase de obiecte corespunztoare fiecrui concept cunoscut. Din fericire, pentru o problem dat,
conceptele implicate n rezolvarea ei sunt relativ puine i pot fi uor izolate, simplificate i definite.
Restrngerea la minimum a arborelui de concepte necesar rezolvrii unei anumite probleme fr a se
afecta generalitatea soluiei este un talent pe care fiecare programator trebuie s i-l descopere i s i-l
cultive cu atenie. De alegerea acestor concepte depinde eficiena i flexibilitatea aplicaiei.
O clas de obiecte derivat dintr-o alt clas pstreaz toate proprietile i operaiile acesteia
din urm aducnd n plus proprieti i operaii noi. De exemplu, dac la nivelul clasei de obiecte om
am definit forma biped a acestuia i capacitatea de a vorbi i de a nelege, toate acestea vor fi
motenite i de ctre clasele derivate din clasa om, i anume clasa brbailor i cea a femeilor. Fiecare
dintre aceste clase de obiecte derivate i vor defini propriile lor proprieti i operaii pentru a descrie
diferena dintre ele i clasa original.
Unele dintre proprietile i operaiile definite n superclas pot fi redefinite n subclasele de
obiecte derivate. Vechile proprieti i operaii sunt disponibile n continuare, doar c pentru a le putea
accesa va trebui s fie specificat explicit superclasa care deine copia redefinit. Operaia de redefinire
a unor operaii sau variabile din interiorul unei clase n timpul procesului de derivare o vom numi
rescriere.

www.cartiaz.ro Carti si articole online gratuite de la A la Z


Aceast redefinire ne d de fapt o mare flexibilitate n construcia ierarhiei unei probleme date
pentru c nici o proprietate sau operaie definit ntr-un punct al ierarhiei nu este impus definitiv
pentru conceptele derivate din acest punct direct sau nu.
Revenind pentru un moment la protejarea informaiilor interne ale unui obiect s precizm
faptul c gradul de similitudine de care vorbeam mai sus este mrit n cazul n care vorbim de dou
clase derivate una din cealalt. Cu alte cuvinte, o subclas a unei clase are acces de obicei la mult mai
multe informaii memorate n superclasa sa dect o alt clas de obiecte oarecare. Acest lucru este
firesc innd cont de faptul c, uneori, o subclas este nevoit s redefineasc o parte din
funcionalitatea superclasei sale.

Interfee spre obiecte


Un obiect este o entitate complex pe care o putem privi din diverse puncte de vedere. Omul de
exemplu poate fi privit ca un mamifer care nate pui vii sau poate fi privit ca o fiin gnditoare care
nv s programeze calculatoare sau poate fi privit ca un simplu obiect spaio-temporal care are
propria lui form i poziie n funcie de timp.
Aceast observaie ne spune c trebuie s dm definiii despre ce nseamn cu adevrat faptul c
un obiect poate fi privit ca un mamifer sau ca o fiina gnditoare sau ca un obiect spaio-temporal.
Aceste definiii, pe care le vom numi n continuare interfee, sunt aplicabile nu numai clasei de obiecte
om dar i la alte clase de obiecte derivate sau nu din acesta, superclase sau nu ale acesteia. Putem s
gsim o mulime de clase de obiecte ale cror instane pot fi privite ca obiecte spaio-temporale dar care
s nu aib mare lucru n comun cu omul. Practic, atunci cnd construim o interfa, definim un set
minim de operaii care trebuie s aparin obiectelor care respect aceast interfa. Orice clas
de obiecte care declar c respect aceast interfa va trebui s defineasc toate operaiile.
Operaiile ns, sunt definite pe ci specifice fiecrei clase de obiecte n parte. De exemplu,
orice obiect spaial trebuie s defineasc o operaie de modificare a poziiei n care se afl. Dar aceast
operaie este diferit la un om, care poate s-i schimbe singur poziia, fa de o minge care trebuie
ajutat din exterior pentru a putea fi mutat. Totui, dac tim cu siguran c un obiect este o instan a
unui clase de obiecte care respect interfaa spatio-temporal, putem linitii s executm asupra
acestuia o operaie de schimbare a poziiei, fr s trebuiasc s cunoatem amnunte despre modul n
care va fi executat aceast operaie. Tot ceea ce trebuie s tim este faptul c operaia este definit
pentru obiectul respectiv.
n concluzie, o interfa este un set de operaii care trebuiesc definite de o clas de obiecte
pentru a se nscrie ntr-o anumit categorie. Vom spune despre o clas care definete toate operaiile
unei interfee c implementeaz interfaa respectiv.
Cu alte cuvinte, putem privi interfeele ca pe nite reguli de comportament impuse claselor de
obiecte. n clipa n care o clas implementeaz o anumit interfa, obiectele din clasa respectiv pot fi
privite n exclusivitate din acest punct de vedere. Interfeele pot fi privite ca nite filtre prin care putem
privi un anumit obiect, filtre care nu las la vedere dect proprietile specifice interfeei, chiar dac
obiectul n vizor este mult mai complicat n realitate.
Interfeele creaz o alt mprire a obiectelor cu care lucrm. n afar de mprirea normal pe
clase, putem s mprim obiectele i dup interfeele pe care le implementeaz. i, la fel cu situaia n
care definim o operaie doar pentru obiectele unei anumite clase, putem defini i operaii care lucreaz
doar cu obiecte care implementeaz o anumit interfa, indiferent de clasa din care acestea fac parte.

www.cartiaz.ro Carti si articole online gratuite de la A la Z

Structura lexical Java


Setul de caractere
Limbajului Java lucreaz n mod nativ folosind setul de caractere Unicode. Acesta este un
standard internaional care nlocuiete vechiul set de caractere ASCII. Motivul acestei nlocuiri a fost
necesitatea de a reprezenta mai mult de 256 de caractere. Setul de caractere Unicode, fiind reprezentat
pe 16 bii are posibiliti mult mai mari.
Vechiul standard ASCII este ns un subset al setului Unicode, ceea ce nseamn c vom regsi
caracterele ASCII cu exact aceleai coduri ca i mai nainte n noul standard.
Java folosete setul Unicode n timpul rulrii aplicaiilor ca i n timpul compilrii acestora.
Folosirea Unicode n timpul execuiei nu nseamn nimic altceva dect faptul c o variabil Java de tip
caracter este reprezentat pe 16 bii iar un ir de caractere va ocupa fizic n memorie de dou ori mai
muli octei dect numrul caracterelor care formeaz irul.
n ceea ce privete folosirea Unicode n timpul compilrii, compilatorul Java accept la intrare
fiiere surs care pot conine orice caractere Unicode. Se poate lucra i cu fiiere ASCII obinuite n
care putem introduce caractere Unicode folosind secvene escape. Fiierele surs sunt fiiere care
conin declaraii i instruciuni Java. Aceste fiiere trec prin trei pai distinci la citirea lor de ctre
compilator:
1. irul de caractere Unicode sau ASCII, memorat n fiierul surs, este transformat ntr-un ir de
caractere Unicode. Caracterele Unicode pot fi introduse i ca secvene escape folosind doar
caractere ASCII.
2. irul de caractere Unicode este transformat ntr-un ir de caractere n care sunt evideniate
separat caracterele de intrare fa de caracterele de sfrit de linie.
3. irul de caractere de intrare i de sfrit de linie este transformat ntr-un ir de cuvinte ale
limbajului Java.
n primul pas al citirii fiierului surs, sunt generate secvene escape. Secvenele escape sunt
secvene de caractere ASCII care ncep cu caracterul backslash \. Pentru secvenele escape Unicode, al
doilea caracter din secven trebuie s fie u sau U. Orice alt caracter care urmeaz dup backslash va fi
considerat ca fiind caracter nativ Unicode i lsat nealterat. Dac al doilea caracter din secvena escape
este u, urmtoarele patru caractere ASCII sunt tratate ca i cifre hexazecimale (n baza 16) care
formeaz mpreun doi octei de memorie care reprezint un caracter Unicode.
Se pot folosi la intrare i fiiere ASCII normale, pentru c ASCII este un subset al Unicode. De
exemplu, putem scrie:
int f\u0660 = 3;
Numele variabilei are dou caractere i al doilea caracter este o cifr codificat Unicode.
Exemple de secvene Unicode:
\uaa08

\U0045

\u6abe

n al doilea pas al citirii fiierului surs, sunt recunoscute ca i caractere de sfrit de linie
caracterele ASCII CR i ASCII LF. n acelai timp, secvena de caractere ASCII CR-ASCII LF este
tratat ca un singur sfrit de linie i nu dou. n acest mod, Java suport n comun standardele de
terminare a liniilor folosite de diferite sisteme de operare: MacOS, Unix i DOS.

www.cartiaz.ro Carti si articole online gratuite de la A la Z


Este important s separm caracterele de sfrit de linie de restul caracterelor de intrare pentru a
ti unde se termin comentariile de o singur linie (care ncep cu secvena //) precum i pentru a raporta
odat cu erorile de compilare i linia din fiierul surs n care au aprut acestea.
n pasul al treilea al citirii fiierului surs, sunt izolate elementele de intrare ale limbajului Java,
i anume: spaii, comentarii i uniti lexicale.
Spaiile pot fi caracterele ASCII SP (spaiu), FF (avans de pagin) sau HT (tab orizontal) precum i
orice caracter terminator de linie.

Uniti lexicale
Unitile lexicale sunt elementele de baz cu care se construiete semantica programelor Java. n
irul de cuvinte de intrare, unitile lexicale sunt separate ntre ele prin comentarii i spaii. Unitile
lexicale n limbajul Java pot fi:

Cuvinte cheie
Identificatori
Literali
Separatori
Operatori

Cuvinte cheie
Cuvintele cheie sunt secvene de caractere ASCII rezervate de limbaj pentru uzul propriu. Cu
ajutorul lor, Java i definete unitile sintactice de baz. Nici un program nu poate s utilizeze aceste
secvene altfel dect n modul n care sunt definite de limbaj. Singura excepie este aceea c nu exist
nici o restricionare a apariiei cuvintelor cheie n iruri de caractere sau comentarii.
Cuvintele cheie ale limbajului Java sunt:
abstract
boolean
break
byte
case
cast
catch
char
class
const
continue
default
do
double
else
extends
final
finally
float

for
future
generic
goto
if
implements
import
inner
instanceof
intinterface
long
native
new
null
operator
outer
package
private
protected

public
rest
return
short
static
super
switch
synchronized
this
throw
throws
transient
try
var
void
volatile
while
byvalue

www.cartiaz.ro Carti si articole online gratuite de la A la Z


Dintre acestea, cele ngroate sunt efectiv folosite, iar restul sunt rezervate pentru viitoare extensii ale
limbajului.

Identificatori
Identificatorii Java sunt secvene nelimitate de litere i cifre Unicode, ncepnd cu o liter.
Identificatorii nu au voie s fie identici cu cuvintele rezervate.
Cifrele Unicode sunt definite n urmtoarele intervale:
Reprezentare Unicode Caracter ASCII
\u0030-\u0039

0-9

Explicaie
cifre ISO-LATIN-1

\u0660-\u0669

cifre Arabic-Indic

\u06f0-\u06f9

cifre Eastern Arabic-Indic

\u0966-\u096f

cifre Devanagari

\u09e6-\u09ef

cifre Bengali

\u0a66-\ u0a6f

cifre Gurmukhi

\u0ae6-\u0aef

cifre Gujarati

\u0b66-\u0b6f

cifre Oriya

\u0be7-\u0bef

cifre Tamil

\u0c66-\u0c6f

cifre Telugu

\u0ce6-\u0cef

cifre Kannada

\u0d66-\u0d6f

cifre Malayalam

\u0e50-\u0e59

cifre Thai

\u0ed0-\u0ed9

cifre Lao

\u1040-\u1049

cifre Tibetan
Tabelul 1 Cifrele Unicode.

Un caracter Unicode este o liter dac este n urmtoarele intervale i nu este cifr:
Reprezentare Unicode Caracter ASCII

Explicaie

\u0024

semnul dolar (din motive istorice)

\u0041-\u005a

A-Z

litere majuscule Latin

www.cartiaz.ro Carti si articole online gratuite de la A la Z


\u005f

underscore (din motive istorice)

\u0061-\u007a

a-z

litere minuscule Latin

\u00c0-\u00d6

diferite litere Latin cu diacritice

\u00d8-\u00f6

diferite litere Latin cu diacritice

\u00f8-\u00ff

diferite litere Latin cu diacritice

\u0100-\u1fff

alte alfabete i simboluri non-CJK

\u3040-\u318f

Hiragana, Katakana, Bopomofo, i Hangul

\u3300-\u337f

cuvinte ptratice CJK

\u3400-\u3d2d

simboluri Hangul coreene

\u4e00-\u9fff

Han (Chinez, Japonez, Corean)

\uf900-\ufaff

compatibilitate Han
Tabelul 2. Literele Unicode.

Literali
Un literal este modalitatea de baz de exprimare n fiierul surs a valorilor pe care le pot lua
tipurile primitive i tipul ir de caractere. Cu ajutorul literalilor putem introduce valori constante n
variabilele de tip primitiv sau n variabilele de tip ir de caractere.
n limbajul Java exist urmtoarele tipuri de literali:

literali ntregi
literali flotani
literali booleeni
literali caracter
literali ir de caractere
Literali ntregi

Literalii ntregi pot fi reprezentai n baza 10, 16 sau 8. Toate caracterele care se folosesc pentru
scrierea literalilor ntregi fac parte din subsetul ASCII al setului Unicode.
Literalii ntregi pot fi ntregi normali sau lungi. Literalii lungi se recunosc prin faptul c se
termin cu sufixul l sau L. Un literal ntreg este reprezentat pe 32 de bii iar unul lung pe 64 de bii.
Un literal ntreg n baza 10 ncepe cu o cifr de la 1 la 9 i se continu cu un ir de cifre de la 0
la 9. Un literal ntreg n baza 10 nu poate s nceap cu cifra 0, pentru c acesta este semnul folosit
pentru a semnaliza literalii scrii n baza 8.
Exemple de literali ntregi n baza 10:

www.cartiaz.ro Carti si articole online gratuite de la A la Z


12356L

234871

2345678908

Exemplul al d oilea i al patrulea sunt literali ntregi lungi.


Pentru a exprima un literal ntreg n baza 16 trebuie s definim cifrele de la 10 la 15. Convenia
va fi urmtoarea:
10 - a, A
11 - b, B
12 - c, C

13 - d, D
14 - e, E
15 - f, F

n plus, pentru c un literal ntreg n baza 16 poate ncepe cu o liter, vom aduga prefixul 0x
sau 0X. Dac nu am aduga acest sufix, compilatorul ar considera c este vorba despre un identificator.
Exemple de literali ntregi n baza 16:
0xa34 0X123

0x2c45L

0xde123abccdL

Ultimele dou exemple sunt literali ntregi lungi.


Pentru a reprezenta un literal ntreg n baza 8, l vom preceda cu cifra 0. Restul cifrelor pot fi
oricare ntre 0 i 7. Cifrele 8 i 9 nu sunt admise n literalii ntregi n baza 8.
Exemple de literali ntregi n baza 8:
0234500123001234567712345677L

Valoarea maxim a unui literal ntreg normal este de 2147483647 (231-1), scris n baza 10. n
baza 16, cel mai mare literal pozitiv se scrie ca 0x7fffffff iar n baza 8 ca 017777777777. Toate trei
scrierile reprezint de fapt aceeai valoare, doar c aceasta este exprimat n baze diferite.
Cea mai mic valoare a unui literal ntreg normal este -2147483648 (-231), respectiv 0x80000000 i
020000000000. Valorile 0xffffffff i 037777777777 reprezint amndou valoarea -1.
Specificarea n surs a unui literal ntreg normal care depete aceste limite reprezint o eroare de
compilare. Cu alte cuvinte, dac folosim n surs numrul: 21474836470 de exemplu, fr s punem
sufixul de numr lung dup el, compilatorul va genera o eroare la analiza sursei.
Valoarea maxim a unui literal ntreg lung este, n baza 10, 9223372036854775807L (2 63-1). n
octal, asta nseamn 0777777777777777777777L iar n baza 16 0x7fffffffffffffffL. n mod asemntor,
valoarea minim a unui literal ntreg lung este -9223372036854775808L (-263-1), n octal aceast
valoare este 0400000000000000000000L iar n baza 16 este 0x8000000000000000L.
La fel ca i la literalii ntregi normali, depirea acestor limite este o eroare de compilare.
Literali flotani
Literalii flotani reprezint numere reale. Ei sunt formai dintr-o parte ntreag, o parte
fracionar, un exponent i un sufix de tip. Exponentul, dac exist, este introdus de litera e sau E
urmat opional de un semn al exponentului.
Este obligatoriu s existe mcar o cifr fie n partea ntreag fie n partea zecimal i punctul
zecimal sau litera e pentru exponent.
Sufixul care indic tipul flotantului poate fi f sau F n cazul n care avem o valoare flotant
normal i d sau D dac avem o valoare flotant dubl. Dac nu este specificat nici un sufix, valoarea
este implicit dubl.
Valoarea maxim a unui literal flotant normal este 3.40282347e+38f iar valoarea cea mai mic
reprezentabil este 1.40239846e-45f, ambele reprezentate pe 32 de bii.
Valoarea
maxim
reprezentabil
a
unui
literal
flotant
dublu
este
de
1.79769313486231570e+308 iar valoarea cea mai mic reprezentabil este 4.94065645841246544e324, ambele reprezentate pe 64 de bii.

www.cartiaz.ro Carti si articole online gratuite de la A la Z


La fel ca i la literalii ntregi, este o eroare s avem exprimat n surs un literal mai mare dect
valoarea maxim reprezentabil sau mai mic dect cea mai mic valoare reprezentabil.
Exemple de literali flotani:
1.0e45f

-3.456f

0.

.01e-3

Primele dou exemple reprezint literali flotani normali, iar celelalte literali flotani dubli.
Literali booleeni
Literalii booleeni nu pot fi dect true sau false, primul reprezentnd valoarea boolean de
adevr iar cellalt valoarea boolean de fals. True i false nu sunt cuvinte rezervate ale limbajului Java,
dar nu vei putea folosi aceste cuvinte ca identificatori.
Literali caracter
Un literal de tip caracter este utilizat pentru a exprima caracterele codului Unicode.
Reprezentarea se face fie folosind o liter, fie o secven escape. Secvenele escape ne permit
reprezentarea caracterelor care nu au reprezentare grafic i reprezentarea unor caractere speciale
precum backslash i nsi caracterul apostrof.
Caracterele care au reprezentare grafic pot fi reprezentate ntre apostrofe, ca n exemplele:
'a' '' ','

Pentru restul caracterelor Unicode trebuie s folosim secvene escape. Dintre acestea, cteva sunt
predefinite n Java, i anume:

Secven escape

Caracterul reprezentat

'\b'

caracterul backspace BS \u0008

'\t'

caracterul tab orizontal HT \u0009

'\n'

caracterul linefeed LF \u000a

'\f'

caracterul formfeed FF \u000c

'\r'

caracterul carriage return CR \u000d

'\"'

caracterul ghilimele \u0022

'\''

caracterul apostrof \u0027

'\\'

caracterul backslash \u005c

Tabelul 3 Secvene escape predefinite n Java.

n form general, o secven escape se scrie sub una din formele:


'\o'

'\oo' '\too'

www.cartiaz.ro Carti si articole online gratuite de la A la Z


unde o este o cifr octal iar t este o cifr octal ntre 0 i 3.
Nu este corect s folosii ca valori pentru literale caracter secvena '\u000d' (caracterul ASCII
CR), sau altele care reprezint caractere speciale, pentru c acestea fiind secvene escape Unicode sunt
transformate foarte devreme n timpul procesrii sursei n caractere CR i sunt interpretate ca
terminatori de linie.
Exemple de secvene escape:
'\n' '\u23a'

'\34'

dac dup caracterul backslash urmeaz altceva dect: b, t, n, f, r, ", ', \, 0, 1, 2, 3, 4, 5, 6, 7 se va


semnala o eroare de compilare.
n acest moment secvenele escape Unicode au fost deja nlocuite cu caractere Unicode native. Dac u
apare dup \, se semnaleaz o eroare de compilare.
Literali ir de caractere
Un literal ir de caractere este format din zero sau mai multe caractere ntre ghilimele.
Caracterele care formeaz irul de caractere pot fi caractere grafice sau secvene escape ca cele definite
la literalii caracter.
Dac un literal ir de caractere conine n interior un caracter terminator de linie va fi semnalat
o eroare de compilare. Cu alte cuvinte, nu putem avea n surs ceva de forma:
"Acesta este
greit! "

chiar dac aparent exprimarea ar reprezenta un ir format din caracterele A, c, e, s, t, a, spaiu, e, s, t, e,


linie nou, g, r, e, , i, t, !. Dac dorim s introducem astfel de caractere terminatoare de linie ntr-un ir
va trebui s folosim secvene escape ca n:
Acesta este\ngreit

Dac irul de caractere este prea lung, putem s-l spargem n buci mai mici pe care s le concatenm
cu operatorul +.
Fiecare ir de caractere este n fapt o instan a clasei de obiecte String declarat standard n
pachetul java.lang.
Exemple de iruri de caractere:
""

"\"""ir de caractere"

"unu" + "doi"

Primul ir de caractere din exemplu nu conine nici un caracter i se numete irul vid. Ultimul
exemplu este format din dou iruri distincte concatenate.

Separatori
Un separator este un caracter care indic sfritul unei uniti lexicale i nceputul alteia.
Separatorii sunt necesari atunci cnd uniti lexicale diferite sunt scrise fr spaii ntre ele. Acestea se
pot totui separa dac unele dintre ele conin caractere separatori. n Java separatorii sunt urmtorii:
(){}[];,.

Exemple de separare:
a[i]

sin(56)

n primul exemplu nu avem o singur unitate lexical ci patru: a, [, i, ]. Separatorii [ i ] ne dau


aceast informaie. n al doilea exemplu, unitile lexicale sunt tot 4 sin, (, 56, ).

www.cartiaz.ro Carti si articole online gratuite de la A la Z


Atenie, separatorii particip n acelai timp i la construcia sintaxei limbajului. Ei nu sunt identici cu
spaiile dei, ca i acestea, separ uniti lexicale diferite.

Operatori
Operatorii reprezint simboluri grafice pentru operaiile elementare definite de limbajul Java.
Lista tuturor operatorilor limbajului Java este:
= > < ! ~ ?:
= = <= >= != && || ++ -+ - * / & | ^ % << >> >>>
+= -= *= /= &= |= ^= %= <<= >>= >>>=

S mai precizm deocamdat c toi operatorii joac i rol de separatori. Cu alte cuvinte, din secvena
de caractere:
vasile+gheorghe

putem extrage trei uniti lexicale, vasile, + i gheorghe.

Comentarii
Un comentariu este o secven de caractere existent n fiierul surs dar care servete doar
pentru explicarea sau documentarea sursei i nu afecteaz n nici un fel semantica programelor.
n Java exist trei feluri de comentarii:

Comentarii pe mai multe linii, nchise ntre /* i */. Toate caracterele dintre cele dou secvene
sunt ignorate.
Comentarii pe mai multe linii care in de documentaie, nchise ntre /** i */. Textul dintre cele
dou secvene este automat mutat n documentaia aplicaiei de ctre generatorul automat de
documentaie.
Comentarii pe o singur linie care ncep cu //. Toate caracterele care urmeaz acestei secvene
pn la primul caracter sfrit de linie sunt ignorate.

n Java, nu putem s scriem comentarii n interiorul altor comentarii. La fel, nu putem introduce
comentarii n interiorul literalilor caracter sau ir de caractere. Secvenele /* i */ pot s apar pe o linie
dup secvena // dar i pierd semnificaia. La fel se ntmpl cu secvena // n comentarii care ncep
cu /* sau /**.
Ca urmare, urmtoarea secven de caractere formeaz un singur comentariu:
/* acest comentariu /* // /* se termin abia aici: */

Variabile
Declaraii de variabile
O variabil n limbajul Java este o locaie de memorie care poate pstra o valoare de un anumit
tip. n ciuda denumirii, exist variabile care i pot modifica valoarea i variabile care nu i-o pot
modifica, numite n Java variabile finale. Orice variabil trebuie s fie declarat pentru a putea fi
folosit. Aceast declaraie trebuie s conin un tip de valori care pot fi memorate n locaia rezervat
variabilei i un nume pentru variabila declarat. n funcie de locul n sursa programului n care a fost
declarat variabila, aceasta primete o clas de memorare local sau static. Aceast clas de memorare
definete intervalul de existen al variabilei n timpul execuiei.
n forma cea mai simpl, declaraia unei variabile arat n felul urmtor:
Tip NumeVariabil [, NumeVariabil];

Tipul unei variabile


Tipul unei variabile poate fi fie unul dintre tipurile primitive definite de limbajul Java fie o
referin. Creatorii limbajului Java au avut grij s defineasc foarte exact care sunt caracteristicile
fiecrui tip primitiv n parte i care este setul de valori care se poate memora n variabilele care au
tipuri primitive. n plus, a fost exact definit i modalitatea de reprezentare a acestor tipuri primitive n
memorie. n acest fel, variabilele Java devin independente de platforma hardware i software pe care
lucreaz.
n acelai spirit, Java definete o valoare implicit pentru fiecare tip de dat, n cazul n care
aceasta nu a primit nici o valoare de la utilizator. n acest fel, tim ntotdeauna care este valoarea cu
care o variabil intr n calcul. Este o practic bun ns aceea ca programele s nu depind niciodat
de aceste iniializri implicite.
Numele variabilelor
Numele variabilei poate fi orice identificator Java. Convenia nescris de formare a numelor
variabilelor este aceea c orice variabil care nu este final are un nume care ncepe cu liter minuscul
n timp ce variabilele finale au nume care conin numai majuscule. Dac numele unei variabile care nu
este final conine mai multe cuvinte, cuvintele ncepnd cu cel de-al doilea se scriu cu litere minuscule
dar cu prima liter majuscul. Exemple de nume de variabile care nu sunt finale ar putea fi:
culoarea numrulDePai urmtorulElement

Variabilele finale ar putea avea nume precum:


PORTOCALIUVERDEALBASTRUDESCHIS

Iniializarea variabilelor
Limbajul Java permite iniializarea valorilor variabilelor chiar n momentul declarrii acestora.
Sintaxa este urmtoarea:
Tip NumeVariabil = ValoareIniial;

Desigur, valoarea iniial trebuie s fie de acelai tip cu tipul variabilei sau s poat fi
convertit ntr-o valoare de acest tip.
Dei limbajul Java ne asigur c toate variabilele au o valoare iniial bine precizat, este
preferabil s executm aceast iniializare n mod explicit pentru fiecare declaraie. n acest fel
mrim claritatea propriului cod.
Regula ar fi deci urmtoarea: nici o declaraie fr iniializare.

Tipuri primitive
Tipul boolean
Tipul boolean este folosit pentru memorarea unei valori de adevr. Pentru acest scop, sunt
suficiente doar dou valori: adevrat i fals. n Java aceste dou valori le vom nota prin literalii true
i respectiv false. Aceste valori pot fi reprezentate n memorie folosindu-ne de o singur cifr binar,
adic pe un bit.
Valorile booleene sunt foarte importante n limbajul Java pentru c ele sunt valorile care se
folosesc n condiiile care controleaz instruciunile repetitive sau cele condiionale. Pentru a
exprima o condiie este suficient s scriem o expresie al crui rezultat este o valoare boolean,
adevrat sau fals.
Valorile de tip boolean nu se pot transforma n valori de alt tip n mod nativ. La fel, nu
exist transformare nativ dinspre celelalte valori nspre tipul boolean. Cu alte cuvinte, avnd o
variabil de tip boolean nu putem memora n interiorul acesteia o valoare ntreag pentru c
limbajul Java nu face pentru noi nici un fel de presupunere legat de ce nseamn o anumit valoare
ntreag din punctul de vedere al valorii de adevr. La fel, dac avem o variabil ntreag, nu i
putem atribui o valoare de tip boolean.
Orice variabil boolean nou creat primete automat valoarea implicit false. Putem
modifica aceast comportare specificnd n mod explicit o valoare iniial true.
Pentru a declara o variabil de tip boolean, n Java vom folosi cuvntul rezervat boolean ca n
exemplele de mai jos:
boolean terminat;
boolean areDreptate;

Rndurile de mai sus reprezint declaraia a dou variabile de tip boolean numite terminat
respectiv areDreptate. Cele dou variabile au, dup declaraie, valoarea false.
Tipul caracter
Orice limbaj de programare ne ofer ntr-un fel sau altul posibilitatea de a lucra cu caractere
grafice care s reprezinte litere, cifre, semne de punctuaie, etc. n cazul limbajului Java acest lucru
se poate face folosind tipul primitiv numit tip caracter.
O variabil de tip caracter poate avea ca valoare coduri Unicode reprezentate pe 16 bii,
adic doi octei. Codurile reprezentabile astfel sunt foarte multe, putnd acoperi caracterele de baz
din toate limbile scrise existente.
n Java putem combina mai multe caractere pentru a forma cuvinte sau iruri de caractere
mai lungi. Totui, trebuie s precizm c aceste iruri de caractere nu trebuiesc confundate cu
tablourile de caractere pentru c ele conin n plus informaii legate de lungimea irului.

Codul nu este altceva dect o coresponden ntre numere i caractere fapt care permite
conversii ntre variabile ntregi i caractere n ambele sensuri. O parte din aceste transformri pot s
altereze valoarea original din cauza dimensiunilor diferite ale zonelor n care sunt memorate cele
dou tipuri de valori. Convertirea caracterelor n numere i invers poate s fie util la prelucrarea n
bloc a caracterelor, cum ar fi trecerea tuturor literelor minuscule n majuscule i invers.
Atunci cnd declarm un caracter fr s specificm o valoare iniial, el va primi automat
ca valoare implicit caracterul null al codului Unicode, \u0000.
Pentru a declara o variabil de tip caracter folosim cuvntul rezervat char ca n exemplele
urmtoare:
char primaLiter;
char prima, ultima;

n cele dou linii de cod am declarat trei variabile de tip caracter care au fost automat iniializate cu
caracterul null.
Tipuri ntregi
Tipul octet

ntre tipurile ntregi, acest tip ocup un singur octet de memorie, adic opt cifre binare. ntro variabil de tip octet sunt reprezentate ntotdeauna valori cu semn, ca de altfel n toate variabilele
de tip ntreg definite n limbajul Java. Aceast convenie simplific schema de tipuri primitive care,
n cazul altor limbaje include separat tipuri ntregi cu semn i fr.
Fiind vorba de numere cu semn, este nevoie de o convenie de reprezentare a semnului.
Convenia folosit de Java este reprezentarea n complement fa de doi. Aceast reprezentare este
de altfel folosit de majoritatea limbajelor actuale i permite memorarea, pe 8 bii a 256 de numere
ncepnd de la -128 pn la 127. Dac avei nevoie de numere mai mari n valoare absolut, apelai la
alte tipuri ntregi.
Valoarea implicit pentru o variabil neiniializat de tip octet este valoarea 0 reprezentat pe un
octet.
Iat i cteva exemple de declaraii care folosesc cuvntul Java rezervat byte:
byte octet;
byte eleviPeClasa;
Tipul ntreg scurt

Tipul ntreg scurt este similar cu tipul octet dar valorile sunt reprezentate pe doi octei, adic
16 bii. La fel ca i la tipul octet, valorile sunt ntotdeauna cu semn i se folosete reprezentarea n
complement fa de doi. Valorile de ntregi scuri reprezentabile sunt de la -32768 la 32767 iar
valoarea implicit este 0 reprezentat pe doi octei.
Pentru declararea variabilelor de tip ntreg scurt n Java se folosete cuvntul rezervat short,
ca n exemplele urmtoare:
short i, j;
short valoareNuPreaMare;

Tipul ntreg

Singura diferen dintre tipul ntreg i tipurile precedente este faptul c valorile sunt
reprezentate pe patru octei adic 32 bii. Valorile reprezentabile sunt de la -2147483648 la 2147483647
valoarea implicit fiind 0. Cuvntul rezervat este int ca n:
int salariu;
Tipul ntreg lung

n fine, pentru cei care vor s reprezinte numerele ntregi cu semn pe 8 octei, 64 de bii,
tipul ntreg lung. Valorile reprezentabile sunt de la -9223372036854775808 la
9223372036854775807 iar valoarea implicit este 0L.
Pentru cei care nu au calculatoare care lucreaz pe 64 de bii este bine de precizat faptul c
folosirea acestui tip duce la operaii lente pentru c nu exist operaii native ale procesorului care s
lucreze cu numere aa de mari.
Declaraia se face cu cuvntul rezervat long.
exist

Tipuri flotante
Acest tip este folosit pentru reprezentarea numerelor reale sub form de exponent i cifre
semnificative. Reprezentarea se face pe patru octei, 32 bii, aa cum specific standardul IEEE
Tipul flotant

Valorile finite reprezentabile ntr-o variabil de tip flotant sunt de forma:


sm2e

unde s este semnul +1 sau -1, m este partea care specific cifrele reprezentative ale numrului,
numit i mantis, un ntreg pozitiv mai mic dect 224 iar e este un exponent ntreg ntre -149 i 104.
Valoarea implicit pentru variabilele flotante este 0.0f. Pentru declararea unui numr flotant, Java
definete cuvntul rezervat float. Declaraiile se fac ca n exemplele urmtoare:
float procent;
float x,y;
Tipul flotant dublu

Dac valorile reprezentabile n variabile flotante nu sunt destul de precise sau destul de
mari, putei folosi tipul flotant dublu care folosete opt octei pentru reprezentare, urmnd acelai
standard IEEE
Valorile finite reprezentabile cu flotani dubli sunt de forma:
sm2e

unde s este semnul +1 sau -1, m este mantisa, un ntreg pozitiv mai mic dect 253 iar e este un
exponent ntreg ntre -1045 i 1000. Valoarea implicit n acest caz este 0.0d.
Pentru a declara flotani dubli, Java definete cuvntul rezervat double ca n:
double distanaPnLaLun;

n afar de valorile definite pn acum, standardul IEEE definete cteva valori speciale
reprezentabile pe un flotant sau un flotant dublu.
Reali speciali definii de IEEE

Prima dintre acestea este NaN (Not a Number), valoare care se obine atunci cnd efectum
o operaie a crei rezultat nu este definit, de exemplu 0.0 / 0.0.
n plus, standardul IEEE definete dou valori pe care le putem folosi pe post de infinit pozitiv i
negativ. i aceste valori pot rezulta n urma unor calcule.
Aceste valori sunt definite sub form de constante i n ierarhia standard Java, mai precis n clasa
java.lang.Float i respectiv n java.lang.Double. Numele constantelor este POSITIVE_INFINITY,
NEGATIVE_INFINITY, NaN.
n plus, pentru tipurile ntregi i ntregi lungi i pentru tipurile flotante exist definite clase
n ierarhia standard Java care se numesc respectiv java.lang.Integer, java.lang.Long, java.lang.Float
i java.lang.Double. n fiecare dintre aceste clase numerice sunt definite dou constante care
reprezint valorile minime i maxime care se pot reprezenta n tipurile respective. Aceste dou
constante se numesc n mod uniform MIN_VALUE i MAX_VALUE.

Tipuri referin
Tipurile referin sunt folosite pentru a referi un obiect din interiorul unui alt obiect. n acest
mod putem nlnui informaiile aflate n memorie.
Tipurile referin au, la fel ca i toate celelalte tipuri o valoare implicit care este atribuit
automat oricrei variabile de tip referin care nu a fost iniializat. Aceast valoare implicit este
definit de ctre limbajul Java prin cuvntul rezervat null.
Putei nelege semnificaia referinei nule ca o referin care nu trimite nicieri, a crei
destinaie nu a fost nc fixat.
Simpla declaraie a unei referine nu duce automat la rezervarea spaiului de memorie pentru
obiectul referit. Singura rezervare care se face este aceea a spaiului necesar memorrii referinei n
sine. Rezervarea obiectului trebuie fcut explicit n program printr-o expresie de alocare care
folosete cuvntul rezervat new.
O variabil de tip referin nu trebuie s trimit pe tot timpul existenei sale ctre acelai
obiect n memorie. Cu alte cuvinte, variabila i poate schimba locaia referit n timpul execuiei.
Tipul referin ctre o clas
Tipul referin ctre o clas este un tip referin care trimite ctre o instan a unei clase de
obiecte. Clasa instanei referite poate fi oricare clas valid definit de limbaj sau de utilizator.
Clasa de obiecte care pot fi referite de o anumit variabil de tip referin la clas trebuie
declarat explicit. De exemplu, pentru a declara o referin ctre o instan a clasei Minge, trebuie s
folosim urmtoarea sintax:
Minge mingeaMea;

Din acest moment, variabila referin de clas numit mingeaMea va putea pstra doar
referine ctre obiecte de tip Minge sau ctre obiecte aparinnd unor clase derivate din clasa Minge.
De exemplu, dac avem o alt clas, derivat din Minge, numit MingeDeBaschet, putem memora n
referina mingeaMea i o trimitere ctre o instan a clasei MingeDeBaschet.
n mod general ns, nu se pot pstra n variabila mingeaMea referine ctre alte clase de
obiecte. Dac se ncerc acest lucru, eroarea va fi semnalat chiar n momentul compilrii, atunci
cnd sursa programului este examinat pentru a fi transformat n instruciuni ale mainii virtuale
Java.
Tipul referin ctre o interfa

Tipul referin ctre o interfa permite pstrarea unor referine ctre obiecte care respect o
anumit interfa. Clasa obiectelor referite poate fi oricare, atta timp ct clasa respectiv
implementeaz interfaa cerut.
Declaraia se face cu urmtoarea sintax:
ObiectSpaioTemporal mingeaLuiVasile;

n care tipul este chiar numele interfeei cerute. Dac clasa de obiecte Minge declar c
implementeaz aceast interfa, atunci variabila referin mingeaLuiVasile poate lua ca valoare
referina ctre o instan a clasei Minge sau a clasei MingeDeBaschet.
Prin intermediul unei variabile referin ctre o interfa nu se poate apela dect la
funcionalitatea cerut n interfaa respectiv, chiar dac obiectele reale ofer i alte faciliti, ele
aparinnd unor clase mai bogate n metode.
Tipul referin ctre un tablou
Tipul referin ctre un tablou este un tip referin care poate pstra o trimitere ctre locaia
din memorie a unui tablou de elemente. Prin intermediul acestei referine putem accesa elementele
tabloului furniznd indexul elementului dorit.
Tablourile de elemente nu exist n general ci ele sunt tablouri formate din elemente de un
tip bine precizat. Din aceast cauz, atunci cnd declarm o referin ctre un tablou, trebuie s
precizm i de ce tip sunt elementele din tabloul respectiv.
La declaraia referinei ctre tablou nu trebuie s precizm i numrul de elemente din
tablou.
Iat cum se declar o referin ctre un tablou de ntregi lungi:
long numere[];

Numele variabilei este numere. Un alt exemplu de declaraie de referin ctre un tablou:
Minge echipament[];

Declaraia de mai sus construiete o referin ctre un tablou care pstreaz elemente de tip referin
ctre o instan a clasei Minge. Numele variabilei referin este echipament. Parantezele drepte de
dup numele variabilei specific faptul c este vorba despre un tablou.

Clasa de memorare
Fiecare variabil trebuie s aib o anumit clas de memorare. Aceast clas ne permite s
aflm care este intervalul de existen i vizibilitatea unei variabile n contextul execuiei unui
program.
Este important s nelegem exact aceast noiune pentru c altfel vom ncerca s referim variabile
nainte ca acestea s fi fost create sau dup ce au fost distruse sau s referim variabile care nu sunt
vizibile din zona de program n care le apelm.
Variabile locale
Aceste variabile nu au importan prea mare n contextul ntregii aplicaii, ele servind la
rezolvarea unor probleme locale. Variabilele locale sunt declarate, rezervate n memorie i utilizate
doar n interiorul unor blocuri de instruciuni, fiind distruse automat la ieirea din aceste blocuri.
Aceste variabile sunt vizibile doar n interiorul blocului n care au fost create i n subblocurile
acestuia.

Variabile statice
Variabilele statice sunt n general legate de funcionalitatea anumitor clase de obiecte ale
cror instane folosesc n comun aceste variabile. Variabilele statice sunt create atunci cnd codul
specific clasei n care au fost declarate este ncrcat n memorie i nu sunt distruse dect atunci cnd
acest cod este eliminat din memorie.
Valorile memorate n variabile statice au importan mult mai mare n aplicaie dect cele
locale, ele pstrnd informaii care nu trebuie s se piard la dispariia unei instane a clasei. De
exemplu, variabila n care este memorat numrul de picioare al obiectelor din clasa Om nu trebuie
s fie distrus la dispariia unei instane din aceast clas. Aceasta din cauz c i celelalte instane
ale clasei folosesc aceeai valoare. i chiar dac la un moment dat nu mai exist nici o instan a
acestei clase, numrul de picioare ale unui Om trebuie s fie accesibil n continuare pentru
interogare de ctre celelalte clase.
Variabilele statice nu se pot declara dect ca variabile ale unor clase i conin n declaraie
cuvntul rezervat static. Din cauza faptului c ele aparin clasei i nu unei anumite instane a clasei,
variabilele statice se mai numesc uneori i variabile de clas.
Variabile dinamice
Un alt tip de variabile sunt variabilele a cror perioad de existen este stabilit de ctre
programator. Aceste variabile pot fi alocate la cerere, dinamic, n orice moment al execuiei
programului. Ele vor fi distruse doar atunci cnd nu mai sunt referite de nicieri.
La alocarea unei variabile dinamice, este obligatoriu s pstrm o referin ctre ea ntr-o
variabil de tip referin. Altfel, nu vom putea accesa n viitor variabila dinamic. n momentul n
care nici o referin nu mai trimite ctre variabila dinamic, de exemplu pentru c referina a fost o
variabil local i blocul n care a fost declarat i-a terminat execuia, variabila dinamic este
distrus automat de ctre sistem printr-un mecanism numit colector de gunoaie.
Colectorul de gunoaie poate porni din iniiativa sistemului sau din iniiativa programatorului
la momente bine precizate ale execuiei.
Pentru a rezerva spaiu pentru o variabil dinamic este nevoie s apelm la o expresie de
alocare care folosete cuvntul rezervat new. Aceast expresie aloc spaiul necesar pentru un
anumit tip de valoare. De exemplu, pentru a rezerva spaiul necesar unui obiect de tip Minge, putem
apela la sintaxa:
Minge mingeaMea = new Minge( );

iar pentru a rezerva spaiul necesar unui tablou de referine ctre obiecte de tip Minge putem folosi
declaraia:
Minge echipament[] = new Minge[5];

Am alocat astfel spaiu pentru un tablou care conine 5 referine ctre obiecte de tip Minge. Pentru
alocarea tablourilor coninnd tipuri primitive se folosete aceeai sintax. De exemplu, urmtoarea
linie de program aloc spaiul necesar unui tablou cu 10 ntregi, crend n acelai timp i o variabil
referin spre acest tablou, numit numere:
int numere[] = new int[10];

Tablouri de variabile
Tablourile servesc, dup cum s-a vzut, la memorarea secvenelor de elemente de acelai tip.
Tablourile unidimensionale au semnificaia vectorilor de elemente. Se poate ntmpla s lucrm i
cu tablouri de referine ctre tablouri, n acest caz modelul fiind acela al unei matrici
bidimensionale, sau putem extinde definiia i pentru mai mult de dou dimensiuni.
Declaraia variabilelor de tip tablou
Pentru a declara variabile de tip tablou, trebuie s specificm tipul elementelor care vor
umple tabloul i un nume pentru variabila referin care va pstra trimiterea ctre zona de memorie
n care sunt memorate elementele tabloului.
Dei putem declara variabile referin ctre tablou i separat, de obicei declaraia este fcut
n acelai timp cu alocarea spaiului ca n exemplele din paragraful anterior.
Sintaxa Java permite plasarea parantezelor drepte care specific tipul tablou nainte sau dup
numele variabilei. Astfel, urmtoarele dou declaraii sunt echivalente:
int[ ] numere;
int numere[ ];

Dac dorii s folosii tablouri cu dou dimensiuni ca matricile, putei s declarai un tablou de
referine ctre tablouri cu una dintre urmtoarele trei sintaxe echivalente:
float [ ][ ] matrice;
float[ ] matrice[];
float matrice[][];

De precizat c i n cazul dimensiunilor multiple, declaraiile de mai sus nu fac nimic altceva
dect s rezerve loc pentru o referin i s precizeze numrul de dimensiuni. Alocarea spaiului
pentru elementele tabloului trebuie fcut explicit.
Pentru tablourile cu mai multe dimensiuni, rezervarea spaiului se poate face cu urmtoarea sintax:
byte [][]octeti = new byte[23][5];

n expresia de alocare sunt specificate n clar numrul elementelor pentru fiecare dimensiune a
tabloului.
Iniializarea tablourilor.
Limbajul Java permite i o sintax pentru iniializarea elementelor unui tablou. ntr-un astfel
de caz este rezervat automat i spaiul de memorie necesar memorrii valorilor iniiale. Sintaxa
folosit n astfel de cazuri este urmtoarea:
char []caractere = { a, b , c , d };

Acest prim exemplu aloc spaiu pentru patru elemente de tip caracter i iniializeaz aceste
elemente cu valorile dintre acolade. Dup aceea, creeaz variabila de tip referin numit caractere
i o iniializeaz cu referina la zona de memorie care pstreaz cele patru valori.
Iniializarea funcioneaz i la tablouri cu mai multe dimensiuni ca n exemplele urmtoare:
int [][]numere = {
{ 1, 3, 4, 5 },
{ 2, 4, 5 },
{ 1, 2, 3, 4, 5 }
};
double [][][]reali = {
{ { 0.0, -1.0 }, { 4.5 } },
{ { 2.5, 3.0 } }
};

Dup cum observai numrul iniializatorilor nu trebuie s fie acelai pentru fiecare element.

Lungimea tablourilor
Tablourile Java sunt alocate dinamic, ceea ce nseamn c ele i pot schimba dimensiunile pe
parcursul execuiei. Pentru a afla numrul de elemente dintr-un tablou, putem apela la urmtoarea
sintax:
float []tablou = new float[25];
int dimensiune = tablou.length;

// dimensiune primete valoarea 25

sau
float [][]multiTablou = new float[3][4];
int dimensiune1 = multiTablou[2].length;
int dimensiune2 = multiTablou.length;

// dimensiune1 primete valoarea 4


// dimensiune2 primete valoarea 3

Referirea elementelor din tablou


Elementele unui tablou se pot referi prin numele referinei tabloului i indexul elementului
pe care dorim s-l referim. n Java, primul element din tablou este elementul cu numrul 0, al doilea
este elementul numrul 1 i aa mai departe.
Sintaxa de referire folosete parantezele ptrate [ i ]. ntre ele trebuie specificat indexul elementului
pe care dorim s-l referim. Indexul nu trebuie s fie constant, el putnd fi o expresie de
complexitate oarecare.
Iat cteva exemple:
int []tablou = new int[10];
tablou[3] = 1;
// al patrulea element primete valoarea 1
float [][]reali = new float[3][4];
reali[2][3] = 1.0f;
// al patrulea element din al treilea tablou
// primete valoarea 1

n cazul tablourilor cu mai multe dimensiuni, avem n realitate tablouri de referine la tablouri. Asta
nseamn c dac considerm urmtoarea declaraie:
char [][]caractere = new char [5][];

Elementele tabloului sunt de tip referin, iniializate implicit la valoarea null.

Variabila referin numit caractere conine deocamdat un tablou de 5 referine la tablouri de


caractere. Cele cinci referine sunt iniializate cu null. Putem iniializa aceste tablouri prin atribuiri
de expresii de alocare:
caractere[0] = new char [3];
caractere[4] = new char [5];

Noile tablouri sunt referite din interiorul tabloului original. Elementele noilor tablouri sunt caractere.

La fel, putem scrie:


char []tablouDeCaractere = caractere[0];

Variabilele de tip referin caractere[0] i tablouDeCaractere trimit spre acelai tablou rezervat n memorie.

Variabila tablouDeCaractere trimite ctre acelai tablou de caractere ca i cel referit de


primul element al tabloului referit de variabila caractere.
S mai precizm c referirea unui element de tablou printr-un index mai mare sau egal cu lungimea
tabloului duce la oprirea execuiei programului cu un mesaj de eroare de execuie corespunztor.
Alocarea i eliberarea tablourilor
n cazul n care nu avem iniializatori, variabilele sunt iniializate cu valorile implicite
definite de limbaj pentru tipul corespunztor. Aceasta nseamn c, pentru tablourile cu mai multe
dimensiuni, referinele sunt iniializate cu null.
Pentru eliberarea memoriei ocupate de un tablou, este suficient s tiem toate referinele ctre
tablou. Sistemul va sesiza automat c tabloul nu mai este referit i mecanismul colector de gunoaie
va elibera zona. Pentru a tia o referin ctre un tablou dm o alt valoare variabilei care refer
tabloul. Valoarea poate fi null sau o referin ctre un alt tablou.
De exemplu:
float []reali = new float[10];
reali = null; // eliberarea tabloului
sau
reali = new float[15]; // eliberarea n alt fel
sau
{
float []reali = new float[10];

Conversii
Operaiile definite n limbajul Java au un tip bine precizat de argumente. Din pcate, exist
situaii n care nu putem transmite la apelul acestora exact tipul pe care compilatorul Java l
ateapt. n asemenea situaii, compilatorul are dou alternative: fie respinge orice operaie cu
argumente greite, fie ncearc s converteasc argumentele ctre tipurile necesare. Desigur, n
cazul n care conversia nu este posibil, singura alternativ rmne prima.
n multe situaii ns, conversia este posibil. S lum de exemplu tipurile ntregi. Putem s
convertim ntotdeauna un ntreg scurt la un ntreg. Valoarea rezultat va fi exact aceeai. Conversia
invers ns, poate pune probleme dac valoarea memorat n ntreg depete capacitatea de
memorare a unui ntreg scurt.
n afar de conversiile implicite, pe care compilatorul le hotrte, exist i conversii
explicite, pe care programatorul le poate fora la nevoie. Aceste conversii efectueaz de obicei

operaii n care exist pericolul s se piard o parte din informaii. Compilatorul nu poate hotr de
unul singur n aceste situaii.
Conversiile implicite pot fi un pericol pentru stabilitatea aplicaiei dac pot s duc la
pierderi de informaii fr avertizarea programatorului. Aceste erori sunt de obicei extrem de greu
de depistat.
n fiecare limbaj care lucreaz cu tipuri fixe pentru datele sale exist conversii imposibile,
conversii periculoase i conversii sigure. Conversiile imposibile sunt conversiile pe care limbajul nu
le permite pentru c nu tie cum s le execute sau pentru c operaia este prea periculoas. De
exemplu, Java refuz s converteasc un tip primitiv ctre un tip referin. Dei s-ar putea imagina o
astfel de conversie bazat pe faptul c o adres este n cele din urm un numr natural, acest tip de
conversii sunt extrem de periculoase, chiar i atunci cnd programatorul cere explicit aceast
conversie.
Conversii de extindere a valorii
n aceste conversii valoarea se reprezint ntr-o zon mai mare fr s se piard nici un fel de
informaii. Iat conversiile de extindere pe tipuri primitive:

byte la short, int, long, float sau double


short la int, long, float sau double
char la int, long, float sau double
int la long, float sau double
long la float sau double
float la double

S mai precizm totui c, ntr-o parte din aceste cazuri, putem pierde din precizie. Aceast
situaie apare de exemplu la conversia unui long ntr-un float, caz n care se pierd o parte din cifrele
semnificative pstrndu-se ns ordinul de mrime. De altfel aceast observaie este evident dac
inem cont de faptul c un long este reprezentat pe 64 de bii n timp ce un float este reprezentat doar
pe 32 de bii.
Precizia se pierde chiar i n cazul conversiei long la double sau int la float pentru c, dei
dimensiunea zonei alocat pentru cele dou tipuri este aceeai, numerele flotante au nevoie de o
parte din aceast zon pentru a reprezenta exponentul.
n aceste situaii, se va produce o rotunjire a numerelor reprezentate.
Conversii de trunchiere a valorii
Conveniile de trunchiere a valorii pot produce pierderi de informaie pentru c ele convertesc
tipuri mai bogate n informaii ctre tipuri mai srace. Conversiile de trunchiere pe tipurile
elementare sunt urmtoarele:

byte la char
short la byte sau char
char la byte sau short
int la byte, short sau char
long la byte, short char, sau int
float la byte, short, char, int sau long
double la byte, short, char, int, long sau float.

n cazul conversiilor de trunchiere la numerele cu semn, este posibil s se schimbe semnul


pentru c, n timpul conversiei, se ndeprteaz pur i simplu octeii care nu mai ncap i poate
rmne primul bit diferit de vechiul prim bit. Copierea se face ncepnd cu octeii mai puin
semnificativi iar trunchierea se face la octeii cei mai semnificativi.
Conversii pe tipuri referin
Conversiile tipurilor referin nu pun probleme pentru modul n care trebuie executat
operaia din cauz c, referina fiind o adres, n timpul conversiei nu trebuie afectat n nici un fel
aceast adres. n schimb, se pun probleme legate de corectitudinea logic a conversiei. De
exemplu, dac avem o referin la un obiect care nu este tablou, este absurd s ncercm s
convertim aceast referin la o referin de tablou.
Limbajul Java definete extrem de strict conversiile posibile n cazul tipurilor referin pentru a
salva programatorul de eventualele necazuri care pot apare n timpul execuiei. Iat conversiile
posibile:

O referin ctre un obiect aparinnd unei clase C poate fi convertit la o referin ctre un
obiect aparinnd clasei S doar n cazul n care C este chiar S sau C este derivat direct sau
indirect din S.
O referin ctre un obiect aparinnd unei clase C poate fi convertit ctre o referin de
interfa I numai dac clasa C implementeaz interfaa I.
O referin ctre un tablou poate fi convertit la o referin ctre o clas numai dac clasa
respectiv este clasa Object.
O referin ctre un tablou de elemente ale crui elemente sunt de tipul T1 poate fi
convertit la o referin ctre un tablou de elemente de tip T2 numai dac T1 i T2 reprezint
acelai tip primitiv sau T2 este un tip referin i T1 poate fi convertit ctre T2.
Conversii la operaia de atribuire

Conversiile pe care limbajul Java le execut implicit la atribuire sunt foarte puine. Mai
exact, sunt executate doar acele conversii care nu necesit validare n timpul execuiei i care nu pot
pierde informaii n cazul tipurilor primitive.
n cazul valorilor aparinnd tipurilor primitive, urmtorul tabel arat conversiile posibile. Pe
coloane avem tipul de valoare care se atribuie iar pe linii avem tipurile de variabile la care se
atribuie:
boolean char byte short int long float double
boolean

Da

Nu

Nu

Nu

Nu Nu

Nu

Nu

char

Nu

Da

Da

Da

Nu Nu

Nu

Nu

byte

Nu

Da

Da

Nu

Nu Nu

Nu

Nu

short

Nu

Da

Da

Da

Nu Nu

Nu

Nu

int

Nu

Da

Da

Da

Da Nu

Nu

Nu

long

Nu

Da

Da

Da

Da Da

Nu

Nu

float

Nu

Da

Da

Da

Da Da

Da

Nu

double

Nu

Da

Da

Da

Da Da

Da

Da

Conversiile posibile ntr-o operaie de atribuire cu tipuri primitive. Coloanele reprezint tipurile care se atribuie
iar liniile reprezint tipul de variabil ctre care se face atribuirea.

Dup cum se observ, tipul boolean nu poate fi atribuit la o variabil de alt tip.
Valorile de tip primitiv nu pot fi atribuite variabilelor de tip referin. La fel, valorile de tip
referin nu pot fi memorate n variabile de tip primitiv. n ceea ce privete tipurile referin ntre
ele, urmtorul tabel definete situaiile n care conversiile sunt posibile la atribuirea unei valori de
tipul T la o variabil de tipul S: S=T

S este o clas care


nu este final

T este o clas care


nu este final

T este o clas care


este final

T este o interfa

T = B[] este un tablou cu


elemente de tipul B

T trebuie s fie
subclas a lui S

T trebuie s fie o
subclas a lui S

eroare la
compilare

S trebuie s fie Object

eroare la
compilare

eroare la compilare

S este o clas care


T trebuie s fie
T trebuie s fie
este final
aceeai clas ca i S aceeai clas ca i S
S este o interfa

T trebuie s
implementeze
interfaa S

T trebuie s
implementeze
interfaa S

T trebuie s fie o
subinterfa a lui
S

eroare la compilare

S = A[] este un
tablou cu
elemente de tipul
A

eroare la compilare

eroare la compilare

eroare la
compilare

A sau B sunt acelai tip


primitiv sau A este un tip
referin i B poate fi atribuit
lui A

Conversiile posibile la atribuirea unei valori de tipul T la o variabil de tipul S.

Conversii explicite
Conversiile de tip cast, sau casturile, sunt apelate de ctre programator n mod explicit.
Sintaxa pentru construcia unui cast este scrierea tipului ctre care dorim s convertim n paranteze
n faa valorii pe care dorim s o convertim. Forma general este:
( Tip ) Valoare
Conversiile posibile n acest caz sunt mai multe dect conversiile implicite la atribuire pentru c n
acest caz programatorul este prevenit de eventuale pierderi de date el trebuind s apeleze conversia
explicit. Dar, continu s existe conversii care nu se pot apela nici mcar n mod explicit.
n cazul conversiilor de tip cast, orice valoare numeric poate fi convertit la orice valoare
numeric.
n continuare, valorile de tip boolean nu pot fi convertite la nici un alt tip.
Nu exist conversii ntre valorile de tip referin i valorile de tip primitiv.
n cazul conversiilor dintr-un tip referin ntr-altul putem separa dou cazuri. Dac compilatorul
poate decide n timpul compilrii dac conversia este corect sau nu, o va decide. n cazul n care
compilatorul nu poate decide pe loc, se va efectua o verificare a conversiei n timpul execuiei. Dac
conversia se dovedete greit, va apare o eroare de execuie i programul va fi ntrerupt.
Iat un exemplu de situaie n care compilatorul nu poate decide dac conversia este posibil sau nu:
Minge mingeaMea;
....
MingeDeBaschet mingeaMeaDeBaschet;
// MingeDeBaschet este o clas derivat din clasa
Minge
mingeaMeaDeBaschet=(MingeDeBaschet)mingeaMea;

n acest caz, compilatorul nu poate fi sigur dac referina memorat n variabila mingeaMea este de
tip MingeDeBaschet sau nu pentru c variabilei de tip Minge i se pot atribui i referine ctre instane de
tip Minge n general, care nu respect ntru totul definiia clasei MingeDeBaschet sau chiar referin
ctre alte tipuri de minge derivate din clasa Minge, de exemplu MingeDePolo care implementeaz
proprieti i operaii diferite fa de clasa MingeDeBaschet.
Iat i un exemplu de conversie care poate fi decis n timpul compilrii:
Minge mingeaMea;
MingeDeBaschet mingeaMeaDeBaschet;
....
mingeaMea = ( Minge ) mingeaMeaDeBaschet;

n urmtorul exemplu ns, se poate decide n timpul compilrii imposibilitatea conversiei:


MingeDeBaschet mingeaMeaDeBaschet;
MingeDePolo mingeaMeaDePolo;
....
mingeaMeaDePolo = ( MingeDePolo ) mingeaMeaDeBaschet;

n fine, tabelul urmtor arat conversiile de tip cast a cror corectitudine poate fi stabilit n timpul
compilrii. Conversia ncearc s transforme printr-un cast o referin de tip T ntr-o referin de tip
S.

T este o clas care


nu este final

T este o clas care


este final

T este o interfa

T = B[] este un tablou cu


elemente de tipul B

S este o clas care


nu este final

T trebuie s fie
subclas a lui S

T trebuie s fie o
subclas a lui S

Totdeauna corect
la compilare

S trebuie s fie Object

S este o clas care


este final

S trebuie s fie
subclas a lui T

T trebuie s fie
aceeai clas ca i
S

S trebuie s
implementeze
interfaa T

eroare la compilare

S este o interfa

Totdeauna corect
la compilare

T trebuie s
implementeze
interfaa S

Totdeauna corect
la compilare

eroare la compilare

S = A[] este un
tablou cu
elemente de tipul
A

T trebuie s fie
Object

eroare la
compilare

eroare la compilare

A sau B sunt acelai tip


primitiv sau A este un tip
referin i B poate fi
convertit cu un cast la A

Cazurile posibile la convertirea unei referine de tip T ntr-o referin de tip S.

Conversii de promovare aritmetic


Promovarea aritmetic se aplic n cazul unor formule n care operanzii pe care se aplic un
operator sunt de tipuri diferite. n aceste cazuri, compilatorul ncearc s promoveze unul sau chiar
amndoi operanzii la acelai tip pentru a putea fi executat operaia.
Exist dou tipuri de promovare, promovare aritmetic unar i binar.
n cazul promovrii aritmetice unare, exist un singur operand care n cazul c este byte sau
short este transformat la int altfel rmne nemodificat.
La promovarea aritmetic binar se aplic urmtorul algoritm:
1.
2.
3.
4.

Dac un operand este double, cellalt este convertit la double.


Altfel, dac un operand este de tip float, cellalt operand este convertit la float.
Altfel, dac un operand este de tip long, cellalt este convertit la long
Altfel, amndoi operanzii sunt convertii la int.

De exemplu, n urmtoarea operaie amndoi operanzii vor fi convertii la double prin promovare
aritmetic binar:
float f;
double i = f + 3;

Dup efectuarea operaiei, valoarea obinut va fi convertit implicit la double.


n urmtorul exemplu, se produce o promovare unar la int de la short.
short s, r;
...
int min = ( r < -s ) ? r : s;

n expresia condiional, operandul -s se traduce de fapt prin aplicarea operatorului unar - la


variabila s care este de tip short. n acest caz, se va produce automat promovarea aritmetic
unar de la short la int, apoi se va continua evaluarea expresiei.

Obiecte Java
n primul rnd s observm c, atunci cnd scriem programe n Java nu facem altceva dect s
definim noi i noi clase de obiecte. Dintre acestea, unele vor reprezenta nsi aplicaia noastr n
timp ce altele vor fi necesare pentru rezolvarea problemei la care lucrm. Ulterior, atunci cnd dorim
s lansm aplicaia n execuie nu va trebui dect s instaniem un obiect reprezentnd aplicaia n
sine i s apelm o metod de pornire definit de ctre aplicaie, metod care de obicei are un nume
i un set de parametri bine fixate. Totui, numele acestei metode depinde de contextul n care este
lansat aplicaia noastr.
Aceast abordare a construciei unei aplicaii ne spune printre altele c vom putea lansa oricte
instane ale aplicaiei noastre dorim, pentru c fiecare dintre acestea va reprezenta un obiect n memorie
avnd propriile lui valori pentru variabile. Execuia instanelor diferite ale aplicaiei va urma desigur
ci diferite n funcie de interaciunea fiecreia cu un utilizator, eventual acelai, i n funcie de unii
parametri pe care i putem defini n momentul crerii fiecrei instane.

Declaraia unei noi clase de obiecte


Pasul 1: Stabilirea conceptului reprezentat de clasa de obiecte
S vedem ce trebuie s definim atunci cnd dorim s crem o nou clas de obiecte. n primul
rnd trebuie s stabilim care este conceptul care este reprezentat de ctre noua clas de obiecte i s
definim informaiile memorate n obiect i modul de utilizare a acestuia. Acest pas este cel mai
important din tot procesul de definire al unei noi clase de obiecte. Este necesar s ncercai s respectai
dou reguli oarecum antagonice. Una dintre ele spune c nu trebuiesc create mai multe clase de obiecte
dect este nevoie, pentru a nu face dificil nelegerea modului de lucru al aplicaiei la care lucrai. Cea
de-a doua regul spune c nu este bine s mixai ntr-un singur obiect funcionaliti care nu au nimic n
comun, crend astfel clase care corespund la dou concepte diferite.
Medierea celor dou reguli nu este ntotdeauna foarte uoar. Oricum, v va fi mai uor dac
pstrai n minte faptul c fiecare clas pe care o definii trebuie s corespund unui concept real bine
definit, necesar la rezolvarea problemei la care lucrai. i mai pstrai n minte i faptul c este inutil s
lucrai cu concepte foarte generale atunci cnd aplicaia dumneavoastr nu are nevoie dect de o
particularizare a acestora. Riscai s pierdei controlul dezvoltrii acestor clase de obiecte prea generale
i s ngreunai dezvoltarea aplicaiei.

Pasul 2: Stabilirea numelui clasei de obiecte


Dup ce ai stabilit exact ce dorii de la noua clas de obiecte, suntei n msur s gsii un
nume pentru noua clas, nume care trebuie s urmeze regulile de construcie ale identificatorilor
limbajului Java definite n capitolul anterior.
Stabilirea unui nume potrivit pentru o nou clas nu este ntotdeauna un lucru foarte uor.
Problema este c acest nume nu trebuie s fie exagerat de lung dar trebuie s exprime suficient de bine
destinaia clasei. Regulile de denumire ale claselor sunt rezultatul experienei fiecruia sau al unor
convenii de numire stabilite anterior. De obicei, numele de clase este bine s nceap cu o liter
majuscul. Dac numele clasei conine n interior mai multe cuvinte, aceste cuvinte trebuie de
asemenea ncepute cu liter majuscul. Restul caracterelor vor fi litere minuscule.
De exemplu, dac dorim s definim o clas de obiecte care implementeaz conceptul de motor Otto
vom folosi un nume ca MotorOtto pentru noua clas ce trebuie creat. La fel, vom defini clasa

MotorDiesel sau MotorCuReacie. Dac ns avem nevoie s definim o clas separat


pentru un motor Otto cu cilindri n V i carburator, denumirea clasei ca
MotorOttoCuCilindrinVSiCarburator nu este poate cea mai bun soluie. Poate c n
acest caz este preferabil o prescurtare de forma MotorOttoVC. Desigur, acestea sunt doar cteva
remarci la adresa acestei probleme i este n continuare necesar ca n timp s v creai propria
convenie de denumire a claselor pe care le creai.

Pasul 3: Stabilirea superclasei


n cazul n care ai definit deja o parte din funcionalitatea de care avei nevoie ntr-o alt
superclas, putei s derivai noua clas de obiecte din clasa deja existent. Dac nu exist o astfel
de clas, noua clas va fi automat derivat din clasa de obiecte predefinit numit Object. n Java,
clasa Object este superclas direct sau indirect pentru orice alt clas de obiecte definit de
utilizator.
Alegerea superclasei din care derivai noua clas de obiecte este foarte important pentru c
v ajut s refolosii codul deja existent. Totui, nu alegei cu uurin superclasa unui obiect pentru
c astfel putei ncrca obiectele cu o funcionalitate inutil, existent n superclas. Dac nu exist
o clas care s v ofere doar funcionalitatea de care avei nevoie, este preferabil s derivai noua
clas direct din clasa Object i s apelai indirect funcionalitatea pe care o dorii.

Pasul 4: Stabilirea interfeelor pe care le respect clasa


Stabilirea acestor interfee are dublu scop. n primul rnd ele instruiesc compilatorul s
verifice dac noua clas respect cu adevrat toate interfeele pe care le-a declarat, cu alte cuvinte
definete toate metodele declarate n aceste interfee. A doua finalitate este aceea de a permite
compilatorului s foloseasc instanele noii clase oriunde aplicaia declar c este nevoie de un
obiect care implementeaz interfeele declarate.
O clas poate s implementeze mai multe interfee sau niciuna.

Pasul 5: Stabilirea modificatorilor clasei


n unele cazuri trebuie s oferim compilatorului informaii suplimentare relative la modul n
care vom folosi clasa nou creat pentru ca acesta s poat executa verificri suplimentare asupra
descrierii clasei. n acest scop, putem defini o clas ca fiind abstract, final sau public folosindune de o serie de cuvinte rezervate numite modificatori. Modificatorii pentru tipurile de clase de mai
sus sunt respectiv: abstract, final i public.
n cazul n care declarm o clas de obiecte ca fiind abstract, compilatorul va interzice
instanierea acestei clase. Dac o clas este declarat final, compilatorul va avea grij s nu putem
deriva noi subclase din aceast clas. n cazul n care declarm n acelai timp o clas de obiecte ca
fiind abstract i final, eroarea va fi semnalat nc din timpul compilrii pentru c cei doi
modificatori se exclud.
Pentru ca o clas s poat fi folosit i n exteriorul contextului n care a fost declarat ea trebuie
s fie declarat public. Orice clas de obiecte care va fi instaniat ca o aplicaie trebuie
declarat public.

Pasul 6: Scrierea corpului declaraiei


n sfrit, dup ce toi ceilali pai au fost efectuai, putem trece la scrierea corpului
declaraiei de clas. n principal, aici vom descrie variabilele clasei mpreun cu metodele care
lucreaz cu acestea. Tot aici putem preciza i gradele de protejare pentru fiecare dintre elementele
declaraiei.
Uneori numim variabilele i metodele unei clase la un loc ca fiind cmpurile clasei.

Forma general a unei declaraii de clas


Sintaxa exact de declarare a unei clase arat n felul urmtor:

{ abstract | final | public } class NumeClas


[ extends NumeSuperclas ]
[ implements NumeInterfa [ , NumeInterfa ] ]
{ [ CmpClas ] }

Variabilele unei clase


n interiorul claselor se pot declara variabile. Aceste variabile sunt specifice clasei
respective. Fiecare dintre ele trebuie s aib un tip, un nume i poate avea iniializatori. n afar de
aceste elemente, pe care le-am prezentat deja n seciunea n care am prezentat variabilele,
variabilele definite n interiorul unei clase pot avea definii o serie de modificatori care altereaz
comportarea variabilei n interiorul clasei, i o specificaie de protecie care definete cine are
dreptul s acceseze variabila respectiv.

Modificatori
Modificatorii sunt cuvinte rezervate Java care precizeaz sensul unei declaraii. Iat lista acestora:
static
final
transient
volatile

Dintre acetia, transient nu este utilizat n versiunea curent a limbajului Java. Pe viitor
va fi folosit pentru a specifica variabile care nu conin informaii care trebuie s rmn persistente
la terminarea programului.
Modificatorul volatile specific faptul c variabila respectiv poate fi modificat
asincron cu rularea aplicaiei. n aceste cazuri, compilatorul trebuie s-i ia msuri suplimentare n
cazul generrii i optimizrii codului care se adreseaz acestei variabile.
Modificatorul final este folosit pentru a specifica o variabil a crei valoare nu poate fi
modificat. Variabila respectiv trebuie s primeasc o valoare de iniializare chiar n momentul
declaraiei. Altfel, ea nu va mai putea fi iniializat n viitor. Orice ncercare ulterioar de a seta
valori la aceast variabil va fi semnalat ca eroare de compilare.
Modificatorul static este folosit pentru a specifica faptul c variabila are o singur
valoare comun tuturor instanelor clasei n care este declarat. Modificarea valorii acestei variabile
din interiorul unui obiect face ca modificarea s fie vizibil din celelalte obiecte. Variabilele statice
sunt iniializate la ncrcarea codului specific unei clase i exist chiar i dac nu exist nici o
instan a clasei respective. Din aceast cauz, ele pot fi folosite de metodele statice.

Protecie
n Java exist patru grade de protecie pentru o variabil aparinnd unei clase:
privat
protejat
public
prietenoas
O variabil public este accesibil oriunde este accesibil numele clasei. Cuvntul rezervat
este public.
O variabil protejat este accesibil n orice clas din pachetul creia i aparine clasa n
care este declarat. n acelai timp, variabila este accesibil n toate subclasele clasei date, chiar
dac ele aparin altor pachete. Cuvntul rezervat este protected.
O variabil privat este accesibil doar n interiorul clasei n care a fost declarat. Cuvntul
rezervat este private.

O variabil care nu are nici o declaraie relativ la gradul de protecie este automat o
variabil prietenoas. O variabil prietenoas este accesibil n pachetul din care face parte clasa n
interiorul creia a fost declarat, la fel ca i o variabil protejat. Dar, spre deosebire de variabilele
protejate, o variabil prietenoas nu este accesibil n subclasele clasei date dac aceste sunt
declarate ca aparinnd unui alt pachet. Nu exist un cuvnt rezervat pentru specificarea explicit a
variabilelor prietenoase.
O variabil nu poate avea declarate mai multe grade de protecie n acelai timp. O astfel de
declaraie este semnalat ca eroare de compilare.

Accesarea unei variabile


Accesarea unei variabile declarate n interiorul unei clasei se face folosindu-ne de o expresie
de forma:
ReferinInstan.NumeVariabil
Referina ctre o instan trebuie s fie referin ctre clasa care conine variabila. Referina
poate fi valoarea unei expresii mai complicate, ca de exemplu un element dintr-un tablou de
referine.
n cazul n care avem o variabil static, aceasta poate fi accesat i fr s deinem o referin ctre
o instan a clasei. Sintaxa este, n acest caz:
NumeClas.NumeVariabil

Vizibilitate
O variabil poate fi ascuns de declaraia unei alte variabile cu acelai nume. De exemplu,
dac ntr-o clas avem declarat o variabil cu numele unu i ntr-o subclas a acesteia avem
declarat o variabil cu acelai nume, atunci variabila din superclas este ascuns de cea din clas.
Totui, variabila din superclas exist nc i poate fi accesat n mod explicit. Expresia de referire
este, n acest caz:
NumeSuperClas.NumeVariabil
sau
super.NumeVariabil

n cazul n care superclasa este imediat.


La fel, o variabil a unei clase poate fi ascuns de o declaraie de variabil dintr-un bloc de
instruciuni. Orice referin la ea va trebui fcut n mod explicit. Expresia de referire este, n acest
caz:
this.NumeVariabil

Variabile predefinite: this i super


n interiorul fiecrei metode non-statice dintr-o clas exist predefinite dou variabile cu
semnificaie special. Cele dou variabile sunt de tip referin i au aceeai valoare i anume o
referin ctre obiectul curent. Diferena dintre ele este tipul.
Prima dintre acestea este variabila this care are tipul referin ctre clasa n interiorul
creia apare metoda. A doua este variabila super al crei tip este o referin ctre superclasa
imediat a clasei n care apare metoda. n interiorul obiectelor din clasa Object nu se poate folosi
referina super pentru c nu exist nici o superclas a clasei de obiecte Object.
n cazul n care super este folosit la apelul unui constructor sau al unei metode, ea acioneaz ca
un cast ctre superclasa imediat.

Metodele unei clase


Fiecare clas i poate defini propriile sale metode pe lng metodele pe care le motenete
de la superclasa sa. Aceste metode definesc operaiile care pot fi executate cu obiectul respectiv. n
cazul n care una dintre metodele motenite nu are o implementare corespunztoare n superclas,
clasa i poate redefini metoda dup cum dorete.
n plus, o clas i poate defini metode de construcie a obiectelor i metode de eliberare a
acestora. Metodele de construcie sunt apelate ori de cte ori este alocat un nou obiect din clasa
respectiv. Putem declara mai multe metode de construcie, ele diferind prin parametrii din care
trebuie construit obiectul.
Metodele de eliberare a obiectului sunt cele care elibereaz resursele ocupate de obiect n
momentul n care acesta este distrus de ctre mecanismul automat de colectare de gunoaie. Fiecare
clas are o singur metod de eliberare, numit i finalizator. Apelarea acestei metode se face de
ctre sistem i nu exist nici o cale de control al momentului n care se produce acest apel.

Declararea metodelor
Pentru a declara o metod, este necesar s declarm numele acesteia, tipul de valoare pe care
o ntoarce, parametrii metodei precum i un bloc n care s descriem instruciunile care trebuiesc
executate atunci cnd metoda este apelat. n plus, orice metod are un numr de modificatori care
descriu proprietile metodei i modul de lucru al acesteia.
Declararea precum i implementarea metodelor se face ntotdeauna n interiorul declaraiei
de clas. Nu exist nici o cale prin care s putem scrie o parte dintre metodele unei clase ntr-un
fiier separat care s fac referin apoi la declaraia clasei.
n form general, declaraia unei metode arat n felul urmtor:
[Modificator] TipRezultat Declaraie [ClauzeThrows] CorpulMetodei
Modificatorii precum i clauzele throws pot s lipseasc.
Numele i parametrii metodelor

Recunoaterea unei anumite metode se face dup numele i tipul parametrilor si. Pot exista
metode cu acelai nume dar avnd parametri diferii. Acest fenomen poart numele de
suprancrcarea numelui unei metode.
Numele metodei este un identificator Java. Avem toat libertatea n a alege numele pe care l
dorim pentru metodele noastre, dar n general este preferabil s alegem nume care sugereaz
utilizarea metodei.
Numele unei metode ncepe de obicei cu liter mic. Dac acesta este format din mai multe
cuvinte, litera de nceput a fiecrui cuvnt va fi majuscul. n acest mod numele unei metode este
foarte uor de citit i de depistat n surs.
Parametrii metodei sunt n realitate nite variabile care sunt iniializate n momentul apelului
cu valori care controleaz modul ulterior de execuie. Aceste variabile exist pe toat perioada
execuiei metodei. Se pot scrie metode care s nu aib nici un parametru.
Fiind o variabil, fiecare parametru are un tip i un nume. Numele trebuie s fie un
identificator Java. Dei avem libertatea s alegem orice nume dorim, din nou este preferabil s
alegem nume care s sugereze scopul la care va fi utilizat parametrul respectiv.
Tipul unui parametru este oricare dintre tipurile valide n Java. Acestea poate fi fie un tip
primitiv, fie un tip referin ctre obiect, interfa sau tablou.
n momentul apelului unei metode, compilatorul ncearc s gseasc o metod n interiorul
clasei care s aib acelai nume cu cel apelat i acelai numr de parametri ca i apelul. Mai mult,
tipurile parametrilor de apel trebuie s corespund cu tipurile parametrilor declarai ai metodei
gsite sau s poat fi convertii la acetia.

Dac o astfel de metod este gsit n declaraia clasei sau n superclasele acesteia,
parametrii de apel sunt convertii ctre tipurile declarate i se genereaz apelul ctre metoda
respectiv.
Este o eroare de compilare s declarm dou metode cu acelai nume, acelai numr de
parametri i acelai tip pentru parametrii corespunztori. ntr-o asemenea situaie, compilatorul n-ar
mai ti care metod trebuie apelat la un moment dat.
De asemenea, este o eroare de compilare s existe dou metode care se potrivesc la acelai
apel. Acest lucru se ntmpl cnd nici una dintre metodele existente nu se potrivete exact i cnd
exist dou metode cu acelai nume i acelai numr de parametri i, n plus, parametrii de apel se
pot converti ctre parametrii declarai ai ambelor metode.
Rezolvarea unei astfel de probleme se face prin conversia explicit (cast) de ctre
programator a valorilor de apel spre tipurile exacte ale parametrilor metodei pe care dorim s o
apelm n realitate.
n fine, forma general de declaraie a numelui i parametrilor unei metode este:
NumeMetod( [TipParametru NumeParametru] [,TipParametru NumeParametru] )
Modificatori de metode

Modificatorii sunt cuvinte cheie ale limbajului Java care specific proprieti suplimentare
pentru o metod. Iat lista complet a acestora n cazul metodelor:
static - pentru metodele statice
abstract - pentru metodele abstracte
final - pentru metodele finale
native - pentru metodele native
synchronized - pentru metodele sincronizate
Metode statice
n mod normal, o metod a unei clase se poate apela numai printr-o instan a clasei
respective sau printr-o instan a unei subclase. Acest lucru se datoreaz faptului c metoda face
apel la o serie de variabile ale clasei care sunt memorate n interiorul instanei i care au valori
diferite n instane diferite. Astfel de metode se numesc metode ale instanelor clasei.
Dup cum tim deja, exist i un alt tip de variabile, i anume variabilele de clas sau
variabilele statice care sunt comune tuturor instanelor clasei respective i exist pe toat perioada
de timp n care clasa este ncrcat n memorie. Aceste variabile pot fi accesate fr s avem nevoie
de o instan a clasei respective.
n mod similar exist i metode statice. Aceste metode nu au nevoie de o instan a clasei
sau a unei subclase pentru a putea fi apelate pentru c ele nu au voie s foloseasc variabile care
sunt memorate n interiorul instanelor. n schimb, aceste metode pot s foloseasc variabilele
statice declarate n interiorul clasei.
Orice metod static este implicit i final.
Metode abstracte
Metodele abstracte sunt metode care nu au corp de implementare. Ele sunt declarate numai
pentru a fora subclasele care vor s aib instane s implementeze metodele respective.
Metodele abstracte trebuie declarate numai n interiorul claselor care au fost declarate
abstracte. Altfel compilatorul va semnala o eroare de compilare. Orice subclas a claselor abstracte
care nu este declarat abstract trebuie s ofere o implementare a acestor metode, altfel va fi
generat o eroare de compilare.
Prin acest mecanism ne asigurm c toate instanele care pot fi convertite ctre clasa care
conine definiia unei metode abstracte au implementat metoda respectiv dar, n acelai timp, nu

este nevoie s implementm n nici un fel metoda chiar n clasa care o declar pentru c nu tim pe
moment cum va fi implementat.
O metod static nu poate fi declarat i abstract pentru c o metod static este implicit
final i nu poate fi rescris.
Metode finale
O metod final este o metod care nu poate fi rescris n subclasele clasei n care a fost
declarat. O metod este rescris ntr-o subclas dac aceasta implementeaz o metod cu acelai
nume i acelai numr i tip de parametri ca i metoda din superclas.
Declararea metodelor finale este util n primul rnd compilatorului care poate genera
metodele respective direct n codul rezultat fiind sigur c metoda nu va avea nici o alt
implementare n subclase.
Metode native
Metodele native sunt metode care sunt implementate pe o cale specific unei anumite
platforme. De obicei aceste metode sunt implementate n C sau n limbaj de asamblare. Metoda
propriu-zis nu poate avea corp de implementare pentru c implementarea nu este fcut n Java.
n rest, metodele native sunt exact ca orice alt metod Java. Ele pot fi motenite, pot fi
statice sau nu, pot fi finale sau nu, pot s rescrie o metod din superclas i pot fi la rndul lor
rescrise n subclase.
Metode sincronizate
O metod sincronizat este o metod care conine cod critic pentru un anumit obiect sau
clas i nu poate fi rulat n paralel cu nici o alt metod critic sau cu o instruciune
synchronized referitoare la acelai obiect sau clas.
nainte de execuia metodei, obiectul sau clasa respectiv sunt blocate. La terminarea
metodei, acestea sunt deblocate.
Dac metoda este static atunci este blocat o ntreag clas, clasa din care face parte
metoda. Altfel, este blocat doar instana n contextul creia este apelat metoda.
Protejarea metodelor

Accesul la metodele unei clase este protejat n acelai fel ca i accesul la variabilele clasei.
n Java exist patru grade de protecie pentru o metod aparinnd unei clase:
privat
protejat
public
prietenoas
O metod declarat public este accesibil oriunde este accesibil numele clasei. Cuvntul
rezervat este public.
O metod declarat protejat este accesibil n orice clas din pachetul creia i aparine
clasa n care este declarat. n acelai timp, metoda este accesibil n toate subclasele clasei date,
chiar dac ele aparin altor pachete. Cuvntul rezervat este protected.
O metod declarat privat este accesibil doar n interiorul clasei n care a fost declarat.
Cuvntul rezervat este private.
O metod care nu are nici o declaraie relativ la gradul de protecie este automat o metod
prietenoas. O metod prietenoas este accesibil n pachetul din care face parte clasa n interiorul
creia a fost declarat la fel ca i o metod protejat. Dar, spre deosebire de metodele protejate, o
metod prietenoas nu este accesibil n subclasele clasei date dac aceste sunt declarate ca
aparinnd unui alt pachet. Nu exist un cuvnt rezervat pentru specificarea explicit a metodelor
prietenoase.

O metod nu poate avea declarate mai multe grade de protecie n acelai timp. O astfel de
declaraie este semnalat ca eroare de compilare.

Apelul metodelor
Pentru a apela o metod a unei clase este necesar s dispunem de o cale de acces la metoda
respectiv. n plus, trebuie s dispunem de drepturile necesare apelului metodei.
Sintaxa efectiv de acces este urmtoarea:
CaleDeAcces.Metod( Parametri )
n cazul n care metoda este static, pentru a specifica o cale de acces este suficient s
furnizm numele clasei n care a fost declarat metoda. Accesul la numele clasei se poate obine fie
importnd clasa sau ntreg pachetul din care face parte clasa fie specificnd n clar numele clasei i
drumul de acces ctre aceasta.
De exemplu, pentru a accesa metoda random definit static n clasa Math aparinnd pachetului
java.lang putem scrie:
double aleator = Math.random();

sau, alternativ:
double aleator = java.lang.Math.random();

n cazul claselor definite n pachetul java.lang nu este necesar nici un import pentru c
acestea sunt implicit importate de ctre compilator.
Cea de-a doua cale de acces este existena unei instane a clasei respective. Prin aceast
instan putem accesa metodele care nu sunt declarate statice, numite uneori i metode ale
instanelor clasei. Aceste metode au nevoie de o instan a clasei pentru a putea lucra, pentru c
folosesc variabile non-statice ale clasei sau apeleaz alte metode non-statice. Metodele primesc
acest obiect ca pe un parametru ascuns.
De exemplu, avnd o instan a clasei Object sau a unei subclase a acesteia, putem obine o
reprezentare sub form de ir de caractere prin:
Object obiect = new Object();
String sir = obiect.toString();

n cazul n care apelm o metod a clasei din care face parte i metoda apelant putem s
renunm la calea de acces n cazul metodelor statice, scriind doar numele metodei i parametrii.
Pentru metodele specifice instanelor, putem renuna la calea de acces, dar n acest caz metoda
acceseaz aceeai instan ca i metoda apelant. n cazul n care metoda apelant este static,
specificarea unei instane este obligatorie n cazul metodelor de instan.
Parametrii de apel servesc mpreun cu numele la identificarea metodei pe care dorim s o
apelm. nainte de a fi transmii, acetia sunt convertii ctre tipurile declarate de parametri ai
metodei, dup cum este descris mai sus.
Specificarea parametrilor de apel se face separndu-i prin virgul. Dup ultimul parametru nu se
mai pune virgul. Dac metoda nu are nici un parametru, parantezele rotunde sunt n continuare
necesare. Exemple de apel de metode cu parametri:
String numar = String.valueOf( 12 );
// 12 -> String
double valoare = Math.abs( 12.54 );
// valoare absolut
String prima = numar.substring( 0, 1 );
// prima litera

Valoarea de retur a unei metode


O metod trebuie s-i declare tipul valorii pe care o ntoarce. n cazul n care metoda dorete s
specifice explicit c nu ntoarce nici o valoare, ea trebuie s declare ca tip de retur tipul void ca n
exemplul:

void a() { }

n caz general, o metod ntoarce o valoare primitiv sau un tip referin. Putem declara acest tip ca
n:
long abs( int valoare ) { }

Pentru a returna o valoare ca rezultat al execuiei unei metode, trebuie s folosim instruciunea
return, aa cum s-a artat n seciunea dedicat instruciunilor. Instruciunea return trebuie s
conin o expresie a crei valoare s poat fi convertit la tipul declarat al valorii de retur a metodei.
De exemplu:
long abs( int valoare ) {
return Math.abs( valoare );
}

Metoda static abs din clasa Math care primete un parametru ntreg returneaz tot un ntreg. n
exemplul nostru, instruciunea return este corect pentru c exist o cale de conversie de la ntreg
la ntreg lung, conversie care este apelat automat de compilator nainte de ieirea din metod.
n schimb, n exemplul urmtor:
int abs( long valoare ) {
return Math.abs( valoare );
}

compilatorul va genera o eroare de compilare pentru c metoda static abs din clasa Math care
primete ca parametru un ntreg lung ntoarce tot un ntreg lung, iar un ntreg lung nu poate fi
convertit sigur la un ntreg normal pentru c exist riscul deteriorrii valorii, la fel ca la atribuire.
Rezolvarea trebuie s conin un cast explicit:
int abs( long valoare ) {
return ( int )Math.abs( valoare );
}

n cazul n care o metod este declarat void, putem s ne ntoarcem din ea folosind instruciunea
return fr nici o expresie. De exemplu:
void metoda() {

if( )
return;

Specificarea unei expresii n acest caz duce la o eroare de compilare. La fel i n cazul n care
folosim instruciunea return fr nici o expresie n interiorul unei metode care nu este declarat
void.

Vizibilitate
O metod este vizibil dac este declarat n clasa prin care este apelat sau ntr-una din
superclasele acesteia. De exemplu, dac avem urmtoarea declaraie:
class A {

void a() { }
}
class B extends A {
void b() {
a();
c();

}
void c() { .. }

Apelul metodei a n interiorul metodei b din clasa B este permis pentru c metoda a este declarat n
interiorul clasei A care este superclas pentru clasa B. Apelul metodei c n aceeai metod b este
permis pentru c metoda c este declarat n aceeai clas ca i metoda b.
Uneori, o subclas rescrie o metod dintr-o superclas a sa. n acest caz, apelul metodei
respective n interiorul subclasei duce automat la apelul metodei din subclas. Dac totui dorim s
apelm metoda aa cum a fost ea definit n superclas, putem prefixa apelul cu numele superclasei.
De exemplu:
class A {

void a() { }
}
class B extends A {
void a() { .. }
void c() {
a();// metoda a din clasa B
A.a();// metoda a din clasa A

Iniializatori statici
La ncrcarea unei clase sunt automat iniializate toate variabilele statice declarate n
interiorul clasei. n plus, sunt apelai toi iniializatorii statici ai clasei.
Un iniializator static are urmtoarea sintax:
static

BlocDeInstruciuni

Blocul de instruciuni este executat automat la ncrcarea clasei. De exemplu, putem defini
un iniializator static n felul urmtor:
class A {
static double a;
static int b;
static {
a = Math.random();
// numr dublu ntre 0.0 i 1.0
b = ( int )( a * 500 );
// numr ntreg ntre 0 i 500
}

Declaraiile de variabile statice i iniializatorii statici sunt executate n ordinea n care apar n clas.
De exemplu, dac avem urmtoarea declaraie de clas:
class A {
static int i = 11;
static {
i += 100;
i %= 55;
}
static int j = i + 1;
}

valoarea final a lui i va fi 1 ( ( 11 + 100 ) % 55 ) iar valoarea lui j va fi 2.

Constructori i finalizatori
constructori
La crearea unei noi instane a unei clase sistemul aloc automat memoria necesar instanei
i o iniializeaz cu valorile iniiale specificate sau implicite. Dac dorim s facem iniializri
suplimentare n interiorul acestei memorii sau n alt parte putem descrie metode speciale numite
constructori ai clasei.
Putem avea mai muli constructori pentru aceeai clas, acetia diferind doar prin parametrii
pe care i primesc. Numele tuturor constructorilor este acelai i este identic cu numele clasei.
Declaraia unui constructor este asemntoare cu declaraia unei metode oarecare, cu
diferena c nu putem specifica o valoare de retur i nu putem specifica nici un fel de modificatori.
Dac dorim s returnm dintr-un constructor, trebuie s folosim instruciunea return fr nici o
expresie. Putem ns s specificm gradul de protecie al unui constructor ca fiind public, privat,
protejat sau prietenos.
Constructorii pot avea clauze throws.
Dac o clas nu are constructori, compilatorul va crea automat un constructor implicit care
nu ia nici un parametru i care iniializeaz toate variabilele clasei i apeleaz constructorul
superclasei fr argumente prin super( ). Dac superclasa nu are un constructor care ia zero
argumente, se va genera o eroare de compilare.
Dac o clas are cel puin un constructor, constructorul implicit nu mai este creat de ctre
compilator.
Cnd construim corpul unui constructor avem posibilitatea de a apela, pe prima linie a
blocului de instruciuni care reprezint corpul constructorului, un constructor explicit. Constructorul
explicit poate avea dou forme:
this(

[Parametri] );

super(

[Parametri] );

Cu aceast sintax apelm unul dintre constructorii superclasei sau unul dintre ceilali constructori
din aceeai clas. Aceste linii nu pot aprea dect pe prima poziie n corpul constructorului. Dac
nu apar acolo, compilatorul consider implicit c prima instruciune din corpul constructorului este:
super();

i n acest caz se va genera o eroare de compilare dac nu exist un constructor n


superclas care s lucreze fr nici un parametru.
Dup apelul explicit al unui constructor din superclas cu sintaxa super( ) este executat
n mod implicit iniializarea tuturor variabilelor de instan (non-statice) care au iniializatori
explicii. Dup apelul unui constructor din aceeai clas cu sintaxa this( ) nu exist nici o alt
aciune implicit, deci nu vor fi iniializate nici un fel de variabile. Aceasta datorit faptului c
iniializarea s-a produs deja n constructorul apelat.
Exemplu:
class A extends B {
String valoare;
A( String val ) {
// aici exist apel implicit
// al lui super(), adic B()
valoare = val;
}
A( int val ) {
this( String.valueOf( val ) );// alt constructor
}
}

Finalizatori
n Java nu este nevoie s apelm n mod explicit distrugerea unei instane atunci cnd nu
mai este nevoie de ea. Sistemul ofer un mecanism de colectare a gunoaielor care recunoate
situaia n care o instan de obiect sau un tablou nu mai sunt referite de nimeni i le distruge n mod
automat.
Acest mecanism de colectare a gunoaielor ruleaz pe un fir de execuie separat, de prioritate
mic. Nu avem nici o posibilitate s aflm exact care este momentul n care va fi distrus o instan.
Totui, putem specifica o funcie care s fie apelat automat n momentul n care colectorul de
gunoaie ncearc s distrug obiectul.
Aceast funcie are nume, numr de parametri i tip de valoare de retur fixe:
void

finalize()

Dup apelul metodei de finalizare (numit i finalizator), instana nu este nc distrus pn


la o nou verificare din partea colectorului de gunoaie. Aceast comportare este necesar pentru c
instana poate fi revitalizat prin crearea unei referine ctre ea n interiorul finalizatorului.
Totui, finalizatorul nu este apelat dect o singur dat. Dac obiectul revitalizat redevine candidat
la colectorul de gunoaie, acesta este distrus fr a i se mai apela finalizatorul. Cu alte cuvinte, un
obiect nu poate fi revitalizat dect o singur dat.
Dac n timpul finalizrii apare o excepie, ea este ignorat i finalizatorul nu va mai fi apelat din
nou.

Crearea instanelor
O instan este creat folosind o expresie de alocare care folosete cuvntul rezervat new. Iat care
sunt paii care sunt executai la apelul acestei expresii:
Se creeaz o nou instan de tipul specificat. Toate variabilele instanei sunt iniializate pe
valorile lor implicite.
Se apeleaz constructorul corespunztor n funcie de parametrii care sunt transmii n
expresia de alocare. Dac instana este creat prin apelul metodei newInstance, se
apeleaz constructorul care nu ia nici un argument.
Dup creare, expresia de alocare returneaz o referin ctre instana nou creat.
Exemple de creare:
A o1 = new A();
B o2 = new B();
class C extends B {
String valoare;
C( String val ) {
// aici exist apel implicit
// al lui super(), adic B()
valoare = val;
}
C( int val ) {
this( String.valueOf( val ) );
}
}
C o3 = new C( "Vasile" );
C o4 = new C( 13 );

O alt cale de creare a unui obiect este apelul metodei newInstance declarate n clasa Class.
Iat paii de creare n acest caz:
Se creeaz o nou instan de acelai tip cu tipul clasei pentru care a fost apelat metoda
newInstance. Toate variabilele instanei sunt iniializate pe valorile lor implicite.
Este apelat constructorul obiectului care nu ia nici un argument.

Dup creare referina ctre obiectul nou creat este returnat ca valoare a metodei
newInstance. Tipul acestei referine va fi Object n timpul compilrii i tipul clasei reale n
timpul execuiei.

Derivarea claselor
O clas poate fi derivat dintr-alta prin folosirea n declaraia clasei derivate a clauzei
extends. Clasa din care se deriv noua clas se numete superclas imediat a clasei derivate.
Toate clasele care sunt superclase ale superclasei imediate ale unei clase sunt superclase i pentru
clasa dat. Clasa nou derivat se numete subclas a clasei din care este derivat.
Sintaxa general este:
class

SubClas extends SuperClas

O clas poate fi derivat dintr-o singur alt clas, cu alte cuvinte o clas poate avea o singur
superclas imediat.
Clasa derivat motenete toate variabilele i metodele superclasei sale. Totui, ea nu poate accesa
dect acele variabile i metode care nu sunt declarate private.
Putem rescrie o metod a superclasei declarnd o metod n noua clas avnd acelai nume i
aceiai parametri. La fel, putem declara o variabil care are acelai nume cu o variabil din
superclas. n acest caz, noul nume ascunde vechea variabil, substituindu-i-se. Putem n continuare
s ne referim la variabila ascuns din superclas specificnd numele superclasei sau folosindu-ne de
variabila super.
Exemplu:
class A {
int a = 1;
void unu() {
System.out.println( a );
}
}
class B extends A {
double a = Math.PI;
void unu() {
System.out.println( a );
}
void doi() {
System.out.println( A.a );
}
void trei() {
unu();
super.unu();
}
}
Dac apelm metoda unu din clasa A, aceasta va afia la consol numrul 1.

Dac apelm metoda unu din clasa B, aceasta va afia la consol numrul PI. Apelul l putem face
de exemplu cu instruciunea:
B obiect = new B();
obiect.unu();

Observai c n metoda unu din clasa B, variabila referit este variabila a din clasa B. Variabila a
din clasa A este ascuns. Putem ns s o referim prin sintaxa A.a ca n metoda doi din clasa B.
n interiorul clasei B, apelul metodei unu fr nici o alt specificaie duce automat la apelul metodei
unu definite n interiorul clasei B. Metoda unu din clasa B rescrie metoda unu din clasa A. Vechea
metod este accesibil pentru a o referi n mod explicit ca n metoda trei din clasa B. Apelul acestei
metode va afia mai nti numrul PI i apoi numrul 1.

Dac avem declarat o variabil de tip referin ctre o instan a clasei A, aceast variabil poate s
conin n timpul execuiei i o referin ctre o instan a clasei B. Invers, afirmaia nu este
valabil.
n clipa n care apelm metoda unu pentru o variabil referin ctre clasa A, sistemul va apela
metoda unu a clasei A sau B n funcie de adevratul tip al referinei din timpul execuiei. Cu alte
cuvinte, urmtoarea secven de instruciuni:
A tablou[] = new A[2];
tablou[0] = new A();
tablou[1] = new B();
for( int i = 0; i < 2; i++ ) {
tablou[i].unu();
}

va afia dou numere diferite, mai nti 1 i apoi PI. Aceasta din cauz c cel de-al doilea element
din tablou este, n timpul execuiei, de tip referin la o instan a clasei B chiar dac la compilare
este de tipul referin la o instan a clasei A.
Acest mecanism se numete legare trzie, i nseamn c metoda care va fi efectiv apelat este
stabilit doar n timpul execuiei i nu la compilare.
Dac nu declarm nici o superclas n definiia unei clase, atunci se consider automat c noua clas
deriv direct din clasa Object, motenind toate metodele i variabilele acesteia.

Interfee
O interfa este n esen o declaraie de tip ce const dintr-un set de metode i constante
pentru care nu s-a specificat nici o implementare. Programele Java folosesc interfeele pentru a
suplini lipsa motenirii multiple, adic a claselor de obiecte care deriv din dou sau mai multe alte
clase.
Sintaxa de declaraie a unei interfee este urmtoarea:
Modificatori interface NumeInterf [ extends [Interfa][, Interfa]]
Corp
Modificatorii unei interfee pot fi doar cuvintele rezervate public i abstract. O
interfa care este public poate fi accesat i de ctre alte pachete dect cel care o definete. n
plus, fiecare interfa este n mod implicit abstract. Modificatorul abstract este permis dar nu
obligatoriu.
Numele interfeelor trebuie s fie identificatori Java. Conveniile de numire a interfeelor le urmeaz
n general pe cele de numire a claselor de obiecte.
Interfeele, la fel ca i clasele de obiecte, pot avea subinterfee. Subinterfeele motenesc toate
constantele i declaraiile de metode ale interfeei din care deriv i pot defini n plus noi elemente.
Pentru a defini o subinterfa, folosim o clauz extends. Aceste clauze specific superinterfaa
unei interfee. O interfa poate avea mai multe superinterfee care se declar separate prin virgul
dup cuvntul rezervat extends. Circularitatea definiiei subinterfeelor nu este permis.
n cazul interfeelor nu exist o rdcin comun a arborelui de derivare aa cum exist pentru
arborele de clase, clasa Object.
n corpul unei declaraii de interfa pot s apar declaraii de variabile i declaraii de
metode. Variabilele sunt implicit statice i finale. Din cauza faptului c variabilele sunt finale, este
obligatoriu s fie specificat o valoare iniial pentru aceste variabile. n plus, aceast valoare
iniial trebuie s fie constant (s nu depind de alte variabile).
Dac interfaa este declarat public, toate variabilele din corpul su sunt implicit declarate
publice.

n ceea ce privete metodele declarate n interiorul corpului unei interfee, acestea sunt
implicit declarate abstracte. n plus, dac interfaa este declarat public, metodele din interior sunt
implicit declarate publice.
Iat un exemplu de declaraii de interfee:
public interface ObiectSpatial {
final int CUB = 0;
final int SFERA = 1;
double greutate();
double volum();
double raza();
int tip();
}
public interface ObiectSpatioTemporal extends ObiectSpatial {
void centrulDeGreutate( long moment, double coordonate[] );
long momentInitial();
long momentFinal();
}

Cele dou interfee definesc comportamentul unui obiect spaial respectiv al unui obiect
spaio-temporal. Un obiect spaial are o greutate, un volum i o raz a sferei minime n care se poate
nscrie.
n plus, putem defini tipul unui obiect folosindu-ne de o serie de valori constante
predefinite precum ar fi SFERA sau CUB.
Un obiect spaio-temporal este un obiect spaial care are n plus o poziie pe axa timpului.
Pentru un astfel de obiect, n afar de proprietile deja descrise pentru obiectele spaiale, trebuie s
avem n plus un moment iniial, de apariie, pe axa timpului i un moment final. Obiectul nostru nu
exist n afara acestui interval de timp. n plus, pentru un astfel de obiect putem afla poziia
centrului su de greutate n fiecare moment aflat n intervalul de existen.
Pentru a putea lucra cu obiecte spaiale i spaio-temporale este nevoie s definim diverse
clase care s implementeze aceste interfee. Acest lucru se face specificnd clauza implements n
declaraia de clas. O clas poate implementa mai multe interfee. Dac o clas declar c
implementeaz o anumit interfa, ea este obligatoriu s implementeze toate metodele declarate n
interfaa respectiv.
De exemplu, putem spune c o minge este un obiect spaial de tip sfer. n plus, mingea are
o poziie n funcie de timp i un interval de existen. Cu alte cuvinte, mingea este chiar un obiect
spaio-temporal. Desigur, n afar de proprietile spaio-temporale mingea mai are i alte
proprieti precum culoarea, proprietarul sau preul de cumprare.
Iat cum ar putea arta definiia clasei de obiecte de tip minge:
import java.awt.Color;
class Minge extends Jucarie implements ObiectSpatioTemporal
int culoare = Color.red;
double pret = 10000.0;
double raza = 0.25;
long nastere;
long moarte;
// metodele din ObiectSpatial
double greutate() {
return raza * 0.5;
}
double raza() {
return raza;
}
double volum() {
return ( 4.0 / 3.0 ) * Math.PI * raza * raza * raza;
}
int tip() {
return SFERA;
}

// metodele din interfaa ObiectSpatioTemporal


boolean centrulDeGreutate( long moment, double coordonate[] ) {
if( moment < nastere || moment > moarte ) {
return false;
}

coordonate[0] = x;
coordonate[1] = y;
coordonate[2] = z;
return true;
}
long momentInitial() {
return nastere;
}
long momentFinal() {
return moarte;
}
int ceCuloare() {
return culoare;
}
double cePret() {
return pret;
}
}

Observai c noua clas Minge implementeaz toate metodele definite n interfaa


ObiectSpatioTemporal i, pentru c aceasta extinde interfaa ObiectSpatial, i
metodele definite n cea din urm. n plus, clasa i definete propriile metode i variabile.
S presupunem n continuare c avem i o alt clas, Rezervor, care este tot un obiect spaiotemporal, dar de form cubic. Declaraia acestei clase ar arta ca:
class Rezervor extends Constructii implements ObiectSpatioTemporal
{

Desigur, toate metodele din interfeele de mai sus trebuiesc implementate, plus alte metode
specifice.
S mai observm c cele dou obiecte deriv din clase diferite: Mingea din Jucrii iar Rezervorul
din Construcii. Dac am putea deriva o clas din dou alte clase, am putea deriva Minge din
Jucarie i ObiectSpatioTemporal iar Rezervor din Constructie i
ObiectSpaioTemporal. ntr-o astfel de situaie, nu ar mai fi necesar ca
ObiectSpaioTemporal s fie o interfa, ci ar fi suficient ca acesta s fie o alt clas.
Din pcate, n Java, o clas nu poate deriva dect dintr-o singur alt clas, aa c este obligatoriu n
astfel de situaii s folosim interfeele. Dac ObiectSpaioTemporal ar fi putut fi o clas, am
fi avut avantajul c puteam implementa acolo metodele cu funcionare identic din cele dou clase
discutate, acestea fiind automat motenite fr a mai fi nevoie de definirea lor de dou ori n fiecare
clas n parte.
Putem crea n continuare metode care s lucreze cu obiecte spaio-temporale, de exemplu o metod
care s afle distana unui corp spaio-temporal fa de un punct dat la momentul su iniial. O astfel
de metod se poate scrie o singur dat, i poate lucra cu toate clasele care implementeaz interfaa
noastr. De exemplu:

double distanta( double punct[], ObiectSpatioTemporal obiect ) {


double coordonate[] = new double[3];
obiect.centrulDeGreutate( obiect.momentInitial(),coordonate );
double x = coordonate[0] - punct[0];
double y = coordonate[1] - punct[1];
double z = coordonate[2] - punct[2];

return Math.sqrt( x * x + y * y + z * z );
}

Putem apela metoda att cu un obiect din clasa Minge ct i cu un obiect din clasa Rezervor.
Compilatorul nu se va plnge pentru c el tie c ambele clase implementeaz interfaa
ObiectSpaioTemporal, aa c metodele apelate n interiorul calculului distanei
(momentInitial i centruDeGreutate) sunt cu siguran implementate n ambele clase. Deci, putem
scrie:
Minge minge;
Rezervor rezervor;
double punct[] = { 10.0, 45.0, 23.0 };
distana( punct, minge );
distana( punct, rezervor );

Desigur, n mod normal ar fi trebuit s proiectm i un constructor sau mai muli care s iniializeze
obiectele noastre cu valori rezonabile. Aceti constructori ar fi stat cu siguran n definiia claselor
i nu n definiia interfeelor. Nu avem aici nici o cale de a fora definirea unui anumit constructor
cu ajutorul interfeei.

Modele de programare
Un nou limbaj de programare nu are anse s se impun fr s ofere, pe lng sintaxa propriu-zis
un set de biblioteci sau o ierarhie de clase coerent i ct mai general. Atunci cnd limbajul C a fost
prezentat pentru prima dat, mpreun cu el a fost prezentat i biblioteca standard de intrare ieire. Primul
program C pe care l-am nvat coninea deja apelul:
printf( "hello, world!" );

Limbajul Java nu face excepie de la aceast regul. Interfaa Java pentru programarea aplicaiilor
(API) ofer o ierarhie de clase care include funcionalitate pentru lucrul cu mai multe fire de execuie,
lucrul n reea, crearea interfeelor utilizator complexe, grafic, etc.
Exist mai multe moduri de a aborda scrierea unui program. Unul dintre acestea este scrierea unui
program care are iniiativa pe toat perioada rulrii. Acest tip de programe execut n permanen o
secven de cod, fie i numai o bucl de ateptare a crei condiie depinde de elemente exterioare precum ar
fi o apsare de tast sau sosirea unui pachet de date din reea.
Alternativa este aceea de a scrie programe care intr n execuie doar atunci cnd sunt generate
anumite evenimente n sistem. n clipa n care apar aceste evenimente, programul le analizeaz i execut o
secven de cod specific evenimentului respectiv. Dup execuia codului, programul se oprete din nou
pn la apariia unui nou eveniment.
Aceste dou alternative diferite de a aborda scrierea unui program i au rdcinile n moduri
diferite de lucru ale sistemelor de operare i n moduri diferite de a gndi interfaa cu utilizatorul.
Java implementeaz ambele stiluri de programe discutate mai sus. n primul caz, avem o clas de
pornire care conine o funcie public principal i care va fi lansat n execuie la apelarea programului. n
acest caz programul i controleaz complet execuia ulterioar. n termenii limbajului Java, aceasta este o
aplicaie.
n al doilea caz, codul ruleaz n interiorul unui navigator Internet. Clasa de pornire trebuie s aib
implementate metode de rspuns la anumite evenimente pe care le genereaz navigatorul, precum ar fi
iniializare, pornire, oprire, desenare, etc. Acest al doilea tip de programe Java le vom numi apleturi.
Distincia dintre cele dou moduri de organizare a codului este destul de vag, din cauz c cele
dou moduri de lucru se pot amesteca n realitate, un obiect aplet putnd fi n acelai timp lansat ca
aplicaie independent i invers. Totul depinde de metodele care au fost definite n interiorul clasei de
pornire a programului.

Aplicaii Java
Cea mai simpl aplicaie Java este declaraia unei clase de pornire coninnd o singur metod,
main, ca n exemplul urmtor:

public class HelloWorld {


public static void main( String args[] ) {
System.out.println( "Hello, world!" );
}
}

Acest exemplu definete o funcie principal care afieaz un simplu mesaj pe consola aplicaiei.
Afiarea este lsat n sarcina clasei java.lang.System care conine n interior implementarea ieirii i intrrii
standard precum i a ieirii standard de eroare sub forma unor referine ctre obiecte de tip InputStream
pentru in (intrarea standard) respectiv PrintStream pentru out i err (ieirea standard i ieirea standard de
eroare).

Numele metodei main este obligatoriu, la fel i parametrul acesteia. Atunci cnd lansm
interpretorul Java mpreun cu numele unei clase care reprezint clasa de pornire, interpretorul
caut n interiorul acestei clase definiia unei metode numite main . Aceast metod trebuie s fie
obligatoriu public i static. n acelai timp, metoda main trebuie s nu ntoarc nici un rezultat i
s accepte un singur parametru de tip tablou de iruri de caractere.
Dac interpretorul gsete aceast metod n interiorul clasei apelate, el lanseaz n execuie
metoda main. Atenie, metoda main fiind de tip static, nu poate apela dect variabile statice. De
obicei ns, metoda main nu face nimic altceva dect s-i prelucreze parametrul dup care s creeze
o serie de obiecte care vor controla execuia ulterioar a aplicaiei.
Singurul parametru al metodei main este un tablou care conine argumentele aflate pe linia
de comand n momentul apelului. Nu este necesar transmiterea numrului de argumente care au
fost gsite pe linia de comand pentru c tablourile Java conin n interior informaii relative la
numrul de elemente. Acest numr de elemente se poate obine prin accesarea variabilei length din
interiorul tabloului ca n exemplul urmtor care listeaz parametrii de pe linia de comand la
lansarea unei clase:
public class Arguments {
public static void main( String args[ ] ) {
for( int i = 0; i < args.length; i++ ) {
System.out.println( args[i] );
}
}
}
Iat un exemplu de rulare a acestei aplicaii:
>java Arguments unu doi trei
unu
doi
trei
>

Apleturi Java
Apleturile Java ruleaz ntr-un document HTML. n acest document, fiecare aplet are
rezervat o fereastr dreptunghiular prin care comunic cu utilizatorul. Dreptunghiul de ncadrare
al ferestrei este definit ntr-un tag HTML numit APPLET. Aceast fereastr este n exclusivitate la
dispoziia apletului care este responsabil de desenarea ei i de tratarea eventualelor evenimente care
se refer la ea.
mpreun cu definirea interfeei dintre apleturi i navigator, Sun a definit i o sintax
specific noului tag HTML care permite poziionarea i dimensionarea ferestrei apletului n
document precum i specificarea unor parametri care s poat altera modul de lucru al apletului.
Iat un prim exemplu de aplet:
import java.awt.Graphics;
public class HelloWorldApplet extends java.applet.Applet {
public void init() {
resize( 150,25 );
}
public void paint( Graphics g ) {
g.drawString( "Hello world!", 50, 25 );
}
}

n mod minimal, apletul nu definete dect dou metode i anume una de iniializare,
necesar pentru organizarea mediului n care ruleaz apletul i una de desenare a spaiului destinat
apletului n interiorul documentului HTML. Metoda de iniializare nu face n acest caz dect s

redimensioneze spaiul alocat n mod corespunztor necesitilor sale n timp ce metoda de desenare
afieaz n acest spaiu un mesaj de salut.
Pentru a vedea rezultatele rulrii acestui aplet trebuie s construim un document minimal HTML,
care poate s arate n felul urmtor:
<HTML>
<HEAD>
<TITLE> Hello World Applet </TITLE>
</HEAD>
<BODY>
<APPLET CODE="HelloWorldApplet.class" WIDTH=150 HEIGHT=25>
....
</APPLET>
</BODY>
</HTML>

Spre deosebire de o aplicaie normal Java, apleturile nu pot primi parametri pe linia de
comand pentru c nu exist linie de comand. Din acest motiv, trebuie s introducem parametrii
apletului n fiierul HTML. De exemplu am putea introduce, imediat dup linia de declaraie a
apletului o linie de forma:
<PARAM NAME=mesaj VALUE="Salutare, lume!">

i s modificm codul apletului dup cum urmeaz:


import java.awt.Graphics;
public class HelloWorldApplet extends java.applet.Applet {
private String sir;
public void init() {
sir=getParameter( "mesaj" );
if( sir == null ) {
sir = "Hello, World!";
}
resize( 150,25 );
}
public void paint( Graphics g ) {
g.drawString( sir, 50, 25 );
}
}

n acest mod putem s controlm la lansare iniializarea apletului. n definiia clasei Applet
exist i dou funcii care permit navigatorului regsirea unui minim de informaii despre aplet.
Aceste informaii reprezint descrierea apletului i a parametrilor acestuia. Funciile care trebuiesc
definite n noua clas derivat din Applet sunt getAppletInfo i getParameterInfo. De exemplu, putem
introduce n clasa HelloWorldApplet dou noi funcii:
public String getAppletInfo() {
return "Applet scris de XXX ";
}
public String [ ][ ] getParameterInfo( ) {
String info[ ][ ] = {
{ "Parametru", "String", "Textul de afisat" }
};
return info;
}

Execuia unui aplet este marcat de cteva evenimente importante generate de ctre
navigator. Atunci cnd navigatorul ntlnete o etichet APPLET, pornete n primul rnd
ncrcarea codului necesar rulrii apletului. Pn cnd acest cod nu a ajuns pe calculatorul client,
apletul nu poate fi pornit.
Dup ncrcarea codului, apletul este apelat pentru iniializare. Acesta este momentul n care
apletul i pregtete parametrii i obine de la sistem resursele necesare rulrii. Dup ce
iniializarea a fost terminat, navigatorul trimite ctre aplet o comand de pornire. Aceasta este
comanda care pune efectiv apletul n funciune deschiznd interaciunea cu utilizatorul.

Un aplet ruleaz atta timp ct navigatorul este activ. La schimbarea paginii curente,
apleturile din vechea pagin nu sunt distruse, dar primesc o comand de oprire temporar (pe care
de altfel pot s o ignore). La rencrcarea paginii, o alt comand de pornire este lansat spre aplet
i acest ciclu se poate relua. n sfrit, la oprirea navigatorului, apletul primete o comand de oprire
definitiv, caz n care el trebuie s elibereze toate resursele pe care le blocheaz.
Orice aplet Java reprezint, din punctul de vedere al limbajului un nou tip de obiect, derivat
din obiectul standard Applet. Atunci cnd navigatorul lanseaz un nou aplet el nu face altceva dect
s instanieze un nou obiect din aceast clas. Subrutinele care trateaz evenimentele descrise
anterior trebuiesc definite ca metode n interiorul acestui nou tip de obiecte.
n continuare, ntre dou evenimente de pornire i respectiv de oprire temporar a apletului
navigatorul transmite ctre aplet evenimente specifice oricrei interfee grafice cum ar fi
evenimentul care provoac redesenarea spaiului destinat apletului, evenimente legate de apsarea
unor taste sau a unor butoane ale mausului, etc. Ca rspuns la aceste evenimente, apletul trebuie s
reacioneze schimbnd coninutul ferestrei, lansnd mesaje sonore, etc. Iat i un exemplu de aplet
care ne arat fazele prin care trece un aplet n timpul existenei sale:
import java.applet.Applet;
import java.awt.*;
public class Evenimente extends Applet {
public void init() {
// metoda de iniializare
// este apelat la construcia noii instane de aplet
System.out.println("init");
}
public void paint(Graphics g) {
// metoda de desenare
// este apelat ori de cte ori este necesar
// redesenarea ferestrei apletului
System.out.println("paint");
}
public void start() {
// metoda de lansare in execuie
// este apelat la pornire
//sau la rentoarcerea n pagina apletului
System.out.println("start");
}
public void stop() {
// metoda de oprire temporar a execuiei
System.out.println( "stop" );
}
public void destroy() {
// metoda de oprire definitiv
System.out.println("destroy");
}
public void update(Graphics g) {
// metoda de actualizare a ferestrei apletului
// este apelata atunci cnd nu este necesar redesenarea
// ntregii ferestre. n mod implicit,
// metoda apeleaz metoda paint.
System.out.println("update");
}
public boolean mouseUp(Event e, int x, int y) {

// S-a ridicat butonul mouse-lui n fereastra apletului.


System.out.println("mouseUp");
return false;
}
public boolean mouseDown(Event e, int x, int y) {
// S-a apsat butonul mouse-lui n fereastra apletului
System.out.println("mouseDown");
return false;
}
public boolean mouseDrag(Event e, int x, int y) {
// S-a micat mouse-ul n fereastra apletului
// cu butonul apsat
System.out.println("mouseDrag");
return false;
}
public boolean mouseMove(Event e, int x, int y) {
// S-a micat mouse-ul n fereastra apletului
System.out.println("mouseMove");
return false;
}
public boolean mouseEnter(Event e, int x, int y) {
// Mouse-ul a ptruns n fereastra apletului
System.out.println("mouseEnter");
return false;
}
public boolean mouseExit(Event e, int x, int y) {
// mouse-ul a ieit din fereastra apletului
System.out.println("mouseExit");
return false;
}
public void gotFocus() {
// Fereastra apletului a devenit fereastra activ
System.out.println("gotFocus");
}
public void lostFocus() {
// Fereastra apletului nu mai este fereastra activa
System.out.println("lostFocus");
}
public boolean keyDown(Event e, int x) {
// S-a apsat o tasta i aceasta
// este destinata apletului
System.out.println("keyDown");
return true;
}
}

Putei rula apletul de mai sus pentru a vedea care este ordinea n care sunt apelate aceste
metode de ctre navigator. Apletul de mai sus produce ieiri la consol (o fereastr text) i nu n
fereastra apletului. Dac nu vedei consola, ncercai s cutai prin meniurile navigatorului opiunea
de afiare a consolei Java.
Din cele spuse pn acum se poate deduce c apleturile Java nu au o via proprie, ele fiind
doar apelate din cnd n cnd de navigator. Ceea ce nu este ntocmai adevrat pentru c biblioteca

standard de clase Java ofer suport pentru aplicaii care folosesc mai multe fire de execuie.
Apleturile pot astfel crea fire de execuie care s lucreze independent fa de navigator.

Eticheta (tagul) APPLET


Descrierea tagului pe care Sun l-a definit pentru introducerea unui aplet ntr-un document
HTML este urmtoarea.
< APPLET
[CODEBASE = codebaseURL]
CODE = appletFile
[ALT = alternateText]
[NAME = appletInstanceName]
WIDTH = pixels
HEIGHT = pixels
[ALIGN = alignment]
[VSPACE = pixels]
[HSPACE = pixels]
>
[< PARAM NAME = appletParameter1 VALUE = value >]
[< PARAM NAME = appletParameter2 VALUE = value >]
...
[alternateHTML]
</APPLET>

CODEBASE = codebaseURL
Acest atribut opional specific URL-ul de baz al appletului directorul (folderul) care
conine codul apletului. Dac acest atribut nu este utilizat atunci se consider directorul
curent al documentului html.
CODE = appletFile
Acest atribut este obligatoriu i specific numele fiierului care conine forma compilat a
appletului (clasa). Acest atribut este relative la URL ul de baz.
Dac codul clasei este n acelai director cu documentul HTML este suficient s fie
specificat atributul CODE cu numele fiierului unde este acesta memorat. Dac este nevoie de un
director diferit, trebuie completat i atributul CODEBASE n care se menioneaz directorul. De
exemplu, dac fiierele .class sunt ntr-un subdirector numit /clase al directorului care conine
documentul HTML, atunci exemplul de mai sus devine:
<APPLET CODE="HelloWorldApplet.class" CODEBASE="clase"
WIDTH=200 HEIGHT=150>
Text care apare dac navigatorul nu tie Java
</APPLET>

ALT = alternateText
Acest atribut opional specific un text care trebuie s fie afiat dac browserul nelege
atributul APPLET dar nu tie s execute appleturi Java.
NAME = appletInstanceName

Este un atribut opional care specific un nume pentru instana apletului, care face posibil
comunicarea ntre apleturile din aceeai pagin.
WIDTH = pixels
HEIGHT = pixels
Aceste dou attribute opionale specific dimensiunile (n pixeli) ale ferestrei (zonei de
afiare) ale appletului.
ALIGN = alignment
Atributul ALIGN specific modul n care fereastra destinat apletului va fi aliniat n pagin.
Valorile sale posibile sunt: LEFT, RIGHT, TOP, TEXTTOP, MIDDLE, ABSMIDDLE,
BASELINE, BOTTOM i ABSBOTTOM. Valoarea implicit este BASELINE.

LEFT, RIGHT - alinierea va fi n stnga, respectiv dreapta, textului din linie.


TOP - alinierea se va face cu elementul cel mai nalt din linie, fie el un alt aplet, o imagine
sau textul nsui.
TEXTTOP - alinierea se face cu cea mai nalt poziie ocupat de textul liniei.
ABSMIDDLE - mijlocul apletului va fi aliniat cu mijlocul elementului cel mai mare din
linie.
MIDDLE - mijlocul apletului se va alinia cu mijlocul liniei de baz a textului.
BASELINE, BOTTOM - baza apletului se va alinia cu linia de baz a textului.
ABSBOTTOM - baza apletului va fi aliniat cu elementul cel mai de jos din linie.

VSPACE = pixels
HSPACE = pixels
Atributele VSPACE i HSPACE specific, n pixeli, spaiul care desparte apletul de textul care l
nconjoar. Sunt atribute opionale.
< PARAM NAME = appletParameter1 VALUE = value >
Eticheta <PARAM> este singura modalitate prin care unui applet i se pot transmite
parametrii. Appletul preia aceti parametrii cu ajutorul metodei getParameter(), aa cum
s-a artat mai sus.
alternateHTML
Dac pagina html care conine eticheta APPLET este vizualizat cu ajutorul unui browser
care nu nelege aceast etichet, atunci browserul va ignora cele dou etichete APPLET i
TAG . Browserele compatibile Java vor ignora acest cod.
Atributele obligatorii ale acestei definiii sunt numele fiierului n care este memorat codul
i dimensiunea spaiului rezervat apletului. Minimal, tag APPLET arat n felul urmtor:
<APPLET CODE="HelloWorldApplet.class" WIDTH=200 HEIGHT=150>
Text care apare dac navigatorul nu tie Java
</APPLET>

Atributele opionale ale tagului descriu locaia de baz a codului apletului, modul de aliniere
n pagin, spaierea i eventualii parametrii care pot fi transmii apletului din interiorul
documentului HTML.

Structura programelor
Pachete de clase

Clasele Java sunt organizate pe pachete. Aceste pachete pot avea nume ierarhice. Numele de
pachete au forma urmtoare:
[NumePachet.] NumeComponentPachet
Numele de pachete i de componente ale acestora sunt identificatori Java. De obicei, aceste
nume urmeaz structura de directoare n care sunt memorate clasele compilate. Rdcina arborelui
de directoare n care sunt memorate clasele este indicat de o variabil sistem CLASSPATH. n
DOS aceasta se seteaz n felul urmtor:
set CLASSPATH=.;c:\java\lib

Din aceast rdcin, fiecare pachet are propriul director. n director exist codul binar pentru
componentele pachetului respectiv. Dac pachetul conine subpachete, atunci acestea sunt
memorate ntr-un subdirector n interiorul directorului pachetului.
Creatorii Java recomand folosirea unei reguli unice de numire a pachetelor, astfel nct s nu apar
conflicte. Convenia recomandat de ei este aceea de a folosi numele domeniului Internet aparinnd
productorului claselor. Astfel, numele de pachete ar putea arta ca n:
COM.Microsoft.OLE
COM.Apple.quicktime.v2

i aa mai departe.

Importul claselor
Este nevoie ca o clas s poat folosi obiecte aparinnd unei alte clase. Pentru aceasta,
definiia clasei respective trebuie s importe codul binar al celeilalte clase pentru a ti care sunt
variabilele i metodele clasei respective.
Importul se face cu o instruciune special:
import

numeClas ;

unde numele clasei include i pachetul din care aceasta face parte. De exemplu:
import java.awt.Graphics;
import java.applet.Applet;

Se poate importa i un pachet ntreg, adic toate clasele aparinnd acelui pachet, printr-o
instruciune de forma:
import

numePachet.*;

De exemplu:
import java.awt.*;

Fiiere surs
Codul surs Java trebuie introdus cu un editor ntr-un fiier text pe care l vom numi n
continuare fiier surs. Un fiier surs poate s conin declaraia mai multor clase i interfee, dar
doar una dintre acestea poate fi declarat public. Utilizarea celorlalte clase este limitat la fiierul
respectiv. Mai mult, nu putem avea n acelai timp o interfa public i o clas public declarate n
acelai fiier surs.
Dac dorim s nregistrm codul clasei ntr-un anumit pachet, putem s includem la nceputul
fiierului surs o declaraie de forma:

package

numePachet;

dac aceast declaraie lipsete, clasa va fi plasat n pachetul implicit, care nu are nume.
Structura general a unui fiier surs este urmtoarea:
[ DeclaraiePachet ][ InstruciuneImport ][ DeclaraieDeTip ]
unde declaraia de tip poate fi o declaraie de clas sau de interfa.

Compilare i execuie
Fiierele surs Java au obligatoriu extensia .java. Numele lor este identic cu numele clasei
sau interfeei publice declarate n interior. n urma compilrii rezult fiiere cu nume identice cu
numele claselor dar cu extensia .class indiferent dac este vorba de o clas sau o interfa. Fiierul
.class este generat n directorul local i nu direct la locaia pachetului.
Compilarea se face cu o comand de forma:
javac FiierSurs.java

Comanda aceasta, ca i celelalte descrise n acest paragraf este specific mediului de


dezvoltare Java pus la dispoziie de Sun, numit JDK (Java Development Kit). Exist ns i multe
alte medii de dezvoltare care au propriile lor compilatoare i interpretoare.
La compilare, variabila sistem CLASSPATH trebuie s fie deja setat pentru c nsui
compilatorul Java actual este scris n Java.
Pentru lansarea n execuie a unei aplicaii Java, trebuie s introducei comanda:
java NumeClas

unde numele clasei este numele aplicaiei care conine metoda main . Interpretorul va cuta un fiier
cu numele NumeClas.class i va ncerca s instanieze clasa respectiv.
Pentru lansarea unui aplet vei avea nevoie de un document HTML care conine tagul APPLET i
ca parametru al acesteia
name=NumeClas.class

La lansarea unui aplet, clasele care sunt apelate de clasa principal sunt mai nti cutate pe
sistemul pe care ruleaz navigatorul. Dac nu sunt acolo, ele vor fi transferate n reea. Asta
nseamn c transferul de cod este relativ mic, trebuie transferat doar codul specific aplicaiei.

Eticheta <OBJECT>
Eticheta <APPLET> este o extensie HTML introdus special pentru a insera programe Java n
paginile Web. In prezent exist i alte tipuri de programe care ruleaz interactiv ntr-o pagin, cum
ar fi controale ActiveX. Pentru a trata toate aceste tipuri de programe fr a fi nevoie de cte o
etichet explicit pentru fiecare, specificaia HTML a introdus i eticheta <OBJECT>.
Eticheta <OBJECT> este folosit pentru toate obiectele - programe interactive sau alte elemente
externe - care pot fi prezentate drept parte a paginii Web. Aceast etichet este suportat ncepnd
de la versiunile 4.0 ale Netscape Navigator sau Microsoft Internet Explorer. Browserele mai vechi
nu suport aceast nou etichet, aa nct n multe cazuri va trebui s folosii tot eticheta <APPLET>.
Eticheta <OBJECT> are urmtoarea form:
<OBJECT CLASSID="java:Bix.class" CODEBASE="javaclasses* HEIGHT=40 WIDTH=400>
</OBJECT>
Trecerea de la eticheta <APPLET> la <OBJECT> presupune urmtoarele modificri:
Eticheta <OBJECT> trebuie folosit n loc de <APPLET>

Atributul CODE trebuie nlocuit de CLASSID. n plus, nainte de numele clasei applet-ului
trebuie specificat "java:". De exemplu, dac applet-ul are clasa AppletJoc.class, atunci
atributul CLASSID trebuie s fie java: AppletJoc.class.
n rest, atributele (CODEBASE, HEIGHT, WIDTH, ALIGN) rmn aceleai. <OBJECT> poate folosi
i etichetele opionale <PARAM>.

Arhive Java
Modalitatea standard de amplasare a unui applet Java ntr-o pagin Web este de a folosi
etichetele <APPLET> sau <OBJECT> pentru a indica numele clasei primare a applet-ului. Se folosete
apoi un browser compatibil Java, care transfer i execut applet-ul. Orice alte clase sau fiiere
folosite de applet sunt transferate de pe serverul Web.
Problema cu rularea n acest fel a applet-urilor este c fiecare fiier de care are nevoie applet-ul - fie
acesta o alt clas extern, un fiier imagine, audio, text sau orice altceva -necesit o conexiune
separat de la browserul Web la serverul care conine fiierul. Deoarece intervalul de timp necesar
pentru a stabili conexiunea nu este neglijabil, acest lucru poate mri timpul total pentru transferul
applet-ului i al celorlalte fiiere necesare pentru rulare.
Soluia acestei probleme este crearea unui arhive Java, adic un fiier JAR. 0 arhiv Java reprezint
o colecie de clase Java i alte fiiere, mpachetat ntr-un singur fiier. Folosind o arhiv Java,
browserului i este suficient o singur conexiune la serverul Web. Reducnd numrul de fiiere
transferate de pe server, applet-ul poate fi ncrcat i rulat mai rapid. Arhivele Java pot fi i
comprimate, sczndu-le astfel dimensiunea i micorndu-se timpul de transfer - chiar dac va mai
dura puin din partea browserului s le decomprime nainte de a le rula.
Versiunile de Netscape Navigator i Microsoft Internet Explorer ncepnd cu 4.0 conin suport
pentru fiiere JAR. Pentru a crea aceste arhive, JDK conine un utilitar denumit jar, care poate
mpacheta sau despacheta fiierele n/din arhive Java. Fiierele JAR pot fi comprimate n format Zip
sau mpachetate fr a folosi comprimarea. Urmtoarea comand mpacheteaz toate clasele i
imaginile GIF dintr-un director ntr-o singur arhiv Java, denumit Animat.jar:
jar cf Animat.jar *.class *.gif
Argumentul cf specific dou opiuni n linie de comanda, care sunt folosite de programul jar.
Opiunea c indic faptul c arhiva Java trebuie creat, iar f arat c unul dintre urmtoarele
argumente din linia de comand reprezint numele fiierului arhiv.
Putei, de asemenea, aduga ntr-o arhiv Java alte fiiere, folosind o comand de genul:
jar cf Smiley.jar ShowSmiley.class ShowSmiley.html spinhead.gif
Aceasta creeaz o arhiv Java cu numele Smiley.jar, care conine trei fiiere:
ShowSmiley.class, ShowSmiley.html i spinhead.gif.
Rulnd utilitarul jar fr argumente, vei obine lista de opiuni care pot fi folosite.
Dup ce ai creat arhiva Java, n eticheta <APPLET> se folosete atributul ARCHIVE pentru a indica locul
unde se gsete arhiva. Putei folosi arhiva Java n felul urmtor:
<APPLET CODE="ShowSmiley.class" ARCHIVE="Smiley.jar" WIDTH=45 HEIGHT =42>
</APPLET>
Aceast etichet specific faptul c arhiva numit Smiley.jar conine fiierele folosite de applet.
Browserele i utilitarele de navigare care suport fiiere JAR tiu s caute n interiorul arhivelor
fiierele necesare pe timpul rulrii applet-ului.
Atenie
Cu toate c o arhiv Java poate conine fiiere clas, atributul ARCHIVE nu presupune eliminarea
atributului CODE. Pentru a o ncrca, browserul trebuie totui s tie numele clasei principale a
applet-ului.

Transferul de parametri ctre applet-uri


n aplicaiile Java putei transmite parametri metodei main ( ) specificnd argumente n linia de
comand. Apoi putei prelucra aceti parametri n corpul clasei, aplicaia comportndu-se
corespunztor argumentelor primite.
n schimb, applet-urile nu posed o linie de comand. Applet-urile pot obine diferite date de
intrare din fiierul HTML care conine eticheta <APPLET> sau <OBJECT>, folosind parametri de appleturi. Pentru a defini i a trata parametri ntr-un applet avei nevoie de dou lucruri:
etichet special de parametru n fiierul HTML
Codul din cadrul applet-ului care s trateze aceti parametri
Parametrii unui applet sunt compui din dou pri: un nume, care este ales de dumneavoastr, i o
valoare, care determin valoarea respectivului parametru. De exemplu, putei indica ntr-un applet
culoarea unui text folosind un parametru cu numele culoare i valoarea rou. Putei determina viteza
de derulare a unei animaii folosind un parametru cu numele viteza i valoarea 5.
n fiierul HTML care conine applet-ul, fiecare parametru este indicat folosind eticheta
<PARAM> , care conine dou atribute, pentru nume i valoare, denumite NAME i VALUE. Eticheta
<PARAM> se introduce ntre etichetele <APPLET> de nceput i de sfrit, ca n exemplul:
<APPLET CODE="Exemplu.class" WIDTH=100 HEIGHT=100>
<PARAM NAME=font VALUE="TimesRoman">
<PARAM NAME=dim VALUE="24">
Aici este inserat un applet Java.
</APPLET>
Acest exemplu definete doi parametri pentru applet-ul Exemplu: unul, denumit font, care are
valoarea TimesRoman, i cellalt, denumit dim, care are valoarea 24.
Folosirea etichetei <PARAM> este aceeai pentru applet-urile care folosesc eticheta <OBJECT> n loc
de <APPLET>.
Parametrii sunt transmii applet-ului la ncrcarea acestuia. n metoda init() a applet-ului putei
obine aceti parametri folosind metoda getParameter(). Aceasta preia ca argument un ir ce
reprezint numele parametrului cutat i ntoarce un ir care conine valoarea respectivului
parametru. (Ca i argumentele aplicaiilor Java, toate valorile parametrilor sunt returnate drept
iruri.) Pentru a obine valoarea parametrului font din fiierul HTML, metoda init() ar trebui s
conin ceva de genul:
String numeleFontului = getParameter("font");
Observaie
Numele parametrilor specificai n eticheta <PARAM> i numele parametrilor metodei
getParameter () trebuie s fie identice, inclusiv majusculele sau minusculele folosite. Cu alte
cuvinte, <PARAM NAME="meminescu"> este diferit de <PARAM NAME="MEminescu">. Dac
parametrii dumneavoastr nu sunt transferai corect applet-ului, asigurai-v c au folosit acelai tip
de caractere (majuscule sau minuscule) n denumirea parametrilor.
Reinei c dac parametrul ateptat nu a fost specificat in fiierul HTML, metoda getParameter() ntoarce
valoarea null. De obicei, ar trebui sa testai valoarea null a parametrului si sa oferii o valoare implicit, ca in exemplul
urmtor:

if (numeleFontului == null)
numeleFontului = "Courier";
inei minte ca metoda getParameter () returneaz iruri; dac dorii ca parametrul sa fie alt tip de
obiect sau de data, trebuie sa l convertii singur. De exemplu, sa luam fiierul HTML pentru appletul Exemplu. Pentru a trata parametrul dim si a-l atribui unei variabile ntregi, numit dimensiunea,
ai putea folosi urmtorul cod:
int dimensiunea;
String s = getParameter("dim");
if (s == null)
dimensiunea = 12;
else dimensiunea = Integer.parseInt(s);

S cream un exemplu de applet care folosete aceast tehnic. Vom crea un applet Palindrom
pentru a afia alte texte, cum ar fi ,,Dennis and Edna sinned" sau ,,No, sir, prefer prison". Numele
este transmis applet-ului printr-un parametru HTML. Proiectul va primi numele Palindrom.
import java.awt.Graphics;
import java.awt.Font;
import java.awt.Color;
public class Palindrom extends java.applet.Applet {
Font f = new Font ("TimesRoman", Font.BOLD, 36);
String palindrom;
public void paint(Graphics ecran) {
ecran.setFont(f);
ecran.setColor(Color.red);
ecran.drawString(palindrom, 5, 40);
}
public void init() {
palindrom = getParameter("palindrom");
if (palindrom == null)
palindrom = "Dennis and Edna sinned";
}
}

Fiierul HTML care va conine acest applet este urmtorul


<HTML>
<HEAD>
<TITLE>Pagina cu palindrom</TITLE>
</HEAD>
<BODY>
<P>
<APPLET CODE=Palindrom.class" WIDTH=600 HEIGHT=100>
<PARAM NAME=palindrom VALUE="No, sir, prefer prison">
Browserul dumneavoastr nu suporta Java!
</APPLET>
</BODY>
</HTML>

Remarcai eticheta <APPLET>, care desemneaz fiierul clas pentru applet i valorile pentru
lime i nlime (600, respectiv 100 de pixeli). Imediat sub aceast linie (n linia 8) se afl eticheta

<PARAM>, care este folosit pentru a transmite parametrul applet-ului. n acest exemplu, numele
parametrului este palindrom, iar valoarea sa este irul No, sir, prefer prison".
Dac nu este specificat nici o valoare pentru parametrul palindrom, textul implicit este Dennis
and Edna sinned".
Urmtorul fiier HTML nu conine nici o etichet de parametru
<HTML>
<HEAD>
<TITLE>Noua pagina cu palindrom</TITLE>
</HEAD>
<BODY>
<P>
<APPLET CODE="PalindromNou.class" WIDTH=600 HIGHT=100>
Browserul dumneavoastr nu suporta Java!
</APPLET>
</BODY>
</HTML>
Deoarece aici nu a fost specificat nici un parametru, applet-ul va folosi valoarea implicit.

Clasa Graphics
Putei s v imaginai applet-ul drept o pnz pe care se vor desfura operaii grafice. Ai
folosit deja metoda drawString () pentru a desena text ntr-un applet. Fontul i culoarea textului
au fost alese anterior desenrii textului, n acelai fel n care un artist i alege culoarea i pensula
nainte de a picta.
Textul nu este singurul lucru pe care l putei desena n fereastra unui applet. Putei desena
i linii, ovale, cercuri, arcuri, dreptunghiuri i alte poligoane.
Majoritatea principalelor operaii de desenare sunt metode definite n clasa Graphics.
ntr-un applet nu este nevoie s creai un obiect Graphics pentru a putea desena ceva aa
cum poate v mai amintii, unul dintre argumentele metodei paint () este un obiect Graphics.
Acest obiect reprezint fereastra applet-ului, iar metodele sale sunt folosite pentru a desena n
applet.
Clasa Graphics este parte a pachetului java.awt, deci toate applet-urile care deseneaz ceva
trebuie s foloseasc instruciunea import pentru a putea folosi aceast clas.

Sistemul de coordonate grafice


Ca i metoda drawString(), toate celelalte metode grafice posed argumente care indic coordonatele x,y.
Unele dintre acestea au mai multe seturi de coordonate, cum ar fi o linie, care posed un set de coordonate x,y ce
indic punctul de nceput al liniei i nc un set de coordonate x,y care corespunde punctului final al liniei.

Sistemul de coordonate Java folosete ca unitate de msur pixelul. Coordonatele


punctului de origine 0,0 sunt situate n colul din stnga - sus al ferestrei Applet. Valoarea
coordonatei x crete la dreapta originii 0,0, iar valoarea coordonatei y crete n jos. Acest lucru
difer fa de alte sisteme de coordonate, n care originea 0,0 se afl n colul din stnga -jos i
valoarea coordonatei y crete n sus.
Toate valorile de pixeli sunt ntregi - nu se pot folosi valori zecimale pentru a afia ceva
aflat ntre dou valori ntregi.

Desenarea i umplerea
Pentru majoritatea formelor pe care le desenai ntr-un applet sunt disponibile dou tipuri de metode: metode
de desenare, care deseneaz conturul formei, i metode de umplere, care umplu forma cu culoarea curent. n fiecare
tip de metod, conturul obiectului este, de asemenea, desenat cu culoarea curent.

Linii
Metoda drawLine este folosit pentru a desena o linie ntre dou puncte. Metoda primete patru
argumente: coordonatele x,y ale punctului de nceput i coordonatele x, y ale punctului final.
drawLine(x1, y1, x2, y2) ;
Aceast metod deseneaz o linie ncepnd cu punctul de coordonate (x1, y1) i pn la punctul de
coordonate (x2, y2). Grosimea liniei este de un pixel.

Dreptunghiuri
Clasa Graphics conine metode pentru dou tipuri de dreptunghiuri: dreptunghiuri normale i
dreptunghiuri cu coluri .
Ambele tipuri de dreptunghiuri pot fi desenate sub form de contur sau umplute cu culoarea curent.

Pentru a desena un dreptunghi normal se folosete metoda drawRect() pentru contururi sau
metoda fillRect() pentru forme umplute. Ambele metode preiau patru argumente:
Coordonatele x i y ale colului din stnga - sus al dreptunghiului
Limea dreptunghiului
nlimea dreptunghiului
drawRect(x,y,l,h)

Poligoane
Poligoanele pot fi desenate folosind metodele drawPolygon() i fillPolygon().
Pentru a desena un poligon avei nevoie de coordonatele x,y ale fiecrui punct care definete colurile
poligonului. Poligoanele pot fi definite drept o serie de linii conectate una cu cealalt - se deseneaz o linie de la un
punct iniial la un punct final, apoi punctul final este folosit ca punct iniial pentru o alt linie i aa mai departe.

Putei specifica aceste coordonate n dou moduri:


Ca o pereche de tablouri cu ntregi, dintre care unul pstreaz toate valorile coordonatei x i
cellalt pstreaz toate valorile coordonatei y.
Ca un obiect Polygon, creat folosind un tablou cu valori ntregi ale coordonatei x i un
tablou cu valori ntregi ale coordonatei y.
A doua metod este mai flexibil, deoarece permite adugarea individual a punctelor unui
poligon, nainte de desenarea sa.
n afar de coordonatele x i y, trebuie s specificai numrul de puncte al poligonului. Nu se
pot specifica mai multe coordonate x,y dect numrul de puncte i nici invers. n oricare din aceste
cazuri, compilatorul va semnala o eroare.
Pentru a crea un obiect polygon, primul pas const n crearea unui poligon gol, printr-o instruciune
new, ca n cazul urmtor:
Polygon polig = new Polygon();
Mai putei crea un poligon pornind de la un set de puncte, folosind tablouri cu valori ntregi.
Aceasta necesit un apel ctre constructorul Polygon (int [], int [], int), unde se specific tabloul cu

valori pentru coordonata x, tabloul cu valori pentru coordonata y i numrul de puncte (coluri). Iat
un exemplu de folosire a acestui constructor:
int x[] = { 10, 20, 30, 40, 50 };
int y[] = { 15, 25, 35, 45, 55 };
int puncte = x.length;
Polygon polig = new Polygon(x, y, puncte);
Dup ce se creeaz obiectul Polygon, se pot aduga puncte folosind metoda addpoint().
Aceasta preia ca argumente coordonatele x, y i adaug punctul n poligon. lat un exemplu:
polig.addPoint(60, 65);
Atunci cnd obiectul Polygon are toate punctele necesare, el poate fi desenat folosind una
dintre metodele drawPolygon() sau fillPolygon() . Aceste metode au drept unic argument obiectul
Polygon, ca n exemplul urmtor:
ecran.drawPolygon(polig) ;
Dac folosii metoda drawPolygon() n Java 1.02, putei nchide poligonul stabilind pentru
ultimele coordonate x,y valori identice cu primele. Altfel, poligonul va rmne deschis pe una
dintre laturi.
Metoda fillPolygon() nchide automat forma poligonal, fr a mai fi nevoie de stabilirea
coordonatelor finale.

Ovale
Metodele drawOval() i fillOval() sunt folosite pentru a desena cercuri i ovale (elipse).
Metodele preiau patru argumente:
coordonatele x, y ale ovalului
limea i nlimea ovalului, care n cazul cercurilor iau valori egale
Ovalele sunt tratate n acelai mod ca i colurile dreptunghiurilor rotunjite. Coordonata x,y va reprezenta
colul din stnga - sus al zonei n care va fi desenat ovalul, aflndu-se de fapt la stnga i mai sus dect forma oval
propriu-zis.

Arce
Un arc este o parte a unui oval, fiind implementat n Java ca o form eliptic parial desenat.

Arcele sunt desenate folosind metodele drawArc() i fillArc(), care preiau ase argumente:
coordonatele x, y ale ovalului din care face parte arcul;
limea i nlimea ovalului;
unghiul de unde se ncepe trasarea arcului;
numrul de grade al arcului. Primele patru argumente sunt aceleai ca n cazul ovalului i se
comport identic.
Unghiul de nceput al arcului ia valori ntre 0 i 359 de grade i crete n sens trigonometric (invers
acelor de ceasornic).

Copierea i tergerea
Clasa Graphics conine i cteva funcii de gen decupeaz-i-lipete (cut-and-paste),

aplicabile ferestrei Applet:


Metoda copyArea (), care copiaz o regiune dreptunghiular a ferestrei Applet ntr-o alt
regiune a ferestrei.
Metoda clearRect (), care decupeaz" o regiune dreptunghiular din fereastra Applet
Metoda copyArea () preia ase argumente:
Coordonatele x, y ale regiunii dreptunghiulare de copiat.
Limea i nlimea regiunii.
Distana pe orizontal i pe vertical, n pixeli, cu care se deplaseaz copia fa de regiunea
iniial, nainte de afiare.
Urmtoarea instruciune copiaz o regiune de 100x100 pixeli ntr-o zon aflat cu 50 de pixeli
mai la dreapta i cu 25 de pixeli mai jos:
ecran.copyArea(0, 0, 100, 100, 50, 25);
Metoda clearRect() preia aceleai patru argumente ca i metodele drawRect() sau fillRect(),
umplnd regiunea dreptunghiular astfel definit cu culoarea curent de fundal a applet-ului. Dac
dorii s tergei ntreaga fereastr Applet, putei determina mai nti dimensiunea ferestrei folosind
metoda size(). Aceasta returneaz un obiect Dimension, care posed variabilele width (lime) i
height (nlime); acestea reprezint dimensiunile applet-ului.
lat un exemplu de folosire a acestei metode:
ecran.clearRect(0, 0, size().width, size().height);

Text i fonturi
Obiectele clasei java.awt.Font sunt folosite pentru a putea utiliza metoda drawString() cu diferite fonturi.
Obiectele Font conin numele, stilul i dimensiunea n puncte a unui font. O alt clas, FontMetrics, ofer metode
pentru determinarea dimensiunilor i a caracterelor afiabile cu un anumit font, care pot fi folosite pentru lucruri cum ar
fi formatarea i centrarea textului.

Crearea obiectelor Font


Un obiect Font este creat prin apelarea constructorului su cu trei argumente:
Numele fontului
Stilul fontului
Dimensiunea n puncte a fontului
Numele poate fi denumirea unui font specific, cum ar fi Arial sau Garamond Old Style, care
va putea fi folosit dac este prezent (instalat) n sistemul pe care se ruleaz programul Java.
Exist i alte nume care pot fi folosite pentru selectarea fonturilor interne, proprii Java: TimesRoman,
Helvetica, Courier, Dialog i DialogInput.

Pot fi selectate trei stiluri de fonturi, folosind constantele Font. PLAIN, Font. BOLD i Font.
ITALIC. Aceste constante sunt ntregi i pot fi nsumate pentru a obine o combinaie de efecte.
Ultimul argument al constructorului Font () este dimensiunea fontului. Urmtoarea
instruciune creeaz un font Dialog de 24 de puncte, cu aldine cursive.
Font f = new Font("Dialog", Font.BOLD + Font.ITALIC, 24);
Desenarea caracterelor i a irurilor

Pentru a seta fontul curent se folosete metoda setFont() a clasei Graphics, mpreun cu un
obiect Font. Urmtoarea instruciune folosete un obiect Font denumit ft:
ecran.setFont(ft);
Textul poate fi afiat ntr-o fereastr Applet folosind metoda drawString(). Aceast metod folosete fontul
curent selectat; dac nu a fost selectat nici un font, este folosit unul implicit. Poate fi selectat oricnd un nou font cu
ajutorul metodei setFont ().

Urmtoarea metod paint () creeaz un nou obiect Font, stabilete fontul curent la acest
obiect, dup care afieaz irul Acesta este un font. la coordonatele 10,100.
public void paint(Graphics ecran) {
Font f = new Font("TimesRoman", Font.PLAIN, 72);
ecran.setFont(f);
ecran.drawString(Acesta este un font.", 10, 100);
}
Ultimele dou argumente ale metodei drawString () sunt coordonatele x, y. Valoarea x reprezint locul de
nceput al marginii din stnga a textului, iar y este valoarea la care se afieaz linia de baz a irului de text.

Aflarea de informaii despre un font


Clasa FontMetrics poate fi folosit pentru obinerea de informaii detaliate despre fontul
curent, cum ar fi limea sau nlimea caracterelor pe care le poate afia.
Pentru a folosi metodele clasei, trebuie mai nti creat un obiect FontMetrics prin metoda
getFontMetrics (). Metoda primete un singur argument: un obiect Font.
Tabelul prezint unele informaii pe care le putei obine despre dimensiunile fontului. Toate aceste metode
pot fi apelate pentru un obiect FontMetrics.

Tabelul Metode FontMetrics.


Nume metod

Aciune

stringWidth (String)
charWidth (char)
getHeight ()

ntoarce limea total a irului, n pixeli


ntoarce limea unui caracter dat
ntoarce nlimea total a fontului

Culori
Clasele Color i ColorSpace din pachetul java.awt pot fi folosite pentru a aduce puin
culoare n applet-urile i aplicaiile dumneavoastr. Cu ajutorul acestor clase putei stabili culorile
curente folosite n operaiile de desenare, ca i culoarea de fundal pentru un applet sau alte ferestre.
De asemenea, putei translata o culoare dintr-un sistem de descriere n altul.
n mod prestabilit, Java folosete culorile conform unui sistem de descriere denumit sRGB. n acest sistem, o
culoare este descris prin cantitatea de rou, verde i albastru pe care o conine - de aici i iniialele R(ed), G(reen) i
B(lue). Fiecare dintre aceste trei componente poate fi reprezentat ca un ntreg din gama 0-255. Negrul este 0, 0, 0 lipsa complet a tuturor componentelor rou, verde, albastru. Albul este 255, 255, 255 - valoarea maxim a tuturor

componentelor. Mai putei reprezenta valori sRGB folosind trei numere n virgul mobil, n domeniul dintre 0 i 1,0.
Folosind sRGB, Java poate reprezenta milioane de culori aflate ntre cele dou extreme.

Un sistem de descriere a culorilor mai este numit i palet sau spaiu de culori (color space),
iar sRGB este doar unul dintre acestea. Exist i CMYK, un sistem folosit de imprimante i care
descrie culorile prin procentul de Cyan (azuriu), Magenta (purpuriu), Yellow (galben) i Black
(negru) pe care l conin. Java 2 suport folosirea oricrui spaiu de culori dorii, att timp ct
folosii un obiect ColorSystem care definete respectivul sistem de descriere a culorilor. De
asemenea, putei converti culorile din sRGB n alt spaiu de culori i invers.
Reprezentarea intern a culorilor n Java folosind sRGB reprezint numai spaiul de culoare folosit n program.
Dispozitivele de ieire, cum ar fi monitoarele sau imprimantele, pot avea i ele propriile spaii de culoare.

Atunci cnd afiai sau tiprii ceva cu o anumit culoare, dispozitivul de ieire s-ar putea s nu
suporte culoarea respectiv. n acest caz, culoarea va fi nlocuit cu o alta sau cu o culoare impur
(dithered), folosit pentru a aproxima culoarea care nu este disponibil. Acest lucru se ntmpl
frecvent pe World Wide Web, cnd o culoare indisponibil este nlocuit cu una impur, care
aproximeaz culoarea lips.
Practic, culorile definite conform modelului sRGB nu vor putea fi reprezentate pe orice
dispozitiv de ieire. Dac avei nevoie de un control mai precis al culorii, putei folosi ColorSpace
sau alte clase din pachetul java.awt. color, introdus o dat cu Java 2.
Pentru majoritatea programelor, folosirea sRGB, sistemul intern de reprezentare a culorilor, va fi suficient.

Folosirea obiectelor Color


Pentru a stabili culoarea curent pentru desenare, trebuie fie s creai un obiect Color care s
reprezinte culoarea respectiv, fie s folosii una dintre culorile standard existente n clasa Color.
Pentru a crea o culoare, exist dou metode de apelare a metodei constructor Color;
Folosirea a trei ntregi care s reprezinte valorile sRGB pentru culoarea dorit
Folosirea a trei numere n virgul mobil, care s reprezinte valorile sRGB pentru culoarea
dorit
Putei defini deci valoarea sRGB a culorii folosind fie trei variabile int, fie trei variabile float.
lat un exemplu de instruciuni de acest gen:
Color c1 = new Color(0.807F, 1F, OF);
Color c2 = new Color(255, 204, 102);
Obiectul c1 definete o culoare verde-neon, iar c2 o culoare maro-aurie

Testarea i stabilirea culorilor curente


Culoarea curent pentru desenare este desemnat folosind metoda setColor() a clasei
Graphics. Aceast metod trebuie apelat pentru obiectul Graphics care reprezint zona n care
desenai. ntr-un applet, acest obiect este cel transmis metodei paint ().
O modalitate de a stabili culoarea de desenare este folosirea uneia dintre culorile standard,
disponibile ca variabil de clas n clasa Color.
Aceste culori folosesc urmtoarele variabile Color (avnd valorile sRGB indicate ntre paranteze):
black (negru) (0,0,0)
magenta (purpuriu)(255,0,255)
blue (albastru) (0,0,255)
orange (portocaliu)(255,200,0)
cyan (azuriu)(0,255,255)
pink (roz) (255.175,175)

darkGray(gri nchis)(64,64,64)
gray (gri) (128,128,128)
green (verde) (0,255,0)
lightGray(gri deschis)(192,192,192)

red (rosu) (255,0,0)


white (alb) (255,255,255)
yellow (galben) (255,255,0)

Urmtoarea instruciune stabilete culoarea curent pentru obiectul ecran folosind una dintre
variabilele de clas standard:
ecran.setColor(Color.pink) ;
Dac ai creat un obiect Color, el poate fi setat ntr-un mod asemntor:

Color pensula = new Color(255, 204, 102);


ecran.setColor(pensula) ;
Dup ce ai stabilit culoarea curent, toate operaiile de desenare o vor folosi pe aceasta.
Putei stabili culoarea de fundal (background) ntr-o fereastr Applet folosind metodele
proprii applet-ului, setBackground() i setForeground(). Acestea sunt motenite de clasa Applet de
la una dintre superclasele sale, aa nct toate applet-urile create vor moteni i ele aceste metode.
Metoda setBackground() seteaz culoarea de fundal a ferestrei Applet. Ea primete ca singur
argument un obiect color:
setBackground(Color.white) ;
Exist i o metod setForeground(), care este apelat pentru componentele interfeei
utilizator, nu pentru obiectele Graphics. Funcioneaz la fel ca metoda setColor (), ns schimb
culoarea unei componente a interfeei, cum ar fi un buton sau o fereastr.
Deoarece un applet este o fereastr, putei folosi metoda setForeground() n metoda init()
pentru a seta culorile pentru operaiile de desenare. Aceast culoare va fi folosit pn la alegerea
unei alte culori cu una dintre metodele setForeground() sau setColor ().
Dac dorii s aflai care este culoarea curent, putei folosi metoda getColor() pentru un
obiect grafic, respectiv una dintre metodele getForeground() sau getBackground() pentru clasa
Applet.
Urmtoarea instruciune stabilete culoarea curent pentru ecran - un obiect Graphics - ca
fiind aceeai cu fundalul applet-ului:
ecran.setColor(getBackground());

Operaii grafice avansate folosind Java2D


Una dintre mbuntirile aduse n Java2 este Java2D, un set de clase pentru crearea unor imagini i
texte bidirecionale de nalt calitate. Funciile Java2D conin:
Modele speciale de umplere
Linii de diferite grosimi
Anti-aliasing pentru netezirea marginilor obiectelor desenate
Conversia prin cast a unui obiect Graphics2D
Operaiile de desenare nvate pn acum sunt apelate pentru obiecte Graphics. Pentru Java2D,
acest obiect se utilizeaz pentru a crea un nou obiect Graphics2D
public void paint(Graphics ecran) {
Graphics2D ecran2D = (Graphics2D)ecran;
}

Fire de execuie i sincronizare


O aplicaie Java ruleaz n interiorul unui proces al sistemului de operare. Acest proces
const din segmente de cod i segmente de date mapate ntr-un spaiu virtual de adresare. Fiecare
proces deine un numr de resurse alocate de ctre sistemul de operare, cum ar fi fiiere deschise,
regiuni de memorie alocate dinamic, sau fire de execuie. Toate aceste resurse deinute de ctre un
proces sunt eliberate la terminarea procesului de ctre sistemul de operare.
Un fir de execuie este unitatea de execuie a unui proces. Fiecare fir de execuie are asociate
o secven de instruciuni, un set de regitri CPU i o stiv. Atenie, un proces nu execut nici un fel
de instruciuni. El este de fapt un spaiu de adresare comun pentru unul sau mai multe fire de
execuie. Execuia instruciunilor cade n responsabilitatea firelor de execuie. n cele ce urmeaz
vom prescurta uneori denumirea firelor de execuie, numindu-le pur i simplu fire .
n cazul aplicaiilor Java interpretate, procesul deine n principal codul interpretorului iar
codul binar Java este tratat ca o zon de date de ctre interpretor. Dar, chiar i n aceast situaie, o
aplicaie Java poate avea mai multe fire de execuie, create de ctre interpretor i care execut,
seturi distincte de instruciuni binare Java.
Fiecare dintre aceste fire de execuie poate rula n paralel pe un procesor separat dac
maina pe care ruleaz aplicaia este o main cu mai multe procesoare. Pe mainile monoprocesor,
senzaia de execuie n paralel a firelor de execuie este creat prin rotirea acestora pe rnd la
controlul unitii centrale, cte o cuant de timp fiecare.
Mediul de execuie Java execut propriul su control asupra firelor de execuie. Algoritmul
pentru planificarea firelor de execuie, prioritile i strile n care se pot afla acestea sunt specifice
aplicaiilor Java i implementate identic pe toate platformele pe care a fost portat mediul de execuie
Java. Totui, acest mediu tie s profite de resursele sistemului pe care lucreaz. Dac sistemul
gazd lucreaz cu mai multe procesoare, Java va folosi toate aceste procesoare pentru a-i planifica
firele de execuie.
n cazul mainilor multiprocesor, mediul de execuie Java i sistemul de operare sunt
responsabile cu repartizarea firelor de execuie pe un procesor sau altul. Pentru programator, acest
mecanism este complet transparent, neexistnd nici o diferen ntre scrierea unei aplicaii cu mai
multe fire pentru o main cu un singur procesor sau cu mai multe. Desigur, exist ns diferene n
cazul scrierii aplicaiilor pe mai multe fire de execuie fa de acelea cu un singur fir de execuie,
diferene care provin n principal din cauza necesitii de sincronizare ntre firele de execuie
aparinnd aceluiai proces.
Sincronizarea firelor de execuie nseamn c acestea se ateapt unul pe cellalt pentru
completarea anumitor operaii care nu se pot executa n paralel sau care trebuie executate ntr-o
anumit ordine. Java ofer i n acest caz mecanismele sale proprii de sincronizare, extrem de uor
de utilizat i nglobate n chiar sintaxa de baz a limbajului.
La lansarea n execuie a unei aplicaii Java este creat automat i un prim fir de execuie,
numit firul principal. Acesta poate ulterior s creeze alte fire de execuie care la rndul lor pot crea
alte fire, i aa mai departe. Firele de execuie dintr-o aplicaie Java pot fi grupate n grupuri pentru
a fi manipulate n comun.
n afar de firele normale de execuie, Java ofer i fire de execuie cu prioritate mic care
lucreaz n fundalul aplicaiei atunci cnd nici un alt fir de execuie nu poate fi rulat. Aceste fire de
fundal se numesc demoni i execut operaii costisitoare n timp i independente de celelalte fire de
execuie. De exemplu, n Java colectorul de gunoaie lucreaz pe un fir de execuie separat, cu
proprieti de demon. n acelai fel poate fi gndit un fir de execuie care execut operaii de
ncrcare a unor imagini din reea.

O aplicaie Java se termin atunci cnd se termin toate firele de execuie din interiorul ei
sau cnd nu mai exist dect fire demon. Terminarea firului principal de execuie nu duce la
terminarea automat a aplicaiei.

Crearea firelor de execuie


Exist dou ci de definire de noi fire de execuie: derivarea din clasa Thread a noi clase i
implementarea ntr-o clas a interfeei Runnable .
n primul caz, noua clas motenete toate metodele i variabilele clasei Thread care
implementeaz n mod standard, n Java, funcionalitatea de lucru cu fire de execuie. Singurul lucru
pe care trebuie s-l fac noua clas este s reimplementeze metoda run care este apelat automat de
ctre mediul de execuie la lansarea unui nou fir. n plus, noua clas ar putea avea nevoie s
implementeze un constructor care s permit atribuirea unei denumiri firului de execuie.
Dac firul are un nume, acesta poate fi obinut cu metoda getName care returneaz un obiect
de tip String .
Iat un exemplu de definire a unui nou tip de fir de execuie:
class FirNou extends Thread {
public FirNou( String nume ) {
// apeleaz constructorul din Thread
super( nume );
}
public void run() {
while( true ) { // fr sfrit
System.out.println( getName() +" Tastati ^C" );
}
}
}
Dac vom crea un nou obiect de tip FirNou

i l lansm n execuie acesta va afia la infinit


mesajul "Tastai ^C". ntreruperea execuiei se poate face ntr-adevr prin tastarea caracterului ^C,
caz n care ntreaga aplicaie este terminat. Atta timp ns ct noul obiect nu va fi ntrerupt din
exterior, aplicaia va continua s se execute pentru c mai exist nc fire de execuie active i
indiferent de faptul c firul de execuie principal s-a terminat sau nu.
Iat i un exemplu de aplicaie care folosete aceast clas:
public class TestFirNou {
public static void main( String[] arg) {
new FirNou( "Primul" ).start();
}
}

Metoda start, predefinit n obiectul Thread lanseaz execuia propriu-zis a firului. Desigur
exist i ci de a opri execuia la nesfrit a firului creat fie prin apelul metodei stop , prezentat mai
jos, fie prin rescrierea funciei run n aa fel nct execuia sa s se termine dup un interval finit de
timp.
A doua cale de definiie a unui fir de execuie este implementarea interfeei Runnable ntr-o
anumit clas de obiecte. Aceast cale este cea care trebuie aleas atunci cnd clasa pe care o crem
nu se poate deriva din clasa Thread pentru c este important s fie derivat din alt clas. Desigur,
motenirea multipl ar rezolva aceast problem, dar Java nu are motenire multipl.

Aceast nou cale se poate folosi n modul urmtor:


class Oclasa {

}
class FirNou extends Oclasa implements Runnable {
public void run() {
for( int i = 0; i < 100; i++ ) {
System.out.println( "pasul " + i );
}
}

}
public class TestFirNou {
public static void main( String argumente[ ] ) {
new Thread( new FirNou() ).start();
// Obiectele sunt create i folosite imediat
// La terminarea instruciunii, ele sunt automat
// eliberate nefiind referite de nimic
}
}
Dup se observ, clasa Thread are i un constructor care primete ca argument o instan a
unei clase care implementeaz interfaa Runnable. n acest caz, la lansarea n execuie a noului fir, cu
metoda start , se apeleaz metoda run din acest obiect i nu din instana a clasei Thread .

Atunci cnd dorim s crem un aplet care s ruleze pe un fir de execuie separat fa de
pagina de navigator n care ruleaz pentru a putea executa operaii n fereastra apletului i n acelai
timp s putem folosi n continuare navigatorul, suntem obligai s alegem cea de-a doua cale de
implementare. Aceasta pentru c apletul nostru trebuie s fie derivat din clasa standard Applet .
Singura alternativ care ne rmne este aceea de a implementa n aplet interfaa Runnable .

Strile unui fir de execuie


Un fir de execuie se poate afla n Java n mai multe stri, n funcie de ce se ntmpl cu el
la un moment dat.
Atunci cnd este creat, dar nainte de apelul metodei start, firul se gsete ntr-o stare pe care
o vom numi Fir Nou Creat . n aceast stare, singurele metode care se pot apela pentru firul de
execuie sunt metodele start i stop . Metoda start lanseaz firul n execuie prin apelul metodei run .
Metoda stop omoar firul de execuie nc nainte de a fi lansat. Orice alt metod apelat n aceast
stare provoac terminarea firului de execuie prin generarea unei excepii de tip
IllegalThreadStateException .
Dac apelm metoda start pentru un Fir Nou Creat firul de execuie va trece n starea Ruleaz.
n aceast stare, instruciunile din corpul metodei run se execut una dup alta. Execuia poate fi
oprit temporar prin apelul metodei sleep care primete ca argument un numr de milisecunde care
reprezint intervalul de timp n care firul trebuie s fie oprit. Dup trecerea intervalului, firul de
execuie va porni din nou.
n timpul n care se scurge intervalul specificat de sleep, obiectul nu poate fi repornit prin
metode obinuite. Singura cale de a iei din aceast stare este aceea de a apela metoda interrupt.
Aceast metod genereaz o excepie de tip InterruptedException care nu este interceptat de sleep dar
care trebuie interceptat obligatoriu de metoda care a apelat metoda sleep. De aceea, modul standard
n care se apeleaz metoda sleep este urmtorul:

try {
sleep( 1000 ); // o secund
} catch( InterruptedException ) {

Dac dorim oprirea firului de execuie pe timp nedefinit, putem apela metoda suspend.
Aceasta trece firul de execuie ntr-o nou stare, numit Nu Ruleaz. Aceeai stare este folosit i
pentru oprirea temporar cu sleep. n cazul apelului suspend ns, execuia nu va putea fi reluat
dect printr-un apel al metodei resume. Dup acest apel, firul va intra din nou n starea Ruleaz .
Pe timpul n care firul de execuie se gsete n starea Nu Ruleaz , acesta nu este planificat
niciodat la controlul unitii centrale, aceasta fiind cedat celorlalte fire de execuie din aplicaie.
Firul de execuie poate intra n starea Nu Ruleaz i din alte motive. De exemplu se poate
ntmpla ca firul s atepte pentru terminarea unei operaii de intrare/ieire de lung durat caz n
care firul va intra din nou n starea Ruleaz doar dup terminarea operaiei.
O alt cale de a ajunge n starea Nu Ruleaz este aceea de a apela o metod sau o secven de
instruciuni sincronizat dup un obiect. n acest caz, dac obiectul este deja blocat, firul de execuie
va fi oprit pn n clipa n care obiectul cu pricina apeleaz metoda notify sau notifyAll .
Atunci cnd metoda run i-a terminat execuia, obiectul intr n starea Mort. Aceast stare
este pstrat pn n clipa n care obiectul este eliminat din memorie de mecanismul de colectare a
gunoaielor. O alt posibilitate de a intra n starea Mort este aceea de a apela metoda stop .
Desigur, firul de execuie poate fi terminat i pe alte ci, caz n care metoda stop nu este
apelat. n aceste situaii este preferabil s ne folosim de o clauz finally ca n exemplul urmtor:

try {
firDeExecutie.start( );

} finally {
..// curenie
}

n fine, dac nu se mai poate face nimic pentru c firul de execuie nu mai rspunde la
comenzi, putei apela la calea disperat a metodei destroy. Din pcate, metoda destroy termin firul
de execuie fr a proceda la curirile necesare n memorie.
Atunci cnd un fir de execuie este oprit cu comanda stop, mai este nevoie de un timp pn
cnd sistemul efectueaz toate operaiile necesare opririi. Din aceast cauz, este preferabil s
ateptm n mod explicit terminarea firului prin apelul metodei join:
firDeExecutie.stop( )
try {
firDeExecutie.join( );
} catch( InterruptedException e ) {

Excepia de ntrerupere trebuie interceptat obligatoriu. Dac nu apelm metoda join pentru
a atepta terminarea i metoda stop este de exemplu apelat pe ultima linie a funciei main , exist
ansa ca sistemul s cread c firul auxiliar de execuie este nc n via i aplicaia Java s nu se
mai termine rmnnd ntr-o stare de ateptare. O putei desigur termina tastnd ^C.

Prioritatea firelor de execuie


Fiecare fir de execuie are o prioritate cuprins ntre valorile MIN_PRIORITY i
MAX_PRIORITY. Aceste dou variabile finale sunt declarate n clasa Thread. n mod normal ns,
un fir de execuie are prioritatea NORM_PRIORITY, de asemenea definit n clasa Thread .
Mediul de execuie Java planific firele de execuie la controlul unitii centrale n funcie de
prioritatea lor. Dac exist mai multe fire cu prioritate maxim, acestea sunt planificate dup un
algoritm numit round-robin. Firele de prioritate mai mic intr n calcul doar atunci cnd toate firele
de prioritate mare sunt n starea Nu Ruleaz .

Prioritatea unui fir de execuie se poate interoga cu metoda getPriority care ntoarce un
numr ntreg care reprezint prioritatea curent a firului de execuie. Pentru a seta prioritatea, se
folosete metoda setPriority care primete ca parametru un numr ntreg care reprezint prioritatea
dorit.
Schimbarea prioritii unui fir de execuie este o treab periculoas dac metoda cu
prioritate mare nu se termin foarte repede sau dac nu are opriri dese. n caz contrar, celelalte
metode nu vor mai putea primi controlul unitii centrale.
Exist ns situaii n care putem schimba aceast prioritate fr pericol, de exemplu cnd
avem un fir de execuie care nu face altceva dect s citeasc caractere de la utilizator i s le
memoreze ntr-o zon temporar. n acest caz, firul de execuie este n cea mai mare parte a
timpului n starea Nu Ruleaz din cauz c ateapt terminarea unei operaii de intrare/ieire. n clipa
n care utilizatorul tasteaz un caracter, firul va iei din starea de ateptare i va fi primul planificat
la execuie din cauza prioritii sale ridicate. n acest fel utilizatorul are senzaia c aplicaia
rspunde foarte repede la comenzile sale.
n alte situaii, avem de executat o sarcin cu prioritate mic. n aceste cazuri, putem seta
pentru firul de execuie care execut aceste sarcini o prioritate redus.
Alternativ, putem defini firul respectiv de execuie ca un demon. Dezavantajul n aceast
situaie este faptul c aplicaia va fi terminat atunci cnd exist doar demoni n lucru i exist
posibilitatea pierderii de date. Pentru a declara un fir de execuie ca demon, putem apela metoda
setDaemon. Aceast metod primete ca parametru o valoare boolean care dac este true firul este
fcut demon i dac nu este adus napoi la starea normal. Putem testa faptul c un fir de execuie
este demon sau nu cu metoda isDemon.

Grupuri de fire de execuie


Uneori avem nevoie s acionm asupra mai multor fire de execuie deodat, pentru a le
suspenda, reporni sau modifica prioritatea n bloc. Din acest motiv, este util s putem grupa firele
de execuie pe grupuri. Aceast funcionalitate este oferit n Java de ctre o clas numit
ThreadGroup .
La pornirea unei aplicaii Java, se creeaz automat un prim grup de fire de execuie, numit
grupul principal, main. Firul principal de execuie face parte din acest grup. n continuare, ori de
cte ori crem un nou fir de execuie, acesta va face parte din acelai grup de fire de execuie ca i
firul de execuie din interiorul cruia a fost creat, n afar de cazurile n care n constructorul firului
specificm explicit altceva.
ntr-un grup de fire de execuie putem defini nu numai fire dar i alte grupuri de execuie. Se
creeaz astfel o arborescen a crei rdcin este grupul principal de fire de execuie.
Pentru a specifica pentru un fir un nou grup de fire de execuie, putem apela constructorii
obinuii dar introducnd un prim parametru suplimentar de tip ThreadGroup . De exemplu, putem
folosi urmtorul cod:
ThreadGroup tg = new ThreadGroup( "Noul grup" );
Thread t = new Thread( tg, "Firul de executie" );

Acest nou fir de execuie va face parte dintr-un alt grup de fire dect firul principal. Putem
afla grupul de fire de execuie din care face parte un anumit fir apelnd metoda getThreadGroup , ca
n secvena:
Thread t = new Thread( "Firul de Executie" );
ThreadGroup tg = t.getThreadGroup();

Operaiile definite pentru un grup de fire de execuie sunt clasificabile n operaii care
acioneaz la nivelul grupului, cum ar fi aflarea numelui, setarea unei prioriti maxime, etc., i
operaii care acioneaz asupra fiecrui fir de execuie din grup, cum ar fi stop, suspend sau resume.

Enumerarea firelor de execuie


Pentru a enumera firele de execuie active la un moment dat, putem folosi metoda enumerate
definit n clasa Thread precum i n clasa ThreadGroup . Aceast metod primete ca parametru o
referin ctre un tablou de referine la obiecte de tip Thread pe care l umple cu referine ctre
fiecare fir activ n grupul specificat.
Pentru a afla cte fire active sunt n grupul respectiv la un moment dat, putem apela metoda
activeCount din clasa ThreadGroup . De exemplu:
ThreadGroup grup = Thread.currentThread().getThreadGroup();
int numarFire = grup.activeCount();
Thread fire[] = new Thread[numarFire];
grup.enumerate( fire );
for( int i = 0; i < numar; i++ ) {
System.out.println( fire[i].toString() );

Metoda enumerate ntoarce numrul de fire memorate n tablou, care este identic cu numrul de fire
active.

Sincronizare
n unele situaii se poate ntmpla ca mai multe fire de execuie s vrea s acceseze aceeai
variabil. n astfel de situaii, se pot produce ncurcturi dac n timpul unuia dintre accese un alt fir
de execuie modific valoarea variabilei.
Limbajul Java ofer n mod nativ suport pentru protejarea acestor variabile. Suportul este
construit de fapt cu granulaie mai mare dect o singur variabil, protecia fcndu-se la nivelul
obiectelor. Putem defini metode, n cadrul claselor, care sunt sincronizate.
Pe o instan de clas, la un moment dat, poate lucra o singur metod sincronizat. Dac un
alt fir de execuie ncearc s apeleze aceeai metod pe aceeai instan sau o alt metod a clasei
de asemenea declarat sincronizat, acest al doilea apel va trebui s atepte nainte de execuie
eliberarea instanei de ctre cealalt metod.
n afar de sincronizarea metodelor, se pot sincroniza i doar blocuri de instruciuni. Aceste
sincronizri se fac tot n legtur cu o anumit instan a unei clase. Aceste blocuri de instruciuni
sincronizate se pot executa doar cnd instana este liber. Se poate ntmpla ca cele dou tipuri de
sincronizri s se amestece, n sensul c obiectul poate fi blocat de un bloc de instruciuni i toate
metodele sincronizate s atepte, sau invers.
Declararea unui bloc de instruciuni sincronizate se face prin:
synchronize ( Instan ) {
Instruciuni
}
iar declararea unei metode sincronizate se face prin folosirea modificatorului synchronize la
implementarea metodei.

Un exemplu
Exemplul urmtor implementeaz soluia urmtoarei probleme: ntr-o ar foarte ndeprtat
triau trei nelepi filozofi. Aceti trei nelepi i pierdeau o mare parte din energie certndu-se
ntre ei pentru a afla care este cel mai nelept. Pentru a trana problema o dat pentru totdeauna, cei
trei nelepi au pornit la drum ctre un al patrulea nelept pe care cu toii l recunoteau c ar fi mai
bun dect ei.

Cnd au ajuns la acesta, cei trei i-au cerut s le spun care dintre ei este cel mai nelept.
Acesta, a scos cinci plrii, trei negre i dou albe, i li le-a artat explicndu-le c i va lega la ochi
i le va pune n cap cte o plrie, cele dou rmase ascunzndu-le. Dup aceea, le va dezlega ochii,
i fiecare dintre ei va vedea culoarea plriei celorlali dar nu i-o va putea vedea pe a sa. Cel care
i va da primul seama ce culoare are propria plrie, acela va fi cel mai nelept.
Dup explicaie, neleptul i-a legat la ochi, le-a pus la fiecare cte o plrie neagr i le-a
ascuns pe celelalte dou. Problema este aceea de a descoperi care a fost raionamentul celui care a
ghicit primul c plria lui este neagr.
Programul urmtor rezolv problema dat n felul urmtor: Fiecare nelept privete plriile
celorlali doi. Dac ambele sunt albe, problema este rezolvat, a lui nu poate fi dect neagr. Dac
vede o plrie alb i una neagr, atunci el va trebui s atepte puin s vad ce spune cel cu plria
neagr. Dac acesta nu gsete soluia, nseamn c el nu vede dou plrii albe, altfel ar fi gsit
imediat rspunsul. Dup un scurt timp de ateptare, neleptul poate s fie sigur c plria lui este
neagr.
n fine, dac ambele plrii pe care le vede sunt negre, va trebui s atepte un timp ceva mai
lung pentru a vedea dac unul dintre concurenii si nu ghicete plria. Dac dup scurgerea
timpului nici unul nu spune nimic, nseamn c nici unul nu vede o plrie alb i una neagr.
nseamn c propria plrie este neagr.
Desigur, raionamentul pleac de la ideea c ne putem baza pe faptul c toi nelepii
gndesc i pot rezolva probleme uoare. Cel care ctig a gndit doar un pic mai repede. Putem
simula viteza de gndire cu un interval aleator de ateptare pn la luarea deciziilor. n realitate,
intervalul nu este aleator ci dictat de viteza de gndire a fiecrui nelept.
Cei trei nelepi sunt implementai identic sub form de fire de execuie. Nu ctig la
fiecare rulare acelai din cauza caracterului aleator al implementrii. neleptul cel mare este firul de
execuie principal care controleaz activitatea celorlalte fire i le servete cu date, culoarea
plriilor, doar n msura n care aceste date trebuie s fie accesibile. Adic nu se poate cere propria
culoare de plrie.
Culoarea iniial a plriilor se poate rescrie din linia de comand.
import java.awt.Color;
// clasa Filozof implementeaza comportamentul unui concurent
class Filozof extends Thread {
// parerea concurentului despre culoarea palariei sale.
// Null daca nca nu si-a format o parere.
Color parere = null;
Filozof( String nume ) {
super( nume );
}
public void run() {
// concurentii firului curent
Filozof concurenti[] = new Filozof[2];
// temporar
Thread fire[] = new Thread[10];
int numarFire = enumerate( fire );
for( int i = 0, j = 0; i < numarFire && j < 2; i++ ) {
if( fire[i] instanceof Filozof && fire[i] != this ) {
concurenti[j++] = (Filozof)fire[i];
}
}
while( true ) {
Color primaCuloare = Concurs.culoare( this, concurenti[0] );
Color adouaCuloare = Concurs.culoare( this, concurenti[1] );
if( primaCuloare == Color.white && adouaCuloare == Color.white ) {
synchronized( this ) {
parere = Color.black;
}

} else if( primaCuloare == Color.white ){


try{
sleep( (int)( Math.random()*500) );
} catch( InterruptedException e ){
};
if( Concurs.culoare( this, concurenti[1]) != concurenti[1].aGhicit()) {
synchronized( this ) {
parere = Color.black;
};
}
} else if( adouaCuloare == Color.white ) {
try{
sleep( (int)( Math.random()*500));
} catch( InterruptedException e ) {
};
if( Concurs.culoare(this, concurenti[0] ) != concurenti[0].aGhicit()) {
synchronized( this ) {
parere = Color.black;
};
}
} else {
try {
sleep( (int)( Math.random()*500)+500 );
} catch( InterruptedException e ) {
};
if( Concurs.culoare(this, concurenti[0]) != concurenti[0].aGhicit() &&
Concurs.culoare( this, concurenti[1] ) !=concurenti[1].aGhicit() ) {
synchronized( this ) {
parere = Color.black;
};
}
}
}
}
public synchronized Color aGhicit() {
return parere;
}
}

import java.awt.Color;
public class Concurs {
private static Color palarii[] = {
Color.black, Color.black, Color.white
};
private static Filozof filozofi[] = new Filozof[3];
public static void main( String args[] ) {
for( int i = 0; i < args.length && i < 3; i++ ) {
if( args[i].equalsIgnoreCase( "alb" ) ) {
palarii[i] = Color.white;
} else if(args[i].equalsIgnoreCase("negru")) {
palarii[i] = Color.black;
}
}
for( int i = 0; i < 3; i++ ) {
filozofi[i] = new Filozof( "Filozoful " + ( i + 1 ) );
}

for( int i = 0; i < 3; i++ ) {


filozofi[i].start();
}
System.out.println( "Concurenti:" );
for( int i = 0; i < 3; i++ ) {
System.out.println( "\t" +filozofi[i].getName() + " "+ (( palarii[i] == Color.white ) ?"alb":"negru" ) );
}
boolean gata=false;
while( !gata) {
for( int i = 0; i < 3; i++ ) {
if( filozofi[i].aGhicit()==palarii[i] ) {
System.out.println(
filozofi[i].getName() +" a ghicit." );
gata=true;
}
}
}
for( int i = 0; i < 3; i++ ) {
filozofi[i].stop();
try {
filozofi[i].join();
} catch( InterruptedException e ) {};
}
}
public static Color culoare( Filozof filozof, Filozof concurent ) {
if( filozof != concurent ) {
for( int i = 0; i < 3; i++ ) {
if( filozofi[i] == concurent ) {
return palarii[i];
}
}
}
return null;
}
}

Abstract Windowing Toolkit

Abstract Windowing Toolkit, pe scurt AWT, este un set de clase cu ajutorul crora putei
crea o interfa grafic utilizator care s reacioneze la datele de intrare primite de la mouse i
tastatur.
Deoarece Java este un limbaj independent de platform, AWT ofer o modalitate de
proiectare a unei interfee care s prezinte aceeai nfiare i aceleai caracteristici pe orice sistem
pe care ar fi rulat.
Folosind AWT, o interfa este compus din urmtoarele:
Componente. Orice poate fi plasat pe o interfa utilizator, cum ar fi butoane, liste derulante,
meniuri pop-up, casete de validare sau cmpuri de text.
Containere. Acestea sunt componente care pot conine alte componente. Ai folosit deja un
astfel de container - fereastra Applet; alte exemple ar fi panouri, casete de dialog sau ferestre
independente.
Administratori de dispunere. Obiecte care definesc modul cum sunt aranjate (dispuse)
componentele ntr-un container. Administratorul de dispunere nu este vizibil ntr-o interfa,
ns sunt vizibile rezultatele muncii" sale.
Toate clasele AWT fac parte din pachetul java.awt. Pentru a face toate aceste clase
disponibile ntr-un program, poate fi folosit urmtoarea instruciune de import, introdus la
nceputul codului surs:
import java.awt.*;
Aceast instruciune are ca rezultat importarea tuturor componentelor, containerelor i
administratorilor de dispunere pe care i vei folosi la proiectarea unei interfee. Putei folosi i
instruciuni import individuale, numai pentru clasele care vor fi utilizate ntr-un program.
Clasele AWT, ca oricare alte pri ale unei biblioteci de clase Java, sunt aranjate ierarhic.

Componentele interfetei utilizator


Componentele sunt poziionate pe interfaa utilizator prin adugarea lor ntr-un container. Un container este el
nsui o component, deci poate fi adugat n alte containere. Vei folosi aceast caracteristic atunci cnd vei ncepe s
lucrai cu administratori de dispunere (layout managers) pentru a aranja o interfa.

Cea mai uoar modalitate de a demonstra cum se proiecteaz o interfa este folosirea
containerului cu care ai lucrat pn acum - clasa Applet.

Adugarea componentelor ntr-un


container
O component este adugat ntr-un container astfel:
Creai componenta.
Apelai metoda add() a containerului, pentru componenta respectiv.
Deoarece toate applet-urile sunt containere, putei folosi metoda add() ntr-un applet pentru a
aduga o component direct n fereastra Applet.
Fiecare component AWT este o clas, deci componenta respectiv este creat prin crearea
unui obiect al clasei respective.

Clasa Button reprezint butoanele din cadrul unei interfee (suprafee pe care se poate executa
clic). Un buton se creeaz specificnd eticheta sa n metoda constructorului, ca n urmtorul
exemplu:
Button atentie = new Button(Atenie!) ;
Aceast instruciune creeaz un buton etichetat cu textul Atenie!.
O dat creat o component, cea mai simpl metod de a o aduga ntr-un container este de
a apela metoda add () a containerului, avnd ca argument componenta respectiv.
Deoarece un applet este un container, putei folosi urmtoarea instruciune pentru a aduga
obiectul atenie ntr-o fereastr Applet:
add(atentie) ;
Adugarea unei componente nu duce imediat la afiarea acesteia. De fapt, aceasta va fi
afiat numai la apelarea metodei paint() a containerului. De acest lucru se ocup n culise" Java,
ns putei fora un apel al metodei paint() a applet-ului folosind metoda repaint() a acestuia.
Atunci cnd adugai o component ntr-un container, nu se specific coordonatele x,y ale
locului unde va fi plasat aceasta. De aranjamentul componentelor se ocup administratorul de
dispunere (layout manager) care aparine containerului respectiv.

Etichete
Cea mai simpl component a unei interfee utilizator este eticheta, care este creat din clasa
Label. Etichetele se folosesc de obicei pentru a identifica rolul celorlalte componente aflate pe
interfa; acestea nu pot fi modificate direct de utilizator.
Folosirea unei etichete pentru text este preferabil folosirii metodei drawString(), din
urmtoarele motive:
Etichetele sunt desenate automat dup creare i nu trebuie s fie tratate explicit de metoda
paint().
Etichetele vor fi aranjate corespunztor administratorului de dispunere curent i nu la o
anumit coordonat x,y cum este cazul irului.
Pentru a crea o etichet folosii unul dintre urmtorii constructori:
Label() creeaz o etichet goal (vid), cu textul aliniat la stnga.
Label (String) creeaz o etichet cu irul de text dat, aliniat, de asemenea, la stnga.
Label (String, int) creeaz o etichet cu irul de text dat i alinierea indicat de argumentul
ntreg. Pentru stabilirea alinierii se folosesc urmtoarele variabile de clas: Label.RIGHT,
Label.LEFT, Label.CENTER.

Butoane
Butoanele (zone pe care se poate efectua clic) pot fi create folosind clasa Button. Butoanele
sunt folosite ntr-o interfa pentru a declana o aciune, cum este butonul Quit (Terminare) folosit
pentru a prsi un program.
Pentru a crea un buton, folosii unul dintre constructorii:
Button() creeaz un buton care nu conine nici un text pentru explicarea funciei sale.
Button(String) creeaz un buton pe care este afiat irul de text primit ca argument.
Dup crearea unui buton, putei s i modificai eticheta folosind metoda setLabel (String) sau
putei afla textul scris folosind metoda getLabel()

Casete de validare
Casetele de validare (check boxes) sunt mici casete, etichetate sau nu, care pot fi validate
(bifate") sau goale. Acestea sunt, de obicei, folosite pentru a selecta sau deselecta anumite opiuni
ntr-un program, cum ar fi opiunile Disable Sound (Dezactivare sunet) sau Password Protected
(Protecie cu parol) dintr-o protecie de ecran (screen saver) Windows.
n mod normal, casetele de validare sunt neexclusive, ceea ce nseamn c, dac avei cinci
casete de validare ntr-un container, toate cinci pot fi validate sau nu simultan.
Aceste componente pot fi organizate i n grupuri de validare, care mai sunt denumite i
butoane radio (radio buttons). Ele i-au luat numele de la vechile aparate de radio, la care apsarea
unui buton ducea la ridicarea altuia care era apsat pn atunci.
Ambele tipuri de casete de validare sunt create folosind clasa Checkbox. Putei crea o caset de
validare neexclusiv folosind unul din urmtorii constructori:
Checkbox() creeaz o caset de validare neetichetat, care nu este validat.
Checkbox(String) creeaz o caset de validare nevalidat i care are ca etichet irul
dat.
Dup ce ai creat un obiect Checkbox, putei folosi metoda setState (boolean) pentru a
modifica starea acestuia, astfel: valoarea true pentru a valida caseta i valoarea false pentru a o
anula. Metoda getState() returneaz o valoare Boolean care indic starea de validare a casetei.
Pentru a organiza mai multe casete de validare ntr-un grup, cu scopul de a nu permite dect
validarea unei singure opiuni la un moment dat, se creeaz un obiect CheckboxGroup, printr-o
instruciune de genul:
CheckboxGroup radio = new CheckboxGroup();
Obiectul CheckboxGroup pstreaz starea tuturor casetelor de validare din grupul su.
Acest obiect va fi folosit ca argument suplimentar pentru constructorul Checkbox.
Checkbox (String, GrupCaseteValidare, boolean) creeaz o caset de validare etichetat cu
irul dat de primul argument i care aparine grupului indicat de cel de-al doilea argument. Cel de-al
treilea argument trebuie setat pe true dac se dorete validarea casetei de dialog i false n caz
contrar.

Liste de opiuni
Listele de opiuni (choice lists), create din clasa Choice, sunt componente care permit
alegerea unei singure opiuni dintr-o list derulant (pull-down list). Vei ntlni de multe ori acest
tip de liste atunci cnd completai un formular dintr-o pagin World Wide Web.
Primul pas n crearea unei liste de opiuni const n crearea obiectului Choice care va pstra
lista, ca n exemplul urmtor:
Choice sex = new Choice();
Elementele se adaug ntr-o list de opiuni folosind metoda addItem(String) a obiectului.
Urmtoarele instruciuni adaug dou elemente n lista de opiuni sex:
sex.addItem("Masculin");
sex.addItem("Feminin");
Putei continua s folosii metoda addItem() pentru a aduga opiuni n list chiar i dup ce lista a
fost introdus ntr-un container.

Cmpuri de text
Cmpurile de text (text fields) sunt folosite pentru a crea componente n care textul poate fi
modificat de utilizator. Aceste componente sunt create din clasa TextField.
Pentru a crea un cmp de text, folosii unul din urmtorii constructori:

TextField() creeaz un cmp gol, fr o lime specificat.


TextField(int) creeaz un cmp gol, care are o lime suficient pentru a afia numrul
specificat de caractere.
TextField(String) creeaz un cmp completat cu irul dat i fr o lime specificat.

TextField (String, int) creeaz cmp completat cu irul dat i cu limea specificata de
argumentul ntreg.
Atributul responsabil cu limea cmpului are relevan doar n cazul folosirii unor
administratori de dispunere (layout managers) care nu redimensioneaz componentele, cum ar fi
administratorul FlowLayout.
Urmtoarea instruciune creeaz un cmp de text gol, care ofer suficient spaiu pentru 30 de
caractere:
TextField nume = new TextField(30) ;
Urmtoarea instruciune poate fi folosit dac dorii s iniializai cmpul cu irul de text
"Ion I. Ionescu":
TextField nume = new TextField("Ion I. Ionescu", 30);
Putei crea i un cmp de text care s ascund caracterele tastate, afind n locul lor un
caracter oarecare. Aceast facilitate se folosete de obicei n cmpurile de introducere a parolelor,
pentru a ascunde parola de priviri indiscrete.
Pentru a defini un astfel de caracter de mascare, n Java 1.02 se folosete metoda
setEchoCharacter(char), iar n versiunile urmtoare, metoda setEchoChar(char). Dac se
folosete un literal, acesta trebuie ncadrat ntre ghilimele simple, ca de exemplu '*'. Java
interpreteaz orice literal ncadrat de ghilimele duble ca fiind un obiect de tip String (ir).

Zone de text
Zonele de text (text areas), create din clasa textArea, sunt cmpuri de text modificabile
care pot conine mai multe linii de text. Zonele de text posed bare de defilare orizontale i
verticale, care permit utilizatorului s parcurg ntreg textul coninut n component.
Pentru a crea o zon de text putei folosi unul din urmtorii constructori:
TextArea() creeaz o zon de text goal, cu nlime i lime nespecificate.
TextArea (int, int) creeaz o zon goal, care conine numrul de rnduri dat de primul
argument i are limea n caractere dat de al doilea argument.
TextArea (String) creeaz o zon de text care conine irul specificat i are limea i
nlimea nespecificate.
TextArea(String, int, int) creeaz o zon de text care conine irul specificat, numrul de
rnduri fiind dat de primul argument, iar limea n caractere de al doilea argument.
Liste de derulare

Listele de derulare (scrolling lists), create din clasa List, sunt asemntoare listelor de
opiuni, cu dou diferene semnificative:
Lista de derulare poate fi configurat aa nct s poat fi selectate mai multe opiuni la un
moment dat.
Listele de derulare se prezint asemntor unei zone de text n care sunt afiate mai multe
opiuni. Dac lista conine mai multe opiuni dect pot fi afiate, se folosete o bar de
derulare pentru a se parcurge ntreaga list.
O list de derulare este definit prin crearea unui obiect List i adugarea n list a unor
elemente. Clasa List posed urmtorii constructori:
List() creeaz o list de parcurgere vid care permite selectarea unui singur element la un
moment dat.
List(int, boolean) creeaz o list de derulare care posed numrul de elemente vizibile
indicat de primul argument (numr care poate fi mai mic dect numrul total de elemente).
Argumentul boolean indic dac pot fi selectate mai multe elemente (true) sau nu (false).
Dup crearea unui obiect List se folosete metoda addItem(String) pentru a aduga
elemente n list. (Nota: ncepnd cu Java 2, metoda nu se mai recomand i a fost nlocuit de
metoda add(String)).

Bare de derulare i glisoare


Barele de derulare (scrollbars) sunt componente care permit selectarea unei valori prin
deplasarea unei casete ntre dou sgei. Exist mai multe componente care au nglobate bare de
derulare, cum ar fi zonele de text sau listele de derulare. Clasa Scrollbar este folosit pentru alte
tipuri de bare de derulare. O bar de derulare poate fi orizontal sau vertical.
Barele de derulare sunt folosite n mod normal pentru specificarea valorilor minime i maxime
care pot fi stabilite prin utilizarea componentei.
Pentru a crea o bar de derulare putei folosi urmtorii constructori:
Scrollbar() creeaz o bar de derulare vertical care are valorile maxim i minim setate
iniial la 0.
Scrollbar(int) creeaz o bar de derulare care are valorile maxim i minim setate la 0, iar
orientarea este dat de valoarea ntreag. Argumentul poate lua urmtoarele valori, care sunt
variabile de clas: Scrollbar.HORIZONTAL i Scrollbar.VERTICAL.
Putei folosi, de asemenea, un al treilea constructor, care primete cinci argumente:
Scrollbar ( int, int, int, int, int). Argumentele acestei metode sunt, n ordine, urmtoarele:
Orientarea, care este Scrollbar.HORIZONTAL sau Scrollbar.VERTICAL.
Valoarea iniial a barei de derulare, care trebuie s se afle ntre valorile minim i maxim
ale barei sau s fie egal cu una dintre acestea.
Limea sau nlimea general a casetei folosite pentru modificarea valorii barei de
derulare. Aceasta poate fi egal cu 0 atunci cnd se folosete dimensiunea prestabilit.
Valoarea minim a barei de derulare.
Valoarea maxim a barei de derulare.

Suprafee de desenare

Suprafeele de desenare (canvas) sunt componente folosite, n principal, drept loc de afiare
pentru imagini sau animaie. Putei desena i pe alte componente, ns obiectele Canvas sunt cele
mai simplu de folosit n acest scop.
Pentru a folosi o suprafa de desenare trebuie s creai o subclas a clasei Canvas. Aceast
subclas se poate ocupa de toate operaiunile de desenare care trebuie s aib loc, n metoda sa
paint().
O dat creat o subclas Canvas, aceasta poate fi folosit n program prin apelarea
constructorului su i prin adugarea noului obiect Canvas ntr-un container.

Aranjarea componentelor ntr-o interfa utilizator


Putei dispune componente pe o interfa, ns nu prea vei avea controlul asupra locului
unde vor fi amplasate.
Pentru a impune o anumit form interfeei proiectate cu ajutorul Abstract Windowing
Toolkit trebuie s folosii un set de clase denumite administratori de dispunere (layout managers).

Dispunerea componentelor interfeei


Un administrator de dispunere determin modul cum vor fi aranjate (dispuse) componentele
adugate ntr-un container.
Administratorul de dispunere implicit este clasa FlowLayout. Aceast component permite
dispunerea secvenial a obiectelor, de la stnga la dreapta, n ordinea n care acestea sunt adugate
n container. Atunci cnd nu mai este loc pe un rnd, celelalte obiecte se dispun n continuare pe
rndul urmtor, continund secvena de la stnga la dreapta.
Biblioteca AWT conine cinci administratori de dispunere principali: FlowLayout,
GridLayout, BorderLayout, CardLayout i GridBagLayout. Pentru a crea un administrator de
dispunere pentru un container, se creeaz o instan a clasei container folosind o instruciune de
genul:
FlowLayout flo = new FlowLayout();
Dup ce ai creat un administrator de dispunere, l vei declara drept administrator de
dispunere pentru container folosind metoda setLayout() a acestuia. Administratorul de dispunere
trebuie stabilit nainte de a aduga componentele n container. Dac nu este stabilit nici un
administrator de dispunere, se folosete implicit dispunerea n secven (flow layout).
Urmtoarele instruciuni reprezint punctul de ncepere pentru un applet n care se creeaz
un administrator de dispunere i se folosete metoda setLayout() pentru a controla dispunerea
tuturor componentelor ce vor fi adugate n fereastra Applet:
public class Starter extends java.applet.Applet {
FlowLayout ad = new FlowLayout();
public void init() {
setLayout(ad) ;
}
}
Dup stabilirea administratorului de dispunere curent, putei ncepe s adugai
componentele n containerul pe care acesta l controleaz. Pentru unii dintre administratorii de
dispunere, cum ar fi FlowLayout, ordinea n care se adaug componentele este important.

Dispunerea secvenial
FlowLayout este cea mai simpl clas de administrare a dispunerii. Ea aranjeaz
componentele ntr-o manier asemntoare dispunerii cuvintelor ntr-o pagin - de la stnga la
dreapta pn la captul rndului, apoi n continuare pe rndul urmtor.
n mod prestabilit, dac folosii constructorul FlowLayout() fr argumente, componentele
de pe fiecare rnd vor fi centrate. Dac dorii ca acestea s fie aliniate la marginea din stnga sau
din dreapta a containerului, trebuie folosite drept argument pentru constructor variabilele de clas
FlowLayout.LEFT sau FlowLayout.RIGHT:
FlowLayout dreapta = new FlowLayout(FlowLayout.RIGHT);
Variabila de clas FlowLayout.CENTER este folosit pentru dispunerea pe centru a
componentelor.

Dispunerea tabelar
Administratori de dispunere tabelar (grid) aranjeaz componentele ntr-un caroiaj (tabel)
format din rnduri i coloane.
Componentele sunt adugate ncepnd cu celula aflat cel mai n stnga pe primul rnd al
tabelului i continund spre dreapta. Dup completarea tuturor celulelor de pe primul rnd se
continua cu cel de-al doilea rnd, de la stnga la dreapta, i aa mai departe.
Dispunerea tabelar este stabilit pornind de la clasa GridLayout. Constructorul
GridLayout primete dou argumente - numrul de rnduri i numrul de coloane din tabel.
Urmtoarea instruciune creeaz un administrator de dispunere tabelar pentru 10 rnduri i 3
coloane:
GridLayout gr = new GridLayout(10,3);
Ca i n cazul dispunerii secveniale, dac se folosesc dou argumente suplimentare, putei
specifica spaiul pe orizontal i pe vertical care trebuie lsat ntre componente. Urmtoarea
instruciune creeaz un tabel cu 10 rnduri, 3 coloane, un spaiu pe orizontal de 5 pixeli i un
spaiu pe vertical de 8 pixeli:
GridLayout gr2 = new GridLayout(10, 3, 5, 8);
Spaiul ntre componentele dispunerii tabelare este implicit 0 pixeli, att pe orizontal ct si pe
vertical.

Dispunerea marginal
Dispunerile marginale (border layouts), create pornind de la clasa BorderLayout, mpart un
container n cinci seciuni: nord, sud, est, vest i centru.
Folosind dispunerea marginal, componentele din cele patru puncte cardinale vor ocupa
spaiul de care au nevoie, iar centrul obine spaiul rmas disponibil. De obicei, acest aranjament are
ca rezultat o component central de dimensiuni mari, nconjurat de patru componente mai
subiri".
Dispunerea marginal se obine folosind unul dintre constructorii Borderlayout() sau
BorderLayout(int, int). Primul constructor creeaz o dispunere marginal fr nici un spaiu ntre
componente. Al doilea constructor specific spaiul pe orizontal, respectiv pe vertical.

Dup ce ai creat o dispunere marginal i ai stabilit-o drept administrator curent de


dispunere pentru un container, componentele sunt adugate folosind o alt apelare a metodei add()
dect cele folosite anterior:
add(String, componenta)
Al doilea argument al acestei metode este componenta care trebuie adugat n container.
Primul argument este un ir care indic zona unde va fi plasat componenta. Exist cinci valori
posibile: "North" (nord), "South" (sud), "East" (est), "West" (vest) i "Center" Centru).
Urmtoarea instruciune adaug un buton, denumit butonTenninare, n poriunea nordic:
add( "North" , butonTerminare) ;
Combinarea administratorilor de dispunere
Pentru a gsi dispunerea potrivit, de cele mai multe ori trebuie folositi mai multi
administratori pentru aceeai interfa. Acest lucru se poate face adugnd mai multe containere
ntr-un container principal, fiecare dispunnd de propriul administrator de dispunere.
Aceste containere se numesc panouri (panels) i sunt derivate din clasa Panel. Panourile sunt
containere folosite pentru a grupa diferite componente. Cnd lucrai cu panouri trebuie s ine cont
de urmtoarele:
Panoul se umple cu componente nainte de a fi introdus ntr-un container mai mare;
Panoul posed propriul administrator de dispunere.
Crearea unui panou:
Panel panou=new Panel();
Panoului i se atribuie o metod de dispunere prin apelarea metodei setLayout(), ca n exemplul:
BorderLayout b1=new BorderLayout();
panou.setLayout(b1);
Componentele se adaug apoi folosind metoda add().

Dispuneri complexe
Dispunerea n stiv

O dispunere n stiv (card layout) difer de celelalte deoarece ascunde vederii unele
componente. O dispunere n stiv este un grup de containere sau de componente afiate cte unul o
dat. Fiecare container din grup este denumit card (cartel).
n mod normal, dispunerea n stiv folosete un panou pentru fiecare cartel. Mai nti se introduc
componente n panouri, dup care acestea se introduc n containerul pe care s-a stabilit o dispunere
n stiv.
O dispunere n stiv se creeaz cu ajutorul clasei CardLayout, apelnd constructorul acesteia:
CardLayout cc=new CardLayout();
Pentru a stabili administratorul de dispunere pentru un container se folosete metoda
setLayout(). Dup ce ai stabilit un container se folosete metoda add(String, container). Al doilea
argument specific containerul sau componenta care reprezint cartela. Dac este vorba de un
container acesta trebuie s conin deja toate componentele necesare. Primul argument este un ir
care reprezint numele cartelei. Acesta poate fi oricare, ca n exemplul:
add(Cartela de optiuni, optiuni)
prin care se adaug n container un panou numit optiuni i i se atribuie numele Cartela de optiuni.

Dup ce s-a adugat cartela n containerul principal al programului, se poate folosi metoda show() a
administratorului de dispunere n stiv, metod ce primete dou argumente:
Containerul n care au fost adugate cartelele. Dac containerul este chiar fereastra
principal se poate folosi this.
Numele cartelei
Urmtorul exemplu apeleaz metoda show() a administratorului de dispunere n stiv denumir cc:
cc.show(this,Cartela de date)

La afiarea unei cartele, cartela afiat anterior este ascuns.


Dispunerea tabelar neproporional

O astfel de dispunere difer de una tabelar simpl prin urmtoarele:


O component poate ocupa mai multe celule ale tabelului
Proporiile dintre diferitele rnduri i coloane ale tabelului nu trebuie s fie aceleai
Componentele dispuse n cadrul celulelor pot fi aranjate n diverse moduri
Pentru a crea un astfel de mod de dispunere se folosesc clasele GridBagLayout i o clas extern
GridBagConstraints. Prima este administratorul de dispunere iar a doua este folosit pentru a
defini restriciile fiecrei componente.
Se parcurg etapele:
1. crearea unui obiect GridBagLayout i definirea sa drept administrator curent
2. crearea unei noi instane a clasei GridBagConstraints
3. definirea restriciilor pentru o component
4. anunarea componentei i a restriciilor sale n administratorul de dispunere
5. introducerea componentei n container
Exemplu:
GridBagLayout tabel=new GridBagLayout();
GridBagConstraints restrictii = new GridBagConstraints();
setLayout(tabel);
Button b=new Button(Salvare);
restrictii.gridx=0;
restrictii.gridy=0;

restrictii.gridwidth=1;
restrictii.gridheight=1;
restrictii.weightx=30;
restrictii.weighty=30;
restrictii.fill= GridBagConstraints.NONE;
restrictii.anchor= GridBagConstraints.CENTER;
tabel.setConstraints(b,restrictii);
add(b);
Etapele care trebuie parcurse la dispunerea tabelara neproporional
Etapa 1. Proiectarea tabelului

Initial se face o proiectare pe hrtie a tabelului, etichetnd celulele tabelului dup


coordonatele lor x i y. Astfel, celula din colul de stnga sus are coordonatele 0,0, cea alturat are
coordonatele 0,1 .a.m.d.
Etapa a doua. Crearea tabelului

O variant ar fi s se creeze o metod ajuttoare, care preia mai multe valori i stabilete
restriciile pentru acestea. Asftel metoda definireRestrictii() preia apte argumente: un obiect
GridBagConstraints i ase valori ntregi, care reprezint variabilele de instan gridx, gridy,
gridwidth, gridheight, weightx i weighty. Metoda definireRestrictii este urmtoarea:
void definireRestrictii(GridBagConstraints gbc, int gx, int gy, int gw, int
gh, int wx, int wy) {
gbc.gridx=gx;
gbc.gridy=gy;
gbc.gridwidth=gw;
gbc.gridheight=gh;
gbc.weightx=wx;
gbc.weighty=wy;
}
Se creeaz apoi metoda init() , n care se creeaz de fapt dispunerea.
public void init()
{GridBagLayout tabel=new GridBagLayout();
GridBagConstraints restrictii =new GridBagConstraints();
SetLayout(tabel);
restrictii.fill=GridBagConstraints.BOTH;
}
Se vor defini apoi restrictii corespunztoare fiecrei componente din interfa, ca n
exemplul urmtor:
definireRestrictii(restrictii, 0,0,1,1,100,100);
Button eticheta1=new Button(nume);
tabel.setConstraints(eticheta1,restrictii);
add(eticheta1);
Aceste linii vor stabili restriciile pentru un obiect, vor crea un buton, vor asocia acestuia restriciile
i l vor aduga n panou.
Primele dou argumente reprezint valorile gridx i gridy ale restriciilor. Acestea
reprezint chiar coordonatele celulei ce conine componenta. Dac o component ocup mai multe
celule se vor introduce coordonatele componentei cea mai din stnga-sus. Urmtoarele argumente
reprezint gridwidth i gridheight. Ele nu reprezint laimea i nlimea n pixeli, ci reprezint
numrul de celule pe care le ocup componenta. Ultimele dou argumente sunt proporiile weightx
i weighty, folosite pentru a stabili proporiile rndurilor i a coloanelor, adic modul de distribuire
al spaiului suplimentar care rmne neutilizat dup amplasarea componentei. Dup stabilirea
proporiilor ele pot fi atribuite unui obiect folosind metoda GridBagConstraints().

Etapa a treia: Determinarea proporiilor

La determinarea proporiilor se ine cont de obiectele care se extind pe mai multe celule.
Acestea trebuie s primeasc valoarea 0 n direcia n care se extind.
Etapa a patra. Adugarea i aranjarea componentelor

n aceast etap se stabilesc restriciile care arajeaz componentele n cadrul celulei. Exist
dou astfel de restricii: fill (umplere) i anchor (ancorare).
Restricia fill determin pentru componentele care se pot extinde n orice direcie n ce direcie
se face aceast extindere i poate avea una dintre urmtoarele valori:
GridBagConstraints.BOTH, care extinde componenta pentru a umple celula n ambele direcii
GridBagConstraints.NONE, care determin componenta s fie afiat la cea mai mic dimensiune
a sa
GridBagConstraints.HORIZONTAL, care extinde componenta pe direcie orizontal
GridBagConstraints.VERTICAL, care extinde componenta pe direcie vertical.
Implicit restricia fill este NONE.
A doua restricie care afecteaz modul n care apare o component ntr-o celul este anchor
(ancorare) i ea se aplic doar componentelor care nu umplu ntreaga celul, indicnd funciilor
AWT unde s plaseze componenta n cadrul celulei. Valori posibile:
GridBagConstraints.NORTH, GridBagConstraints.SOUTH, GridBagConstraints.NORTHEAST,
GridBagConstraints.SOUTHWEST, GridBagConstraints.EAST, GridBagConstraints.WEST,
GridBagConstraints.SOUTHEAST, GridBagConstraintsNORTHWEST, GridBagConstraints.CENTER.

Valoarea implicit este GridBagConstraints.CENTER.

Tratarea evenimentelor
Unul dintre lucrurile pe care le-ai nvat atunci cnd ai creat pentru prima dat un applet
este c, atunci cnd acesta ruleaz, n fundal se desfoar o mulime de activiti. Sistemul de
ferestre al Java apeleaz automat metode cum ar fi paint(), init() sau start(), atunci cnd este nevoie,
fr nici o intervenie din partea dumneavoastr.
Ca i programarea applet-urilor, tratarea evenimentelor presupune apelarea automat a unor
metode atunci cnd aciunea unui utilizator duce la apariia unui eveniment.

Tipuri de evenimente
Un eveniment este generat ca rspuns la aproape orice aciune pe care o poate ntreprinde un
utilizator pe parcursul ciclului de via al unui program Java. O micare a mouse-ului, un clic
executat pe un buton, o apsare de tast, toate genereaz un eveniment.
n programele dumneavoastr nu trebuie s tratai toate evenimentele ce por aprea. De fapt,
v vei ocupa de acele evenimente la care vrei s rspund programul dumneavoastr; restul vor fi
ignorate. De exemplu, dac utilizatorul execut un clic cu mouse-ul sau apas o tast, putei face ca
programul s rspund la aceste evenimente.
Iat cteva dintre evenimentele care pot fi tratate n programele dumneavoastr:
Clicuri cu mouse-ul. Apsarea butonului mouse-ului (mouse down), eliberarea acestuia
(mouse up) sau apsarea i eliberarea butonului pe aceeai poziie (mouse clic).

Micri ale mouse-ului. Cursorul mouse-ului care prsete sau ptrunde pe suprafaa
ocupat de o component a interfeei sau tragerea cu mouse-ul (drag - micrile efectuate de
cursor atunci cnd butonul mouse-ului este apsat).
Apsri de taste. Apsarea tastei, eliberarea tastei, tastarea (apsarea i eliberarea unei
taste).
Evenimente ale interfeei utilizator. Execuia de clicuri pe butoane, derularea listelor,
afiarea meniurilor derulante i aa mai departe.
Metoda handleEvent ()

Tratarea evenimentelor reprezint domeniul n care au aprut cele mai multe modificri n
trecerea de la Java 1.02 la Java 2. Evenimentele sunt generate i executate aproximativ n acelai
mod, indiferent de versiunea de limbaj pe care o folosii; diferena const n modul cum acestea sunt
recepionate i procesate.
n Java 1.02, toate evenimentele care apar n ciclul de via al unui program sunt tratate de o
metod denumit handleEvent(). Aceasta este definit n clasa Component, care este motenit de
java.applet.Applet, devenind astfel disponibil tuturor applet-urilor.
Atunci cnd un eveniment este transmis metodei handleEvent (), aceasta apeleaz apoi o
metod specific de tratare a evenimentului, n funcie de tipul acestuia. Exemple de astfel de
metode specifice sunt mouseDown(), mouseUp() sau keyDown().
Pentru a trata un eveniment n programele dumneavoastr, va trebui s suprascriei una
dintre aceste metode specifice. Apoi, la apariia evenimentului respectiv, metoda respectiv va fi
apelat. De exemplu, putei suprascrie metoda mouseDown() pentru a afia un mesaj n fereastra
Applet. Atunci cnd apare un eveniment de acest tip (apsarea butonului mouse-ului), mesajul va fi
afiat.
Tratarea clicurilor de mouse
Unul dintre cele mai des ntlnite evenimente care v-ar putea interesa este efectuarea unui
clic cu mouse-ul. Evenimentele de acest tip apar atunci cnd utilizatorul execut un clic cu mouseul undeva, pe interfaa programului.
Putei intercepta clicurile mouse-ului pentru diferite lucruri simple - de exemplu, pentru a
activa sau dezactiva sunetul ntr-un applet, pentru a trece la urmtoarea plan a unei prezentri sau
pentru a terge ecranul. De asemenea, clicurile cu mouse-ul pot fi folosite mpreun cu deplasrile
acestuia pentru a realiza o form de interaciune mai complex cu utilizatorul.
Evenimentele mouse down i mouse up
Atunci cnd utilizatorul execut un clic cu mouse-ul, se genereaz dou evenimente: un
eveniment mouse down, atunci cnd se apas butonul mouse-ului, i un eveniment mouse up, atunci
cnd acesta este eliberat. Aceast divizare permite executarea unor aciuni diferite n cele dou
etape ale clicului.
Tratarea evenimentelor mouse-ului n applet-ul dumneavoastr este simpl; se suprascrie
metoda corespunztoare, care va fi apelat la apariia respectivului eveniment. Iat un exemplu de
semntur de metod pentru un eveniment mouse down:
public boolean mouseDown(Event evt, int x, int y) {

//. . .
}
Metoda mouseDown() (ca i metoda mouseUp()) primete trei parametri: evenimentul n
sine i coordonatele x i y unde a aprut evenimentul respectiv.
Argumentul evt reprezint o instan a clasei Event. Toate evenimentele genereaz o
instan a clasei Event, care conine informaii privind locul i perioada cnd a avut loc
evenimentul, tipul lui, precum i alte informaii. Uneori, existena unui astfel de pointer ctre un
obiect Event este folositoare, aa cum vei descoperi mai trziu n aceast seciune.
Coordonatele x i y ale evenimentului, aa cum au fost ele transmise prin argumentele x i y
ale metodei mouseDown(), v permit s determinai cu precizie locul unde s-a efectuat , clicul. Deci
de exemplu, dac evenimentul mouse down a aprut n zona unui buton grafic, putei activa acel
buton. Reinei c putei obine coordonatele x i y i din cadrul obiectului Event; n aceast metod,
ele au fost transmise ca argumente separate pentru a se lucra mai uor cu ele.

Tratarea micrilor mouse-ului


Ori de cte ori se deplaseaz mouse-ul, se genereaz un eveniment. Deplasarea mouse-ului
de la un capt la altul ale ferestrei applet-ului poate avea ca rezultat generarea a zeci de evenimente.
AWT definete dou tipuri distincte de micri ale mouse-ului:
"tragerea" mouse-ului (mouse drag), n care micrile se fac innd butonul mouse-ului apsat, i
micri simple (mouse move), n care butonul nu este apsat.
n plus, ori de cte ori mouse-ul intr pe sau iese de pe suprafaa applet-ului sau a oricrei
componente sau container al acestuia, se genereaz evenimente mouse enter, respectiv mouse exit.
Pentru fiecare dintre aceste evenimente exist metode speciale care le intercepteaz, aa cum
metodele mouseDown() i mouseUp() interceptau clicurile mouse-ului.

Evenimentele mouse drag i mouse move


Pentru interceptarea i tratarea evenimentelor de deplasare a mouse-ului se folosesc
metodele mouseDrag() i mouseMove().
Metoda mouseMove(), care trateaz micrile simple de mouse, adic cele cnd nu este inut
apsat butonul mouse-ului, seamn foarte mult cu metodele care tratau clicurile de mouse:
public boolean mouseMove(Event evt, int x, int y) {
// ...
}
Metoda mouseDrag() trateaz micrile mouse-ului executate avnd butonul apsat (o
micare complet de tragere" - drag - const dintr-un eveniment mouse down, o serie de
evenimente mouse drag pentru fiecare pixel pe care se deplaseaz mouse-ul, urmat de un
eveniment mouse up, la eliberarea butonului. Metoda mouseDrag() arat astfel:
public boolean mouseDrag(Event evt, int x, int y) {
// ...
}
De reinut c n cadrul ambelor metode, mouseMove() i mouseDrag(), argumentele pentru
coordonatele x i y reprezint noua poziie a mouse-ului, i nu locul de pornire.

Evenimentele mouse enter i mouse exit


Metodele mouseEnter() i mouseExit() sunt apelate cnd indicatorul mouse-ului ptrunde
sau prsete un applet sau o poriune a acestuia. Att mouseEnter(), ct i mouseExit() posed
semnturi similare cu metodele pentru tratarea clicurilor. Acestea primesc trei argumente: obiectul
Event i coordonatele x i y ale punctului unde mouse-ul a ptruns n applet sau l-a prsit.
Urmtoarele exemple prezint semnturile metodelor mouseEnter() i mouseExit():
public boolean mouseEnter(Event evt, int x, int y) {
// . . .
}
public boolean mouseExit(Event evt, int x, int y) {
// ...
}
Tratarea evenimentelor de tastatur
Un eveniment de tastatur este generat ori de cte ori utilizatorul apas o tast. Prin folosirea
acestor evenimente putei memora valorile tastelor apsate de utilizator pentru a executa o anumit
aciune sau pentru a obine date de intrare de la utilizatorii applet-ului.
Pentru ca evenimentul de tastatur sa fie recepionat de o component, aceasta trebuie s fie
selectat (focused - n centrul ateniei"; cu alte cuvinte, s fie acea component a interfeei
selectat pentru a primi datele de intrare). Vei nva mai trziu despre aceast selectare a
componentelor, atunci cnd vei lucra cu evenimente de selectare (focus events). Selectarea este
mai uor de neles dac luai exemplul unei interfee care conine mai multe cmpuri de text.
Cursorul plpie n cmpul de text selectat, iar utilizatorul poate introduce text n acel cmp
folosind tastatura. Nici un alt cmp nu poate primi date de la tastatur pn cnd nu este selectat.
Toate componentele, inclusiv containerele, pot fi configurate pentru a fi selectate.
Pentru a indica explicit c o component este selectat pentru a primi date de intrare (input
focus), poate fi apelat metoda requestFocus() a componentei, fr argumente. Urmtoarea
instruciune selecteaz un obiect Button, denumit terminare:
terminare.requestFocus() ;
Putei selecta fereastra Applet apelnd metoda requestFocus() a acesteia.

Evenimentele key down i key up


Pentru a trata un eveniment de tastatur poate fi folosit metoda keyDown():
public boolean keyDown(Event evt, int tasta) {
// ...
}
Valorile generate de evenimentele key down - tast apsat - (i transmise metodei
keyDown() drept argumentul tasta) sunt ntregi care reprezint valori Unicode, cum ar fi caractere

alfanumerice, taste funcionale, tabulatori, tasta return (retur de car) i aa mai departe. Pentru a le
folosi drept caractere (de exemplu, pentru a le tipri) trebuie s le convertii n caractere, astfel:
caracterCrt = (char)tasta;
Iat un exemplu simplu de metod keyDown(), care nu face altceva dect s afieze tasta pe
care ai apsat-o, att ca valoare Unicode, ct i drept caracter :
public boolean keyDown(Event evt, int tasta) {
System.out.println("Valoare UNICODE: " + tasta) ;
System.out.println("Caracter: " + (char) tasta) ;
return true;
}
Ca i n cazul clicurilor de mouse, fiecare eveniment key down are i corespondentul key up
tast ridicat. Pentru a intercepta evenimentele key up se folosete metoda keyUp():
public boolean keyUp(Event evt, int tasta) {
// ...
}

Taste prestabilite
Clasa Event ofer un set de variabile de clas care reprezint cteva taste standard nealfanumerice, cum ar fi tastele funcionale sau tastele direcionale (cu sgei). Dac interfaa appletului dumneavoastr folosete aceste taste, putei crea un cod mai lizibil prin testarea acestora n
metoda keyDown(), n loc s testai valorile numerice echivalente (de asemenea, dac folosii aceste
variabile, codul dumneavoastr va funciona cu mai mare probabilitate pe alte platforme). De
exemplu, cnd dorii s testai dac a fost apsat tasta direcional cu sgeata n sus (up arrow),
putei folosi urmtoarea secven de cod:
if (tasta = Event.UP) {
// ...
}
Deoarece valorile acestor variabile de clas sunt ntregi, putei folosi pentru testarea lor
instruciunea switch.
n tabelul urmtor se prezint variabilele de clas Event pentru diferite taste, precum i semnificaia
acestora.
Tastele standard definite n clasa Event.
Variabila de clas

Tasta reprezentat

Event.HOME
Event.END
Event.PGUP
Event.PGDN
Event.UP
Event.DOWN

Tasta Home
Tasta End
Tasta Page Up
Tasta Page Down
Tasta Up
Tasta Down

Event.LEFT

TastaLeft

Event.RIGHT
Event.F1
Event.F2
Event.P3
Event.F4
Event.F5
Event.F6
Event.F7
Event.F8
Event.F9
Event.F10
Event.F11
Event.F12

Tasta Right
Tasta F1
Tasta F2
Tasta F3
Tasta F4
TastaF5
Tasta F6
Tasta F7
Tasta F8
Tasta F9
Tasta F10
TastaF11
TastaF12

Tratarea evenimentelor componentelor

Tehnicile de tratare a evenimentelor pe care le-ai nvat pn acum sau axat pe


interaciunea cu utilizatorul - execuia unui clic cu mouse-ul, apsarea unor taste i altele de acest
gen. Exist i altfel de evenimente, care au loc pe componente cum ar fi butoane, zone de text sau
alte elemente de interfa. De exemplu, butoanele folosesc evenimente declanate la apsarea lor.
Nu trebuie s v intereseze evenimentul mouse down sau mouse up sau locul unde a aprut
interaciunea respectiv; componenta se va ocupa de toate aceste evenimente n locul
dumneavoastr.
Urmtoarele evenimente pot fi generate prin interaciunea cu componentele interfeei:
Evenimente de aciune (action events). Sunt principalele evenimente ale majoritii
componentelor interfeei, prin care se indic faptul c acestea au fost "activate".
Evenimentele de aciune sunt generate atunci cnd este apsat un buton, cnd se selecteaz
sau se deselecteaz o caset de validare sau un buton radio, cnd se alege o opiune dintr-un
meniu sau cnd utilizatorul apas tasta Return sau Enter ntr-un cmp de text.
Evenimente de selectare sau deselectare a listelor (list select/deselect events). Aceste
evenimente sunt generate atunci cnd se selecteaz o caset de validare sau o opiune dintrun meniu (list). Aceste exemple declaneaz, de asemenea un eveniment de aciune.
Evenimente de primire sau cedare a seleciei (got/lost focus events). Aceste evenimente pot
fi generate de orice component, fie ca rspuns la un clic de mouse, fie la selecionarea prin
tasta Tab. Primirea seleciei (got focus) nseamn c acea component este selecionat i
poate fi activat sau poate primi date de intrare. Cedarea seleciei (lost focus) nseamn c sa selecionat o alt component.
Tratarea evenimentelor de aciune
Un eveniment de aciune reprezint cel mai des ntlnit eveniment al unei interfee i, din
acest motiv, exist o metod special pentru a-l trata, la fel cum exist metode pentru aciunile de
mouse sau de tastatur.
Pentru a intercepta un eveniment de aciune generat de o component se definete n applet o
metod denumit action(),cu urmtoarea semntur:
public boolean action(Event evt, Object arg) {
// ...
}
Aceast metod action() ar trebui s arate asemntor cu metodele de tratare a evenimentelor
de mouse sau de tastatur. Ca i acele metode, aceasta primete ca argument un obiect care refer
evenimentul respectiv. Ea mai primete, de asemenea, un obiect suplimentar (n acest caz,
parametrul arg), care poate fi de orice tip.
Tipul acestui al doilea argument al metodei de aciune depinde de componenta interfeei care
a generat aciunea. O caracteristic de baz ar fi c este vorba de "orice fel de argument",
determinat de componenta nsi, care poate transmite informaiile suplimentare necesare pentru a
procesa aciunea respectiv. Tabelul urmtor prezint argumentele suplimentare pentru fiecare tip
de component.
Componente
Butoane
Casete de validare
Butoane radio

Tip de argument
String
Boolean
Boolean

Ce conine
Eticheta butonului
ntotdeauna true
ntordeauna true

Meniuri de opiuni
Cmpuri de text

String
String

Eticheta elementului selectat


Textul din cadrul cmpului

n cadrul metodei action(), primul lucru care trebuie fcut este s testai care component a
generat aciunea (spre deosebire de evenimentele de mouse sau de tastatur, n care aceasta nu
conta, deoarece toate componentele puteau genera aciuni). Din fericire, obiectul Event pe care l
primii ca argument n apelul metodei action() conine o variabil de instan denumit target (int),
care conine o referin ctre obiectul ce a generat evenimentul. Putei folosi operatorul instanceof
pentru a afla ce component a generat evenimentul, ca n urmtorul exemplu:
public boolean action(Event evt, Object arg) {
if (evt.target instanceof textField)
return handleText(evt.target);
else if (evt.target instanceof Choice);
return handleChoice(arg);
// ...
return false;
}
n acest exemplu, metoda action() putea fi generat fie de o component TextField (cmp de
text), fie de un meniu cu opiuni; instruciunea if determin care dintre acestea dou a generat
evenimentul i apeleaz o alt metod (aici, handleText() sau handlechoice()), care trateaz, de fapt,
evenimentul respectiv. (Nici handleText() i nici handleChoice() nu sunt metode AWT; sunt doar
exemple de nume ce pot fi folosite drept metode ajuttoare. Se obinuiete s se creeze astfel de
metode ajuttoare - helper - aa nct metoda action() s nu devin prea ncrcat cu cod.)
Ca i n cazul altor metode de tratare a evenimentelor, action() returneaz o valoare Boolean.
La fel, trebuie s returneze true dac va trata evenimentul respectiv i false dac acesta va fi ignorat
sau tratat n alt parte. n acest exemplu ai transferat controlul metodelor handleText() sau
handleChoice(), care vor returna true sau false, aa ca putei returna false (reinei, vei returna true
numai daca metoda proceseaz evenimentul).
Pot aprea complicaii dac avei mai multe componente aparinnd toate aceleiai clase - de
exemplu, o mulime de butoane. Toate genereaz aciuni i toate sunt instane ale clasei Button. Aici
intervine argumentul suplimentar: folosind cteva comparaii simple de iruri, putei folosi
etichetele, elementele sau coninutul componentei pentru a determina care dintre ele a generat
evenimentul. (Nu uitai s convertii prin cast argumentul n obiectul corespunztor.)
public boolean action(Event evt, Object arg) {
if (evt.target instanceof Button) {
String eticheta = (String)arg;
if (eticheta.equals("OK"))
// trateaza butonul OK
else if (eticheta.equals ("Anulare"))
// trateaza butonul Anulare
else if (eticheta.equals("Navigare"))
// trateaza butonul Navigare
// ...
}
}

Tratarea evenimentelor de selectare


Aa cum am artat mai devreme, evenimentele de aciune sunt de departe cele mai des
ntlnite evenimente pe care le vei trata ntr-o interfa. Totui, mai exist i alte elemente pe care
le putei folosi n programele dumneavoastr: list select (selecie list), list deselect (deselecie
list), got focus (primire selecie) i lost focus (cedare selecie). Pentru evenimentele got focus i
lost focus se pot folosi metodele gotFocus() i lostFocus(), care se folosesc la fel ca metoda
action(). Iat semnturile lor:
public boolean gotFocus(Event evt, Object arg) {
// ...
}
public boolean lostFocus(Event evt, Object arg) {
// ...
}
Pentru evenimentele de selectare i deselectare de liste nu sunt disponibile metode uor de
suprascris. Pentr a trata aceste evenimente trebuie folosit metoda handleEvent(), ca n exemplul
urmtor:
public boolean handleEvent(Event evt) {
if (evt.id == Event.LIST_SELECT)
handleSelect(Event);
else if (evt.id == Event.LIST_DESELECT)
handleDeselect(Event) ;
else return super.handleEvent(evt);
}
n acest extras de cod, Event.LIST_SELECT i Event.LIST_DESELECT reprezint
identificatorii oficiali ai evenimentelor de selectare/deselectare liste, iar controlul este transferat
ctre dou metode ajuttoare ( handleSelect() i handleDeselect () ), care se presupune c sunt
definite n alt parte. Remarcai, de asemenea, apelul ctre super.handleEvent() din final; acesta
permite celorlalte evenimente s fie transferate fr probleme ctre metoda handleEvent() original.
Evenimente ale zonelor de text
Zonele de text prezint aceleai evenimente ca i cmpurile de text. Putei folosi metodele
gotFocus() i lostFocus() pentru a intercepta evenimentele de primire/cedare a selecei:
public boolean gotFocus(Event evt, Object arg) {
// . ..
}
public. boolean lostFocus(Event evt, Object arg) {
// ...
}
Evenimente ale listelor derulante

Listele derulante genereaz trei tipuri de evenimente diferite; selectarea sau deselectarea
unui element individual al listei are ca efect un eveniment de selectare/deselectare list, iar dublul
clic executat pe un element al listei are ca efect un eveniment de aciune.
Putei suprascrie metoda action() pentru a trata elementul din list pe care s-a efectuat dubluclic. Pentru seleciile i deseleciile din list, putei s suprascriei metoda handleEvent() i s testai
identificatorii de eveniment LIST_SELECT i LIST_DESELECT.

Evenimente ale barelor de derulare


Numai pentru diferitele tipuri de micri ale acestora este generat o ntreag gam de
evenimente. Pentru toate acestea va trebui s folosii metoda handleEvent(). Tabelul urmtor
prezint identificatorii de evenimente care v intereseaz i micrile care declaneaz aceste
evenimente.
Evenimente ale barelor de derulare
Ce reprezint
Identificatorul evenimentului
SCROLL_ABSOLUTE
SCROLL_LINE_DOWN
SCROLL_LINE_UP
SCROLL_PAGE_DOWN
SCROLL_PAGE_UP

Generat la deplasarea casetei barei de derulare


Generat la selectarea butonului din captul de
jos sau din stnga al barei de derulare
Generat la selectarea butonului din captul de
sus sau din dreapta al barei de derulare
Generat la selectarea spaiului aflat dedesubtul
(sau la stnga) casetei barei de derulare
Generat la selectarea spaiului aflat deasupra
(sau la dreapta) casetei barei de derulare

Dezvoltarea de interfee utilizator avansate folosind AWT


Ferestre, cadre i casete de dialog
n afar de ceea ce vi s-a prezentat pn acum, AWT mai ofer posibilitatea crerii
de elemente de interfa n afara suprafeei applet-ului sau a ferestrei browserului,
elemente cum ar fi ferestre, cadre sau casete de dialog. Aceste faciliti v permit s creai
aplicaii complete, ca parte a applet-ului sau ca aplicaii Java independente.

Clasele Window
Clasele AWT care produc ferestre sau casete de dialog motenesc o clas comun, Window. Clasa Window
motenete clasa Container, ca i componentele panou i applet, i ofer un comportament generic pentru toate
elementele derivate din ferestre.

De obicei nu se folosesc instane ale clasei Window, ci ale celor dou subclase principale
ale sale: Frame i Dialog.
Clasa Frame (cadru) ofer o fereastr care conine o bar de titlu, butoane de
nchidere i alte elemente specifice unei ferestre pentru un anumit sistem. De asemenea,
cadrele permit adugarea unor bare de meniuri. Clasa Dialog este o variant mai limitat
a clasei Frame, care, de obicei, nu are un titlu. FileDialog, o subclas a clasei Dialog,
ofer o caset de dialog standard pentru alegerea unui fiier (de obicei, aceasta poate fi
folosit doar n cadrul aplicaiilor Java, deoarece applet-urile impun restricii de securitate).
Pentru a aduga o fereastr sau o caset de dialog n applet-ul sau aplicaia dumneavoastr
trebuie s creai subclase ale claselor Frame sau Dialog.

Cadre
Cadrele (frames) sunt ferestre independente de fereastra applet-ului sau a browserului care
conine applet-ul; ele sunt ferestre separate, care conin titluri proprii, butoane de redimensionare
sau de nchidere i bare de meniuri. Putei crea cadre, n applet-uri, pentru a produce ferestre sau le
putei folosi n aplicaii pentru a pstra coninutul acestora.
Un cadru reprezint o fereastr specific unei anumite platforme, care conine un titlu, o
bar de meniuri, butoane de nchidere i de redimensionare i alte elemente specifice unei ferestre.
Pentru a crea un cadru se folosete unul din urmtorii constructori:

new Frame () creeaz un cadru simplu, fr titlu.


new Frame (String) creeaz un cadru simplu, cu titlul dat de irul primit ca argument.
Deoarece cadrele motenesc clasa Window, care motenete clasa Container, care
motenete clasa Component, cadrele sunt create i folosite cam n acelai fel cu celelalte
componente AWT. Cadrele sunt containere, ca i panourile, deci putei aduga n ele diferite
componente folosind metoda add (), ca i n panouri (panels). Dispunerea prestabilit pentru cadre

este BorderLayout. Iat un exemplu care creeaz un cadru, stabilete dispunerea componentelor n
acesta i adaug dou butoane:
win = new Frame("Fereastra mea") ;
win.setLayout(new BorderLayout(10, 20));
win.add("North", new Button("Start")) ;
win.add("Center", new Button("Mutare"));
Pentru a stabili dimensiunea noului cadru se folosete metoda resize (), care primete ca
argumente limea i nlimea acesteia. De exemplu, aceast linie de cod redimensioneaz fereastra
la dimensiunile de 100 pixeli lime i 200 pixeli nlime:
win.resize(100, 200);
Deoarece n sisteme diferite se calculeaz n mod diferit reprezentrile pixelilor i exist
rezoluii diferite, este dificil crearea unui cadru de dimensiuni bune" pentru oricare platform.
Ferestrele care sunt potrivite ntr-un sistem pot fi prea mici sau prea mari ntr-un altul.
O metod de evitare a acestei probleme este folosirea metodei pack() n locul metodei
resize(). Metoda pack(), care nu primete argumente, creeaz o fereastr de cea mai mic
dimensiune posibil, date fiind dimensiunile curente ale componentelor pe care le conine,
administratorul de dispunere i inseriile folosite. Urmtorul exemplu creeaz dou butoane i le
adaug ntr-o fereastr. Dup aceasta, fereastra este adus la cele mai mici dimensiuni posibile cnd
conine aceste dou butoane.
FlowLayout flo = new FlowLayout() ;
Button ok = new Button("OK");
Button anulare = new Button("Anulare");
win.setLayout(flo);
win.add(ok) ;
win.add(anulare);
win.pack() ;
Atunci cnd creai o fereastr, aceasta este invizibil. Pentru a fi afiat pe ecran trebuie s
folosii metoda show(). Pentru a o ascunde din nou putei folosi metoda hide(). Exemplu:
win.show() ;
Reinei c atunci cnd o fereastr este afiat de un applet, browserul v atrage atenia c
aceasta nu este o fereastr a sa, de obicei, printr-un mesaj n cadrul ferestrei.

Casete de dialog
Casetele de dialog, din punct de vedere funcional, sunt asemntoare cadrelor prin faptul c afieaz ferestre
pe ecran. Totui, ele sunt destinate pentru a fi folosite drept ferestre temporare adic pentru a v prezenta mesaje de
avertizare, pentru a v cere anumite informaii i aa mai departe.

Casetele de dialog nu au, de obicei, bare de titlu sau alte elemente caracteristice unei ferestre
(cu toate c putei crea i casete de dialog cu bare de titlu). Ele pot fi definite aa nct s nu fie
redimensionabile sau pot fi definite drept modale. (Casetele de dialog modale mpiedic accesarea
altor ferestre pn n momentul cnd se renun la ele.)
Casetele de dialog sunt ferestre temporare avnd rolul de a alerta utilizatorul cu privire la un anumit eveniment
sau de a prelua date de la utilizator. Spre deosebire de cadre, casetele de dialog nu posed, de obicei, bare de titlu sau
butoane de nchidere.

O caset de dialog modal nu permite introducerea de date n alte ferestre pn cnd nu este
nchis. Nu vei putea aduce n prim plan o alt fereastr i nici minimiza caseta de dialog modal;
aceasta trebuie nchis explicit pentru a se putea continua lucrul n sistem. De obicei, avertismentele
sunt casete de dialog modale.

AWT ofer dou tipuri de casete de dialog: clasa Dialog, care produce o caset de dialog
generic, i FileDialog, care produce o caset de dialog pentru cutarea de fiiere, specific
platformei respective.

Obiecte dialog
Casetele de dialog se creeaz i se folosesc asemntor ferestrelor. Pentru crearea unei casete de dialog
generice se folosete unul din urmtorii constructori:
Dialog (Frame, boolean) creeaz o caset de dialog invizibil, ataat cadrului curent, fie

modal (true), fie nemodal (false).


Dialog(Frame, String, boolean) creeaz o caset de dialog invizibil, cu titlul dat de
argumentul ir, ataat cadrului curent, modal (true) sau nu (false).
Fereastra de dialog, ca i cadrul de fereastr (frame), este un panou pe care se pot dispune i
desena componente de interfa sau pe care se pot realiza operaii grafice, la fel cum s-ar proceda cu
oricare alt panou. Ca i alte ferestre, i cea de dialog este iniial invizibil, ns o putei afia sau
ascunde folosind metodele show() , respectiv hide().

Ataarea casetelor de dialog la applet-uri


Casetele de dialog pot fi ataate numai cadrelor (frames). Pentru a crea o caset de dialog, trebuie s transmitei
o instan a clasei Frame uneia dintre metodele constructor ale casetei de dialog. Acest lucru nseamn c nu putei crea
casete de dialog ataate applet-urilor. Deoarece applet-urile nu sunt cadre, nu le putei transmite ca argument unei clase
Dialog. Totui, cu puin ndemnare, putei face rost de un obiect cadru care conine un applet (adesea, chiar browserul
sau fereastra de vizualizare a applet-ului), dup care s folosii acest obiect drept cadru pentru caseta de dialog.

Codul care face acest lucru folosete metoda getParent(), definit pentru toate
componentele AWT. Metoda getParent() returneaz obiectul care conine obiectul curent. Deci
printele tuturor aplicaiilor AWT trebuie s fie un cadru. Applet-urile se comport n acelai mod.
Prin apelarea n mod repetat a metodei getParent() vei ajunge, pn la urm, s obinei o instan
a clasei Frame. lat codul pe care trebuie s l introducei n applet-ul dumneavoastr:
Object ancora = getParent();
while (! (ancora instanceof Frame))
ancora = ((Component)ancora).getParent();
n prima linie a codului se creeaz o variabil local, denumit ancora, care va memora n final
cadrul acestui applet. Obiectul atribuit variabilei poate fi de mai multe tipuri, aa nct va fi
declarat de tip Object.
Urmtoarele dou linii de cod definesc un ciclu while care apeleaz metoda getParent() n
lan, pentru fiecare obiect, pn cnd ajunge la un obiect de tip Frame. Se observ aici c, deoarece
metoda getParent() este definit doar pentru obiectele care motenesc clasa Component, trebuie s
convertii prin cast valoarea ancora la tipul Component de fiecare dat cnd apelai metoda
getParent().
Dup ncheierea ciclului, obiectul coninut de variabila ancora va fi o instan a clasei Frame
(sau a uneia dintre subclasele acesteia). Putei crea un obiect Dialog ataat acestui cadru convertind
prin cast variabila ancora, pentru a v asigura c obinei un obiect Frame:
TextDialog dl = new TextDialog((Frame)ancora, "Enter Text",true);

Casete de dialog pentru sistemul de fiiere


Clasa FileDialog permite crearea unei casete de dialog de tip File Open/Save (pentru deschiderea sau salvarea
fiierelor), care v permite s accesai sistemul local de fiiere. Clasa FileDialog este independent de sistem, ns n
funcie de platform este folosit caseta de dialog Open File (Deschidere fiier) sau Save File (Salvare fiier).

Folosirea de instane ale clasei FileDialog n applet-uri depinde de browser. Din cauza
restriciilor de securitate existente n applet-uri, majoritatea browserelor produc o excepie de
securitate atunci cnd ncercai acest lucru. Obiectele FileDialog sunt mai folositoare n aplicaiile
independente.
Pentru a crea o caset de dialog pentru fiiere, folosii unul din urmtorii constructori:
FileDialog(Frame, String) creeaz o caset de dialog ataat unui cadru dat i cu un titlu
dat, pentru ncrcarea unui fiier.
FileDialog(Frame, String, int) creeaz tot o caset de dialog, ns argumentul ntreg este
folosit pentru a stabili dac este vorba despre o caset de dialog pentru ncrcarea sau pentru
salvarea unui fiier. (Singura diferen este eticheta butoanelor; de fapt, aceast caset de
dialog nu deschide sau nu salveaz nimic.) Opiunile pentru acest argument sunt
FileDialog.LOAD sau FileDialog.SAVE.
Dup crearea unei instane a clasei FileDialog se folosete metoda show() pentru a o afia:
FileDialog fd = new FileDialog(this, "FileDialog=) ;
fd.show() ;
Atunci cnd utilizatorul alege un fiier i nchide caseta de dialog, el poate accesa numele fiierului
ales folosind metodele getDirectory() i getFile(). Ambele metode returneaz un ir care conine
valorile alese de utilizator. Dup aceasta, putei deschide fiierul folosind metodele de lucru cu
fiiere i fluxuri (streams) de date, apoi putei citi sau scrie din/n acest fiier.

Evenimente de fereastr
Ai ajuns acum la ultimul tip de evenimente pe care le putei trata n AWT: evenimentele pentru ferestre i
casete de dialog. (n ceea ce privete evenimentele, caseta de dialog este tot un tip de fereastr.) Evenimentele de
fereastr apar atunci cnd starea unei ferestre se modific: de exemplu, cnd este mutat, redimensionat, minimizat,
restabilit, mutat n prim-plan sau nchis. ntr-o aplicaie ngrijit programat, aceste evenimente trebuie tratate - de
exemplu, pentru a opri firele aflate n execuie atunci cnd o fereastr este minimizat sau pentru a face curenie" la
nchiderea ferestrei.

Putei folosi metoda handleEvent() pentru a testa evenimentele prezentate n tabelul


urmtor folosind instruciunea switch pentru variabila de instan id (identificator).
Evenimente de fereastr.
Numele evenimentului
WINDOW_DESTROY
WINDOW_EXPOSE
WINDOW_ICONIFY
WINDOW_DEICONIFY
WINDOW_MOVED

Cnd apare
Generat atunci cnd o fereastr este nchis folosind butonul Close sau
opiunea de meniu Close
Generat atunci cnd fereastra este adus n prim-plan din spatele altor ferestre
Generat atunci cnd fereastra este minimizat (redus la dimensiunea unei
pictograme)
Generat atunci cnd fereastra este restabilit (cnd se revine de la starea de
pictogram)
Generat atunci cnd fereastra este mutat

Meniuri
O bar de meniuri (menu bar) este o colecie de meniuri. Un meniu, n schimb, conine o
colecie de opiuni, care pot avea denumiri i, opional, prescurtri (shortcuts). Biblioteca AWT
ofer clase pentru toate aceste elemente de meniu, cum ar fi MenuBar, Menu i MenuItem.

Bare de meniuri i meniuri


O bar de meniuri (menu bar) reprezint un set de meniuri care apare n partea de sus a unei
ferestre. Deoarece ele sunt caracteristice ferestrelor, nu putei crea bare de meniuri n ferestre applet
(dar, dac applet-ul afieaz o fereastr independent, aceasta poate conine o bar de meniuri).
Pentru a crea o bar de meniuri pentru o anumit fereastr vei crea o instan a clasei
MenuBar:
MenuBar mbar = new Menubar();
Acum vei folosi metoda setMenuBar() (definit n clasa Frame) pentru a asocia aceast
bar de meniuri cu fereastra:
fereastra.setMenuBar(mbar);
Putei aduga meniuri individuale (File, Edit i aa mai departe) n bara de meniuri prin
crearea lor, urmat de adugarea n bara de meniuri prin metoda add(). Argumentul pentru
constructorul Menu este numele meniului, aa cum va aprea el n bara de meniuri.
Menu meniulMeu = new Menu("File") ;
mbar.add(meniulMeu) ;
Unele sisteme ofer un meniu Help special, care este afiat n partea din dreapta a barei de meniuri, nu n
partea stng. Putei indica faptul c acest meniu este un meniu Help (de ajutor) prin folosirea metodei setHelpMenu().
Meniul respectiv trebuie adugat n bara de meniuri nainte de a fi declarat meniu de ajutor.

Menu meniuHelp = new Menu("Help") ;


mbar.add(meniuHelp) ;
mbar.setHelpMenu(meniuHelp) ;
Dac, pentru un motiv sau altul, dorii ca un utilizator s nu aib acces la un meniu, acesta
poate fi dezactivat folosind metoda disable() (i metoda enable() pentru a-l reactiva):
meniulMeu.disable();

Elemente de meniu
n meniurile individuale putei aduga patru tipuri de elemente (opiuni):
Instane ale clasei MenuItem, pentru elemente de meniu obinuite
Instane ale clasei CheckBoxMenuItem, pentru elemente de meniu care au strile
activat/dezactivat

Alte meniuri, care conin propriile elemente de meniu


Separatori, pentru liniile care separ grupuri de elemente de meniu

Crearea elementelor de meniu


Elementele (opiunile) de meniu obinuite sunt create i adugate ntr-un meniu folosind
clasa MenuItem. Mai nti se creeaz o nou instan a clasei MenuItem, dup care se adaug o
component Menu folosind metoda add():
Menu meniulMeu = new Menu("Utilitare");
MenuItem m1= new MenuItem("Info")
meniulMeu.add(m1) ;
meniulMeu.add(new MenuItem("Culori")) ;
Submeniurile pot fi adugate prin simpla creare a unei noi instane a clasei Menu i
adugarea n primul meniu. Dup aceasta, putei aduga elemente n acest meniu:
Menu submeniu = new Menu("Dimensiuni") ;
meniulMeu.add(submeniu) ;
submeniu.add(new Menultem("Mic")) ;
submeniu.add(new Menultem("Mediu")) ;
submeniu.add(new Menultemf"Mare"));
Clasa CheckBoxMenuItem creeaz un element de meniu care posed o caset de validare, permind ca
aceasta s fie activat sau dezactivat. (Prin selectarea elementului, acesta devine activat - n dreptul su apare un semn
de validare; o nou selectare a elementului duce la dispariia acestui semn i, implicit, la dezactivarea sa). Putei crea i
aduga un element de meniu de acest tip n acelai fel ca elementele de meniu obinuite:

CheckBoxMenuItem coord = new CheckBoxMenuItem("Afisare coordonate") ;


meniulMeu.add(coord) ;
Pentru a aduga un separator ntr-un meniu (o linie care separ grupurile de opiuni dintr-un meniu), creai i
adugai un element de meniu care s conin ca nume o liniu (-). Acest element special de meniu va fi reprezentat ca
o linie de separare. Urmtoarele dou linii de cod Java creeaz un astfel de separator i l adaug n meniul meniulMeu:

MenuItem sep = new MenuItem("-");


meniulMeu.add(sep) ;
Orice element de meniu poate fi dezactivat folosind metoda disable(), dup care poate fi
reactivat folosind metoda enable().
Elementele de meniu dezactivate nu pot fi selectate.
Menultem element = new MenuItem("Umplere") ;
meniulMeu.add(element) ;
element.disable() ;

Evenimente de meniu
Aciunea de selectare a unui meniu cu ajutorul mouse-ului sau a comenzii rapide asociate
genereaz un eveniment. Putei trata acest eveniment folosind metoda action(), aa cum ai procedat
i n aplicatiile anterioare.
n afar de evenimente de aciune, elementele de tip checkBoxMenuItem genereaz
evenimente de selectare i deselectare a listelor, care pot fi tratate cu ajutorul metodei
handleEvent().
Atunci cnd procesai evenimentele generate de elementele de meniu simple sau cele cu
casete de validare, inei cont de faptul c deoarece CheckBoxMenuItem este o subclas a
MenuItem, nu trebuie s tratai acel element de meniu drept un caz special. Vei trata aciunea sa n
acelai mod ca pe alte aciuni.

Crearea unor aplicaii AWT independente


Nu exist diferene prea mari ntre un applet Java i o aplicaie grafic Java. Tot ce ai nvat pn acum
despre AWT, cum ar fi metodele grafice, tehnicile de animaie, evenimente, componente ale interfeei, ferestre i casete
de dialog, poate fi folosit n aplicaiile Java n acelai fel n care a fost folosit n applet-uri.

Pentru crearea unei aplicaii Java clasa aplicaiei principale trebuie s moteneasc clasa
Frame. Dac folosete fire de execuie (pentru animaie sau alte procesri), trebuie s
implementeze, de asemenea, clasa Runnable:
class AplicatieAWT extends Frame implements Runnable {
//...
}
Pentru aplicaia dumneavoastr vei crea n metoda main() o nou instan a clasei; deoarece
clasa motenete clasa Frame, vei obine o nou fereastr AWT, pe care apoi o putei
redimensiona i afia ca pe orice fereastr AWT.
Caracteristicile AWT normale pentru o fereastr, care se declarau de obicei n cadrul
metodei init() a unui applet, se realizeaz aici n cadrul metodei constructor a clasei: se stabilete
titlul, se declar un administrator de dispunere, se creeaz i adaug componente cum ar fi bara de
meniuri sau alte elemente de interfa, se lanseaz fire de execuie i aa mai departe.
Un exemplu de aplicaie simpl:

import java.awt.* ;
class AplicatieAWT extends Frame {
AplicatieAWT(String titlu) {
super(titlu) ;
setLayout(new FlowLayout()) ;
add(new Button("OK") ;
add (new Button("Reset");
add( new Button("Cancel) ;
}
public static void main(String args[ ]) {
AplicatieAWT apl = new AplicatieAWT("Prima aplicatie") ;
apl.resize(300, 300);
apl.show() ;
}
}
Pentru controlul i administrarea unei aplicaii putei folosi aproape oricare dintre metodele
nvate. Singurele metode care nu pot fi folosite sunt cele specifice applet-urilor (adic cele
definite n java.applet.Applet, cum ar fi cele pentru apelarea informaiilor de la diferite adrese
URL).
Este bine de cunoscut nc o diferen ntre aplicaii i applet-uri: atunci cnd tratai un
eveniment de nchidere a unei ferestre, n afar de ascunderea sau distrugerea ferestrei trebuie s
mai apelai i metoda System.exit(0), care indic sistemului c aplicaia dumneavoastr s-a
terminat.
public void nchidereFereastra(WindowEvent e) {
fr.hide() ;
fr.destroy() ;
System.exit(0) ;

Rolul claselor: pachete, interfee i alte caracteristici


Cu cunotinele dobndite pn acum se pot scrie programe funcionale, ns le vor lipsi
cteva dintre caracteristicile avansate n care st adevrata trie a acestui limbaj. Vor fi prezentate
urmtoarele subiecte:
Controlul accesului la metode i variabile din afara unei clase
Finalizarea claselor, metodelor i variabilelor astfel nct s nu permit derivarea de
subclase, iar valorile sau definiiile lor s nu poat fi suprascrise
Crearea de clase i de metode abstracte pentru gruparea comportamentului comun n
superclase
Gruparea claselor n pachete
Folosirea interfeelor pentru a umple golurile din ierarhia de clase
Modificatori

Tehnicile de programare prezentate n acest capitol folosesc strategii i modaliti de abordare


diferite privind organizarea claselor. Singurul lucru pe care l au n comun este faptul c folosesc
cuvinte cheie speciale, denumite n Java modificatori (modifiers).
Limbajul Java folosete mai multe tipuri de modificatori, printre care:
Modificatori pentru controlul accesului la o clas, metod sau variabil: public,
protected i private
Modificatorul static, pentru crearea metodelor i variabilelor de clas
Modificatorul final, pentru finalizarea implementrilor de clase, metode i variabile
Modificatorul abstract, pentru crearea de clase i metode abstracte
Modificatorii synchronized i volatile, folosii pentru fire de execuie.
Pentru a folosi un modificator, vei include cuvntul cheie care l reprezint n definiia clasei,
metodei sau variabilei ce urmeaz a fi modificat. Modificatorul trebuie dispus naintea definiiei
propriu-zise, ca n urmtoarele exemple:
public class AppletulMeu extends java.applet.Applet { ... }
private boolean oK;
static final double x =9.5;
protected static final int ZILE=42;
public static void main (String argumente [] ) { }
Dac folosii mai muli modificatori ntr-o instruciune, i putei folosi n orice ordine, att
timp ct acetia preced elementul pe care l modific. Atenie, nu considerai tipul de retur al
metodei - cum ar fi void - drept modificator.
Modificatorii sunt opionali, ns exist destule motive pentru a-i folosi.

Controlul accesului la metode i variabile


Modificatorii pe care i vei folosi cel mai adesea n programele dumneavoastr sunt cei care
controleaz accesul la metode i variabile: public, private i protected. Acetia determin ce
variabile i metode sunt vizibile n alte clase.
Prin controlul accesului putei stabili modul cum va fi accesat clasa pe care ai creat-o din
alte clase. Unele variabile i metode ale clasei sunt folositoare doar n interiorul acesteia, deci ar
trebui s fie invizibile pentru alte clase care pot interaciona cu clasa nou creat. Acest proces se

numete ncapsulare (encapsulation): un obiect poate controla modul cum este vzut i cum se poate
interaciona cu el din exterior.
ncapsularea este procesul de prevenire a citirii sau a modificrii unor variabile aparinnd
unei clase de ctre alte clase. Singura metoda de folosire a acestor variabile este prin apelarea
metodelor clasei, dac acestea sunt disponibile. Limbajul Java ofer patru niveluri de control al
accesului: public, private, protected i un nivel special, care este specificat prin absena
modificatorului.
Accesul prestabilit
Pentru majoritatea exemplelor de pn acum nu s-a specificat nici un tip de control al
accesului. Variabilele sau metodele au fost declarate prin instruciuni de genul:
String nume = "Popescu Ion";
boolean este ( ) {
return true;
}
O variabil sau o metod declarat fr nici un modificator al accesului este disponibil
tuturor celorlalte clase dintr-un acelai pachet. Mai nainte ai putut vedea cum clasele i bibliotecile
Java sunt organizate n pachete (packages). Pachetul java. awt este unul dintre ele - un set de clase
cu comportament asemntor, care alctuiesc Abstract Windowing Toolkit.
Orice variabil declarat fr modificator poate fi citit sau modificat de orice clas care
face parte din acelai pachet. Orice metod declarat astfel poate fi apelat de orice clas din acelai
pachet. Alte clase nu pot accesa aceste elemente n nici un mod.
Acest nivel de control de fapt nu controleaz prea mult accesul. Atunci cnd vei analiza mai
bine modul cum vor fi folosite clasele dumneavoastr de alte clase, vei folosi n locul controlului
prestabilit al accesului unul dintre cei trei modificatori specializai.
Accesul privat
Pentru a ascunde complet o metod sau o variabil, n scopul de a nu fi folosit de nici o alt
clas, se folosete modificatorul private. In acest fel, metodele sau variabilele nu pot fi accesate
dect din clasa curent, unde sunt definite.
De exemplu, o variabil de instan privat poate fi utilizat de metodele din aceeai clas,
ns nu i de obiectele din alte clase. n acelai fel, metodele private pot fi accesate din clasa unde
sunt definite, ns nu i din altele. Aceast restricie afecteaz i motenirea: nici variabilele private
i nici metodele private nu pot fi motenite de subclase.
Variabilele private sunt foarte folositoare n dou cazuri:
Atunci cnd alte clase nu au nici un motiv s foloseasc variabila respectiv
Atunci cnd alt clasa poate produce dezastre dac variabila respectiv este folosit
necorespunztor.
De exemplu, s considerm o clas Java, denumit Bingo, care genereaz numere de bingo
pentru un site Internet de jocuri. Aceast clas conine o variabil denumit rataCastiguri, prin care
se poare controla numrul de ctiguri i de pierderi generate. Aceast variabil are un impact
deosebit asupra jocului. Dac ea ar putea fi modificat de alte clase, performana jocului s-ar putea
modifica substanial. Pentru a v proteja mpotriva unui astfel de scenariu, putei declara variabila
rataCastiguri drept private.
Folosirea modificatorului private reprezint principala metod pentru ncapsularea unui
obiect. Fr utilizarea acestuia pentru a ascunde variabile i metode, nu putei limita modul n care
este folosit o clas; accesul este liber la toate variabilele i metodele din cadrul clasei.

Accesul public
n unele cazuri vei avea nevoie ca o metod sau o variabil a clasei s fie disponibil complet
oricrei alte clase care dorete s o foloseasc. O astfel de variabil este variabila de clas black a
clasei Color. Aceast variabil este folosit atunci cnd o clas dorete s foloseasc culoarea
neagr, deci nu trebuie s existe nici o restricie de acces.
De obicei, variabilele de clas sunt declarate publice.
Modificatorul public face ca o metod sau o variabil s fie complet disponibil unei alte clase. Ai
folosit acest modificator n toate aplicaiile pe care le-ai scris pn acum, ca n instruciunea
urmtoare:
public static void main(String[ ] argumente) {
// ...
}
Metoda main ( ) a unei aplicaii trebuie s fie public. Altfel, ea nu poate fi apelat de
interpretorul java pentru a lansa n execuie clasa.
Datorit motenirii, toate variabilele i metodele publice ale unei clase sunt preluate i de
subclasele sale.
Accesul protejat
Al treilea nivel de control al accesului este limitarea vizibilitii unei metode sau variabile doar
pentru urmtoarele dou grupuri:
Subclasele unei clase
Alte clase din acelai pachet
Putei realiza acest lucru folosind modificatorul protected, ca n urmtorul exemplu:
protected boolean avemNevoieDeMaiMultaOdihna = true;
Acest nivel de control al accesului este folositor dac dorii implementarea unei subclase. Clasa
dumneavoastr poate conine o metod sau o variabil care s ajute i la realizarea sarcinilor
subclasei.
Deoarece o subclas motenete cea mai mare parte a comportamentului i atributelor, ea sar putea s aib cam aceleai sarcini de realizat.
Accesul protejat ofer subclasei ansa de a apela metoda sau variabila ajuttoare i, n acelai timp,
nu permite folosirea acestora de alte clase cu care nu are relaii de rudenie".
Compararea nivelurilor de control al accesului
Diferena dintre diferitele tipuri de protecii poate deveni puin neclar, mai ales n cazul
metodelor i variabilelor protejate. Tabelul urmtor, care prezint n rezumat ceea ce este permis i
unde, v ajut s v dai seama de diferenele existente ntre cea mai puin restrictiv form de
protecie (public) i cea mai restrictiv (private).
Vizibilitate
Din aceeai clas
Din orice clas care aparine aceluiai
pachet
Din orice clasa din afara pachetului
Dintr-o subclas a aceluiai pachet
Dintr-o subclas din afara pachetului

public
da

protected
da

default
da

private
da

da

da

da

nu

da
da
da

nu
da
da

nu
da
nu

nu
nu
nu

Controlul accesului i motenirea


O ultim consideraie n ceea ce privete controlul accesului se refer la subclase. Atunci cnd
creai o subclas i suprascriei o metod, trebuie s luai n considerare controlul accesului definit
pentru metoda original.
Astfel, metodele clasei Applet, cum ar fi init ( ) sau paint ( ), trebuie declarate public n appleturile dumneavoastr.
Ca regul general, nu putei s suprascriei o metod n Java i s facei noua metoda mai
controlabil dect originalul. Totui, putei s o facei mai puin controlabil (mai public).
n cazul metodelor motenite se impun urmtoarele reguli:
Metodele public dintr-o superclas trebuie s fie, de asemenea, public n toate subclasele
(din acest motiv, majoritatea metodelor applet-urilor sunt public).
Metodele protected dintr-o superclas pot fi protected sau public n subclase; ele nu pot fi
declarate private.
Metodele declarate far control al accesului (deci fr modificator) pot fi declarate n
subclase cu un grad de protecie mai ridicat.
Metodele declarate private nu sunt motenite deloc, deci nu li se aplic regulile de mai sus.
Metode de accesare
n multe cazuri, ntr-o clas putei avea o variabil de instan cu reguli stricte pentru
valorile pe care le conine. Un exemplu ar fi o variabil codPostal. Un cod potal din Romnia
trebuie s fie un numr din patru cifre; valorile valide sunt n domeniul 1000... 9999; orice alte
valori n afara acestui domeniu nu pot reprezenta coduri potale.
Pentru a evita ca o clasa externa s modifice incorect variabila codPostal, o putei declara privat,
printr-o instruciune de genul:
private int codPostal;
Dar dac i alte clase trebuie s fie n msur s modifice aceast variabil? n acest caz,
putei s permitei accesul acestora la variabila respectiv prin folosirea unei metode de accesare
(accessor) definit n aceeai clas ca i variabila codPostal.
Metodele de accesare au primit acest nume deoarece permit accesul la ceva care n mod
normal nu este accesibil. Prin folosirea unei metode de acces la o variabil private putei controla
modul cum este folosit aceast variabil, n exemplul cu codul potal, clasa poate interzice
atribuirea unor valori incorecte pentru variabila codPostal.
De multe ori, pentru citirea i scrierea variabilelor se folosesc metode de accesare diferite.
Se folosete convenia ca denumirea metodelor care citesc valoarea unei variabile s nceap cu get,
iar cele care seteaz valoarea variabilei s nceap cu set. Astfel, pentru exemplul dat, metodele s-ar
numi setCodPostal (int) i getCodPostal ( ).
Folosirea metodelor pentru accesul la variabilele de instana este o tehnic foarte rspndit
n programarea orientat obiect. Acest mod de abordare mrete gradul de reutilizare a codului
deoarece evit folosirea lui necorespunztoare.

Variabile i metode statice


Un modificator pe care l-ai folosit deja n programe este static. Modificatorul static este
folosit pentru crearea metodelor i variabilelor de clas, ca n urmtorul exemplu:
public class Cerc {
public static float pi = 3.14159265F;

public float arie(float r) {


return pi * r * r;
}
}
Variabilele i metodele de clas pot fi accesate folosind numele clasei urmat de un punct i de
numele variabilei sau metodei, ca de exemplu Color.black sau Cerc.pi. Putei, de asemenea, folosi
numele unui obiect al clasei, ns pentru variabilele i metodele de clas este mai bine s folosii
numele clasei. Aceast convenie stabilete mai clar tipul variabilei sau al metodei cu care lucrai;
variabilele i metodele de instan nu pot fi referite niciodat prin numele clasei.
Urmtoarele instruciuni folosesc variabile i metode de clas:
float circumferinta = 2 * Cerc.pi * getRaza ( ) ;
float numarAleator = Math.random ( ) ;

Clase, metode i variabile finale


Modificatorul final este folosit cu clase, metode i variabile pentru a indica faptul c acestea
nu vor mai fi modificate. El are nelesuri diferite pentru fiecare dintre aceste categorii:
Dintr-o clas final nu se mai pot deriva subclase.
O metod final nu poate fi suprascris de nici o subclas.
O variabil final nu i poate schimba valoarea.
Variabile finale
Acestea mai sunt denumite i variabile constante (sau, mai simplu, constante), deoarece nu
i pot modifica valoarea.
In cazul variabilelor, modificatorul final este folosit, de obicei, mpreun cu modificatorul
static, pentru a crea din constant o variabil de clas. Dac valoarea nu poate fi modificat, nu
exist motive ca fiecare instan a clasei s posede o copie a valorii; toate pot folosi o variabil de
clas cu acelai rol.
Urmtoarele instruciuni sunt exemple de declaraii de constante:
public static final float pi = 3.1415927;
ncepnd cu Java 2, orice tip de variabil poate deveni variabil final: clas, instan sau
variabil local.
Metode finale
Metodele finale sunt acele metode care nu pot fi suprascrise niciodat de o subclas. Acestea
sunt declarate folosind modificatorul final .
Singurul motiv pentru care ai declara o metod drept final este pentru o execuie mai eficient. n
mod normal, atunci cnd un mediu de execuie Java (cum este interpretorul java) ruleaz o metod,
el caut metoda mai nti n clasa curent, dup aceea n superclas i urc" mai departe n ierarhie
pn ce gsete definiia acesteia. Prin acest proces se pierde din vitez n favoarea flexibilitii i a
uurinei n dezvoltare.
Dac o metod este declarat final, compilatorul Java poate introduce codul executabil
(bytecode) al acesteia n oricare dintre programele care o apeleaz. Oricum, metoda nu s-ar putea
modifica niciodat din cauza suprascrierii de ctre una dintre subclase.
Atunci cnd proiectai o clas, nu prea avei motive s folosii modificatorul final. Totui,
dac dorii ca aceasta s se execute mai rapid, putei declara unele metode final, pentru a mri puin

viteza de execuie. Aceast abordare elimin posibilitatea de a deriva mai trziu subclase, aa c
trebuie s v gndii bine nainte de a face aceast schimbare.
Biblioteca de clase Java declar multe dintre metodele mai des folosite drept final, aa nct
acestea pot fi executate rapid atunci cnd sunt apelate din programe.
Clase finale
Clasele sunt finalizate prin introducerea modificatorului final n declaraia acestora, ca n
exemplul:
public final class OAltaProblema {
// ...
}
Dintr-o clas final nu se pot deriva subclase. Ca i n cazul metodelor, acest proces aduce
unele avantaje legate de viteza de execuie.
Majoritatea claselor mai des folosite sunt finale, cum ar fi java. lang.String, java.lang.Math,
java.net. InetAddress. Dac dorii s creai o clas care s se comporte ca un ir, dar s aib unele
modificri, nu vei putea s o derivai din clasa String i s definii doar comportamentul diferit; va
trebui s o scriei de la zero.
Toate metodele dintr-o clas final sunt automat finale, deci nu va mai trebui s folosii acest
modificator n declaraiile lor.
Nu avei prea multe motive s v declarai propriile clase drept finale, deoarece clasele care
pot s-i pun la dispoziie metodele i atributele unor subclase sunt mult mai folositoare.

Clase i metode abstracte


ntr-o ierarhie de clase, cu ct clasa se afla pe un nivel mai nalt, cu att definirea sa este mai
abstract. O clas aflat ierarhic deasupra altor clase poate defini doar comportamentul i atributele
comune celorlalte. Definirea unor atribute i metode specifice urmeaz s se fac undeva mai jos n
ierarhie.
n procesul de definire a unei ierarhii de clase, atunci cnd cutai comportamentele i
atributele comune unor grupuri de clase, vei descoperi uneori cte o clas care nu se instaniaz
direct. De fapt, aceasta servete doar ca loc de pstrare a metodelor i atributelor pe care le folosesc
n comun subclasele sale.
Aceste clase se numesc clase abstracte i sunt create folosind modificatorul abstract.
Iat un exemplu:
public abstract class Animal {
// ...
}
Un alt exemplu de clas abstract este java.awt.Component, care este superclasa tuturor
componentelor din Abstract Windowing Toolkit. Toate componentele motenesc aceast clas, deci
ea conine metode i variabile folositoare tuturor. Totui, ea nu este o componenta generic ce poate
fi adugat ntr-o interfa, deci nu vei avea motive s creai obiecte Component ntr-un program.
Clasele abstracte pot conine aceleai elemente ca o clas normal, inclusiv metode
constructor, deoarece subclasele lor pot avea nevoie sa moteneasc aceste metode. Clasele
abstracte pot conine, de asemenea, metode abstracte, care sunt, de fapt, doar semnturi de metode,
fr nici o implementare. Aceste metode sunt implementate n subclasele clasei abstracte. Metodele
abstracte sunt declarate folosind modificatorul abstract. Nu se poate declara o metod abstract ntro clas non-abstract. Dac o clas abstract nu conine altceva dect metode abstracte, este mai
bine s se foloseasc o interfa.

Pachete

Folosirea pachetelor, reprezint o modalitate de a organiza grupuri de clase. Un pachet


(package) conine un numr de clase nrudite ca scop, ca domeniu sau din punct de vedere al
motenirii.
Dac programele dumneavoastr sunt mici i folosesc un numr limitat de clase, s-ar putea
s descoperii c nu avei deloc nevoie de pachete. ns, cu ct vei crea mai multe programe Java,
cu att vei avea mai multe clase. i, chiar dac aceste clase sunt bine proiectate, reutilizabile,
ncapsulate i cu interfee specifice ctre alte clase, vei simi nevoia s folosii o entitate
organizaionala mai mare, care s v permit s grupai clasele.
Pachetele sunt folositoare din mai multe motive:
Permit organizarea claselor n uniti (grupuri). Aa cum pe hard disc avei directoare i
subdirectoare pentru a v organiza fiierele i aplicaiile, pachetele v permit s v organizai
clasele n grupuri din care putei folosi doar ceea ce avei nevoie pentru fiecare program.
Reduc problemele datorate conflictelor de nume. Cu ct crete numrul de clase Java, cu
att crete posibilitatea de a folosi un nume de clas deja existent, ceea ce va duce la apariia unor
conflicte i erori la integrarea acestora n programe. Pachetele v permit s ascundei clasele i
deci s evitai aceste conflicte.
V permit s protejai clasele, variabilele i metodele n mai multe moduri dect la nivel de
clas.
Pot fi folosite la identificarea claselor. De exemplu, dac implementai un set de clase
pentru a realiza o anumit sarcin, putei folosi pentru pachetul de clase respectiv un identificator
unic, care s v desemneze pe dumneavoastr sau organizaia dumneavoastr.
Chiar dac un pachet este n esen, o colecie de clase, acesta poate conine i alte pachete,
formnd un alt nivel de organizare cumva asemntor ierarhiei de clase. Fiecare nivel" reprezint,
de obicei, o grupare de clase mai mic i cu sarcini mai precise.
Biblioteca de clase Java este organizat i ea dup aceste principii. Nivelul superior este
denumit java; urmtorul nivel conine denumiri cum ar fi io, net, util sau awt. Ultimul pachet (awt)
conine nc un subnivel, unde se poate gsi pachetul image.

Folosirea pachetelor
Ai folosit pachetele pe tot cuprinsul acestui curs: ori de cte ori ai folosit instruciunea
import sau ori de cte ori ai referit o clas prin denumirea sa complet (de exemplu,
java.awt.Color).
Pentru a folosi o clas coninut ntr-un pachet, putei folosi unul dintre urmtoarele trei
mecanisme:
Cnd clasa pe care dorii s o folosii se afl n pachetul java. lang (de exemplu, System
sau Date), o putei referi pur i simplu prin numele ei. Clasele din java. lang sunt automat
disponibile n toate programele.
Cnd clasa pe care dorii s o folosii se afla ntr-un alt pachet, putei sa o referii
folosindu-i numele complet, adic inclusiv pe cel al pachetului (de exemplu, java. awt. Font).
Pentru clasele pe care le folosii frecvent din alte pachete, putei importa clasele
individuale sau ntregul pachet de clase. Dup ce clasa sau pachetul au fost importate, putei s
referii clasa doar prin numele su.
Clasele care nu sunt declarate ca fcnd parte dintr-un anumit pachet sunt automat incluse
ntr-un pachet prestabilit. Aceste clase pot fi referite prin numele lor, de oriunde din cod.

Pachete complete i nume de clase

Pentru a referi o clas dintr-un alt pachet, putei folosi numele ei complet: numele clasei,
precedat de toate numele pachetului. Pentru aceasta nu este nevoie s importai clasa sau pachetul:
java.awt.Font f = new java.awt.Font( );
Are sens sa folosii denumirea complet doar pentru clasele pe care le folosii o dat sau de
dou ori n cadrul programului. Dac folosii aceste clase de mai multe ori sau dac numele
pachetului este prea lung i conine mai multe subpachete, este mai bine s importai clasa
respectiv, pentru a economisi timpul pe care l-ai pierde cu tastarea.

Comanda import
Pentru a importa clasele dintr-un pachet se folosete comanda import, aa cum ai vzut n
toate exemplele prezentate n aceast carte. Putei importa o anumit clas, ca n exemplul urmtor:
import java.util.Vector;
Sau putei importa un ntreg pachet de clase, folosind simbolul asterisc (*) n locul numelor de
clas, astfel:
import java.awt .*;
Instruciunea import trebuie folosit n prima parte a definiiei clasei, nainte de orice alte
definiii (ns dup definiia pachetului).
Importarea unui grup de clase nu ncetinete programul i nici nu i mrete dimensiunile;
vor fi ncrcate doar clasele de care avei nevoie n codul dumneavoastr. Ins importarea unui
pachet ntreg face ca lucrurile s fie mai neclare pentru cei care citesc codul dumneavoastr, pentru
c nu se va ti de unde provin clasele folosite. Opiunea pentru importuri individuale sau n grup
depinde de stilul dumneavoastr de programare.

Conflicte de nume
Dup ce ai importat o clas sau un pachet de clase, putei s v referii la clas doar prin
numele sau, fr identificatorul de pachet. ntr-un singur caz va trebui s fii mai explicit: atunci
cnd avei mai multe clase cu acelai nume, care provin din pachete diferite.
Iat un exemplu: S presupunem c importai clase provenite din dou pachete diferite, aparinnd
unor programatori diferii :
import claseMihai.*;
import claseMarcel.*;
n cadrul pachetului lui Mihai se afl o clas denumit Vector. i n pachetul lui Marcel exist o
clas cu acelai nume, dar cu implementare i definiie total diferite. V vei ntreba acum care
dintre versiunile clasei este folosit atunci cnd facei n programul dumneavoastr o referire la
clasa Vector:
Vector vect = new Vector(10) ;
Rspunsul este nici una"; compilatorul Java va semnala un conflict de nume i va refuza s
compileze programul. In acest caz, chiar dac ai importat ambele clase, va trebui totui s v
referii la clasa dorit prin numele su complet, ca n exemplul:
claseMihai.Vector vect = new claseMihai.Vector(10);

Variabila CLASSPATH i locul de dispunere a claselor


Pentru ca Java s poat folosi o clas, trebuie s afle locul unde este dispus n sistemul de
fiiere; altfel, va fi generat o eroare referitoare la inexistena clasei. Pentru gsirea claselor Java

folosete dou elemente: numele pachetului i directoarele referite de variabila de mediu CLASSPATH
(dac folosii un sistem Windows).
Numele pachetelor corespund unor nume de directoare ale sistemului de fiiere, deci clasa
java.applet.Applet se va gsi n directorul applet, care face parte i el din directorul java (este vorba
de java\applet\Applet. class).
Java caut aceste directoare, pe rnd, n cadrul directoarelor referite de variabila CLASSPATH,
dac aceasta este definit. Dac nu este configurat nici o variabil CLASSPATH, Java caut n
directorul prestabilit, java/lib, aflat n directorul cu versiunea JDK pe care o folosii, precum i n
directorul curent. Java caut n aceste directoare clasa referit n sursa dumneavoastr folosindu-se
de numele pachetului i al clasei, iar dac nu o gsete returneaz un mesaj de eroare. Majoritatea
erorilorde tip 'class not found' (clas inexistent) sunt cauzate de o configurare greit a variabilei
de mediu CLASSPATH .

Crearea propriilor pachete


Crearea unui pachet pentru clasele dumneavoastr Java nu este mai complicar dect crearea
unei clase. Trebuie numai s urmai cele trei etape prezentate n continuare.

Alegerea unui nume pentru pachet


Primul pas consta n alegerea unui nume. Numele ales pentru pachet depinde de modul cum
dorii s folosii aceste clase. Putei denumi pachetul cu numele dumneavoastr saucu un nume
sugestiv. Dac intenionai s distribuii pachetul n Internet sau ca parte a unui produs comercial,
trebuie s folosii un nume de pachet care identific n mod unic autorul.
Convenia de denumire a pachetelor, recomandat de Sun este de a folosi numele de
domeniu Internet, cu elementele inversate.
Ideea este de a v asigura c numele pachetului dumneavoastr este unic. Chiar dac
pachetele pot ascunde conflictele ntre nume de clase, protecia se oprete aici. Nu putei fi sigur c
pachetul dumneavoastr nu va intra n conflict cu pachetul altcuiva, dac folosii aceleai nume de
pachete.
Prin convenie, numele pachetelor ncep cu liter mic, pentru a le deosebi de numele claselor.
Astfel, n cazul denumirii complete a clasei String (java. lang. String), putei separa vizual foarte
uor numele pachetului de numele clasei. Aceast convenie ajut i ea la reducerea conflictelor de
nume.

Crearea structurii de directoare


Etapa a doua n crearea unui pachet const n crearea pe hard disc a unei structuri de
directoare conform numelui pachetului. Daca pachetul dumneavoastr are un singur nume
(pachetulmeu), este suficient s creai un director cu acest nume. Dac numele pachetului este
compus din mai multe pri, trebuie s creai i subdirectoarele respective.

Adugarea unei clase ntr-un pachet


Pasul final este de a introduce clasa n pachet i de a aduga o instruciune n definiia clasei,
nainte de orice instruciuni import care vor fi folosite. Instruciunea package se folosete mpreun
cu denumirea pachetului, n felul urmtor:
package figurigeometrice;
Instruciunea package, dac exist, trebuie s fie pe prima linie a codului fiierului sursa,
eventual dup comentarii sau linii goale, ns nainte de orice comenzi import.

Dup ce vei ncepe s folosii pachetele, trebuie s v asigurai c toate clasele


dumneavoastr aparin aceluiai pachet, pentru a reduce eventualele confuzii asupra locului unde se
gsesc.

Pachetele i controlul accesului la clase


Am vzut care sunt modificatorii de control ai accesului pentru metode i variabile. Putei,
de asemenea, controla accesul la clase, aa cum ai remarcat din folosirea modificatorului public n
unele declaraii de clase din exemplele anterioare.
Dac nu este specificat nici un modificator, claselor li se atribuie un control prestabilit al
accesului; aceasta nseamn c respectiva clas este disponibil tuturor claselor din acelai pachet,
ns nu i n afara pachetului - nici mcar subpachetelor. Ea nu poate fi importat sau referit prin
nume; clasele cu protecie de pachet sunt vizibile doar n cadrul pachetului care le conine.
Protecia de pachet este stabilit atunci cnd definii o clas n felul urmtor:
class ClasaAscunsa extends OAltaClasaAscunsa
{
// . . .
}
Pentru a permite unei clase s fie vizibil i importabil n afara pachetului, i vei atribui protecia
public prin folosirea modificatorului public n definiia sa:
public class ClasaVizibila
{
// . . .
}
Clasele declarate public pot fi importate de orice alte clase din afara pachetului.
Reinei c, atunci cnd folosii n instruciunea import simbolul asterisc (*), vei importa
doar clasele publice din cadrul pachetului respectiv. Clasele ascunse (hidden) rmn invizibile i
pot fi folosite doar de celelalte clase din pachetul respectiv.
De ce s dorii s ascundei o clas n cadrul unui pachet? Din acelai motiv pentru care
dorii s ascundei variabilele i metodele n cadrul unei clase: pentru c astfel avei clase utilitare i
metode care sunt folosite doar de implementarea dumneavoastr sau pentru c putei limita interfaa
programului dumneavoastr, minimiznd efectul unor modificri de amploare. Atunci cnd v
proiectai clasele, ar trebui s luai n considerare ntregul pachet i s hotri pe care clase dorii s
le declarai public i pe care dorii s le ascundei.
Programul urmtor prezint dou clase care demonstreaz acest lucru. Prima este o clas public ce
implementeaz o list nlnuit; a doua reprezint un nod privat al listei.
Textul complet al programului
ListaInlantuita. java
1: package colectie;
2:
3: public class Liatalnlantuita {
4:
private Nod radacina;
5:
6:
public void add(0bject o)
{
7:
radacina = new Nod(o, radacina);
8:
}
9:
// ...
10 }
11:
12: class Nod
{
// Nu este publica
13:
private Object continut;
14:
private Nod urmatorul;

15:
16:
17:
18:
19:
20:
21:

Nod(0bject o, Nod n)
continut = o;
urmatorul = n;
}
// ...

Clasa public ListaInlantuita ofer un set de metode publice (cum ar fi add ( ) ) altor clase
care ar avea nevoie s le foloseasc. Celelalte clase nu trebuie s tie de alte clase pe care
ListaInlantuita le folosete pentru a-i ndeplini sarcinile. Nod, una dintre aceste clase ajuttoare,
este declarata din acest motiv fr modificatorul public i deci nu va face parte din interfaa public
a pachetului colecie.
Faptul c Nod nu este o clas public nu nseamn c Listalnlantuita nu va mai avea acces la
ea dup ce este importat ntr-o alt clas. Atunci cnd importai i folosii clasa Listalnlantuita,
clasa Nod va fi, de asemenea, ncrcat n sistem, ns doar instanele clasei Listalnlantuita vor avea
permisiunea s o foloseasc.
Crearea unui pachet bine proiectat presupune definirea unui set mic de clase publice i de
metode care pot fi folosite de alte clase i implementarea lor folosind un numr de clase ajuttoare,
invizibile n exterior.

Interfee
Interfeele, ca i clasele sau metodele abstracte, ofer un model de comportament care se
presupune c va fi implementat de alte clase. Totui, interfeele ofer posibiliti mult mai mari
dect clasele i metodele abstracte, att pentru Java, ct i pentru proiectarea obiectelor i a claselor,
n general.
Problema unicei moteniri
Dup ce vei ctiga ceva mai mult experien n proiectare, va vei da seama c simplitatea
ierarhiei de clase Java este oarecum restrictiv, mai ales atunci cnd dorii s folosii unele metode
din clase aflate pe diferite ramuri" ale aceleiai ierarhii.
S lum un exemplu care va clarifica aceast problem. S presupunem c avei o ierarhie
de clase referitoare la biologie, pe primul nivel aflndu-se clasa Animal, iar mai jos, clasele
Mamifer i Pasare. Printre atributele clasei Mamifer se numr naterea de pui vii i existena
blnii. Clasa Pasare conine atribute cum ar fi depunerea de ou i existena ciocului. Dar cum vei
defini o clas pentru ornitorinc, care, se tie, are blan, cioc i depune ou? Pentru crearea clasei
Ornitorinc va trebui s combinai atributele din cele dou clase. Dar, deoarece clasele pot avea n
Java o singur superclas, acest tip de problem nu poate fi rezolvat prea elegant.
Alte limbaje OOP (orientate obiect) conin conceptul de motenire multipl, care rezolv
aceast problem. Dac se folosete motenirea multipl, o clas poate avea mai multe superclase,
mprumutnd atribute de la toate. Una dintre problemele motenirii multiple este aceea c limbajul
de programare devine mai dificil de nvat, de folosit i de implementat. Problemele legate de
apelarea metodelor i de modul de organizare a ierarhiei de clase devin mult mai complicate i este
mult mai probabil s produc ambiguiti i confuzii. Deoarece unul din scopurile limbajului Java
este simplitatea, s-a renunat la motenirea multipl n favoarea mai simplei moteniri unice.
Pentru rezolvarea acestor probleme Java conine o alt ierarhie, total separat de ierarhia principal,
care conine clase cu comportament combinat. Astfel, atunci cnd creai o nou clas, aceasta are o
singur superclas primar, ns poate alege i alte comportamente din cealalt ierarhie. Aceast
nou ierarhie se numete ierarhie de interfee. O interfa Java este o colecie de comportamente
abstracte, care pot fi combinate n orice clas pentru a introduce n acea clas comportamente care
nu pot fi motenite de la superclas. Tehnic, o interfa Java nu conine nimic altceva dect definiii
de metode abstracte i constante - fr variabile de instan sau implementri de metode.
Interfeele sunt implementate i folosite n biblioteca de clase Java ori de cte ori este nevoie
ca un anumit comportament s fie implementat n alte clase. Ierarhia de clase Java, de exemplu,
definete i folosete interfeele java.lang.Runnable, java.awt.image.ImageConsumer i java. awt.
image.ImageProducer.
Interfeele i clasele
Clasele i interfeele, chiar dac au definiii diferite, au foarte multe n comun. Interfeele, ca
i clasele, sunt declarate n fiiere surs, cte un fiier pentru fiecare interfa. Ca i clasele, acestea
sunt compilate n fiiere .class folosind compilatorul Java. i, n majoritatea cazurilor, oriunde se
poate folosi o clas (ca tip de dat pentru variabile, ca rezultat al unei conversii prin cast i aa mai
departe) se poate folosi i o interfa. Programatorii Java folosesc termenul clas" pentru a se referi
att la clase, ct i la interfee. Interfeele completeaz i extind puterea claselor i de aceea pot fi
tratate aproape n acelai fel. Una dintre puinele diferene existente ntre clase i interfee este aceea
c nu se poate obine o instan a unei interfee: operatorul new se folosete doar pentru crearea
de instane ale unei clase.
Implementarea i folosirea interfeelor

Cu interfeele putei face dou lucruri: s le folosii n clasele dumneavoastr sau s definii
unele proprii. S ncepem cu primul caz.
Pentru a folosi o interfa, trebuie folosit cuvntul cheie implements ca parte a definiiei clasei. Un
astfel de exemplu este cel care a fost prezentat ntr-unul dintre capitolele anterioare:
public class Neko extends java.applet.Applet implements Runnable
{
// . . .
}
n acest exemplu, java.applet.Applet este superclasa, ns interfaa Runnable extinde
comportamentul implementat de aceasta.
Deoarece interfeele nu ofer nimic altceva dect definiii abstracte de metode, va trebui s
implementai aceste metode n clasele dumneavoastr folosind semnturile de metode provenite din
interfa. Reinei c o dat inclus o interfa, va trebui s implementai toate metodele acesteia; nu
putei s alegei doar metodele de care avei nevoie. Prin implementarea unei interfee, nseamn c
declarai utilizatorilor clasei c vei suporta toate metodele acesteia. (Aceasta este o alt diferen
ntre interfee i clasele abstracte; subclasele claselor abstracte pot alege care dintre metode s fie
implementate sau suprascrise i s le ignore pe celelalte.)
Dup ce clasa pe care ai scris-o implementeaz o interfa, subclasele acesteia vor moteni
toate noile metode (care pot fi suprascrise sau suprancrcate) ca i cnd acestea ar fi fost definite n
superclas. Cnd o clas motenete o superclas care implementeaz o anumit interfa, nu mai
trebuie s folosii cuvntul cheie implements n definiia clasei respective.
S lum un exemplu simplu - crearea unei noi clase, denumit Portocala. S presupunem c
posedai deja o implementare bun a clasei Fruct i o interfa, ModelFruct, care reprezint ceea ce
un Fruct este capabil s fac. Dorii ca portocala s fie un fruct, ns dorii s fie i un obiect sferic
care s poate fi aruncat, rotit i aa mai departe. Iat cum se pot defini toate acestea:
interface ModelFruct {
void stricare ( );
void stoarcere ( );
// ...
}
class Fruct implements ModelFruct {
private Color culoareaMea;
private int zilePanaLaStricare;
//...
}

interface ModelSfera {
void aruncare ( );
void rotire ( );
// ...
}
class Portocala extends Fruct implements ModelSfera {
// aruncare ( ) poate sa provoace stoarcere ( )
// (caracteristici unice pentru clasa Portocala)
}
Remarcai c n clasa Portocala nu este nevoie s se implementeze interfaa ModelFruct, deoarece,
prin motenirea clasei Fruct, deja o implementeaz! Unul dintre avantajele acestei structuri este

acela c v putei rzgndi n privina clasei de unde se deriv clasa Portocala (de exemplu, dac
este implementat o clas mai bun, denumit Sfera) i totui clasa Portocala va nelege aceleai
dou interfee:
class Sfera implements ModelSfera {
// derivata direct din clasa Object
private float raza;
// .. .
}
class Portocala extends Sfera implements ModelFruct {
// ...utilizatorii clasei Portocala nu vor remarca aceasta
// modificare!
}
Implementarea unor interfee multiple
Spre deosebire de ierarhia de clase cu motenire unic n clasele dumneavoastr putei folosi oricte
interfee dorii; clasa rezultat va implementa comportamentul combinat: al tuturor interfeelor
incluse. Pentru a include mai multe interfee ntr-o clas, separai numele acestora prin virgule:
public class Neko extends java. applet. Applet
implements Runnable, Comestibil, Sortabil, Observable {
// ...
}
Reinei totui c folosirea unor interfee multiple poate da natere la complicaii. Ce se ntmpl
dac dou interfee definesc aceeai metod? Putei rezolva aceast problem n trei moduri:
Dac metoda are aceeai semntur n ambele interfee, implementai n clasa dumneavoastr o
metod a crei definiie satisface ambele interfee.
Dac metodele au liste de parametri diferite, vei avea o situaie de suprancrcare a metodelor;
implementai ambele metode, fiecare dintre definiii satisfcnd interfaa respectiv.
Dac ambele metode au aceeai list de parametri, ns returneaz tipuri diferite, nu vei putea
crea o metod care s le satisfac pe amndou (deoarece suprancrcarea metodelor ine cont doar
de lista de parametri, nu de tipul de retur). n acest caz, ncercarea de compilare a unei clase care
implementeaz ambele interfee va produce o eroare. Dac ajungei n aceast situaie, nseamn c
interfeele dumneavoastr au erori de proiectare i trebuie reanalizate.
Alte utilizri ale interfeelor
Aproape oriunde putei folosi o clas, putei folosi i o interfa. De exemplu, s declarm o variabil de tip
interfa:

Runnable unObiectExecutabil = new ClasaMeaDeAnimatie( ) ;


Atunci cnd se declar o variabil de tipul interfa, acest lucru presupune ca obiectul pe care l
refer variabila s aib implementat acea interfa; deci se presupune c nelege toate metodele
specificate de interfa. n acest caz, deoarece variabila unObiectExecutabil conine un obiect de tip
Runnable, se presupune c se poate apela metoda unObiectExecutabil.run( ).
De asemenea, putei converti prin cast un obiect ntr-o interfa aa cum l convertii ntr-o alt
clas. S ne ntoarcem la definiia clasei Portocala, care implementa att interfaa ModelFruct (prin
superclasa sa, Fruct), ct i interfaa ModelSfera. Putei converti prin cast instane ale clasei
Portocala att n clase, ct i n interfee:
Portocala oPortocala = new Portocala ( ) ;
Fruct unFruct = (Fruct)oPortocala;
ModelFruct unModelFruct = (ModelFruct)oPortocala;

ModelSfera unModelSfera = (ModelSfera)oPortocala;


unFruct. stricare ( ); // fructele se strica
unModelFruct .stoarcere ( ); // si se storc
unModelFruct.aruncare ( ); // lucrurile care sunt ca fructele
// nu se arunca
unModelSfera.aruncare ( ); // dar lucrurile care sunt ca
// sferele da
oPortocala. stricare ( ); // portocalele pot face de toate
oPortocala.stoarcere ( );
oPortocala.aruncare ( ) ;
oPortocala.rotire ( );
Declaraiile i conversiile prin cast sunt folosite n acest exemplu pentru a limita comportamentul
portocalei mai aproape de fruct sau de sfer.
n final, reinei c interfeele, chiar dac se folosesc pentru combinarea metodelor diferitelor clase,
pot fi folosite i pentru combinarea unor constante utile. De exemplu, dac o interfa definete un
set de constante care sunt folosite apoi n mai multe clase, valoarea acestor constante poate fi
modificat global fr a trebui s modificai toate clasele. Acesta este un alt caz n care folosirea
interfeelor pentru separarea proceselor de proiectare i de implementare conduce la obinerea unui
cod mai generic i mai uor de ntreinut.

Crearea i extinderea interfeelor


Dup o perioad de folosire a interfeelor putei trece la definirea unor interfee proprii. Acestea
arat destul de asemntor claselor; ele sunt declarate cam n acelai fel i pot fi aranjate ntr-o
ierarhie. Totui, pentru declararea unei interfee trebuie s respectate anumite reguli.
Interfee noi
Declararea unei interfee noi se face n felul urmtor:
public interface Crescator {
// ....
}
Acest enun este practic identic cu definiia unei clase, cu singura diferen c este folosit cuvntul
cheie interface n locul cuvntului class. n definiia interfeei putei avea metode i constante.
Metodele din cadrul unei interfee sunt public i abstract; putei s le declarai explicit n acest fel
sau, dac nu, oricum vor fi transformate n metode public i abstract. Nu putei declara o metod
private sau protected n cadrul unei interfee. De exemplu, n urmtoarea definiie a interfeei
Crescator, metoda crescut ( ) este declarat explicit public i abstract. n timp ce metoda
maicrescut ( ) este declarat implicit:
public interface Crescator {
public abstract void crescut ( ); // declarata explicit public
// si abstract
void maiCrescut ( ); // declarata implicit public si
// abstract
}
Observai c, la fel ca i n cazul metodelor abstracte din clase, metodele din interfee nu au
coninut. Reinei: o interfa necesit doar proiectare, nu presupune i implementare.
In afar de metode, interfeele pot conine i variabile, ns acestea trebuie declarate public, static i
final (deci constante). Ca i n cazul metodelor, acest lucru nu trebuie fcut explicit; variabilele sunt
considerate implicit public, static i final chiar i fr a folosi aceti modificatori. Iat definiia
interfeei Crescator, care conine dou noi variabile:
public interface Crescator {

public static final int incrementare = 10;


long nrmax = 1000000; // devine public, static si final
public abstract void crescut ( ); // declarata explicit public
// si abstract
void maiCrescut ( ); // declarata implicit public si abstract
}
Interfeele trebuie s posede, ca i clasele, o protecie de pachet sau public. O interfa nepublic
are metode i constante de acelai tip, acestea neputnd fi folosite dect n clasele sau interfeele din
acelai pachet.
Interfeele, ca i clasele, pot aparine unui pachet dac folosii instruciunea package n prima linie
din fiierul surs. La fel ca i clasele, interfeele pot importa interfee sau clase din alte pachete.
Metodele din cadrul interfeelor
Iat o problem privind metodele din cadrul interfeelor: ele trebuie s fie abstracte i s se aplice oricrui tip de
clas, dar cum se poate defini lista de parametri pentru aceste metode? Nu tii dinainte ce clas urmeaz s le
foloseasc! Rspunsul const n faptul c, aa cum ai nvat mai devreme, putei folosi un nume de interfa
peste tot unde poate fi folosit un nume de clas. Prin definirea parametrilor metodei de tip interfa putei crea
parametri generici care funcioneaz pentru orice clas care ar folosi aceast interfa.

S lum, de exemplu, interfaa ModelFruct, care definete metodele (fr parametri) stricare ( ) i
stoarcere ( ). Mai putei avea o metod, germinareSeminte ( ), care are un singur argument: fructul
nsui. De ce tip urmeaz s fie acest argument? Nu poate fi de tip Fruct, deoarece putei avea o
clas derivat din ModelFruct (deci care implementeaz interfaa ModelFruct) i care s nu fie, de
fapt, un fruct. Soluia este de a declara n interfa argumentul de tip ModelFruct:
public interface ModelFruct {
public germinareSeminte (ModelFruct fr) {
//
}
}
Apoi, n implementarea acestei metode ntr-o clas, putei converti prin cast argumentul
genericModelFruct n obiectul corespunztor:
public class Portocala extends Fruct {
public germinareSeminte(ModelFruct fr) {
Portocala oPortocala = (Portocala)fr;
// . . .
}
}
Derivarea interfeelor
Ca i n cazul claselor, interfeele pot fi organizate ntr-o ierarhie. Atunci cnd o interfa
motenete o alt interfa, subinterfaa" primete toate metodele i constantele definite n
superinterfa". Pentru a deriva (extinde) o interfa vei folosi cuvntul cheie extends, la fel ca n
cazul definiiilor claselor:
public interface ModelFruct extends ModelMancare {
// ...
}
Totui, spre deosebire de clase, ierarhia de interfee nu posed echivalentul unei clase Object;
aceast ierarhie nu are un vrf". Interfeele pot exista independent sau pot moteni o alt interfa.
De asemenea, spre deosebire de ierarhia de clase, ierarhia de interfee este una cu motenire
multipl. De exemplu, o singur interfa poate moteni oricte clase are nevoie (separate prin

virgul, n acea parte a definiiei care folosete cuvntul cheie extends); noua interfa va conine o
combinaie de metode i constante motenite de la prini". Iat definiia unei interfee care
motenete mai multe interfee:
public interface InterfataAglomerata extends Runnable, Crescator, ModelFruct, Observable {
// ...
}
n interfeele cu motenire multipl, regulile de gestionare a conflictelor ntre numele metodelor
sunt aceleai ca pentru clasele care folosesc mai multe interfee; metodele care difer numai prin
tipul de retur vor genera o eroare de compilare.

Clase interioare
Clasele cu care ai lucrat pn acum sunt toate membre ale unui pachet, fie c ai folosit
instruciunea package, urmat de numele unui pachet, fie c a fost folosit pachetul prestabilit.
Clasele care aparin unui pachet sunt cunoscute drept clase de nivel nalt (top-level classes). La
introducerea Java, acestea erau singurele clase suportate de limbaj.
ncepnd cu Java 1.1, putei defini o clasa n interiorul altei clase, ca i cnd ar fi o metod sau o
variabil. Astfel de clase se numesc clase interioare (inner classes). Listingul urmtor prezint
applet-ul Interior, care folosete o clas interioar, denumit ButonAlbastru pentru a reprezenta
butoanele care au culoarea de fundal albastr.
Textul complet al programului Interior.java.
1: import java.awt.Button;
2: import java.awt.Color;
3:
4: public class Interior extends java.applet.Applet {
5:
Button b1 = new Button ("0ne");
6:
ButonAlbastru b2 = new ButonAlbastru("Two");
7:
8:
public void init ( ) {
9:
add(b1);
10:
add(b2);
}
11:
12:
class ButonAlbastru extends Button {
13:
ButonAlbastru (String eticheta) {
14:
super(eticheta) {
15:
this .setBackground(Color.blue) ;
16:
}
17:
}
18: }
n acest exemplu, clasa ButonAlbastru nu este dect o clas ajuttoare inclus n acelai fiier surs
ca i clasa principal a programului. Singura diferen este c aceast clas ajuttoare este definit
n cadrul fiierului clas, ceea ce aduce cteva avantaje:
Clasele interioare sunt invizibile pentru alte clase, ceea ce nseamn c nu trebuie s v facei
probleme privind conflictele de nume cu alte clase.
Clasele interioare pot avea acces la variabilele i metodele din domeniul de vizibilitate al
clasei de nivel superior, lucru care nu ar fi fost valabil dac ar fi fost separate.

n majoritatea cazurilor, o clas interioar este o clas de dimensiuni reduse i cu un scop limitat. n
applet-ul Interior, deoarece clasa ButonAlbastru nu conine atribute sau metode complexe, este
indicat pentru a fi implementat drept clas interioar.
Numele clasei interioare este asociat cu numele clasei care o conine i este atribuit automat la
compilarea programului. n exemplul clasei ButonAlbastru, JDK i va atribui numele
Interior$ButonAlbastru.class.
Clasele interioare, chiar dac par c aduc mbuntiri minore limbajului Java, reprezint, de fapt, o
modificare semnificativ a limbajului.
Regulile care guverneaz domeniul de vizibilitate al unei clase interioare sunt aceleai care se aplic
i variabilelor. Numele unei clase interioare nu este vizibil n afara domeniului su, exceptnd cazul
cnd se folosete numele complet, lucru care ajut la structurarea claselor n cadrul pachetului.
Codul unei clase interioare poate folosi nume simple, din domeniile de vizibilitate pe care le
cuprinde, cum ar fi variabilele de clas i de instan ale claselor pe care le conine, precum i
variabilele locale din blocurile incluse.
n plus, putei defini o clas de nivel nalt ca membru static al unei alte clase de nivel nalt. Spre
deosebire de o clas interioar, o clas de nivel nalt nu poate folosi direct variabilele de instan ale
unei alte clase. Posibilitatea de a imbrica n acest fel clasele permite oricrei clase de nivel nalt s
ofere o organizare de tipul pachetelor pentru un grup de clase de nivel mai sczut, nrudite din punct
de vedere logic.

Exceptii Java
Pn n acest moment, este mai mult ca sigur c ai ntlnit cel puin o situaie de excepie Java - probabil
atunci cnd ai introdus greit numele unei metode sau ai fcut o greeal n cod care a dus la apariia unei probleme.

Se poate, de asemenea, ca programul s se termine anormal, dup ce a afiat pe ecran ceva


erori. Aceste erori sunt excepii. Atunci cnd programul se termin brusc, este din cauz c a fost
semnalat o excepie (thrown - aruncat"). Excepiile fi semnalate de sistem sau, explicit, de
programul pe care l-ai scris.
Am folosit termenul "semnalate" deoarece excepiile pot fi i interceptate (caught).
Interceptarea unei excepii presupune tratarea situaiilor speciale pentru ca programul
dumneavoastr s nu se mai blocheze. Faptul c o excepie a fost semnalat nseamn, n Java, c "a
aprut o eroare".
Excepiile Java sunt, de fapt, obiecte, instane ale unor clase care motenesc clasa
Throwable. O instan a clasei Throwable este creat atunci cnd se semnaleaz o excepie. Figura
urmtoare prezint o poriune ierarhiei de clase pentru excepii.
Throwable

Error

Exception

IOException
RuntimeException
ClassNotFoundE
xception
AWTException

FileNotFound
Exception
EOFException
MalFormedURL
Exception
SocketException

Clasa Throwable are dou subclase: Error i Exception. Instanele clasei Error reprezint
erori interne ale mediului de lucru Java (maina virtual). Aceste erori sunt rare i, de obicei, fatale;

nu putei face mare lucru cu ele (nici s le interceptai i nici s le semnalai), exist pentru ca Java
s le poat folosi dac are nevoie de ele.
Subclasele Exception se mpart n dou grupuri:
Excepii de execuie (runtime), care sunt subclase ale clasei RuntimeException, cum ar fi
ArrayIndexOutofBounds, SecurityException sau NullPointerException
Alte excepii, cum ar fi EOFException sau MalformedURLException
Majoritatea claselor de excepie fac parte din pachetul java.lang (cum ar fi Throwable,
Exception sau RuntimeException). Celelalte pachete definesc i ele excepii, care pot fi folosite n
toat biblioteca de clase. De exemplu, pachetul java.io definete o clas de excepie generic,
denumit IOException, care nu este folosit doar n pachetul java.io, pentru excepiile de
intrare/ieire (EOFException, FileNotFoundException), ci i n clasele pachetului java.net, pentru
excepii de reea cum ar fi MalformedURLException.

Gestionarea excepiilor

n majoritatea cazurilor, compilatorul Java impune gestionarea excepiilor atunci cnd


ncercai s folosii metode ce presupun apariia unor excepii; dac nu tratai aceste excepii, codul
nu va fi compilat. n aceast seciune vei nva despre verificarea consistenei i despre folosirea
cuvintelor cheie try, catch i finally pentru tratarea excepiilor ce pot aprea.

Verificarea consistenei excepiilor

Cu ct lucrai mai mult cu biblioteci Java, cu att mai mult crete posibilitatea de a ntlni o
eroare (o excepie!) de compilare, asemntoare acesteia:
Program.java:32: Exception java.lang.InterruptedException must be
caught or it must be declared in the throws clause of this method.
(Program.java:32: Excepia java.lang.InterruptedException trebuie interceptat sau trebuie declarat
n clauza throws a acestei metode.)
n Java, o metod poate indica tipurile de erori pe care le poate semnala. De exemplu,
metodele care citesc din fiiere pot semnala excepii IOException, deci aceste metode sunt
declarate cu un modificator special care indic potenialele erori. Atunci cnd folosii aceste metode
n programele dumneavoastr Java, trebuie s v protejai codul mpotriva acestor excepii. Aceast
regul este verificat chiar de compilator, n acelai fel n care verific i dac ai apelat metodele
cu numrul corespunztor de argumente sau dac ai atribuit variabilelor tipurile de date declarate.
De ce se face aceast verificare? Deoarece astfel programele dumneavoastr sunt mai puin
expuse erorilor fatale i terminrii anormale, pentru c tii dinainte ce tipuri de excepii pot fi
semnalate de metodele folosite n program. Nu trebuie s mai citii cu atenie documentaia sau
codul unui obiect pentru a v asigura c ai tratat toate potenialele probleme - Java face aceste
verificri n locul dumneavoastr. Pe de alt parte, dac definii metodele astfel nct s indice
excepiile pe care le pot semnala, Java poate avertiza utilizatorii acestor obiecte c trebuie s trateze
erorile respective.

Protejarea codului i interceptarea erorilor


S presupunem c ai scris un cod i c la un test de compilare ai obinut un mesaj de excepie. n funcie de
mesaj, fie interceptai eroarea, fie declarai c metoda o poate semnala. S lum primul caz: interceptarea potenialelor
excepii.

Pentru a intercepta o excepie trebuie realizate dou lucruri:


Protejai codul care conine metoda ce poate semnala excepia n cadrul unui bloc try.
Testai i tratai excepia n cadrul unui bloc catch.
Operaiunile try (ncearc) i catch (intercepteaz) nseamn, de fapt, ncearc aceast
poriune de cod, care poate cauza o excepie. Dac se execut cu succes, continu programul. dac
nu, intercepteaz excepia i trateaz-o."
Un astfel de caz este atunci cnd creai animaie pe care o oprii o dat pe secund:
try {
Thread.sleep(1000);
} catch (InterruptedException e) { }
Chiar dac aici s-au folosit instruciunile try i catch, acesta nu este un exemplu prea bun.
Iat ce se ntmpl n aceste instruciuni: metoda de clas Thread.sleep() poate s semnaleze o
excepie de tip InterruptedException, ceea ce nseamn c firul de execuie a fost oprit dintr-un
motiv oarecare.
Pentru a trata aceast excepie, apelul metodei sleep() este ncadrat ntr-un bloc try, dup
care se definete un bloc catch asociat. Acest bloc catch primete toate obiectele
InterruptedException care sunt semnalate din blocul try.
Motivul pentru care acest cod nu constituie un bun exemplu de tratare a excepiilor este c
nu exist nimic n interiorul blocului catch - cu alte cuvinte, se intercepteaz excepia atunci cnd
apare, ns ca rspuns la aceasta nu se face nimic. Cu excepia cazurilor simple (cum e acesta, unde
excepia ntr-adevr nu conteaz), trebuie s scriei n cadrul blocului catch un cod care s realizeze
o anumit aciune dup apariia excepiei.
Partea din interiorul instruciunii catch este similar listei de argumente a unei metode. Ea
conine clasa a crei excepie a fost interceptat i un nume de variabil (de obicei se folosete e).
Astfel, n cadrul blocului putei s v referii la obiectul excepie interceptat.
O folosire uzual a acestui obiect este apelarea metodei getMessage(). Aceast metod este
prezent n toate excepiile i afieaz un mesaj detaliat referitor la ceea ce s-a ntmplat.
Urmtorul exemplu reprezint o versiune revizuit a instruciunii try.. . catch,din exemplul
anterior:
try {
Thread.sleep(1000) ;
} catch (InterruptedException e) {
System.out.println("Eroare: " + e.getMessage());
}

Clauza finally
S presupunem c n codul dumneavoastr exist o anumit aciune care trebuie neaprat
executat, indiferent ce se ntmpl, indiferent dac excepia este semnalat sau nu. Acest lucru se
face, de obicei, pentru a elibera anumite resurse dup folosire, pentru a nchide un fiier dup
deschidere sau ceva de acest gen. Chiar dac putei introduce aceste aciuni att n cadrul unui bloc

catch, ct i n afara sa, aceasta nseamn o duplicare a codului n dou locuri diferite. n loc s
procedai astfel, introducei o copie a codului ntr-o poriune special a blocului try. . .catch,
denumit finally.
Urmtorul exemplu prezint modul cum este structurat un bloc try. . .catch . . . finally:
try {
citesteFisierText();
} catch (IOException e) {
// tratati erorile de intrare/iesire
} finally {
inchideFisierText() ;
}
Instruciunea finally este folositoare, de fapt, n afara excepiilor; putei, de asemenea, s o
folosii pentru executarea unui cod de reiniializare dup o instruciune return, break sau continue
din cadrul unui ciclu. n ultimul caz putei folosi o instruciune try doar cu blocul finally, fr
blocul catch.

Declararea metodelor care pot semnala


exceptii
n exemplele anterioare ai nvat cum se trateaz metodele care pot semnala excepii (prin protejarea codului
i interceptarea eventualelor excepii). Compilatorul Java verific dac v-ai ocupat ntr-un fel sau altul de excepiile
care pot aprea - dar cum tie el asupra cror excepii s v atrag atenia?
Rspunsul este c metoda original indic n semntura sa excepiile pe care le poate semnala. Putei folosi
acest mecanism n propriile metode, de fapt, este bine s procedai astfel pentru a v asigura c utilizatorii vor fi
avertizai asupra excepiilor ce pot aprea.

Pentru a indica faptul c o metod poate semnala o excepie, vei folosi n definiia sa o
clauz special, denumit throws.
Clauza throws

Pentru a indica faptul c o poriune a unei metode poate semnala o excepie, este suficient s
adugai cuvntul cheie throws dup semntura metodei (nainte de acolada deschis) i s
specificai numele excepiilor pe care le poate semnala metoda dumneavoastr:
public boolean metodaMea(int x, int y) throws oExceptie {
// ...
}
Dac metoda dumneavoastr poate semnala mai multe tipuri de excepii, putei s le
specificai pe toate n clauza throws, separate prin virgule:
public boolean oAltaMetodaAMea(int x, int y)
throws oExceptie, oADouaExceptie, oATreiaExceptie {
// ...
}

La fel ca n cazul catch, putei folosi o superclas a unui grup de excepii pentru a indica faptul c metoda
dumneavoastr poate semnala oricare dintre subclasele acelei excepii:

public void oAltaMetoda() throws IOException {


// .. .

}
Specificarea clauzei throws n definiia metodei dumneavoastr nu nseamn dect c
metoda poate semnala o excepie dac ceva merge prost, nu i c va face acest lucru. Clauza throws
ofer doar o informaie suplimentar referitoare la potenialele excepii i permite compilatorului
Java s se asigure c metoda este corect folosit de utilizatori.

Manipularea datelor prin fluxuri Java


Majoritatea programelor pe care le creai n Java trebuie s interacioneze cu anumite surse
de date. Exist nenumrate metode de pstrare a informaiilor pe un calculator, cum ar fi fiiere pe
hard disc sau pe CD-ROM, pagini ntr-un site Web sau chiar n memoria calculatorului.
Ai putea crede c exist diferite tehnici pentru manipularea datelor de pe diversele
dispozitive de stocare. Din fericire, nu este cazul. n Java, informaiile pot fi stocate sau apelate
folosind un sistem de comunicaie denumit flux (stream), implementat n pachetul java.io.
Fluxurile reprezint un mecanism puternic de manipulare a datelor.
Introducere n fluxuri

Toate datele din Java sunt scrise sau citite folosind fluxuri. Fluxurile, aa cum le arat i denumirea, transport
ceva dintr-un loc n altul.

Un flux (stream) reprezint calea pe care o urmeaz datele ntr-un program. Un flux de
intrare transport datele de la surs la program, iar un flux de ieire transport datele din program
ctre o destinaie.
Exist dou tipuri de fluxuri: fluxuri de octei i fluxuri de caractere. Octeii pot pstra
valori ntregi din domeniul 0. . . 255. n acest format pot fi reprezentate o multitudine de date, cum
ar fi date numerice, programe executabile, comunicaii Internet sau cod Java (bytecode) - adic
fiierele clas care sunt executate pe o main virtual Java. De fapt, orice tip de date poate fi
reprezentat printr-o serie de octei.
Fluxurile de caractere reprezint un tip special de fluxuri de octei, care se folosesc numai
pentru datele de tip text (tipribile). Ele difer de fluxurile de octei prin faptul c setul de caractere
Java suport codificarea Unicode, un standard prin care se pot reprezenta mai multe caractere dect
dac s-ar folosi octei.
Toate datele de tip text, cum ar fi fiierele text, paginile Web sau alte formate de text,
trebuie s foloseasc fluxuri de caractere.
Folosirea unui flux

Indiferent dac folosii fluxuri de octei sau de caractere, procedura este asemntoare.
n cazul irurilor de intrare, prima etap const n crearea unui obiect asociat cu sursa de
date. De exemplu, dac sursa este un fiier de pe hard discul dumneavoastr, acestuia trebuie s i se
asocieze un obiect de tip FileInputStream.
Odat obinut obiectul asociat fluxului, putei citi informaii din acest flux folosind una
dintre metodele obiectului. Clasa FileInputStream posed o metod read(), care returneaz un
octet citit din fiier.
Atunci cnd ai terminat de citit informaia din flux, trebuie s apelai metoda close(), pentru
a indica faptul c ai terminat de folosit fluxul.
n cazul fluxurilor de ieire, vei ncepe prin a crea un obiect asociat cu destinaia datelor.
Un astfel de obiect poate fi creat pornind de la clasa BufferedReader, care constituie o metod
eficient de creare a fiierelor text.
Metoda write() reprezint cea mai simpl metod de a transmite informaii ctre destinaia
unui flux. De exemplu, metoda write() aparinnd dasei BufferedReader poate transmite caractere
individuale unui flux de ieire.

Ca i n cazul fluxurilor de intrare, pentru un flux de ieire trebuie apelat metoda close ()
atunci cnd nu mai exist date de transmis.
Filtrarea unui flux

Cea mai simpl metod de a folosi un flux este de a l crea i de a-i apela metodele de
transmitere sau de recepie a datelor, n funcie de rolul lui (flux de intrare sau flux de ieire).
Majoritatea claselor folosite n prezent permit obinerea unor rezultate mai sofisticate prin
asocierea fluxului cu un filtru, nainte de a citi sau scrie date.
Un filtru este un tip de flux care schimb modul n care se lucreaz cu un flux existent.
Procedura de folosire a unui filtru pentru un flux presupune urmtoarele:
Crearea unui flux asociat cu sursa de date sau cu destinaia datelor.
Asocierea unui filtru cu acest flux.
Citirea i scrierea datelor de la/n filtru, i nu direct n flux.
Metodele pe care le apelai n cazul filtrelor sunt aceleai cu cele pe care le apelai n cadrul
fluxurilor: exist metodele read () i write (), asemntoare celor ale unui flux nefiltrat.
Putei chiar s asociai un filtru unui alt filtru, crend situaii de genul: un flux de intrare este
asociat unui fiier text, este trecut printr-un filtru de traducere romno-englez i, n final, este trimis
la destinaie - o persoan care dorete s l citeasc.
Fluxuri de octei

Toate fluxurile de octei sunt subclase ale InputStream sau OutputStream. Aceste clase
sunt abstracte, deci nu putei obine un flux prin crearea de obiecte direct din aceste clase. n
schimb, putei crea fluxuri prin folosirea unor subclase ale acestora, cum ar fi:
FileInputStream i FileOutputStream-Octei stocai n fiiere pe disc, pe CD-ROM sau pe
alte dispozitive de stocare.
DataInputStream i DataOutputStream - Un flux de octei filtrat, din care pot fi citite date
de tip ntreg sau n virgul mobil (float). InputStream este superclasa tuturor fluxurilor de intrare.
Fluxuri de fiiere

Fluxurile de octei cu care vei lucra de obicei sunt fluxuri de fiiere folosite pentru
transferul de date ntre program i fiierele aflate pe hard discuri, pe CD-ROM sau pe alte
dispozitive de stocare ce pot fi referite printr-o cale de director i un nume.
Putei transmite octei unui flux de ieire i putei citi octei dintr-un flux de intrare.
Fluxuri de intrare din fiiere

Un flux de intrare din fiier poate fi creat cu ajutorul constructorului FileInputStream


(String). irul transmis ca argument trebuie s fie numele fiierului. Putei include i calea ctre
fiier, n cazurile n care acesta se afl n alt director dect cel care conine clasa. Urmtoarea
instruciune creeaz un flux de intrare pentru fiierul date.dat:
FileInputStream fis = new FileInputStream("date.dat") ;
Dup crearea fluxului de intrare din fiier, putei citi octei din acesta apelndu-i metoda
read (). Aceast metod returneaz o valoare ntreag ce conine urmtorul octet din flux. Dac
metoda retumeaz -1, care nu este o valoare acceptat pentru un octet, nseamn c s-a ajuns la
sfritul fluxului de fiier.
Pentru a citi mai muli octei din flux se folosete metoda read(byte[], int, int), care posed
urmtoarele argumente:
Un tablou de octei n care se vor memora datele
Elementul din cadrul tabloului unde se va stoca primul octet de date
Numrul de octei care se vor citi

Spre deosebire de alte metode read (), aceasta nu retumeaz date din flux, ci un ntreg care
reprezint numrul de octei citii sau -1 dac nu s-au citit octei i s-a ajuns la sfritul fluxului.
Urmtoarele instruciuni folosesc un ciclu while pentru a citi datele din obiectul df de tip
FileInputStream:
int octetNou = 0;
while (octetNou != -1) {
octetNou = df.read();
System.out.println(octetNou +" );
}
Aceast bucl citete ntregul fiier referit de obiectul df, cte un octet o dat, i afieaz valoarea
fiecrui octet, urmat de un spaiu. De asemenea, cnd se ajunge la sfritul fiierului va fi afiat
valoarea -1, lucru pe care l putei evita folosind un test if.
Fluxuri de ieire n fiiere
Un flux de ieire n fiier poate fi creat folosind constructorul FileOutputStream (String).
Utilizarea sa este identic cu cea a constructorului FileInputStream (String), deci putei specifica
i calea pn la fiier, nu numai numele acestuia.
Trebuie s avei grij atunci cnd specificai fiierul n care scriei. Dac folosii numele unui fiier deja existent, o dat
cu nceperea scrierii datelor, acesta va fi ters definitiv.

Putei crea un flux de ieire n fiier care s adauge date (append) la sfritul unui fiier existent
folosind constructorul FileOutputStream(String, boolean). irul specific numele fiierului, iar
argumentul boolean, dac are valoarea true, va aduga datele la sfritul fiierului, n loc s
suprascrie datele existente.
Pentru a scrie octei ntr-un fiier se folosete metoda write ( int) a fluxului de ieire. Dup ce s-a
scris ultimul octet, fluxul trebuie nchis folosind metoda close ().
Pentru a scrie mai muli octei se poate folosi metoda write(byte[], int, int), care funcioneaz
similar metodei read (byte[], int, int) descris anterior. Argumentele acestei metode sunt tabloul
care conine octeii ce vor fi scrii, poziia de nceput din tablou i numrul de octei ce trebuie
scrii.
Filtrarea fluxurilor

Fluxurile filtrate sunt fluxuri care modific informaia trimis printr-un flux existent.
Acestea sunt create folosind subclase ale FilterInputStream sau FilterOutputStream.
Aceste filtre nu realizeaz singure nici un fel de operaie de filtrare. De fapt, ele posed subclase, cum ar fi
BufferInputStream sau DataOutputStream, care sunt folosite pentru anumite tipuri de filtrri.

Filtre de octeti
Informaia este furnizat mai rapid dac poate fi transmis n blocuri de date mai mari, chiar
dac aceste blocuri sunt recepionate mai repede dect pot fi procesate.
Un tampon (buffer) reprezint o zon n care se pot pstra date nainte de a fi nevoie s fie
citite sau scrise de un program. Prin folosirea unui tampon putei avea acces la date fr s accesai
din nou sursa original de date.
Fluxuri cu tampon

Un flux de intrare cu tampon umple un tampon cu date care nu au fost nc procesate; cnd
programul are nevoie de aceste date, le caut n zona tampon nainte de a apela fluxul surs original.
Aceast tehnic este mai eficient. Aceast descongestionare a fluxului nu face altceva dect s

uureze eforturile de folosire a acestuia. Fluxurile de octei folosesc clasele BufferedInputStream


i BufferedOutputStream.
Fluxurile de intrare cu tampon sunt create folosind unul din constructorii:
BufferedInputStream(InputStream) Creeaz un flux de intrare cu tampon pentru obiectul
InputStream specificat.
BufferedInputStream(InputStream, int) Creeaz fluxul de intrare cu tampon InputStream
specificat, avnd o dimensiune a zonei tampon egal cu valoarea argumentului ntreg.
Cea mai uoar modalitate de a citi date dintr-un flux de intrare cu tampon este de a apela metoda read () a acestuia,
fr argumente; aceasta retumeaz o valoare ntreag ntre 0 i 255, care reprezint urmtorul octet din flux. Dac s-a
ajuns la sfritul fluxului i nu s-a gsit nici un octet, se retumeaz valoarea -1.

Putei, de asemenea, folosi metoda read(byte [] , int, int), care este disponibil i pentru alte fluxuri
de intrare, caz n care datele sunt ncrcate ntr-un tablou de octei.
Un flux de ieire cu tampon este creat prin folosirea urmtorilor constructori:

BufferedOutputStream(OutputStream) Creeaz un flux de ieire cu tampon pentru obiectul


OutputStream specificat.
BufferedOutputStream(OutputStream, int) Creeaz fluxul de ieire cu tampon OutputStream
specificat, alocnd o zon tampon de dimensiunea specificat prin argumentul int.
Pentru a scrie un singur octet n fluxul de ieire poate fi folosit metoda write(int) a acestuia, iar
pentru a scrie mai muli octei dintr-o dat se poate folosi metoda write (byte [ ], int, int).
Argumentele acestei metode sunt tabloul de octei, poziia iniial a acestuia i numrul de octei
care trebuie transmis.
Atunci cnd datele sunt direcionate ntr-un flux cu tampon, coninutul acestuia nu va fi transmis
ctre destinaie dect dup ce zona tampon s-a umplut sau dac se apeleaz explicit metoda flush()
a fluxului.
Fluxuri de date

Dac trebuie s lucrai cu date care nu sunt reprezentate drept octei sau caractere, putei
folosi fluxuri de date de intrare i de ieire. Aceste fluxuri filtreaz un flux de octei existent astfel
nct urmtoarele tipuri de date s poat fi citite direct din flux: boolean, byte, double, float, int,
long i short.
Un flux de date de intrare este creat folosind constructorul DataInputStream (InputStream).
Argumentul trebuie s fie un flux de intrare existent, de exemplu, un flux de intrare cu tampon sau
un flux de intrare din fiier. Reciproc, un flux de date de ieire necesit utilizarea constructorului
DataOutputStream (OutputStream), care folosete ca argument fluxul de ieire asociat.
Urmtoarea list prezint metodele de citire i de scriere ce pot fi folosite pentru fluxurile de date de
intrare, respectiv de ieire:
readBoolean(), writeBoolean(boolean)
readByte(), writeByte (int)
readDouble(), writeDouble(double)
:
readFloat(), writeFloat(float)
readInt(), writeInt(int)
readLong(), writeLong(long)
readShort(), writeShort(int)
Fiecare dintre metodele de intrare returneaz tipul de dat primitiv indicat de numele metodei. De
exemplu, metoda readFloat () retumeaz o valoare float.
Exist i metodele readUnsignedByte () i readUnsignedShort (), care pot citi valori de tip octet
sau ntregi scuri fr semn. Aceste tipuri de date nu sunt suportate n Java, deci vor fi retumate ca
valori ntregi.

Octeii fr semn iau valori de la 0 la 255. Aceasta difer de tipul de variabil byte din Java, care ia valori ntre -128 i
127. n acelai fel, o variabil ntreag scurt fr semn ia valori ntre 0 i 65535, n loc de domeniul -32768 i 32767,
suportat de tipul short n Java.

Nu toate metodele de citire dintr-un flux de date de intrare retumeaz o valoare ce poate indica
faptul c s-a ajuns la sfritul fluxului. V mai putei atepta la apariia excepiei EOFException
care este semnalat la atingerea sfritului unui flux. Ciclul n care se citesc date poate fi ncadrat
ntr-un bloc try, iar instruciunea catch asociat trebuie s trateze doar excepiile EOFException.
In cadrul blocului catch putei s apelai i metoda close () i s efectuai alte aciuni de
reiniializare.

Fluxuri de caractere
Aceste fluxuri se folosesc pentru lucrul cu orice text reprezentat n format ASCII sau
Unicode .
Clasele folosite pentru a citi i scrie aceste fluxuri sunt subclase ale daselor Reader i
Writer. Este indicat s folosii aceste clase pentru lucrul cu text, i nu fluxuri de octei.
Tehnicile pentru lucrul cu fluxuri de caractere s-au mbuntit considerabil n versiunile
ulterioare Java 1.02, o dat cu introducerea claselor Reader i Writer i a subclaselor acestora; ele
ofer suport pentru setul de caractere Unicode i permit o manevrare mai uoar a textelor. Un
applet java compatibil cu versiunea 1.02 poate citi caracterele folosind clasele pentru fluxuri de
octei descrise anterior.
Citirea fiierelor text

Principala clas folosit pentru citirea de fluxuri de caractere dintr-un fiier este FileReader.
Aceast clas motenete clasa InputStreamReader, care citete un flux de octei i i convertete
n valorile ntregi corespunztoare caracterelor Unicode.
Un flux de intrare de caractere este asociat unui fiier folosind constructorul FileReader (String).
irul reprezint numele fiierului i poate conine i calea pn la acesta.
Urmtoarea instruciune creeaz un obiect FileReader denumit web i l asociaz cu fiierul text
denumit index. html:
FileReader web = new FileReader("index.html);
Dup ce ai obinut un obiect de acest tip, putei s apelai urmtoarele metode de citire a
caracterelor din fiier:
read () returneaz urmtorul caracter din flux, ca valoare ntreag
read (char [ ], int, int) citete caractere ntr-un tablou i primete ca argumente tabloul de
caractere, poziia de ncepere i numrul de caractere de citit. A doua metod funcioneaz
asemntor echivalentului su din clasele de fluxuri de intrare de octei. n loc s returneze
caracterul urmtor din flux, aceasta returneaz fie numrul de caractere citite, fie -1 dac s-a ajuns
la sfritul fluxului i nu s-a citit nimic.
Urmtoarea metod ncarc un fiier text folosind obiectul FileReader i afieaz caracterele
coninute de acesta:
FileReader text = new FileReader("readme.txt");
int octetCitit;
do {
octetCitit = text.read();
if (octetCitit != -1)
System.out.print( (char)octetCitit) ;
} while (octetCitit != -1) ;
System.out.println(" ");

text.close() ;
Deoarece metoda read () a unui flux de caractere returneaz o valoare ntreag, trebuie s convertii
prin cast aceast valoare nainte de a o afia, de a o salva ntr-un tablou sau de a o folosi ntr-un ir.
Fiecare caracter posed un cod numeric care reprezint poziia sa n setul de caractere Unicode.
Valoarea ntreag citit din flux reprezint chiar acest cod numeric. Dac dorii s citii din fiier o
ntreag linie de text, i nu caracter cu caracter, putei folosi o combinaie a daselor FileReader i
BufferedReader.
Clasa BufferedReader citete un caracter din fluxul de intrare i l memoreaz ntr-o zon tampon,
pentru mai mult eficien. Pentru a crea o versiune care folosete tampon, trebuie s existe un
obiect de tip Reader. Pentru crearea obiectului BufferedReader se pot folosi urmtorii
constructori:
BufferedReader(Reader)
Creeaz un flux de caractere cu zon tampon, asociat obiectului
Reader specificat (de exemplu FileReader).
BufferedReader (Reader, int) Creeaz un flux de caractere asodat obiectului Reader, cu o zon
tampon de dimensiunea specificat de argumentul ntreg.
Dintr-un flux de caractere cu tampon se poate citi folosind metodele read () i read(char[ ] , int,
int), asemntoare celor descrise pentru FileReader. Putei citi o ntreag linie de text folosind
metoda readLine ().
Metoda readLine () returneaz un obiect String care conine urmtoarea linie de text din flux, fr a
include i caracterul (sau caracterele) care reprezint sfritul de linie. Dac se ajunge la sfritul
fluxului, valoarea irului returnat va fi null.
Sfritul de linie este indicat astfel:

Un caracter de linie nou (newline - '\n')


Un caracter de retur de car (carriage return \r)
Un retur de car urmat de o linie nou
Scrierea n fiiere text

Clasa FileWriter este folosit pentru scrierea unui flux de caractere ntr-un fiier. Aceasta
este o subclas a OutputStreamWriter, care are rolul de a converti codurile caracterelor Unicode
n octei.
Exist doi constructori FileWriter: FileWriter (String) i FileWriter (String, boolean).
irul din primul argument reprezint numele fiierului ctre care va fi direcionat fluxul de caractere
i poate conine i calea. Argumentul opional de tip boolean trebuie s ia valoarea true dac se
dorete ca datele s fie adugate la sfritul unui fiier existent. Ca i n cazul altor clase de scriere
n fluxuri, trebuie s avei grij s nu suprascriei accidental un fiier existent.
Clasa FileWriter conine trei metode ce pot fi folosite pentru a scrie date ntr-un flux:
write(int)
Scrie un caracter.
write(char [], int, int)
Scrie caracterele din tabloul specificat, ncepnd de la poziia dat i
avnd numrul de caractere dat.
write(String, int, int)
Scrie caractere din irul specificat, ncepnd de la poziia dat i avnd
numrul de caractere dat.
Urmtorul exemplu scrie un flux de caractere ntr-un fiier folosind clasa FileWriter i metoda
write (int):
FileWriter litere = new FileWriter("alfabet.txt");
for (int i = 65; i < 91; i++) litere.write((char)i) ;
litere.close() ;
Metoda close () este folosit pentru nchiderea fluxului, dup ce toate caracterele au fost trimise n
fiierul destinaie. lat coninutul fiierului alfabet.txt produs de acest cod:
ABCDEFGHIJKLMNOPQRSTUVXYZ

Clasa BufferedWriter poate fi folosit pentru scrierea ntr-un flux de caractere cu zon tampon.
Obiectele acestei clase sunt create folosind constructorul BufferedWriter (Writer) sau
BufferedWriter (Writer, int). Argumentul Writer poate fi oricare dintre clasele de fluxuri de
caractere de ieire, cum ar fi FileWriter. Al doilea argument, opional, este o valoare ntreag ce
indic dimensiunea zonei tampon care va fi folosit.
BufferedWriter posed aceleai trei metode de ieire ca i FileWriter: write(int),
write(char[], int, int) i write(String, int, int).
0 alt metod folositoare este newLine (), care trimite caracterul (sau caracterele) ce specific
sfritul liniei pe platforma folosit pentru rularea programului.
Diferitele caractere de sfrit de linie pot crea neplceri la transferul unui fiier de pe un sistem de
operare pe altul, cum ar fi cazul cnd un utilizator Windows 95 copiaz un fiier pe un server Web
care folosete sistemul de operare Linux. Folosind metoda newLine() n loc de un literal (cum ar fi
'\n'), putei utiliza programul dumneavoastr pe diferite platforme.
Metoda close () este apelat pentru a nchide fluxul de caractere de ieire i pentru a asigura c toate
datele memorate n zona tampon au fost trimise ctre destinaia fluxului.

Filtre de fiiere i de nume de fiiere


n toate exemplele de pn acum, pentru referirea la numele fiierului implicat ntr-o
operaie cu fluxuri s-a folosit un ir. De multe ori, acest lucru este suficient, ns dac dorii s
copiai, s redenumii sau s realizai alte activiti cu fiiere, putei folosi i obiecte de tip File.
Clasa File, care face i ea parte din pachetul java.io, reprezint o referin ctre un fiier sau
un director. Pot fi folosii urmtorii constructori File:
File ( String)
Creeaz un obiect File pentru directorul specificat - nu este indicat nici un nume
de fiier, deci acesta se refer doar la un director.
File(String, String) Creeaz un obiect File pentru directorul specificat i pentru fiierul cu
numele specificat.
File(File, String)
Creeaz un obiect File a crui cale este specificat de obiectul File i al crui
nume este dat de irul specificat.
ntr-un obiect de tip File putei apela mai multe metode folositoare. Metoda exists () returneaz o
valoare boolean care arat dac fiierul exist sub numele i n directorul specificate la crearea
obiectului File. Dac fiierul exist, putei folosi metoda length(), care retumeaz o valoare de tip
ntreg long ce reprezint dimensiunea fiierului n octei.
Metoda renameTo (File) redenumete fiierul sub numele specificat de argumentul File. Se
retumeaz o valoare boolean, care indic dac operaia s-a finalizat cu succes sau nu.
Metoda delete () sau deleteOnExit () se apeleaz pentru tergerea unui fiier sau a unui folder.
Metoda delete () ncearc s fac imediat tergerea (i returneaz o valoare boolean care indic
succesul operaiei). Metoda deleteOnExit () ateapt i ncearc s tearg fiierul dup ce restul
programului i-a terminat execuia. Aceast metod nu retumeaz nici o valoare iar programul
trebuie s se termine la un moment dat pentru ca metoda s funcioneze.
Metoda mkdir () se folosete pentru a crea un director specificat de obiectul File pentru care s-a
apelat. Aceasta retumeaz o valoare boolean care indic succesul sau eecul operaiei. Nu exist o
metod echivalent pentru tergerea directoarelor, deoarece metoda delete () poate fi folosit la fel
de bine i pentru directoare i pentru fiiere.
Ca n cazul tuturor operaiilor care implic lucrul cu fiiere, aceste metode trebuie folosite cu grij pentru a evita
tergerea unor fiiere sau directoare sau suprascrierea unor fiiere. Nu exist nici o metod pentru recuperarea fiierelor
sau a directoarelor terse.

Fiecare dintre aceste metode va semnala o excepie SecurityException dac programul nu are
permisiunile necesare pentru executarea operaiilor respective, deci trebuie folosite blocuri try. . .
catch sau clauze throws pentru a trata aceste excepii.

Proiectarea unei interfete utilizator cu ajutorul Swing

Swing, care face parte din biblioteca JFC (Java Foundation Classes), reprezint o extensie
a pachetului AWT (Abstract Windowing Toolkit), care a fost integrat ncepnd cu versiunea 2 a
Java.
Swing ofer o funcionare mbuntit fa de predecesorul sau - noi componente, funcii
avansate ale acestora, o mai bun tratare a evenimentelor, precum i un aspect adaptabil.
Toate elementele Swing fac parte din pachetul javax.swing. Pentru a folosi o clas Swing,
trebuie s folosii fie o instruciune import explicit, fie una general, cum ar fi urmtoarea:
import javax.swing.* ;
Procesul de folosire a unei componente Swing nu este diferit de cel al folosiri
componentelor AWT. Vei crea componenta apelnd constructorul su, apelnd, dac este nevoie,
metodele componentei i apoi adugnd componenta ntr-un container.
Toate componentele Swing sunt subclase ale clasei JComponent.

Cadrul unei aplicatii


Primul pas n crearea unei aplicaii Swing const n crearea unei subclase a clasei JFrame.
Clasa JFrame este o extensie a clasei Frame (cadru) i poate fi folosit ntr-un mod asemntor

Adugarea de componente ntr-un cadru Swing


Lucrul cu un obiect JFrame este mai complicat dect lucrul cu echivalentul su AWT, n
loc s adugai containerele i componentele direct n cadru, trebuie s le adugai ntr-un container
intermediar, denumit panou de coninut (content pane).
Un cadru JFrame este mprit n mai multe panouri diferite. Panoul principal cu care
lucrai este panoul de coninut, care reprezint aria complet a cadrului n care pot fi plasate
componente.
Pentru a aduga o component n panoul de coninut se procedeaz astfel:

Creai un obiect JPanel (versiunea Swing a panoului - Panel).

Adugai componentele (care pot fi i containere) n obiectul JPanel folosind


metoda add (Component) a acestuia.

Definii acest obiect JPanel drept panou de coninut folosind metoda


setContentPane(Container). Obiectul JPanel este singurul argument al metodei.

Lucrul cu Swing
Exist componente Swing echivalente pentru toate componentele AWT pe care le-ai
nvat pn acum. n majoritatea cazurilor, constructorii componentelor Swing sunt similari

constructorilor AWT, aa c nu va fi nevoie s nvai lucruri noi pentru a putea folosi


componentele Swing.
Pentru multe componente exist i ali constructori, care primesc ca argument un obiect
Icon. O pictogram (icon) este o imagine de dimensiuni mici, de obicei n format GIF, care poate
fi folosit pentru butoane, etichete sau alte elemente ale interfeei pentru identificarea componentei.
Aceste pictograme sunt ntlnite aproape peste tot n sistemele de operare grafice cum sunt
Windows sau MacOS.
Un obiect Icon se creeaz n acelai fel ca un obiect Image. Constructorul primete ca unic
argument numele unui fiier sau o adres URL. Urmtorul exemplu ncarc o pictogram din
fiierul desen.gif i creeaz un obiect JButton avnd ca etichet pictograma respectiv.
ImageIcon fig = new ImageIcon(desen.gif);
JButton buton = new JButton(fig);
JPanel panou = new JPanel();
panou.add(buton);
setContentPane (panou) ;

Etichete
Etichetele sunt implementate n Swing folosind clasa JLabel.
Caracteristicile sunt asemntoare cu ale etichetelor AWT, ns acum putei include i
pictograme. n plus, alinierea unei etichete poate fi specificat folosind una din cele trei variabile
ale clasei
SwingConstants: LEFT, CENTER sau RIGHT.
Iat cteva metode constructor ce pot fi folosite:

JLabel(String,int)
Creeaz o etichet cu irul i alinierea specificate.

JLabel(String,Icon,int)
Creeaz o etichet cu textul, pictograma i alinierea
specificate.

Butoane
Butoanele Swing sunt descrise n clasa JButton. Ele pot folosi o etichet de text (la fel ca
butoanele AWT), o etichet pictogram sau o combinaie a acestora.
lat cteva dintre metodele constructor ce pot fi folosite:
JButton (String)
Creeaz un buton cu textul specificat.
JButton (Icon)
Creeaz un buton cu pictograma specificat.
JButton (String, Icon)
Creeaz un buton cu textul i pictograma specificate.

Cmpuri de text
Cmpurile de text sunt implementate n Swing folosind clasa JTextField. Diferena dintre
aceste cmpuri text i echivalentul lor AWT este c metoda setEchoChar(char) nu mai este
suportat de JTextField pentru mascarea textului introdus.
lat ce metode constructor putei folosi:
JTextField(int)
Creeaz un cmp de text cu limea specificat.
JTextField(String, int)
Creeaz un cmp de text cu textul i limea specificate.
Pentru crearea unui cmp de text care folosete caractere de mascare se folosete clasa
JPasswordField. Aceast clas posed aceleai metode constructor ca i JTextField:
JPasswordField(int) i JPasswordField(String, int).

O dat creat cmpul de text pentru parole, putei folosi metoda setEchoChar(char) pentru a masca
datele de intrare cu caracterul specificat.

Zone de text
Zonele de text sunt implementate n Swing folosind clasa JTextArea. Aceasta folosete
urmtoarele metode constructor;
JTextArea (int, int) Creeaz o zona de text cu numrul de rnduri i de coloane specificat.
JTextArea (String, int, int) Creeaz o zon de text cu textul, numrul de rnduri i de
coloane specificate.

Casete de validare i butoane radio


Clasa JCheckBox implementeaz n Swing casetele de validare. Comportamentul su este
acelai cu cel din AWT, avnd n plus posibilitatea de a folosi pictograme pentru etichetare.
Metodele constructor sunt urmtoarele:
JCheckBox(String) Creeaz o caset de validare cu eticheta text specificat.
JCheckBox(String, boolean) Creeaz o caset de validare cu eticheta text specificat, care
este selectat daca al doilea argument are valoarea true.
JCheckBox(Icon) Creeaz o caset de validare cu eticheta pictogram specificat.
JCheckBox (Icon, boolean) Creeaz o caset de validare cu eticheta pictogram
specificat,.
JCheckBox (String, Icon) Creeaz o caset de validare cu eticheta de text i eticheta
pictogram specificate, care este selectat dac al doilea argument are valoarea true
JCheckBox (String, Icon, boolean) Creeaz o caset de validare cu eticheta de text i
eticheta pictogram specificate
Grupurile de casete de validare sunt implementate n Swing prin clasa ButtonGroup. Aa
cum ai vzut, la un moment dat nu poate fi selectat dect o singur component a unui grup de
casete de validare. Pentru aceasta, vei crea un obiect ButtonGroup i vei folosi metoda add
(Component) pentru a aduga o component n grup.
Butoanele radio sunt implementate n Swing prin intermediul clasei JRadioButton.
Metodele constructor sunt aceleai ca pentru clasa JCheckBox.
Schimbarea numelui din CheckboxGroup n ButtonGroup reflect extensia n
funcionalitate - pot fi grupate att butoanele radio, ct i butoanele.

Liste de opiuni
Listele de opiuni, care n AWT erau create folosind clasa Choice, sunt disponibile acum
prin intermediul clasei JComboBox.
O list de opiuni este creat parcurgnd urmtoarele etape:
1. Se folosete constructorul JComboBox() fr nici un argument.
2. Se folosete metoda addItem(Obiect) a casetei combo pentru a aduga elemente n list.
3. Se folosete metoda setEditable(boolean) a casetei combo, cu argumentul avnd
valoarea false.
Aceast ultim metod transform caseta combo ntr-o list de opiuni - singurele opiuni
disponibile pentru utilizator sunt elementele coninute de list.
Cnd caseta combo este editabil permite introducerea de text din partea utilizatorului, n locul
alegerii unei opiuni din list. De la aceast combinaie provine i numele casetei (combo).

Bare de derulare
Barele de derulare sunt implementate n Swing folosind clasa JScrollBar. Funcionarea
acestora este identic cu cea a barelor de derulare AWT; putei folosi urmtoarele metode
constructor:

JScrollBar(int)
Creeaz o bar de derulare cu orientarea specificat.

JScrollBar(int, int, int, int, int) Creeaz o bar de derulare cu orientarea, valoarea
iniial, dimensiunea casetei de derulare, valoarea minim i valoarea maxim specificate.
Orientarea este specificat prin variabilele clasei SwingConstants, HORIZONTAL sau
VERTICAL.

Noile caracteristici ale Swing


n afar de faptul c extinde modul de funcionare a componentelor i a containerelor fa de
Abstract Windowing Toolkit, Swing ofer i alte caracteristici complet noi, cum ar fi: aspect (look
and feel) configurabil, secvene de taste de accelerare, sfaturi dependente de context (ToolTips) i
casete de dialog standard.

Stabilirea aspectului
Swing posed un administrator de interfa care controleaz aspectul componentelor - modul
n care butoanele, etichetele i celelalte elemente sunt reprezentate pe ecran.
Administrarea aspectului este sarcina clasei UIManager, care face parte din pachetul
javax.swing.*. Opiunile pentru aspect difer n funcie de mediul de dezvoltare folosit. In Java 2
sunt disponibile urmtoarele opiuni:
Un aspect caracteristic Windows 95 sau Windows NT
Un aspect caracteristic sistemului Motif X-Window
Metal, un nou aspect Swing, independent de platform
Clasa UIManager posed metoda setLookAndFeel(LookAndFeel), care este folosit
pentru alegerea aspectului unui program.
Pentru a obine un obiect LookAndFeel care poate fi transmis ca argument metodei
setLookAndFeel() putei folosi una dintre metodele UIManager:
getCrossPlatformLookAndFeelClassName()
Aceast metod returneaz un obiect
LookAndFeel care reprezint aspectul Metal, independent de platform.
getSystemLookAndFeelClassName()
Aceast metod returneaz un obiect
LookAndFeel care reprezint un obiect caracteristic sistemului.
Daca nu poate stabili aspectul interfeei, metoda setLookAndFeel() semnaleaz o excepie
UnsupportedLookAndFeel.
Urmtoarele instruciuni pot fi folosite pentru a stabili un aspect Metal n orice program:
try {
UIManager.setLookAndFeel(

UIManager.getCrossPlatformLookAndFeelClassName ()) ;
} catch (Exception e) {

System.err.println(Nu pot stabili aspectul: + e) ;


}
Pentru a stabili aspectul sistemului, n cadrul metodei setLookAndFeel se foloseste metoda
getSystemLookAndFeelClassName(). Aceasta are rezultate diferite pe sisteme de operare diferite.
Folosind metoda getSystemLookAndFeelClassName(), un utilizator de Windows 95 va obine un
aspect Windows 95, iar un utilizator UNIX va obine un aspect Motif.

Secvente de taste de accelerare


O secven de taste de accelerare (key accelerator), denumit i secven de prescurtare
(keyboard mnemonic), reprezint o grupare de taste care poate fi folosit pentru a controla
comportamentul unei componente a interfeei utilizator. Aceste taste permit folosirea unui program
fr ajutorul mouse-ului; tehnica este nglobat n Swing ca parte a suportului pentru persoane cu
nevoi speciale - clase care permit folosirea programelor Java de ctre nevztori sau alte persoane
cu incapaciti fizice.
Tastele de accelerare simuleaz aciunea mouse-ului, iar modul lor de folosire depinde de
platforma folosit. Pe un calculator care ruleaz Windows 95, tastele de accelerare sunt disponibile
apsnd tasta Alt mpreun cu o alt tast.
Tastele de accelerare sunt stabilite prin apelul metodei setMnemonic(char) a componentei
care va fi controlat prin secvena respectiv. Argumentul char este tasta care va fi folosit n
combinaia de accelerare. Urmtorul exemplu creeaz un obiect JButton i asociaz caracterul i
ca parte a secvenei de accelerare pentru acesta:
JButton butonInfo = new Jbutton ("Informatii");
butonInfo.setMnemonic(i) ;
Apsarea combinaiei Alt+I este echivalent cu executarea unui clic pe componenta
butonInfo.

Sfaturi dependente de context


O alt modalitate de a face ca programul s fie mai prietenos cu utilizatorul este de a asocia
sfaturi dependente de context (ToolTips) cu componentele unei interfee. Elementele TooITip sunt
folosite pentru a descrie scopul unei componente. Atunci cnd nvai s folosii un program pentru
prima dat, aceste sfaturi reprezint un ajutor binevenit.
Pentru a asocia un sfat ToolTip cu o component, apelai metoda setToolTipText (String)
pentru componenta respectiv. irul ar trebui s conin o descriere sumar a rolului componentei.
Urmtorul exemplu creeaz o component JScrollBar i i asociaz acesteia un element
ToolTip.
JScrollBar viteza = new JscrollBar();
viteza.setToolTipText("Modifica viteza de animatie);
Textul ToolTip se poate ntinde pe o singur linie, aa c nu putei folosi caracterul linie
nou (newline \n) pentru a scrie mai multe rnduri.

Descrieri i nume de componente

O alt metod de a face mai accesibil o interfa este de a oferi o descriere text pentru
componentele Swing. Aceast tehnic presupune dou etape:

1. Obinei obiectul AccessibleContext asociat componentei prin apelarea metodei


getAccessibleContext() a acesteia.
2. Apelai metoda setAccessibleDescription(String) pentru obiectul AccessibleContext.
Argumentul ir trebuie s conin textul descrierii componentei.
De exemplu, urmtorul exemplu stabilete descrierea unui obiect JButton:
JButton terminare = new JButton("Terminare");
terminare.getAccessibleContext().setAccessibleDescription( "C
nd executati clic pe acest buton, programul se va termina);
Metoda setAccessibleName (String) funcioneaz n acelai fel ca metoda
setAccessibleDescription (String). Aceasta poate fi folosit pentru a da componentei un nume care
s descrie pe scurt rolul ei. n cazul butonului Terminare din exemplul anterior, numele de "Buton
de terminare" ar fi foarte potrivit. Urmtorul exemplu stabilete pentru cmpul de text cu numele
"Camp text":
JTextField ct = new JTextField();
ct.getAccessibleContext().setAccessibleName("Camp text);

Casete de dialog standard


Clasa JOptionPane ofer mai multe metode care pot fi folosite pentru a crea casete de
dialog standard: mici ferestre n care se pune o ntrebare, se atrage atenia utilizatorului sau se
afieaz un scurt mesaj informativ.
Fr ndoial c ai mai vzut casete de dialog de acest fel - atunci cnd sistemul
dumneavoastr se blocheaz, apare o caset de dialog care v anun vetile proaste. Sau atunci
cnd tergei fiiere se poate folosi, de asemenea, o caset de dialog, care s v ntrebe nc o dat
dac chiar dorii s facei acest lucru. Aceste ferestre reprezint o modalitate eficient de
comunicare cu utilizatorul, far efortul suplimentar de a crea o clas nou care s reprezinte
fereastra, de a aduga componente n ea i de a scrie metode de tratare a evenimentelor pentru
preluarea datelor de intrare. Dac se folosete una dintre casetele de dialog standard oferite de dasa
JOptionPane, toate aceste lucruri sunt realizate automat.
Exist patru tipuri de casete de dialog standard:

ConfirmDialog
O caset de dialog care pune o ntrebare i posed trei
butoane, corespunztoare rspunsurilor Yes, No i Cancel.

InputDialog
O caset de dialog care ateapt introducerea unui text.

MessageDialog
O caset de dialog care afieaz un mesaj.

OptionDialog
O caset de dialog care cuprinde toate celelalte trei tipuri.
Fiecare dintre aceste casete de dialog posed propria metod n cadrul clasei
JOptionPane.

Casete de dialog de confirmare


Cea mai simpl metod de creare a unei casete de dialog Yes/No/Cancel (Da/Nu/Anulare)
este de a folosi metoda showConfirmDialog (Component, Object). Argumentul Component
specific containerul care va fi considerat printele casetei de dialog; aceast informaie este
folosit pentru a determina unde se va afia pe ecran fereastra de dialog. Dac se folosete valoarea
null pentru acest argument sau containerul nu este un obiect Frame, caseta de dialog va fi afiat n
centrul ecranului.

Al doilea argument poate fi un ir, o component sau o pictogram. Dac este un ir de text,
acesta va fi afiat n cadrul casetei de dialog. Dac este o alt component sau o pictograma, n locul
mesajului text va fi afiat obiectul respectiv.
Aceast metod returneaz una dintre cele trei valori posibile, reprezentate prin ntregi, care
sunt variabile de clas ale JOptionPane: YES_OPTION, NO_OPTION sau CANCEL_OPTION.
n continuare se prezint un exemplu care folosete o caset de dialog de confirmare cu un
mesaj text i memoreaz rspunsul n variabila raspuns:
int raspuns;
raspuns = JOptionPane.showConfirmDialog(null, "Pot sa sterg
toate fisierele dumneavoastra personale confidentiale?);
Exist o alt metod ce ofer mai multe opiuni pentru dialogul de confirmare:
showConfirmDialog(Component, Object, String, int, int). Primele dou argumente sunt
aceleai ca pentru cealalt metod, iar ultimele trei sunt urmtoarele:

Un ir care va fi afiat ca bar de titlu a casetei de dialog.

Un ntreg care indic ce butoane vor fi afiate. Acesta trebuie s aib valoarea egal
cu una dintre variabilele de clas YES_NO_CANCEL_OPTION sau YES_NO_OPTION.

Un ntreg care descrie tipul de caset de dialog cu ajutorul variabilelor de clas


ERROR_MESSAGE, INFORMATION_MESSAGE, PLAIN_MESSAGE,
QUESTION_MESSAGE sau WARNING_MESSAGE. Acest argument este folosit pentru a
determina care pictogram se afieaz n caseta de dialog, lng mesaj.
int raspuns = JOptionPane.showConfirmDialog(null, "Error reading file. Want to try
again?", "File Input Error.", JoptionPane.YES_NO_OPTION, JOptionPane.ERROR_MESSAGE);

Casete de dialog de intrare


O caset de dialog de intrare afieaz o ntrebare i folosete un cmp de text pentru a
memora rspunsul.
Cea mai simpl modalitate de a crea o caset de dialog de intrare este de a apela metoda
showInputDialogBox (Component, Object). Argumentele sunt componenta printe, respectiv irul,
componenta sau pictograma care se vor afia n caset.
Exemplu:
String raspuns = JOptionPane.showInputDialogBox (null,"Enter your
name:");
Putei crea o caset de dialog de intrare i cu ajutorul metodei showInputDialog
(Component, Object, String, int). Primele dou argumente sunt aceleai cu ale metodei anterioare,
iar ultimele dou reprezint:

Titlul afiat n bara de titlu a casetei de dialog.

Una din cele cinci variabile de clas care descriu tipul casetei de dialog:
ERROR_MESSAGE, INFORMATION_MESSAGE, PLAIN_MESSAGE,
QUESTION_MESSAGE sau WARNING_MESSAGE.
Urmtoarea instruciune creeaz o caseta de dialog de intrare folosind aceast metod:
String raspuns=JOptionPane.showInputDialog(null, "Care este codul
dunineavoastra postal?", "Introduceti codul postal,
JOptionPane.QUESTION_MESSAGE);

Casete de dialog pentru mesaje


Caseta de dialog pentru mesaje este o fereastr simpl n care se afieaz o informaie.

O caset de dialog pentru mesaje poate fi creat printr-un apel al metodei


showMessageDialog (Component, Object). Ca i n cazul celorlalte casete de dialog, argumentele
sunt componenta printe, respectiv irul, componenta sau pictograma care se vor afia.
Spre deosebire de alte casete de dialog, casetele pentru mesaje nu ntorc nici un fel de
valoare de rspuns
Exemplu:
JOptionPane.showMessageDialog(null, "The program has been
uninstalled.") ;
Mai putei crea o astfel de caset de mesaje i cu ajutorul metodei
showMessageDialogComponent(Object, String, int). Modul de folosire este identic cu al metodei
showInputDialog(), cu aceleai argumente, cu excepia faptului c metoda showMessageDialog()
nu returneaz nici o valoare.
Instruciunea urmtoare creeaz o caset de dialog pentru mesaje folosind aceast ultim
metod:
JOptionPane.showMessageDialog(null,"Un asteroid a distrus Pamantul",
"Alerta: pericol de asteroizi", JOptionPane.WARNING_MESSAGE) ;

Casete de dialog cu opiuni


Cea mai complex caset de dialog este caseta de dialog cu opiuni, care combin
caracteristicile tuturor celorlalte casete de dialog. Aceast caset poate fi creat folosind metoda
showOptionDialog (Component, Object, String, int, int, Icon, Object [ ], Object);
Argumentele acestei metode sunt prezentate n continuare:
Componenta printe a casetei de dialog
Textul, pictograma sau componenta de afiat
irul ce va fi afiat n bara de titlu
Tipul casetei, folosind variabilele de clas YES_NO_OPTION,
YES_NO_CANCEL_OPTION sau literalul 0, dac vor fi folosite alte butoane.
Pictograma care va fi afiat; se folosesc variabilele de clas ERROR_MESSAGE,
INFORMATION_MESSAGE, PLAIN_MESSAGE, QUESTION_MESSAGE,
WARNING_MESSAGE sau literalul 0, dac nu se folosete nici una dintre acestea
Un obiect Icon care va fi afiat n locul uneia dintre pictogramele stabilite de argumentul
anterior
Un tablou de obiecte care pstreaz componentele sau alte obiecte ce vor reprezenta
opiunile casetei de dialog, dac nu se folosesc valorile YES_NO_OPTION sau
YES_NO_CANCEL_OPTION
Obiectul care reprezinta selecia prestabilit, n cazul n care nu se folosesc opiunile
YES_NO_OPTION sau YES_NO_CANCEL_OPTION
Ultimele dou argumente v permit s creai o gam larg de opiuni pentru caseta de
dialog. Putei crea un tablou de butoane, de etichete, de cmpuri de text sau chiar o combinaie de
diferite obiecte. Aceste componente vor fi afiate folosind administratorul de dispunere secvenial
(flow manager); nu exist nici o modalitate de a specifica un alt administrator de dispunere n
cadrul casetei de dialog.

Tratarea evenimentelor utilizator cu ajutorul Swing


Pentru a face dintr-o interfa Java funcional un program Java funcional, va trebui ca
interfaa s rspund la evenimentele produse de utilizator.

Swing trateaz evenimentele n mod diferit, folosind un set de clase denumite interceptoare
de evenimente (event listeners).

Evenimentul principal
n sistemul de tratare a evenimentelor, evenimentele erau prelucrate prin intermediul unui
set de metode disponibile tuturor componentelor. Metode cum ar fi mouseDown(), keyDown() sau
action() puteau fi suprascrise de orice program AWT care dorea s trateze aceste evenimente.
Aceste sistem de tratare a evenimentelor este caracteristic doar Java 1.02, deoarece n urmtoarele
versiuni ale limbajului a fost introdus o versiune mult mbuntit a acestuia.

Acest nou sistem se folosete n aplicaiile Swing.

Interceptoare de evenimente
Dac o clas dorete s rspund unui eveniment utilizator conform sistemului Java 2 de
tratare a evenimentelor, ea trebuie s implementeze o interfa care s prelucreze evenimentele.
Aceste interfee se numesc interceptoare de evenimente (event listeners).
Fiecare interceptor trateaz un anumit tip de eveniment, iar o clas poate implementa oricte
evenimente are nevoie.
Sunt disponibile urmtoarele interceptoare de evenimente:
ActionListener
Trateaz evenimente de aciune, care sunt generate de aciunea unui
utilizator asupra unei componente cum ar fi execuia unui clic pe un buton.
AdjustmentListener
Trateaz evenimente de modificare, care sunt generate de
modificarea unei componente, cum ar fi deplasarea unei bare de derulare,
FocusListener
Trateaz evenimente de selecionare, care sunt generate atunci cnd o
component, cum ar fi un cmp de text, devine selectat sau pierde acest atribut.
ItemListener
Trateaz evenimente de element, care sunt generate atund cnd este
modificat starea unui element cum ar fi o caset de validare.
KeyListener Trateaz evenimente de tastatur, care apar atunci cnd un utilizator
introduce date prin intermediul tastaturii.
MouseListener
Trateaz evenimente de mouse, care sunt generate de clicuri cu
mouse-ul, de ptrunderea indicatorului mouse-ului pe suprafaa unei componente sau de prsirea
acesteia.
MouseMotionListener
Trateaz evenimente de deplasare a mouse-ului, care sunt
folosite pentru a memora toate micarile mouse-ului pe o componenta.
WindowListener Trateaz evenimente de ferestre, care sunt generate de maximizarea,
minimizarea, mutarea sau nchiderea ferestrelor.
Urmtoarea clas este declarat astfel nct s poat trata att evenimentele de aciune, ct i
pe cele de text;
public class Test extends JFrame implements ActionListener,
TextListener {
// . . .
}
Pacherul java.awt.event conine toate interceptoarele principale de evenimente, precum i
pe cele asociate unor evenimente specifice. Pentru a folosi aceste clase n programele
dumneavoastr putei s le importai individual sau s folosii o instruciune de tipul:
import java.awt.event.*;

Configurarea componentelor

Prin definirea unei clase ca interceptor de evenimente ai stabilit faptul c aceasta poate asculta"
(intercepta) un anumit tip de eveniment. Totui nu se va ntmpla nimic dac nu continuai cu un al doilea
pas: trebuie s asociai componentei un interceptor de acelai tip; la folosirea componentei, acesta va
genera evenimentele respective.

Dup crearea unei componente, pentru a o asocia cu un anumit tip de interceptor putei apela
una din urmtoarele metode:
addActionListener() Pentru componente JButton, JCheckBox, JComboBox,
JTextField i JRadioButton
addAdjustmentListener() Pentru componente JScrollBar
addFocusListener() Pentru toate componentele Swing
addItemListener() Pentru componente JButton, JCheckBox, JComboBox i
JRadioButton
addKeyListener() Pentru toate componentele Swing
addMouseListener()
Pentru toate componentele Swing
addMouseMotionListener()
Pentru toate componentele Swing
addWindowListener()
Pentru toate componentele JWindow i JFrame
O greeal des ntlnit n programele Java o constituie modificarea unei componente dup
introducerea acesteia ntr-un container. Metodele de interceptare i celelalte configurri trebuie
stabilite pentru o component nainte de a o aduga ntr-un container; altfel toate acestea vor fi
ignorate la execuia programului.
Urmtorul exemplu creeaz un obiect JButton i i asociaz un interceptor de evenimente de
aciune:

JButton terminare = new JButton("Terminare");


terminare.addActionListener(this) ;
Toate metodele add. . .() folosesc un singur argument: obiectul care intercepteaz
evenimentele de tipul respectiv. Folosirea cuvntului cheie this indic faptul c obiectul interceptor
este chiar clasa curent. Putei specifica i alte obiecte, att timp ct clasa respectiv implementeaz
interfaa de interceptare corespunztoare.

Metode de tratare a evenimentelor


Atunci cnd asociai o interfa unei clase, clasa trebuie s implementeze toate metodele
coninute de interfa.
n cazul interceptoarelor de evenimente, fiecare metod este apelat automat de sistemul de
ferestre atunci cnd are loc evenimentul corespunztor.
Interfaa ActionListener posed o singur metod: actionPerformed(). Toate clasele care
implementeaz ActionListener trebuie s conin o metod cu urmtoarea structur:
public void actionPerformed(ActionEvent evt) {
// aici se trateaza evenimentul
}
Dac n cadrul interfeei grafice utilizator exist o singur component care are asociat un
interceptor de evenimente de aciune, atunci metoda actionPerformed() poate fi folosit pentru a
rspunde la un eveniment generat de component.
Dac mai multe componente au asociate interceptoare de evenimente de aciune, trebuie s
folosii metoda pentru a afla mai nti care dintre componente a fost folosit, dup care s acionai
corespunztor.

n metoda actionPerformed() se transmite ca argument un obiect ActionEvent. Acest


obiect poate fi folosit pentru a afla detalii despre componenta care a generat evenimentul.
ActionEvent i celelalte obiecte eveniment fac parte din pachetul java.awt.event i sunt
subclase ale clasei EventObject.
Fiecare metod de tratare a evenimentelor primete ca argument un obiect eveniment de un
anumit tip. Pentru a determina componenta care a transmis evenimentul se poate folosi metoda
getSource() a obiectului, ca n exemplul urmtor:
public void actionPerformed(ActionEvent evt) {
Object sursa = evt.getSource();
}
Obiectul returnat de metoda getSource() poate fi comparat cu o component folosind
operatorul = =. n exemplul actionPerformed() anterior se pot folosi urmtoarele instruciuni:
if (sursa == butonTerminare)
terminaProgram() ;
else if (sursa == sortareInregistrari)

sorteazaInregistrari() ;
Acest exemplu apeleaz metoda terminareProgram() n cazul cnd evenimentul a fost
generat de obiectul butonTerminare sau metoda sortareInregistrari() dac evenimentul a fost
generat de obiectul sortareInregistrari.
Multe metode de tratare a evenimentelor apeleaz metode diferite pentru fiecare tip de
eveniment sau de component. Aceasta face ca metoda de tratare a evenimentelor s fie uor de
citit. n plus, dac o clas conine mai multe metode de tratare a evenimentelor, fiecare poate apela
aceleai metode pentru realizarea sarcinii dorite.
O alt tehnic util n cadrul unei metode de tratare a evenimentelor o constituie folosirea
operatorului instanceof, care permite testarea fiecrui tip de component care putea genera
evenimentul. Urmtorul exemplu poate fi folosit ntr-un program care conine un buton i un cmp
de text, fiecare dintre acestea genernd evenimente de aciune:
void actionPerformed(ActionEvent evt) {
Object sursa = evt.getSource() ;
if (sursa instanceof JTextField)
calculeazaScor() ;
else if (sursa instanceof JButton)
terminaProgram() ;
}

Evenimente de actiune
Evenimentele de aciune apar atunci cnd utilizatorul realizeaz o aciune asupra unui obiect
de tip JButton, JCheckBox, JTextField sau JRadioButton.
Pentru a trata aceste evenimente, o clas trebuie s implementeze interfaa ActionListener.
n plus, trebuie apelat metoda addActionListener() pentru fiecare component care urmeaz s
genereze evenimente de aciune, cu excepia cazurilor n care dorii s ignorai evenimentele de
aciune ale unei componente.
Interfaa ActionListener conine o singur metod: actionPerformed(ActionEvent) care
are urmtoarea form:
public void actionPerformed(ActionEvent evt) {
// ...
}
n afar de metoda getSource(), putei folosi metoda getActionCommand() cu argumentul
ActionEvent, pentru a afla mai multe informaii despre sursa evenimentului.

n mod prestabilit, comanda aciunii reprezint textul asociat componentei, cum ar fi


eticheta de pe un buton JButton. Putei ns s definii o comand de aciune diferit pentru fiecare
component, folosind metoda setActionCommand(String). Argumentul ir trebuie s conin
textul dorit pentru comanda aciunii.
De exemplu, urmtoarele instruciuni creeaz obiectele JButton i JTextField i le asociaz
amndurora comanda de aciune "Sortare fiiere":
JButton sortare = new JButton("Sortare);
JTextField nume = new JTextField() ;
sortare.setActionCommand(Sortare fisiere);
nume.setActionCommand(Sortare fisiere);

Evenimente de modificare
Evenimentele de modificare (ajustare) apar atund cnd o component JScrollBar este
deplasat folosind sgeile, caseta de derulare sau printr-un clic undeva pe bar. Pentru a trata aceste
evenimente, o clas trebuie s implementeze interfaa AdjustmentListener.
Interfaa AdjustmentListener conine o singur metod, care are urmtoarea form:
adjustmentValueChanged(AdjustmentEvent evt) {
// ...
}
Pentru a obine valoarea curent a obiectului JScrollBar putei folosi metoda getValue()
avnd ca argument obiectul AdjustmentEvent. Aceast metod returneaz o valoare ntreag care
reprezint valoarea barei de derulare..
Putei determina i modul cum a fost deplasat bara de derulare dac folosii metoda
getAdjustmentType() a obiectului AdjustmentEvent. Aceasta returneaz una din urmtoarele
cinci valori, care sunt variabile de clas ale clasei Adjustment:
UNIT_INCREMENT
O cretere cu 1 a valorii, produs de executarea unui clic pe
sgeata de deplasare a barei sau pe o tast cu sgeat
UNIT_DECREMENT
O descretere a valorii cu 1
BLOCK_INCREMENT
O cretere mai mare a valorii, cauzat de un clic pe bara de
derulare, n zona dintre caset i sgeat
BLOCK_DECREMENT O descretere mai mare a valorii
TRACK
O modificare produs de deplasarea casetei de derulare

Evenimente de selecionare
Evenimentele de selecionare (focus events) apar atunci cnd o component primete sau
pierde dreptul de a primi datele de intrare n cadrul interfeei grafice utilizator. Starea de
selecionare determin componenta care este activat la un moment dat pentru a primi date de
intrare de la tastatur. Dac unul din cmpurile de text este selecionat (ntr-o interfa utilizator cu
mai multe cmpuri de text editabile), n acesta se va vedea un cursor care plpie. Orice text
introdus de la tastatura este memorat n componenta selecionat.
Starea de selecionare (focus) se aplic tuturor componentelor care pot primi date de intrare
de la tastarur. n cazul unui obiect JButton selecionat, pe suprafaa acestuia va fi reprezentat un
contur cu linie ntrerupt.

Pentru a trata un eveniment de selecionare, o clas trebuie s implementeze interfaa


FocusListener. Aceast interfa conine dou metode: focusGained(FocusEvent) i
focusLost(FocusEvent), care au urmtoarea form:
public void focusGained(FocusEvent evt) {
// ...
}
public void focusLost(FocusEvent evt) {
// ...
}
Pentru a determina care obiect a obinut sau a pierdut starea de selecionare se poate folosi
metoda getSource() pentru obiectul FocusEvent, primit ca argument de metodele focusGained()
sau focusLost().

Evenimente de element
Evenimentele de element (item events) apar atunci cnd se selecteaz sau se deselecteaz un
element de tip JButton, JCheckBox, JComboBox sau JRadioButton. Pentru a trata aceste
evenimente, o clas trebuie s implementeze interfaa ItemListener.
Aceast interfa conine o singur metod: itemStateChanged (ItemEvent), care are
urmtoarea form:
void itemStateChanged(ItemEvent evt) {
// ...
}
Pentru a determina elementul care a produs evenimentul se poate folosi metoda getItem(),
care primete ca argument obiectul ItemEvent.
De asemenea, putei determina dac elementul a fost selectat sau deselectat folosind metoda
getStateChange(). Aceasta returneaz o valoare ntreag, egal cu una dintre variabilele de clas
ItemEvent. DESELECTED sau ItemEvent.SELECTED.

Evenimente de tastatur
Evenimentele de tastatur (key events) sunt generate atunci cnd se apas o tast. Orice
component poate genera aceste evenimente, iar pentru a fi suportate ntr-o clas, aceasta trebuie s
implementeze interfaa KeyListener.
Aceast interfa conine trei metode: keyPressed(KeyEvent), keyReleased(KeyEvent) i
keyTyped(KeyEvent), care au urmtoarea form:
public void keyPressed(KeyEvent evt) {
//...
}
public void keyReleased(KeyEvent evt) {
// ...
}
public void keyTyped(KeyEvent evt) {
// ...
}

Metoda getkeyChar() a obiectului KeyEvent returneaz caracterul tastei asociate


evenimentului. Dac nu exist caracterul Unicode al tastei, metoda getKeyChar() returneaz o
valoare egal cu variabila de clas KeyEvent.CHAR_UNDEFINED.

Evenimente de mouse
Evenimentele de mouse sunt generate, de obicei, de mai multe tipuri de interaciuni:

Clic de mouse
Indicatorul mouse-ului ptrunde pe suprafaa componentei
Indicatorul mouse-ului prsete suprafaa componentei
Orice component poate genera aceste evenimente, care sunt implementate de o clas prin
intermediul interfeei MouseListener. Aceast interfa posed cinci metode:
mouseClicked(MouseEvent)
mouseEntered(MouseEvent)
mouseExited(Mouse.Event)
mousePressed(Mouse.Event)
mouseReleased(MouseEvent)
Fiecare dintre acestea are forma generic prezentat mai jos pentru mouseReleased
(MouseEvent):
mouseReleased(MouseEvent evt) {
// ...
}
Pentru obiectele MouseEvent pot fi folosite unntoarele metode:
getClickCount() Returneaz o valoare ntreag ce reprezint de cte ori s-a executat clic
getPoint() Returneaz coordonatele x,y ale punctului unde s-a executat clic pe
component, sub forma unui obiect Point.
getX()
Returneaz poziia x
getY()
Returneaz poziia y

Evenimente de deplasare a mouse-ului


Evenimentele de micare a mouse-ului apar atunci cnd mouse-ul este deplasat pe o
component. Ca i n cazul altor evenimente de mouse, orice component poate genera evenimente
de deplasare a mouse-ului. Pentru a suporta aceste evenimente, o clas trebuie s implementeze
interfaa MouseMotionListener.
Aceast interfa conine dou metode: mouseDragged(MouseMotionEvent) i
mouseMoved(MouseMotionEvent), care au urmtoarea form:
public void mouseDragged(MouseEvent evt) {
// ...
}
public void mouseMoved(MouseEvent evt) {
// ...
}
Spre deosebire de alte interfee de interceptoare de evenimente pe care le-ai ntlnit pn
acum, MouseMotionListener nu posed un tip propriu de eveniment, ci folosete evenimente
MouseEvent.
Din acest motiv, putei apela orice metode corespunztoare evenimentelor de mouse:
getClickCount(), getPoint (), getX() sau getY().

Evenimente de fereastr
Evenimentele de fereastr apar atunci cnd utilizatorul deschide sau nchide un obiect
fereastr, cum ar fi JFrame sau JWindow. Orice componenta poate genera aceste evenimente, iar
pentru a le trata, o clas trebuie s implementeze interfaa windowListener.
Interfaa WindowListener conine apte metode:
windowActivated(WindowEvent)
windowClosed(WindowEvent)
windowClosing(WindowEvent)
windowDeactivated(WindowEvent)
windowDeiconified(WindowEvent)
windowIconified(WindowEvent)
windowOpened(WindowEvent)
Toate acestea au urmtoarea form, prezentat aici pentru metoda
windowOpened(WindowEvent):
public void windowOpened(WindowEvent evt) {
// . . .
}
Metodele windowClosing() i windowClosed() sunt asemntoare, ns una este apelat o
dat cu nchiderea ferestrei, iar cealalt - dup nchiderea acesteia. Dac dorii, este posibil ca n
cadrul metodei windowClosing() s decidei anularea nchiderii ferestrei.

Comunicarea prin Internet


Biblioteca de clase Java conine pachetul java.net, care face posibil comunicarea cu
programele Java prin intermediul reelelor. Pachetul ofer funcii abstracte inter-platform pentru
operaiile de reea simple, cum ar fi conectarea i transferul de fiiere folosind protocoale Web sau
crearea de socluri (sockets) specifice UNIX.
Folosite mpreun cu fluxurile de intrare sau de ieire, citirea i scrierea fiierelor prin
reea devin la fel de simple ca folosirea fiierelor de pe discul local.

Comunicaia prin reea n Java


Comunicaia n reea (networking) reprezint capacitatea unui applet sau a unei aplicaii de
a stabili conexiuni cu un alt sistem prin intermediul reelei. Comunicaia prin reea n Java
presupune folosirea claselor din pachetul java.net, care ofer funcii de reea abstracte, multiplatform, pentru principalele operaii de lucru n reea, cum ar fi conectarea i transferul de fiiere
folosind protocoale Web sau crearea de socluri (sockets) tip UNIX. Folosite mpreun cu fluxurile
de intrare sau de ieire, operaiile de citire sau scriere de fiiere prin reea devin la fel de simple ca
i citirea sau scrierea fiierelor pe sistemul local.
Bineneles, exist i restricii. De obicei, applet-urile Java nu pot citi sau scrie pe discul mainii pe
care ruleaz browserul. De asemenea, applet-urile Java nu se pot conecta la alte sisteme dect la cel
de unde au fost ncrcate iniial. Chiar i cu aceste restricii, putei realiza proiecte interesante i
putei beneficia de avantajele oferite de Web pentru citirea sau procesarea informaiilor din Internet.
Aceast seciune descrie dou modaliti simple de comunicare cu sistemele din Internet:
getInputStream() este o metod care deschide o conexiune ctre o adres URL i v
permite s extragei date din acea conexiune
Clasele soclu, Socket i ServerSocket, v permit s deschidei o conexiune standard care
folosete socluri, conexiune prin care putei citi sau scrie date.

Deschiderea de conexiuni Web


n loc s cerei browserului s ncarce coninutul fiierului, uneori este nevoie s obinei
coninutul acestuia pentru a fi prelucrat de un applet. Dac fiierul pe care dorii s l obinei este
stocat n Web i poate fi accesat folosind adrese URL (http, FTP i aa mai departe), programul
dumneavoastr Java poate folosi clasa URL pentru a-l obine.
Din motive de securitate, applet-urile se pot conecta n mod prestabilit doar la maina de
unde au fost ncrcate iniial. Aceasta nseamn c dac applet-urile sunt stocate pe un sistem
denumit www.prefect.com, singura main ctre care applet-ul poate deschide o conexiune este
sistemul respectiv - i, mai precis, cu numele respectiv, deci avei grij la folosirea denumiri-lor
echivalente (alias). Dac fiierul pe care applet-ul dorete s l apeleze se afl pe acelai sistem,
atunci folosirea de conexiuni URL reprezint cea mai simpl metod de a-l obine.

Restriciile de securitate schimb modul de scriere i testare a applet-urilor care ncarc fiiere pe
baza adreselor lor URL. Deoarece pn acum nu ai folosit conexiuni de reea, ai putut testa appleturile pe sistemul local prin simpla ncrcare a fiierelor HTML ntr-un browser sau n utilitarul
appletviewer. Acest lucru nu poate fi fcut n cazul applet-urilor care deschid conexiuni de reea.
Pentru ca aceste applet-uri s funcioneze corect trebuie s procedai ntr-unul din urmtoarele
moduri:
Rulai browserul pe aceeai main pe care ruleaz i serverul Web. Dac nu avei acces la
un server Web, putei instala i rula unul pe propria dumneavoastr main.
Copiai clasa i fiierul HTML pe serverul Web ori de cte ori dorii s le testai, apoi rulai
applet-ul din pagina Web, nu de pe sistemul local.
n acest mod v vei da seama dac applet-ul i conexiunea deschis de acesta se afl pe
aceeai main. Dac ncercai s ncrcai un applet sau un fiier de pe alte servere, vei obine o
excepie de securitate, mpreun cu o mulime de alte mesaje de eroare afiate pe ecran sau pe
consola Java.
Din aceste motive, acunci cnd v conectai la Internet pentru a-i folosi resursele, este
bine s folosii aplicaii, care nu sufer de aceste restricii.

Deschiderea unui flux n reea


Exist mai multe modaliti de transferare a informaiilor prin intermediul unui flux. Clasele
i metodele alese depind de formatul informaiei i de ceea ce dorii s facei cu ele.
Una dintre resursele pe care le putei apela din programele Java o reprezint fiierele text din
World Wide Web, indiferent daca sunt fiiere HTML sau un alt tip de fiiere de text simplu.
Pentru a ncrca un document text din Web i a-l citi linie cu linie, putei folosi urmtoarea
tehnic, format din patru etape:
Creai un obiect URL care reprezint adresa World Wide Web a resursei.
Creai un obiect URLConnection care ncarc obiectul URL i realizeaz o conexiune la
maina care stocheaz resursa respectiv.
Folosind metoda getInputStream() a obiectului URLConnection, creai un flux de intrare
InputStreamReader care poate citi un flux de date de la adresa URL.
Folosind fluxul de intrare, creai un obiect BufferedReader, care mrete eficiena citirii
caracterelor dintr-un flux de intrare.
ntre punctul A (documentul Web) i punctul B (programul Java) se desfoar o mulime
de operaii: adresa URL se folosete pentru a crea o conexiune URL, care se folosete pentru a
crea un flux de intrare, care se folosete pentru a crea un flux de intrare cu tampon. Necesitatea
interceptrii eventualelor excepii care pot aprea pe parcursul acestui proces mrete i mai mult
gradul lui de complexitate.
n continuare este prezentat un exemplu care folosete aceast tehnic n patru pai pentru
a deschide o conexiune la un site web pentru a citi un document html. Dup citirea complet a
documentului acesta este afiat ntr-o zon de text (TextArea).
import
import
import
import

java.awt.*;
java.awt.event.*;
java.net.*;
java.io.*;

public class CitireFisier extends Frame implements Runnable {

Thread executabil;
URL page;
TextArea box = new TextArea("Transfer text ...");
public CitireFisier() {
super("Transfer fisier");
add(box);
try {
page = new URL("http://www.masini.ro//masini.html");
}
catch (MalformedURLException e) {
System.out.println("URL gresit: " + page);
}
}
public static void main(String[] arguments) {
CitireFisier cadru = new CitireFisier();
WindowListener l = new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
};
cadru.addWindowListener(l);
cadru.pack();
cadru.setVisible(true);
if (cadru.executabil == null) {
cadru.executabil = new Thread(cadru);
cadru.executabil.start();
}
}
public void run() {
URLConnection conn = null;
InputStreamReader in;
BufferedReader data;
String line;
StringBuffer buf = new StringBuffer();
try {
conn = this.page.openConnection();
conn.connect();
box.setText("Conexiune deschisa ...");
in = new InputStreamReader(conn.getInputStream());
data = new BufferedReader(in);
box.setText("Citeste date ...");
while ((line = data.readLine()) != null) {
buf.append(line + "\n");
}
box.setText(buf.toString());
}

catch (IOException e) {
System.out.println("Eroare ! :" + e.getMessage());
}
}
}

Socluri
Pentru aplicaiile de reea unde folosirea claselor URL sau URLConnection nu este
suficient (cum ar fi cazurile cnd se folosesc alte protocoale sau pentru comunicaii n reea
generice), Java ofer clasele Socket i ServerSocket drept o metod proprie, echivalent tehnicilor
de programare cu socluri TCP standard (sockets).
Clasa Socket ofer o interfa soclu client asemntoare soclurilor UNIX. Crearea unei noi instane
a clasei Socket, prin care se deschide o conexiune, se face astfel (numeGazda este numele mainii gazd,
iar numarPort este numrul portului):

Socket conexiune = new Socket(numeGazda, numarPort);


Observaie

Dac folosii socluri ntr-un applet, nu uitai c v aflai sub incidena restriciilor de
securitate proprii unui applet, care v interzic s v conectai la un alt sistem dect la cel de unde
provine applet-ul.
O dat soclul deschis, putei folosi fluxuri de intrare sau de ieire pentru a citi din acesta:
BufferedInputStream bis =
new BufferedInputStream(conexiune.getInputStream());
DataInputStream intrare = new DataInputStream(bis);
BufferedOutputStream bos =
new BufferedOutputStream(conexiune.getOutputStream() ) ;
DataOutputStream iesire = new DataOutputStream(bos);
Dup ce ai terminat de lucrat cu un soclu, nu uitai s l nchidei. (Acest lucru va nchide, de
asemenea, fluxurile de intrare sau de ieire pe care le-ai atribuit soclului.)

conexiune.close() ;
Soclurile server funcioneaz asemntor, cu excepia metodei accept(). Un soclu server ascult pe
un port TCP pentru a intercepta o cerere de conexiune din partea unui client; atund cnd clientul se
conecteaz la un port, metoda accept() accept conexiunea de la acesta. Prin folosirea soclurilor client i
server putei crea aplicaii care comunic prin reea.

Pentru a crea un soclu server ataat unui port, se instaniaz clasa ServerSocket, specificnd
numrul portului:
ServerSocket sConexiune = new ServerSocket(8888);
Folosii metoda accept() pentru a asculta portul respectiv i pentru a accepta eventualele
conexiuni ale clienilor:
sConexiune.accept();
O dat conexiunea efectuat, putei folosi fluxuri de intrare i de ieire pentru a citi sau scrie
de la, ctre un client.
Pentru a prezenta comunicaia n reea prin Java, este prezentat aici un program Banal,
care folosete clasele Socket pentru implementarea unei aplicaii client server de reea.
Exemplul funcioneaz n felul urmtor: programul server ateapt conectarea unui client.
La conectarea unui client, serverul pune o ntrebare i ateapt un rspuns. La cellalt capt clientul
recepioneaz ntrebarea, o afieaz ctre utilizator i ateapt un rspuns de la acesta. Utilizatorul
introduce rspunsul, care este trimis napoi ctre server. Serverul verific dac rspunsul este corect

i anun rezultatul. Dup aceasta, serverul ntreab clientul dac dorete s i se pun alt ntrebare;
dac rspunsul este afirmativ, procesul se repet.
Aplicaia are nevoie de 2 pri: pe partea de server este necesar un program care s
monitorizeze un anumit port al calculatorului gazd, acolo unde urmeaz s se conecteze clientul.
La detectarea unui client, serverul alege o ntrebare i o trimite clientului pe portul respectiv. Dup
aceasta, serverul intr ntr-o stare de ateptare pn ce recepioneaz rspunsul de la client. Dup
primirea rspunsului, serverul verific corectitudinea acestuia i anun clientul rezultatul obinut.
Apoi clientul este ntrebat dac dorete o nou ntrebare, .a.m.d. Pe scurt serverul realizeaz
urmtoarele aciuni:
1. Ateapt conectarea unui client
2. Accept conectarea unui client
3. Transmite clientului o ntrebare aleatoare
4. Ateapt rspunsul de la client
5. Verific rspunsul i anun clientul rezultatul
6. ntreab clientul dac dorete o alt ntrebare
7. Ateapt un rspuns (y/n) de la client
8. Dac este cazul revine la pasul 3
Pe partea de client este o aplicaie care ruleaz n linia de comand. Clientul se conecteaz la server
i ateapt o ntrebare. Atunci cnd primete o ntrebare de la server, clientul o afieaz
utilizatorului i ateapt introducerea unui rspuns. Acest rspuns este trimis napoi ctre server,
dup care se ateapt rspunsul acestuia. Clientul afieaz rspunsul de la server i permite
utilizatorului s opteze pentru continuarea programului (dac mai dorete o nou ntrebare). Clientul
trimite apoi rspunsul utilizatorului i i termin execuia, n cazul acesta nu dorete continuarea
conversaiei. Principalele activiti ale clientului sunt urmtoarele:
1. Se conecteaz la server
2. Ateapt trimiterea unei ntrebri
3. Afieaz ntrebarea i primete rspunsul introdus de utilizator
4. Trimite rspunsul ctre server
5. Ateapt un rspuns de la server
6. Afieaz rspunsul i l ntreab pe utilizator dac doret o nou ntrebare
7. Trimite serverului rspunsul utilizatorului
8. Dac este cazul, revine la pasul 2.
Textul surs al aplicaiei este prezentat n continuare.
import java.io.*;
import java.net.*;
import java.util.Random;
public class ServerBanal extends Thread {
private static final int NRPORT = 1234;
private static final int ASTEAPTACLIENT = 0;
private static final int ASTEAPTARASPUNS = 1;
private static final int ASTEAPTACONFIRMARE = 2;
private String[] intrebari;
private String[] raspunsuri;
private ServerSocket serverSocket;
private int nrIntrebari;
private int crt = 0;
private int stare = ASTEAPTACLIENT;
private Random aleator = new Random();

public ServerBanal() {
super("ServerBanal");
try {
serverSocket = new ServerSocket(NRPORT);
System.out.println("ServerBanal este in executie ...");
}
catch (IOException e) {
System.err.println("Exception: nu se poate crea soclul");
System.exit(1);
}
}
public static void main(String[] arguments) {
ServerBanal server = new ServerBanal();
server.start();
}
public void run() {
Socket clientSocket = null;
// Initializare vectori cu intrebari si raspunsuri
if (!initIntRasp()) {
System.err.println("Error: nu se pot initializa intrebarile
si raspunsurile");
return;
}
// Asteapta clientul si pune intrebari banale
while (true) {
// Asteapta un client
if (serverSocket == null)
return;
try {
clientSocket = serverSocket.accept();
}
catch (IOException e) {
System.err.println("Exceptie: nu se poate face
conectarea la soclul client");
System.exit(1);
}
// Se poarta dialogul intrebare/raspuns
try {
InputStreamReader isr = new
InputStreamReader(clientSocket.getInputStream());
BufferedReader is = new BufferedReader(isr);
PrintWriter os = new PrintWriter(new
BufferedOutputStream(clientSocket.getOutputStream()), false);
String linieIesire;
//Transmite cererea serverului

linieIesire = citireIntrari(null);
os.println(linieIesire);
os.flush();
// Citeste si afiseaza intrarile utilizator
while (true) {
String linieIntrare = is.readLine();
if (linieIntrare.length() > 0) {
linieIesire = citireIntrari(linieIntrare);
os.println(linieIesire);
os.flush();
if (linieIesire.equals("La revedere!."))
break;
}
}
// Inchidere fluxuri
os.close();
is.close();
clientSocket.close();
}
catch (Exception e) {
System.err.println("Exception: " + e);
e.printStackTrace();
}
}
}
private boolean initIntRasp() {
try {
File fisierIntrare = new File("intrebari.txt");
FileInputStream inStream = new FileInputStream(fisierIntrare);
byte[] data = new byte[(int)fisierIntrare.length()];
// Se citesc intrebarile si raspunsurile
if (inStream.read(data) <= 0) {
System.err.println("Error: nu se pot citi intrebarile si rasp");
return false;
}
// Numarare intrebari si raspunsuri
for (int i = 0; i < data.length; i++)
if (data[i] == (byte)'\n') nrIntrebari++;
nrIntrebari /= 2;
intrebari = new String[nrIntrebari];
raspunsuri = new String[nrIntrebari];
// Se introduc intrebarile si raspunsurile in tablouri separate
int start = 0, nr = 0;
boolean esteIntr = true;
for (int i = 0; i < data.length; i++)
if (data[i] == (byte)'\n') {

if (esteIntr) {
intrebari[nr] = new String(data, start, i - start - 1);
esteIntr = false;
}
else {
raspunsuri[nr] = new String(data, start, i - start - 1);
esteIntr = true;
nr++;
}
start = i + 1;
}
}
catch (FileNotFoundException e) {
System.err.println("Exceptie: nu se gaseste fisierul cu
intrebari si raspunsuri");
return false;
}
catch (IOException e) {
System.err.println("Exceptie: eroare la citire intrebari");
return false;
}
return true;
}
String citireIntrari(String inStr) {
String outStr = null;
switch (stare) {
case ASTEAPTACLIENT:
// Pune o intrebare
outStr = intrebari[crt];
stare = ASTEAPTARASPUNS;
break;
case ASTEAPTARASPUNS:
// Verifica raspunsul
if (inStr.equalsIgnoreCase(raspunsuri[crt]))
outStr = "Raspuns corect! Doriti o noua intrebare? (y/n)";
else
outStr = "Raspuns gresit! Raspunsul corect este " +
raspunsuri[crt] + ". Doriti alta intrebare? (y/n)";
stare = ASTEAPTACONFIRMARE;
break;
case ASTEAPTACONFIRMARE:
// Se asteapta confirmarea continuarii dialogului
if (inStr.equalsIgnoreCase("Y")) {
crt = Math.abs(aleator.nextInt()) % intrebari.length;
outStr = intrebari[crt];
stare = ASTEAPTARASPUNS;

}
else {
outStr = "La revedere!.";
stare = ASTEAPTACLIENT;
}
break;
}
return outStr;
}
}

import java.io.*;
import java.net.*;
public class Banal {
private static final int NRPORT = 1234;
public static void main(String[] arguments) {
Socket socket = null;
InputStreamReader isr = null;
BufferedReader in = null;
PrintWriter out = null;
String adresa;
// Cauta adresa in argumentele liniei de comanda
if (arguments.length != 1) {
System.out.println("Mod de utilizare: java Banal <adresa>");
return; }
else
adresa = arguments[0];
// Initializare soclu si fluxuri
try {
socket = new Socket(adresa, NRPORT);
isr = new InputStreamReader(socket.getInputStream());
in = new BufferedReader(isr);
out = new PrintWriter(socket.getOutputStream(),true);
}
catch (IOException e) {
System.err.println("Err: nu se poate crea soclul fluxului"
+ e.getMessage());
System.exit(1);
}
// Citeste datele de intrare si raspunsurile serverului si le prelucreaza
try {
StringBuffer str = new StringBuffer(128);
String inStr;
int c;
while ((inStr = in.readLine()) != null) {
System.out.println("Server: " + inStr);
if (inStr.equals("La revedere")) break;

while ((c = System.in.read()) != '\n') str.append((char)c);


System.out.println("Client: " + str);
out.println(str.toString());
out.flush();
str.setLength(0);
}
// Inchide fluxuri
out.close();
in.close();
socket.close();
}
catch (IOException e) {
System.err.println("I/O error: "+ e.toString());
}
}}

Artificii cu applet-uri
Metoda showStatus()
Metoda showStatus() a clasei Applet v permite s afiai un ir n bara de stare a browserului care
ruleaz applet-ul. Putei folosi aceast metod pentru afiarea mesajelor de eroare, a legturilor, pentru
indicaii sau pentru alte mesaje de stare.

Aceast metod poate fi apelat printr-o instruciune de genul:


getAppletContext().showStatus(Pentru a ncepe, executati clic pe
applet);
Metoda getAppletContext() permite applet-ului dumneavoastr s acceseze caracteristicile
browserului care l-a ncrcat. Metoda showStatus() folosete acest mecanism pentru a afia mesaje
de stare.

Informatii despre applet


Biblioteca AWT (Abstract Windowing Toolkit) ofer un mecanism de declarare n cadrul
applet-ului a unor informaii legate de autor, de drepturile de copiere sau alte informaii importante.
Un browser Web poate oferi un mecanism de afiare a acestor informaii, dac acestea au fost
definite de programatorul applet-ului.
Pentru a oferi informaii legate de applet-ul dumneavoastr trebuie s suprascriei metoda
getAppletInfo(), n modul urmtor:
public String getAppletInfo() {
return Copyright 2002 Popescu Ion
}

Crearea de legturi n cadrul applet-urilor


Deoarece applet-urile ruleaz n cadrul browserelor Web, ar fi bine ca acestea s poat
ncrca noi pagini Web. Java ofer un mecanism prin care se poate indica browserului s ncarce o
nou pagin. De exemplu, putei folosi acest mecanism pentru a crea imagini animate care s
ncarce o nou pagin la execuia unui clic pe suprafaa lor.
Vei crea o instan a clasei URL pentru legtura ctre pagina dorit.
Pentru a crea un nou obiect URL putei folosi unul dintre cei patru constructori:

URL (String) creeaz un obiect URL cu o adres Web complet, cum ar fi


http://www.prefect.com/java21 sau ftp://ftp.netscape.com.

URL (URL, String) creeaz un obiect URL avnd o adres de baz provenit din
obiectul URL specificat i o cale relativ provenit din irul transmis ca argument secund. Putei
folosi getDocumentBase() pentru adresa URL a paginii care conine applet-ul sau getCodebase()
pentru adresa URL a clasei applet-ului. Calea relativ va fi concatenat cu adresa de baz.

URL (String, String, int, String) creeaz un obiect URL pornind de la protocol
(cum ar fi http sau ftp), numele mainii (www.prefect.com, ftp.netcom.com etc.), numrul de port
(80 pentru http)i un nume de fiier sau de director.

URL (String, String, String) este identic cu constructorul anterior, minus


argumentul ntreg cu numrul portului.
Atunci cnd folosii constructorul URL (String), trebuie s tratai excepiile
MalformedURLException. Pentru aceasta putei folosi un bloc try. . . catch, ca n exemplul
urmtor:
try {
unURL = new URL ("http://www.mcp.com" );

} catch (MalformedURLException e) {
System.out.println("Adresa URL incorecta: " + unURL) ;
}
O dat obinut obiectul URL, tot ceea ce mai trebuie s facei este s l transmitei
browserului; drept urmare, acesta va ncarca adresa respectiv:
getAppletContext().showDocument(unURL);
Browserul ce conine un applet Java cu codul prezentat mai sus va ncrca i va afia
documentul de la adresa URL respectiv.
Aplicaia urmtoare prezint dou clase: ButonLink i o clas ajuttoare Marcaj. Appletul
ButonLink afieaz trei butoane care indic trei locaii Web diferite; dac se execut clic pe aceste
butoane, va fi ncrcat documentul de la locaia respectiv.
Textul surs al aplicaiei este prezentat n continuare:
import java.awt.*;
import java.net.*;
public class ButonLink extends java.applet.Applet {
Marcaj ListaMarcaje[] = new Marcaj[3];
public void init() {
ListaMarcaje[0] = new Marcaj("Catalog auto",
"http://www.masini.ro");
ListaMarcaje[1] = new Marcaj("Macmillan Computer Publishing",
"http://www.mcp.com");
ListaMarcaje[2]= new Marcaj("JavaSoft",
"http://java.sun.com");
GridLayout gl = new GridLayout(ListaMarcaje.length, 1, 10, 10);
setLayout(gl);
for (int i = 0; i < ListaMarcaje.length; i++) {
add(new Button(ListaMarcaje[i].name));
}
}
public boolean action(Event evt, Object arg) {
if (evt.target instanceof Button) {
saltLa( (String)arg );
return true;
}
else return false;
}
void saltLa(String name) {
URL theURL = null;
for (int i = 0; i < ListaMarcaje.length; i++) {
if (name.equals(ListaMarcaje[i].name))
theURL = ListaMarcaje[i].url;
}
if (theURL != null)
getAppletContext().showDocument(theURL);
}

}
class Marcaj {
String name;
URL url;
Marcaj(String name, String theURL) {
this.name = name;
try {
this.url = new URL(theURL);
} catch (MalformedURLException e) {
System.out.println("URL inexistent: " + theURL);
}
}
}

Comunicarea ntre applet-uri


Uneori dorii s folosii o pagin HTML care s conin mai multe applet-uri diferite. Pentru
aceasta, tot ceea ce trebuie s facei este s folosii de mai multe ori eticheta <APPLET>. Browserul
va crea diferite instane pentru fiecare applet care apare n pagin.
Dar dac dorii s comunicai ntre aceste applet-uri? Dac dorii ca o modificare fcut ntr-un
applet s le afecteze cumva i pe celelalte? Cea mai bun modalitate de accesare a diferitelor applet-uri din
pagin este de a folosi contextele.

Un context reprezint un mijloc prin care se poate descrie mediul din care face parte ceva.
n acest caz, contextul applet-ului este definit n clasa AppletContext i este folosit pentru
comunicaia ntre applet-uri.
Pentru a obine o instan a acestei clase pentru applet-ul dumneavoastr, vei folosi metoda
getAppletContext(), i nu un anumit constructor.
De exemplu, apelarea metodei trimiteMesaj() pentru toate applet-urile dintr-o pagin,
inclusiv cel curent, folosete metoda getApplets() i un ciclu for de genul:
for (Enumeration e = getAppletContext().getApplets();
e.hasMoreElements();) {
Applet curent = (SubclasaMeaApplet) (e.nextElement());
curent.trimiteMesaj ();
}
Metoda getApplets() returneaz un obiect de tip Enumeration care conine o list a appleturilor din pagin. Parcurgerea acestei liste v permite s accesai pe rnd fiecare element. Reinei
c fiecare element al obiectului Enumeration este o instan a clasei Object; pentru ca applet-ul s se
comporte n modul dorit (i s accepte mesaje de la alte applet-uri) trebuie s l convertii prin cast
la o instan a subclasei applet-ului dumneavoastr (n acest caz, clasa SubclasaMeaApplet).
Apelarea unei metode ntr-un anumit applet este ceva mai complicat. Pentru aceasta,
trebuie s asociai fiecrui applet un nume i s facei referirea prin numele respectiv.
Pentru a asocia unui applet un nume se folosete atributul NAME al etichetei <APPLET>:
<P>Acest applet trimite informatii:
<APPLET CODE=AppletulMeu.class" WIDTH=100 HEIGHT=150 NAME=Expeditor>
</APPLET>
<P>Acest applet primeste informatii de la expeditor:
<APPLET CODE="AppletulMeu.class" WIDTH=100 HEIGHT=150 NAME=Destinatar>
</APPLET>

Pentru a obine o referin la un alt applet din aceeai pagin se folosete metoda
getApplet() pentru contextul applet-ului cu acel nume. Aceasta va avea ca rezultat obinerea unei
referine la applet-ul cu numele respectiv. Dup aceasta, v putei referi la acest applet ca la oricare
alt obiect: apelai metode, modificai variabilele de instan i aa mai departe. Iat codul care
realizeaz acest lucru:
// accesati applet-ul destinatar
Applet destinatar = (SubclasaMeaApplet)getAppletContext().
getApplet("Destinatar);
// comandati-i sa se actualizeze
destinatar.actualizare(text, valoare);
n acest exemplu s-a folosit metoda getApplet() pentru a se obine o referin ctre applet-ul
cu numele "Destinatar". Observai c obiectul returnat de getApplet() este o instan a clasei
generice Applet; vei dori, probabil, s l convertii prin cast ctre o instan a subclasei
dumneavoastr. O dat obinut referina ctre applet, putei apela apoi metodele sale ca i cnd ar fi
orice alt obiect din mediul dumneavoastr de execuie. Aici, de exemplu, dac ambele applet-uri
conin o metod denumit actualizare(), putei comanda applet-ului destinatar s se actualizeze
singur folosind informaiile din applet-ul curent.
Denumirea applet-urilor i referirea lor prin metodele prezentate n aceast seciune permit
comunicarea i sincronizarea applet-urilor, obinndu-se astfel un comportament uniform pentru
toate applet-urile din pagin.

Decuparea, copierea i lipirea


ncepnd cu versiunea 1.1 a Java s-a introdus suport pentru operaiunile de decupare,
copiere i lipire (cut, copy, paste) ntre componentele folosite ntr-o interfa utilizator AWT i alte
programe neimplementate n Java, care ruleaz pe aceeai platform.
Anterior, AWT permitea doar copierea i lipirea datelor ntre componentele care posedau
aceast facilitare pe platformele native (de exemplu, textul putea fi copiat i lipit numai ntre
cmpuri sau zone de text). Aceast facilitate a fost extins astfel nct i alte date sau obiecte s
poat fi transferate de la o component la alta.
Pentru a transfera date de la o component la alta trebuie s definii un obiect transferabil,
apoi s modificai sau s creai componente care s aib capacitatea de a transfera obiectul
respectiv.
Clasele i interfeele folosite n acest scop sunt coninute n pachetul java.awt.datatransfer.

Crearea de obiecte transferabile


Un obiect transferabil este un obiect care poate fi mutat dintr-o component n alta folosind
mecanismul de transfer oferit de AWT i care ncapsuleaz un set de date ce urmeaz a fi
transferate (de exemplu, text formatat). Mai concis, un obiect transferabil este un obiect care
implementeaz interfaa Transferable.
Atunci cnd creai un obiect transferabil, trebuie s decidei mai nti ce aspecte va suporta
obiectul respectiv. Un aspect (flavor) este, n acest caz, formatul de date care urmeaz a fi
transferat. De exemplu, dac vrei s copiai text formatat HTML dintr-un browser i s l lipii ntrun alt loc, datele respective pot fi reprezentate n diferite formate: ca text formatat, ca text simplu
sau drept cod HTML. Atributele datelor determin modul n care obiectul copiat i cel care urmeaz
a fi lipit negociaz transferul de date propriu-zis. Dac sursa i destinaia transferului de date nu
suport acelai set de aspecte, transferul de date nu poate avea loc.

Aspectele datelor sunt descrise folosind tipurile MIME, adic mecanismul de negociere a
coninutului care este folosit de programele de pot electronic sau de World Wide Web. n afar
de numele logic al aspectului, acesta mai posed i un nume descriptiv, care poate fi tradus n
diferite limbaje internaionale. Aspectele de date pot avea, de asemenea. o clas reprezentativ - de
exemplu, dac datele sunt un ir Unicode, acesta este reprezentat de clasa String. Dac aspectul de
date nu este reprezentat de nici o clas, va fi folosit implicit clasa InputStream.
Pentru a crea un nou aspect de date trebuie creat o instan a clasei DataFlavor folosind
unul din urmtorii constructori:

DataFlavor(Class, String) creeaz un aspect de date care reprezint o clas Java.


Argumentul String reprezint numele descriptiv al aspectului. Obiectul DataFlavor rezultat va avea
tipul MIME application/x-javaserializedobject.

DataFlavor (String, String) creeaz un aspect de date care reprezint un tip MIME,
unde primul argument este tipul MIME, iar al doilea reprezint numele descriptiv. Clasa care
reprezint acest aspect de date va fi InputStream.
Dup ce ai obinut acest obiect cu aspectul de date, putei interoga valorile sale sau putei
compara tipurile sale MIME cu cele ale altor obiecte aspect de date pentru a negocia modul cum vor
fi transferate datele.
Aspectele de date sunt folosite de obiectele transferabile, care sunt definite folosind interfaa
Transferable. Un obiect transferabil va conine datele ce urmeaz a fi transferate, precum i
instane pentru fiecare dintre aspectele de date care reprezint obiectul respectiv. Pentru ca obiectul
dumneavoastr transferabil s poat fi ntr-adevr negociat i transferat, trebuie s implementai i
metodele getTransferDataFlavors(), isDataFlavorSupported() i getTransferData(). (Pentru
detalii, consultai documentaia interfeei Transferable.)
Clasa StringSelection implementeaz un obiect transferabil simplu, pentru transferul
irurilor de text, folosind obiecte DataFlavor i interfaa Transferable.
Reinei c obiectele transferabile sunt folosite pentru ncapsularea datelor i pentru
descrierea formatului (aspectului) acestora; ele nu au nici un rol n formatarea datelor, la nici una
dintre prile implicate n transfer. Aceasta este responsabilitatea programului dumneavoastr atunci
cnd folosii zona Clipboard pentru a obine date de la o surs.

Folosirea zonei Clipboard


Dup ce ai definit obiectul transferabil, putei folosi zona Clipboard pentru a transfera
obiectul ntre componente sau ntre Java i platforma nativ. Java 2 ofer un mecanism foarte
simplu pentru lucrul cu zona Clipboard, prin care putei copia i accesa informaii n/din aceast
zon. Putei folosi fie zona Clipboard standard a sistemului pentru a face schimb de date cu celelalte
programe care ruleaz pe platforma nativ, fie propriile instane de zone Clipboard sau mai multe
seturi specializate de zone Clipboard.
Zonele Clipboard sunt reprezentate n Java de clasa Clipboard, care face parte tot din
pachetul java.awt.datatransfer. Putei accesa zona Clipboard a sistemului folosind metodele
getToolkit() i getSystemClipboard(); getToolkit () v permite s accesai diferite funcii ale
sistemului:
Clipboard clip = getToolkit().getSystemClipboard();
Important de remarcat pentru zona Clipboard a sistemului: applet-urile nu au voie s
acceseze aceast zon din motive de securitate (aici se pot afla informaii confideniale). Astfel,
applet-urile nu pot face schimburi de informaii n nici un sens cu platforma nativ prin intermediul
zonei Clipboard. Totui, se pot folosi zone Clipboard interne pentru copierea i lipirea datelor ntre
componentele unui applet.
Orice component care dorete s foloseasc zona Clipboard - fie s pun date acolo
folosind copierea (copy) sau decuparea (cut), fie s preia date folosind lipirea (paste) - trebuie s

implementeze interfaa ClipboardOwner. Aceast interfa are o singur metod:


lostOwnership(), care este apelat atunci cnd o alt component preia controlul asupra zonei
Clipboard.
Pentru a implementa operaia de copiere sau decupare (copy sau cut) trebuie parcurse
urmtoarele etape:
1. Creai o instan a obiectului Transferable, care s pstreze datele ce urmeaz a fi
copiate.
2. Creai o instan a obiectului care implementeaz interfaa ClipboardOwner (care poate
fi clasa curent sau chiar obiectul Transferable).
3. Dac folosii zona Clipboard a sistemului, folosii metoda getSystemClipboard() pentru
a obine o referin la aceasta.
4. Apelai metoda setContents() a zonei Clipboard, avnd ca argumente obiectul
transferabil i obiectul care implementeaz interfaa ClipboardOwner. Folosind aceast metod,
obiectul dumneavoastr i-a adjudecat" posesia asupra zonei Clipboard.
5. Metoda lostOwnership() este apelat atunci cnd un alt obiect preia controlul asupra
zonei Clipboard. Aceast metod trebuie implementat dac dorii s realizai o anumit aciune la
apariia evenimentului (sau putei crea o metod vid atund cnd nu v intereseaz dac cineva a
nlocuit coninutul zonei Clipboard).
Pentru implementarea unei operaii de lipire (paste) trebuie parcurse urmtoarele etape:
1. Folosii metoda getContents() a clasei Clipboard, care returneaz un obiect transferabil.
2. Folosii metoda getTransferDataFlavors() a obiectului transferabil pentru a afla ce
aspecte de date suporta obiectul transferabil. Stabilii ce aspect vei folosi.
3. Accesai datele conform aspectului dorit, folosind metoda getTransferData() a obiectului
transferabil.
Un astfel de exemplu este prezentat n continuare.
import java.awt.*;
import java.awt.event.*;
import java.awt.datatransfer.*;
public class CopyPaste extends Frame
implements ActionListener, ClipboardOwner {
Button copy, paste;
TextField tfCopy, tfPaste;
Clipboard clip;
public static void main(String[] arguments) {
CopyPaste test = new CopyPaste();
WindowListener l = new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
};
test.addWindowListener(l);
test.setSize(200, 150);
test.show();
}
CopyPaste() {

super("Copy and Paste");


clip = getToolkit().getSystemClipboard();
FlowLayout flo = new FlowLayout();
setLayout(flo);
copy = new Button("Copy From");
tfCopy = new TextField(25);
paste = new Button("Paste To");
tfPaste = new TextField(25);
copy.addActionListener(this);
paste.addActionListener(this);
paste.setEnabled(false);
add(copy);
add(tfCopy);
add(paste);
add(tfPaste);
}
void doCopy() {
if (tfCopy.getText() != null) {
String txt = tfCopy.getText();
StringSelection trans = new StringSelection(txt);
clip.setContents(trans, this);
paste.setEnabled(true);
}
}
void doPaste() {
Transferable toPaste = clip.getContents(this);
if (toPaste != null) {
try {
String txt = (String)toPaste.getTransferData(
DataFlavor.stringFlavor);
tfPaste.setText(txt);
paste.setEnabled(false);
} catch (Exception e) {
System.out.println("Error -- " + e.toString());
}
}
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == copy)
doCopy();
else if (e.getSource() == paste)
doPaste();
}
public void lostOwnership(Clipboard clip,

Transferable contents) {
}
}

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