Laborator JAVA IESC UNITBV

100
Laborator 1: Introducere în Java Întocmit de: Adina Neculai Îndrumător: Asist. Drd. Gabriel Danciu 2 octombrie 2011

description

Curs faculate, programare JAVA

Transcript of Laborator JAVA IESC UNITBV

Page 1: Laborator JAVA IESC UNITBV

Laborator 1:

Introducere în Java

Întocmit de: Adina Neculai

Îndrumător: Asist. Drd. Gabriel Danciu

2 octombrie 2011

Page 2: Laborator JAVA IESC UNITBV

I. NOŢIUNI TEORETICE

A. Ce este Java?

Java nu este doar un limbaj de programare ci este şi mediu de programare ce oferă utilizato-

rului atât cadrul cât şi uneltele necesare pentru a dezvolta aplicaţii Java. Limbajul Java poate fi

caracterizat ca un limbaj:

1. simplu: tehnologia Java conţine aşa numitul Garbage Colector care eliberează programatorul

de grija dezalocării memoriei.

2. familiar: limbajul Java respectă o mare parte a gramaticii şi a sintaxei de programare

C/C++.

3. robust: un program Java este mai puţin supus erorilor datorită celor două nivele de verificare

ale acestuia. Un nivel de verificare este la compilare şi unul este la rulare.

4. orientat pe obiecte: spre deosebire de limbajul C++, Java este în întregime orientat pe

obiecte.

5. dinamic: multe decizii privind evoluţia programului se iau in momentul rulării, la runtime.

6. ce asigură un nivel ridicat de securitate: programele Java sunt verificate pas cu pas în timpul

rulării, astfel evitându-se accesul la zone nepermise.

7. independent de platformă: un program Java poate fi rulat pe orice platformă pe care a fost

instalată o maşină virtuală Java (Java Virtual Machine).

8. adaptat pentru multithreading: tehnologia Java permite ca un program să execute mai multe

sarcini aparent în acelaşi timp, utilizând mai multe fire de execuţie (thread-uri).

9. adaptat pentru aplicaţii distribuite

B. Pachetul JDK

Mediul JDK (Java Developers Kit) conţine o serie de biblioteci de clase Java necesare scrierii

unui program şi un set de utilitare necesare compilării, execuţiei şi documentării unei aplicaţii

2

Page 3: Laborator JAVA IESC UNITBV

Java. În Java o bibliotecă este cunoscută sub numele de package. Package-urile Java incluse în

JDK formează API (Application Programming Interface). Mai multe informaţii se găsesc aici.

C. Dezvoltarea şi execuţia unei aplicaţii Java

Paşii ce trebuie urmaţi pentru a putea crea un program Java sunt următorii:

1. scrierea codului;

2. compilarea;

3. interpretarea şi lansarea în execuţie.

Aceste operaţii sunt prezentate în figura următoare:

Figura 1: Etapele dezvoltării şi execuţiei unei aplicaţii Java stand-alone.

D. Structura unui program Java

1 package main ;

2

3 public c l a s s MyProgram {

4 public s t a t i c void main ( St r ing args [ ] ) {

5 // i n t r u c t i u n i

6 }

7 }

Listing 1: Descriptive Caption Text

• linia 1: main reprezintă pachetul din care face parte clasa MyProgram. Fizic, un pachet este

un director al proiectului.

3

Page 4: Laborator JAVA IESC UNITBV

• linia 3: clasa MyProgram are modificatorul de acces public;

• linia 4: metoda main are modificatorul de acces public, are ca parametru şirul de caractere

args şi nu returnează nimic. De asemenea, cuvântul rezervat static determină ca metoda

main să depindă de clasa MyProgram şi nu de o instanţă a acesteia.

II. PREZENTAREA LUCRĂRII DE LABORATOR

A. Editarea unei aplicaţii Java

Codul sursă Java constă din unul sau mai multe fişiere text ce au extensia .java. Pentru scrierea

codului se poate folosi orice editor de text. Ca exemplu se foloseşte codul următor:1 public c l a s s HelloWorld {

2 public s t a t i c void main ( St r ing args [ ] ) {

3 System . out . p r i n t l n ( " He l lo ␣World ! ! ! " ) ;

4 }

5 }

Listing 2: Descriptive Caption Text

De reţinut că numele clasei trebuie să coincidă cu numele fişierului a cărui extensie este .java.

B. Compilarea unei aplicaţii Java

Pasul următor este compilarea programului. Acest lucru se realizează dintr-o fereastră de sistem

cu ajutorul comenzii: javac HelloWorld.java

Dacă operaţia de compilare s-a desfăşurat cu succes, în acelaşi director ar trebui să apară

un fişier cu acelaşi nume, dar cu extensia .class. În cazul în care fişierul amintit anterior nu s-a

generat, înseamnă că s-au întâmpinat probleme la compilare.

O posibilă problemă ar fi ca sistemul de operare să nu poată lansa în execuţie utilitarul

javac. Mesajul de eroare este, în acest caz, ” ’javac’ is not recognized as an internal or external

command, operable program or batch file”. Pentru a rezolva această eroare trebuie setată variabila

de sistem path pentru a cuprinde şi directorul în care se află javac (Exemplu: C:\Program Files

\Java \jdk1.6.0_23 \bin).

O altă cauză ar putea fi lipsa pachetului JDK din sistem. Soluţia ar fi instalarea acestuia.

Pachetul poate fi descarcat de la această adresă.

4

Page 5: Laborator JAVA IESC UNITBV

C. Lansarea în execuţie a unei aplicaţii Java

După compilare s-a obţinut HelloWorld.class. Pentru a-l lansa în execuţie se foloseşte comanda:

java HelloWorld. În urma acestei comenzi va apărea în consolă mesajul ”Hello World!!!”.

D. Preluarea parametrilor din linie de comandă

Următorul exemplu este o aplicaţie care spune ”Hello” utilizatorilor ce îşi dau numele ca para-

metru de apel al acesteia. Aplicaţia va prelua toţi aceşti parametri din argumentul metodei main

numit args. Acesta este un tablou de şiruri de caractere ce va conţine toţi parametrii din linie de

comandă ce urmează după numele programului.1 public c l a s s Hel loUsers {

2 public s t a t i c void main ( St r ing args [ ] ) {

3 i f ( args . l ength == 0){//daca nu sunt argumente

4 System . out . p r i n t l n ( " I n t r oduc e t i ␣ c e l ␣ putin ␣un␣nume" ) ;

5 }

6 for ( int i =0; i<args . l ength ; i++){

7 System . out . p r i n t l n ( " Hel lo , ␣ "+args [ i ]+ " ! " ) ; // se a f i s e a z a f i e c a r e element din t ab l ou l args

8 }

9 }

10 }

Listing 3: Descriptive Caption Text

După ce programul a fost compilat şi a fost obţinut fişierul class, se lansează în execuţie astfel:java Hello Mihai Radu Ana. În consolă se afişează:Hello, Mihai!

Hello, Radu!

Hellor, Ana!

III. TEMĂ

Editaţi, compilaţi şi lansaţi în execuţie aplicaţiile:

1. HelloWorld din secţiunea IIA;

2. HelloUsers din secţiunea IID.

5

Page 6: Laborator JAVA IESC UNITBV

Laborator 2:

Instrucţiuni Java şi lucru cu şiruri de caractere

Întocmit de: Adina Neculai

Îndrumător: Asist. Drd. Gabriel Danciu

18 octombrie 2011

Page 7: Laborator JAVA IESC UNITBV

I. NOŢIUNI TEORETICE

A. Instrucţiuni condiţionale

1. Intrucţiunea if else

Forma generală:

if(expresie_condiţională)

secvenţă_if;

else

secvenţă_else;

Dacă expresie_condiţională este evaluată la true, atunci se execută secvenţă_if. În caz con-

trar, se execută secvenţă_else. Este necesar ca expresie_condiţională să fie evaluată la o valoare

booleană. În plus, prezenţa structurii else nu este obligatorie şi pot exista cazuri de folosire a

instrucţiunii if else în cascadă.

2. Intrucţiunea switch

Forma generală:

switch(expresie_condiţie) {

case val1:

secvenţa1;

<break>;

. . . ;

case valN:

secvenţaN;

<break>;

<default:>

secvenţa_default;

}

Pentru utilizarea acestei instrucţiuni este necesar ca atât tipul de date al lui expresie_condiţie

cât şi cel al valorilor val1, . . . , valN să fie din categoria tipurilor numerice: byte, char, short,

2

Page 8: Laborator JAVA IESC UNITBV

int. Astfel că, primul pas constă în evaluarea valorii expresiei expresie_condiţie. Apoi se compară

valoarea evaluată cu prima valoare a lui case, val1. Dacă această valoare este egală cu val1 atunci

se execută secvenţa1 până la întâlnirea lui break. Dacă instrucţiunea break nu este prezentă, atunci

se trece la execuţia celorlalte secvenţe de tipul secvenţaN, fără a mai testa celelalte valori din case.

În cazul în care valoarea din condiţie nu este egală cu nici o valoare din case atunci se execută

secvenţa_default ce urmează lui default:. Cazul default permite executarea secvenţei de după el

indiferent de valoarea expresiei de evaluat. Acesta poate lipsi.

B. Instrucţiuni de ciclare

1. Intrucţiunea for

Forma generală:

for(<secvenţă_iniţializare>;<expresie_condiţie>;<secvenţă_incrementare>)

<secvenţă_repetată>;

Intrucţiunea for face parte din instrucţiunile de ciclare cu test iniţial. De reţinut că

secvenţă_repetată se execută înaintea secvenţă_incrementare şi că variabilele definite în sec-

venţă_iniţializare sunt valabile doar în interiorul for-ului.

Tot ce este între <> poate lipsi, astfel încât putem avea for(;;) pentru a putea realiza un ciclu

infinit.

2. Intrucţiunea while

Forma generală:

while(expresie_condiţie)

secvenţă_repetată;

În execuţia instrucţiunii while, la început, se evaluează expresie_condiţie. Dacă aceasta are

valoarea true atunci se trece la execuţia secvenţă_repetată. Dacă valoarea este de la bun început

false, secvenţa din cadrul buclei nu va mai fi deloc executată. Se observă că şi această instrucţiune

face parte din cele de ciclare cu test iniţial.

3

Page 9: Laborator JAVA IESC UNITBV

3. Intrucţiunea do while

Forma generală:

do

secvenţă_repetată

while(expresie_condiţie);

În execuţia instrucţiunii do while, întâi se execută secvenţă_repetată şi abia apoi se evaluează

expresie_condiţie. Astfel, chiar dacă expresia de evaluat este falsă, secvenţă_repetată tot se execută

măcar o dată. De aceea, instrucţiunea do while face parte din cele de ciclare cu test final.

C. Instrucţiuni de salt

Intrucţiunea:

1. break este utilizată pentru întreruperea execuţiei instrucţiunilor de ciclare şi a celor switch;

2. continue poate fi folosită doar în interiorul instrucţiunilor de ciclare forţând trecerea la un

nou ciclu;

3. return este utilizată pentru ieşirea forţată dintr-o metodă.

D. Lucru cu şiruri de caractere

Cele mai cunoscute clase care lucrează cu şiruri de caractere sunt: String, StringBuffer.

1. Clasa String

Cea mai importantă caracteristică a clasei String este că obiectele o dată iniţializate nu se mai

pot modifica, fiecare dintre aceste obiecte indicând spre o zonă diferită de memorie.

O altă proprietate a obiectelor de tip String este că pot fi utilizate impreună cu operatorul ’+’,

pentru concatenarea şirurilor. Prin concatenare se instanţiază un nou obiect de tip String care va

referenţia un şir alcătuit din şirurile alipite cu ajutorul operatorului ’+’.

Această clasă oferă o serie de metode pentru lucru cu şiruri de caractere. Aceste metode au în

vedere compararea şirurilor, căutarea în şiruri, şamd. Se recomandă studierea API-ului.

4

Page 10: Laborator JAVA IESC UNITBV

2. Clasa StringBuffer

Un obiect StringBuffer reprezintă ca şi în cazul clasei String un şir de caractere. Diferenţa între

cele două este că primul obiect poate suferi modificări. Acest lucru este posibil datorită metodelor

insert() şi append() care permit inserarea, respectiv adăugarea unor şiruri de caractere. Pentru mai

multe informaţii se recomandă studierea API-ului.

II. PREZENTAREA LUCRĂRII DE LABORATOR

A. Instrucţiuni Java

Codul sursă de mai jos exemplifică modul de utilizare al instrucţiunilor din secţiunile IA, I B,

I C.1 import java . u t i l . Scanner ;

2

3 public c l a s s Tes t In t ru c t i un i {

4 public s t a t i c void main ( St r ing args [ ] ) {

5 Scanner s = new Scanner ( System . in ) ; //cu a j u t o ru l a c e s t e i i n s t r u c t i u n i se c i t e s t e text de l a

ta s t a tu ra

6 System . out . p r i n t l n ( " I n t r oduc e t i ␣un␣numar : ␣ " ) ;

7 int x = s . next Int ( ) ; // in x se va r e t i n e numarul t a s t a t

8 System . out . p r i n t l n ( " Rezu l ta tu l ␣ f u n c t i e i ␣ e s t e : ␣ " + t e s t ( x ) ) ; /∗ se ape leaza metoda t e s t cu parametru x

∗/

9 }

10

11 public s t a t i c int t e s t ( int x ) {

12 int suma = 0 ; // se i n i t i a l i z e a z a v a r i a b i l a suma cu 0

13 for ( int i = 0 ; i < 4 ; i++) {

14 System . out . p r i n t l n ( "Am␣ i n t r a t ␣ in ␣ n i v e l ␣1 " ) ;

15 int j = 0 ;

16 while ( j++ < x) {// i n t a i se e f e c tueaza eva luarea e x p r e s i e i j < x s i abia apoi se incrementeaza

v a r i a b i l a j

17 System . out . p r i n t l n ( "Am␣ i n t r a t ␣ in ␣ n i v e l ␣2 " ) ;

18 System . out . p r i n t l n ( " i=␣ " + i + " ; ␣ j=␣ " + j ) ;

19 switch ( i ) {

20 // in cazu l in care i =0, 1 sau 2 se sa r e l a urmatorul pas s i se ignora r e s t u l i n s t r u c t i u n i l o r

de dupa cont inue din c i c l u l curent ( whi le )

21 case 0 :

22 continue ;

23 case 1 :

24 continue ;

25 case 2 :

26 continue ;

27 case 3 : // in cazu l in care i=3 se a c tua l i z e a z a suma s i apoi se i e s e f o r t a t din switch

28 suma += i+j ;

29 break ;

30 }

31 }

32 System . out . p r i n t l n ( "Am␣ i e s i t ␣ din ␣ n i v e l ␣2 " ) ;

5

Page 11: Laborator JAVA IESC UNITBV

33 }

34 System . out . p r i n t l n ( "Am␣ i e s i t ␣ din ␣ n i v e l ␣1 " ) ;

35 return suma ; // se i e s e f o r t a t din metoda t e s t

36 }

37

38 }

B. Lucru cu şiruri de caractere

Exemplul următor evidenţează caracterul imuabil pe care-l au obiectele de tip String. Se citeşte

de la tastatură un şir de caractere şi se verifică dacă acesta coincide cu un alt şir de caractere.1 import java . u t i l . ∗ ;

2 public c l a s s CheckPassword {

3 public s t a t i c void main ( St r ing args [ ] ) {

4 Scanner s = new Scanner ( System . in ) ;

5 St r ing password = " java " ;

6 St r ing user Input ;

7 System . out . p r i n t l n ( " Care␣e␣ paro la ? " ) ;

8 user Input= s . next ( ) ;

9

10 System . out . p r i n t l n ( "Ai␣ t a s t a t : ␣ " ) ;

11 System . out . p r i n t l n ( user Input ) ;

12 System . out . p r i n t l n ( "Dar␣ paro la ␣ e s t e : ␣ " ) ;

13 System . out . p r i n t l n ( password ) ;

14

15 // i f ( password . equa l s ( user Input ) ) {

16 i f ( password == userInput ){

17 System . out . p r i n t l n ( "Ai␣ t r e cu t ␣mai␣ departe ! " ) ;

18 } e l s e{

19 System . out . p r i n t l n ( "NU␣ a i ␣ t r e cu t ␣mai␣ departe ! " ) ;

20 }

21 }

22 }

Deşi variabila userInput ar conţine aceleaşi caractere ca variabila password, folosind operatorul

’==’ se va afişa textul de pe ramura else a instrucţiunii if. Acest lucru se întâmplă din cauza

faptului că se compară adresele de memorie ale variabilelor şi nu conţinutul de la acele zone de

memorie.

Decomentaţi linia 15 şi comentaţi linia 16. Observaţi ce se intâmplă dacă variabilele conţin

acelaşi şir de caractere.

Următorul exemplu citeşte de la tastatură un şir de caractere şi înlocuieşte fiecare vocală

întâlnită cu următorul caracter din alfabet. Acesta foloseşte clasa StringBuffer.

6

Page 12: Laborator JAVA IESC UNITBV

1 import java . u t i l . Scanner ;

2 public c l a s s ReplaceVowel {

3 public s t a t i c void main ( St r ing args [ ] ) {

4 Scanner s = new Scanner ( System . in ) ;

5 System . out . p r i n t l n ( " I n t r oduc e t i ␣ cuvantul : ␣ " ) ;

6 St r ing word = s . nextLine ( ) ;

7 System . out . p r i n t l n ( " Cuvantul␣ r e z u l t a t ␣ e s t e : ␣ "+replaceVowel (word . toLowerCase ( ) ) ) ;

8 }

9

10 public s t a t i c boolean checkVowel ( char c ) {

11 c = Character . toLowerCase ( c ) ;

12 return ( " ae iou " . indexOf ( c ) >= 0) ; /∗∗ se re turneaza true daca metoda indexOf ap l i c a t a s i r u l u i de

13 ca r a c t e r e " ae iou " impreuna cu parametru c returneaza o va loa re po z i t i v a ∗/

14 }

15

16 public s t a t i c St r ing replaceVowel ( S t r ing word ){

17 S t r i ngBu f f e r sb = new St r i ngBu f f e r (word ) ; /∗∗ v a r i a b i l a sb e s t e i n t i a l i z a t a cu va loarea

18 v a r i a b i l e i word∗/

19 for ( int i =0; i<sb . l ength ( ) ; i++){/∗∗ sb se parcurge ca r a c t e r cu ca r a c t e r ∗/

20 i f ( checkVowel ( sb . charAt ( i ) ) ) {/∗∗ f i e c a r e c a r a c t e r a l l u i sb e s t e v e r i f i c a t daca e s t e voca la ∗/

21 sb . setCharAt ( i , ( char ) ( sb . charAt ( i )+1) ) ; /∗∗ se pune pe p o z i t i a i in sb urmatorul c a r a c t e r

22 din a l f a b e t ∗/

23 }

24 }

25 return sb . t oS t r ing ( ) ;

26 }

27 }

III. TEMĂ

1. Rulaţi programele din secţiunea II.

2. Citiţi un şir de caractere de la tastatură. Folosind intrucţiunea switch, realizaţi un meniu

pentru următoarele cerinţe:

(a) să se afişeze lungimea şirului de caractere;

(b) să se returneze ultima poziţie pe care se întâlneşte caracterul ’a’;

(c) să se numere de câte ori apare în şirul de caractere secvenţa ’abc’;

(d) să se verifce dacă şirul de caractere este palindrom.

(e) să se şteargă toate caracterele de pe poziţiile pare.

Implementaţi cerinţele de la punctele 2a pana la 2e.

7

Page 13: Laborator JAVA IESC UNITBV

Laborator 3:

Introducere în Programarea Orientată pe Obiecte

Întocmit de: Adina Neculai

Îndrumător: Asist. Drd. Gabriel Danciu

23 octombrie 2011

Page 14: Laborator JAVA IESC UNITBV

I. NOŢIUNI TEORETICE

A. Clase şi obiecte

Unul dintre conceptele care defineşte programarea orientată pe obiecte este obiectul. Obiectul

este caracterizat prin stare, modelată de atributele unei clase, şi prin comportament, modelat de

metodele unei clase.

Un alt concept este clasa. Clasa este o colecţie de obiecte care partajează aceeaşi lista de

atribute informaţionale (de stare) şi comportamentale. Aşadar, aceasta reprezintă atât structura

unui obiect, cât şi funcţionalitatea acestuia. Mai mult, în acest context se spune că obiectul este o

instanţă a unei clase.

Forma generală a unei clase:

[lista_Modificatori] class NumeClasa[extends NumeClasaDeBaza][implements lista_Interfata]

{

corp clasa

}

Definiţia unei clase trebuie să conţină obligatoriu cuvântul cheie class, numele clasei şi corpul

clasei prins între acolade. Toţi ceilalţi termeni pot lipsi. Vom discuta despre aceşti termeni la

momentul potrivit.

B. Supraîncărcarea metodelor

Forma generală a unei metode:

[lista_Modificatori] tip_de_returnat numeMetoda([lista_parametrii])

{

corp metoda

}

O metodă se defineşte prin semnătură şi prin corp. Semnătura constă în tipul returnat, numele

metodei şi lista de parametri, pe când corpul metodei este reprezentat de instrucţiuni.

În Java, în aceeaşi clasă, se pot defini metode cu acelaşi nume, dar cu semnături diferite.

Diferenţa poate consta în numărul de parametri, în tipul de date al acestora sau în ambele. Acest

2

Page 15: Laborator JAVA IESC UNITBV

proces se numeşte supraîncărcare. Este important de reţinut că Java nu ia în considerare tipul

valorii returnate pentru a face diferenţierea metodelor supraîncărcate.

Motivul pentru care se folosesc acest gen de metode este că se elimină nevoia de a defini metode

complet diferite care să facă în principiu acelaşi lucru. De asemenea, supraîncărcarea face posibilă

comportarea diferită a metodelor în funcţie de argumentele primite.

C. Constructori

Într-o clasă, pe lângă atribute şi metode, se pot defini şi constructori. Aceştia sunt un tip de

metodă specială cu următoarele caracteristici:

• numele lor trebuie să fie identic cu cel al clasei din care fac parte;

• nu au tip de returnat.

[lista_Modificatori] NumeClasa([lista_parametrii])

{

corp constructor

}

Constructorii sunt utilizaţi pentru instanţierea unui obiect care face parte dintr-o anumită clasă

şi sunt apelaţi în funcţie de variabilele pe care le primesc ca parametru. În cazul în care nu se

declară niciun constructor(doar în acest caz) compilatorul creează un constructor implicit, având

numele clasei, fără niciun parametru formal şi având corpul constructorului fără instrucţiuni.

Metodele constructor pot fi şi ele supraîncărcate, la fel ca metodele obişnuite, pentru a crea un

obiect care are proprietăţi specifice în funcţie de argumentele transmise prin operatorul new.

D. Moştenire

Unul dintre principiile programării orientate pe obiecte este moştenirea. Acest principiu se

bazează pe extinderea comportamentului unei clase existente prin definirea unei clase noi care

moşteneşte conţinutul primei clase la care se adaugă noi proprietăţi şi funcţionalităţi.

Clasa existentă, care va fi moştenită, se numeşte clasa de bază, clasă părinte sau superclasă.

3

Page 16: Laborator JAVA IESC UNITBV

Clasa care realizează extinderea se numeşte subclasă, clasă derivată, clasă descendentă sau clasă

copil. Cuvântul predefinit care se utilizează pentru moştenire este extends.

[lista_Modificatori] class NumeSubclasa [extends NumeClasaDeBaza]

{

corp subclasa

}

În ce priveşte tipul de moştenire, în Java este permisă doar cea simplă. Adică, o subclasă poate

extinde o singură superclasă. În aceeaşi ordine de idei, o superclasă poate fi moştenită de mai

multe subclase diferite. Moştenirea multiplă nu este permisă în Java, dar este simulată cu ajutorul

interfeţelor. Acest aspect îl vom trata ulterior.

Prin operaţia de derivare, constructorii clasei de bază nu se moştenesc, în schimb fiecare

constructor al clasei derivate apelează un constructor al clasei de bază. Acest apel se poate face

implicit(adăugat de compilator) sau explicit. Apelul explicit se face prin intermediul cuvântului

cheie super. În plus, constructorii se apelează în ordinea derivării, de la superclasă la sublcasă.

public class NumeSubclasa extends NumeClasaDeBaza {

NumeSubclasa(){

super();

//alte instructiuni constructor

}

}

II. PREZENTAREA LUCRĂRII DE LABORATOR

A. Supraîncărcarea metodelor şi constructorilor

Codul sursă următor exemplifică conceptul de clasă şi obiect, împreună cu ideea de supraîncăr-

care atât a constructorilor unei clase, cât şi a metodelor unei clase. Clasa Point are ca atribute

coordonatele in plan ale unui punct şi calculează distanţa între două puncte. Metoda care descrie

funcţionalitatea clasei Point (computeDistance()) este supraîncărcată. Acest lucru s-a realizat prin

schimbarea numărului de parametri ai acesteia şi tipul lor.(observaţi linia de cod 29)

4

Page 17: Laborator JAVA IESC UNITBV

1 public c l a s s Point {

2 public double x , y ;

3

4 public Point ( ) {// cons t ruc to r f a r a parametr i

5 // t h i s e s t e un cuvant che i e ce r ep r e z i n t a ob i e c t u l curent a l c l a s e i , i n t ru ca t nu se s t i e cum se

numeste ob i e c t u l

6 this . x = 0 ;

7 this . y = 0 ;

8 }

9

10 // cons t ruc to r cu 2 parametr i ; c on s t ru c t o ru l a f o s t supra inca r ca t

11 public Point (double x , double y ) {

12 this . x = x ;

13 this . y = y ;

14 }

15

16 // cons t ruc to r cu un parametru ; c on s t ru c t o ru l a f o s t supra inca r ca t

17 public Point (double x ) {

18 this . x = x ;

19 this . y = 0 ;

20 }

21

22 // metoda ca l cu l e a z a d i s t an ta i n t r e 2 puncte a f l a t e in plan

23 public s t a t i c double computeDistance ( Point p1 , Point p2 ){

24 // se f o l o s e s c metode a l e c l a s e i Math din pachetu l java . lang

25 return Math . sq r t (Math . pow(p1 . x − p2 . x , 2) + Math . pow(p1 . y − p2 . y , 2) ) ;

26 }

27

28 // metoda e s t e supra inca rca ta

29 public s t a t i c double computeDistance (double x1 , double y1 , double x2 , double y2 ){

30 return Math . sq r t (Math . pow( x1 − x2 , 2) + Math . pow( y1 − y2 , 2) ) ;

31 }

32

33 public s t a t i c double computeDistance ( Point p1 ){/∗∗ metoda e s t e supra inca rca ta ∗/

34 return Math . sq r t (Math . pow(p1 . x , 2) + Math . pow(p1 . y , 2) ) ;

35 }

36

37 public St r ing toS t r ing ( ) {

38 return " x=␣ "+x+" ; ␣y=␣ "+y ;

39 }

40 }

Următoarea clasă creează obiecte de tipul Point. Aceste obiecte sunt instanţiate în moduri

diferite. De asemenea, se apelează metoda statică computeDistance() cu parametri diferiţi.1 public c l a s s TestPoint {

2 public s t a t i c void main ( St r ing [ ] a rgs ) {

3 Point p1 = new Point ( ) ;

4 System . out . p r i n t l n ( " I n s t a t i e r e ␣ ob i e c t ␣ pr in ␣ cons t ruc to r ␣ f a r a ␣ parametr i : ␣P1 : ␣ "+p1 . t oS t r i ng ( ) ) ;

5 Point p2 = new Point (2 , 2) ;

6 System . out . p r i n t l n ( " I n s t a t i e r e ␣ ob i e c t ␣ pr in ␣ cons t ruc to r ␣cu␣2␣ parametr i : ␣P2 : ␣ "+p2 . t oS t r ing ( ) ) ;

7 Point p3 = new Point (3 ) ;

8 System . out . p r i n t l n ( " I n s t a t i e r e ␣ ob i e c t ␣ pr in ␣ cons t ruc to r ␣cu␣1␣parametru : ␣P3 : ␣ "+p3 . t oS t r ing ( ) ) ;

9

10 System . out . p r i n t l n ( " Calcu leaza ␣ d i s t an ta ␣ i n t r e ␣P2␣ s i ␣P3 : ␣ "+Point . computeDistance (p2 , p3 ) ) ;

11 System . out . p r i n t l n ( " Calcu leaza ␣ d i s t an ta ␣ i n t r e ␣P2␣ s i ␣P3 : ␣ "+Point . computeDistance ( p2 . x , p2 . y , p3 . x , p3

. y ) ) ;

5

Page 18: Laborator JAVA IESC UNITBV

12 System . out . p r i n t l n ( " Calcu leaza ␣ d i s t an ta ␣ i n t r e ␣P(0 ,0 ) ␣ s i ␣P2 : ␣ "+Point . computeDistance ( p2 ) ) ;

13 }

14 }

B. Moştenire

Pentru a exemplifica principiul moştenirii se dă clasa de bază Fruct.1 public c l a s s Fruct {

2 private St r ing t ipFruct ;

3

4 public Fruct ( St r ing t ipFruct ) {

5 this . t ipFruct = t ipFruct ;

6 System . out . p r i n t l n ( " Constructor ␣Fruct . . . " ) ;

7 }

8

9 //metoda getTipFruct e s t e una de t i p f i n a l , ad ica aceas ta nu mai poate f i mod i f i ca ta de c l a s e l e care o

mostenesc

10 f i n a l St r ing getTipFruct ( ) {

11 return this . t ipFruct ;

12 }

13 }

Clasa Para este subclasă a clasei Fruct. Para este un fruct, aşadar se respectă principiul moşteni-

rii. În clasa Para se adaugă noi atribute informaţionale (greutate, culoare) şi un nou comportament

reprezentat de metodele getGreutate(), getCuloare().1 public c l a s s Para extends Fruct{

2 // a t r i b u t e l e sunt pr ivate , dec i domeniul l o r de v i z i b i l i t a t e se a f l a doar in cadru l c l a s e i Para

3 private double greutate ;

4 private St r ing cu loa r e ;

5

6 public Para ( St r ing t ipFruct , double greutate , S t r ing forma ) {

7 super ( t ipFruct ) ; // ape l a r e e x p l i c i t a a c on s t r u c t o ru l u i c l a s e i de baza cu parametrul t ipFruct

8 System . out . p r i n t l n ( " Constructor ␣Para . . . " ) ;

9 this . g r euta te = greutate ;

10 this . cu l oa r e = forma ;

11 }

12

13 //metodele sunt pub l i c e s i dec i pot f i vazute s i in a fa ra c l a s e i , spre deo s eb i r e de a t r i bu t e

14 public double getGreutate ( ) {

15 return greutate ;

16 }

17

18 public St r ing getCuloare ( ) {

19 return cu l oa r e ;

20 }

21 }

Clasa TestFruct instanţiază un obiect de tip Para, implicit de tip Fruct. De aceea avem acces

şi la metoda getTipFruct() care nu aparţine propriu-zis clasei Para.

6

Page 19: Laborator JAVA IESC UNITBV

1 public c l a s s TestFruct {

2 public s t a t i c void main ( St r ing [ ] a rgs ) {

3 Para obPara = new Para ( " para " , 3 , " galben " ) ; // r e f e r i n t a de t i p u l para

4 System . out . p r i n t l n ( " Tip␣Fruct : ␣ "+obPara . getTipFruct ( ) ) ; // ape l a r e metoda din c l a s a de baza

5 System . out . p r i n t l n ( " g reuta te : ␣ "+obPara . getGreutate ( ) ) ; // ape l a r e metoda din sub l c l a s a

6 System . out . p r i n t l n ( " cu l oa r e : ␣ "+obPara . getCuloare ( ) ) ;

7 }

8 }

Observaţi în urma rulării aplicaţiei ordinea în care se apelează constructorii.

III. TEMĂ

1. Să se construiască o clasă Fractie care să implementeze operaţiile de adunare, scădere, în-

mulţire, împărţire şi simplificare. Să se folosească această clasă într-un program.

2. Să se construiască o clasă Forma2D şi o clasă Cerc care moşteneşte clasa Forma2D. Să se

afişeze lungimea cercului şi suprafaţa acestuia.

7

Page 20: Laborator JAVA IESC UNITBV

Laborator 4:

Continuare Programare Orientată pe Obiecte

Întocmit de: Adina Neculai

Îndrumător: Asist. Drd. Gabriel Danciu

29 octombrie 2011

Page 21: Laborator JAVA IESC UNITBV

I. NOŢIUNI TEORETICE

A. Suprascrierea metodelor

O clasă derivată poate declara o metodă cu aceeaşi semnătură cu a unei metode din clasa

de bază. Metoda din clasa derivată substituie astfel metoda din clasa de bază. Această tehnică

se numeşte suprascriere. Cu alte cuvinte, la apelul metodei suprascrise din clasa derivată se va

executa metoda declarată în clasa derivată. Dacă se doreşte apelul metodei ce aparţine clasei de

bază, atunci în metoda din clasa descendentă se foloseşte cuvântul cheie super urmat de operatorul

”.” şi numele metodei suprascrise.

Sunt cazuri în care suprascrierea unei metode nu este dorită. Acest lucru se poate realiza prin

adăugarea cuvântului cheie final. Astfel că, o metodă declarată final în superclasă nu poate fi

suprascrisă în subclasă.

Diferenţa între o metodă suprascrisă şi una supraîncărcată este că în cazul celei suprascrise

semnătura este identică(atât numărul parametrilor cât şi tipul acestora).

B. Clasa Object

În Java, toate clasele formează o anumită structură arborescentă, care are ca rădăcină clasa

Object. Implicit, aceasta este superclasa tuturor claselor şi nu are o clasă părinte.

Metodele principale ale clasei Object sunt:

• clone

Semnătura aceste metode este: protected Object clone() şi returnează o clonă a obiectului

căruia i se aplică, deci un obiect cu aceeaşi stare şi acelaşi comportament. Cu toate acestea,

obiectul rezultat nu este tocmai identic deoarece adresa de memorie către care face referinţă

este diferită de cea a obiectului original.

După ce se execută instrucţiunea b=a.clone(), în care a şi b sunt referinţe la obiecte, expresia

a==b va avea valoarea false, deoarece valorile variabilelor referinţă a si b sunt diferite, în

timp ce expresia a.equals(b) va întoarce valoarea true, deoarece cele două obiecte comparate

au conţinuturi identice.

2

Page 22: Laborator JAVA IESC UNITBV

• equals

Semnătura metodei este public boolean equals(Object obj) şi returnează valoarea true dacă

şi numai dacă obiectele comparate sunt într-adevăr identice; adică obiectele au acelaşi conţi-

nut şi aceeaşi adresă de memorie.

• hashCode

Semnătura metodei este public int hashCode() şi returnează un întreg care este folosit de

Java pentru a diferenţia două obiecte. Se recomandă ca atunci când se doreşte suprascrierea

metodei equals(), să se suprascrie şi metoda hashcode(). Este important ca două obiecte egale

conform metodei equals() să aibă aceleaşi hashcode-uri.

• toString

Semnătura metodei este public String toString() şi returnează un şir de caractere de forma

java.lang.Object@hashCode în care hashCode este exprimat în hexazecimal. Acest şir de

caractere reprezintă obiectul căruia i se aplică. De aceea, se recomandă suprascrierea metodei

toString() în toate subclasele clasei Object pentru ca mesajul să poată fi înţeles cu mai multă

uşurinţă.

Pentru mai multe informaţii se recomandă citirea API-ului.

C. Clase şi metode abstracte

Forma generală a unei clase abstracte este:

[modificator_acces] abstract class NumeClasa{

}

O clasă abstractă este utilizată pentru modelarea unor concepte abstracte şi poate reprezenta

doar clasa de bază în procesul de moştenire. Un lucru important de reţinut atunci când se lucrează

cu clase abstracte este acela că o clasă abstractă nu poate fi instanţiată.

Alte caracterisitici ale unor clase de acest fel sunt următoarele:

• pot implementa constructori;

• pot avea atribute ce suportă modificări;

3

Page 23: Laborator JAVA IESC UNITBV

• pot avea metode abstracte. O metodă abstractă este o metodă ce nu are corp (instrucţiuni) şi

care într-o clasă descendentă a clasei abstracte trebuie implementată. Dacă metoda declarată

abstractă în clasa de bază nu este implementată în subclasă, atunci trebuie declarată din nou

abstractă. Astfel şi subclasa devine una abstractă.

• pot avea şi metode clasice (corpul acestora este implementat în clasa abstractă);

• deşi clasele abstracte nu pot fi instanţiate, se pot declara obiecte de tipul claselor abstracte

şi să fie instanţiate de clasele derivate.

D. Interfeţe

Forma generală a unei interfeţe este:

[modificator_acces] interface NumeInterfata [extends lista_interfete] {

}

O interfaţă este un fel de clasă abstractă cu diferenţa că într-o interfaţă nici o metodă declarată

nu are voie să aibă corp. Interfeţele sunt utilizate pentru a separa implementarea de definiţia

metodelor.

Spre deosebire de o clasă abstractă, o interfaţă nu poate defini un constructor, iar atributele

existente sunt implicit declarate ca fiind statice şi finale, acestea devenind constante. Iar spre

deosebire de o clasă obişnuită, o interfaţă poate moşteni mai multe interfeţe (intervine ideea de

moştenire multiplă).

Forma generală a unei clase care moşteneşte o interfaţă sau o listă de interfeţe este:

[modificator_acces] class NumeClasa [extends NumeSuperclasa] implements lista_interfete{

}

De aici se poate trage concluzia că o clasă poate implementa una sau mai multe interfeţe.

De asemenea, se păstrează regula de la clasele abstracte cum că o clasă care moşteneşte o

interfaţă trebuie să îi implementeze toate metodele. Dacă acest lucru un se întâmplă, atunci în

clasă metodele devin abstracte.

4

Page 24: Laborator JAVA IESC UNITBV

II. PREZENTAREA LUCRĂRII DE LABORATOR

A. Suprascrierea metodelor

Se dă clasa Superclasa care conţine o singură metodă. Clasa Subclasa moşteneşte Superclasa şi

suprascrie metoda afiseazaDescriere. Observaţi semnăturile metodelor; sunt identice.1 public c l a s s Superc lasa {

2 public void a f i s e a z aDe s c r i e r e ( ) {

3 System . out . p r i n t l n ( " ape l a r e ␣ a f i s e a z aDe s c r i e r e ␣ din ␣ supe r c l a s a . . . " ) ;

4 }

5 }

1 public c l a s s Subclasa extends Superc lasa {

2 public void a f i s e a z aDe s c r i e r e ( ) {

3 // ape l a r e e x p l i c i t a a metodei din c l a s a de baza

4 // super . a f i s e a z aDe s c r i e r e ( ) ;

5 System . out . p r i n t l n ( " ape l a r e ␣ a f i s e a z aDe s c r i e r e ␣ din ␣ subc la sa . . . " ) ;

6 }

7 }

În clasa descendentă, în metoda suprascrisă se poate apela metoda originală (din clasa de bază)

folosind cuvântul cheie super. Decomentaţi linia de cod numărul 4 din Subclasa şi observaţi ce se

afişează la următoarea rulare.1 public c l a s s Tes tSupra s c r i e r e {

2 public s t a t i c void main ( St r ing [ ] a rgs ) {

3 Superc lasa superClasa = new Superc lasa ( ) ;

4 Subclasa subClasa = new Subclasa ( ) ;

5 superClasa . a f i s e a z aDe s c r i e r e ( ) ; System . out . p r i n t l n ( ) ;

6 subClasa . a f i s e a z aDe s c r i e r e ( ) ; System . out . p r i n t l n ( ) ;

7 superClasa = subClasa ;

8 superClasa . a f i s e a z aDe s c r i e r e ( ) ;

9 }

10 }

B. Clasa Object

Clasa Point are două atribute de tipul double şi suprascrie metodele clone, equals, hashCode şi

toString ale clasei Object. Observaţi în linia de cod 1 cuvintele implements Cloneable. Orice clasă

care extinde clasa Object şi care îi suprascrie metodele trebuie să implementeze interfaţa Cloneable.

Despre interfeţe se discută pe larg în secţiunile ID şi IID.

Pentru a respecta proprietăţile metodei hasCode, de a returna un număr întreg care să dife-

renţieze două obiecte diferite, se implementează un algoritm care produce un astfel de număr. În

5

Page 25: Laborator JAVA IESC UNITBV

exemplul prezentat (linia de cod 30), algoritmul constă în înmulţirea cu un număr prim şi însuma-

rea membrilor obiectului. Cu cât algoritmul matematic este mai complex cu atât regulile hashCode

sunt respectate în mai multe cazuri.1 public c l a s s Point implements Cloneable {

2 private double x , y ;

3

4 public void setX (double x ) {

5 this . x = x ;

6 }

7

8 public void setY (double y ) {

9 this . y = y ;

10 }

11

12 protected Point c lone ( ) {

13 Point pObj = new Point ( ) ;

14 pObj . x = this . x ;

15 pObj . y = this . y ;

16 return pObj ; // ob i e c t u l pObj are membrii i d e n t i c i cu c e i a i o b i e c t u l u i curent

17 }

18

19 public boolean equa l s ( Object obj ) {

20 i f ( obj == this )

21 return true ; // r e f e r i n t e ega l e

22 i f ( ! ( obj instanceof Point ) )

23 return f a l s e ; // obj nu e s t e de t i p u l Point

24 Point p = ( Point ) obj ; // se f a c e un downcasting , ad ica obj e s t e c onv e r t i t l a t i p u l Point

25 i f ( this . x != p . x | | this . y != p . y )

26 return f a l s e ; // coordonata x sau y e s t e d i f e r i t a

27 return true ;

28 }

29

30 public int hashCode ( ) {

31 double r e s u l t = 17 ;

32 r e s u l t = 37∗ r e s u l t + this . x ;

33 r e s u l t = 37∗ r e s u l t + this . y ;

34 return ( int ) r e s u l t ; /∗ se f a c e un cas t l a t i p u l int , i n t ru ca t v a r i a b i l a r e s u l t e s t e una

35 de t i p double , i a r f un t i a hashCode returneaza o va loa re de t i p i n t ∗/

36 }

37

38 public St r ing toS t r ing ( ) {

39 return " x=␣ "+x+" ; ␣y=␣ "+y ;

40 }

41 }

Clasa TestObject creează un obiect de tipul Point, îi setează proprietăţile şi îi apelează metodele.1 public c l a s s TestObject {

2 public s t a t i c void main ( St r ing [ ] a rgs ) {

3 Point p1 = new Point ( ) ;

4 p1 . setX (3) ;

5 p1 . setY (4) ;

6 Point p1Clone = p1 . c lone ( ) ;

7 System . out . p r i n t l n ( "P1 : ␣ "+p1 . t oS t r ing ( ) ) ;

8 System . out . p r i n t l n ( " Clona␣ l u i ␣P1 : ␣ "+p1Clone . t oS t r ing ( ) ) ;

9 i f ( p1 . equa l s ( p1Clone ) )

6

Page 26: Laborator JAVA IESC UNITBV

10 System . out . p r i n t l n ( " Ob i ec t e l e ␣ sunt ␣ i d e n t i c e ! " ) ;

11 e l s e System . out . p r i n t l n ( " Ob i ec t e l e ␣nu␣ sunt ␣ i d e n t i c e ! " ) ;

12 System . out . p r i n t l n ( " Hashcode−ul ␣ l u i ␣P1␣ e s t e : ␣ "+p1 . hashCode ( ) ) ;

13 System . out . p r i n t l n ( " Hashcode−ul ␣ c l o n e i ␣ l u i ␣P1␣ e s t e : ␣ "+p1Clone . hashCode ( ) ) ;

14 }

15 }

C. Clase şi metode abstracte

Pentru a exemplifica utilizarea claselor şi metodelor abstracte vom folosi clasa Produs. Să pre-

supunem că vrem să derivăm un număr mai mare de clase din Produs: Carte, RamaFoto, etc. Se

observă că acestea au în comun preţul, o descriere şi eventual o reducere a preţului în funcţie de

anumite proprietăţi ale fiecărui produs în parte.

În acest caz, obiecte de genul Carte sau RamaFoto trebuie să facă parte din clase care moştenesc

o superclasă comună, Produs. Mai mult, ar trebui ca Produs să implementeze metodele afiseaza-

Descriere şi calculeazaReducere. Pentru că implementarea metodelor depinde de tipul obiectului şi

proprietăţilor acestuia, metodele se declară abstracte în clasa Produs.1 public abstract c l a s s Produs {

2 private double pretUnitar ;

3

4 Produs (double pretUnitar ) {

5 this . p retUnitar = pretUnitar ;

6 }

7

8 public double getPretUnitar ( ) {

9 return pretUnitar ;

10 }

11

12 //metodele ab s t r a c t e nu au corp

13 // e l e vor f i implementate in c l a s e l e c o p i l a l e c l a s e i Produs

14 public abstract void a f i s e a z aDe s c r i e r e ( ) ;

15 public abstract double ca l cu l eazaReducere ( int procent ) ;

16 }

Clasa Carte extinde clasa Produs şi implementează metodele abstracte ale acesteia în modul ei

propriu. La fel se întâmplă şi pentru clasa RamaFoto.1 public c l a s s Carte extends Produs{

2 private St r ing t i t l u , autor ;

3

4 public Carte (double pretUnitar , S t r ing t i t l u , S t r ing autor ) {

5 super ( pretUnitar ) ;

6 this . t i t l u = t i t l u ;

7 this . autor = autor ;

8 }

9

7

Page 27: Laborator JAVA IESC UNITBV

10 //metoda a f i s e a z aDe s c r i e r e e s t e implementata in sub l c l a s a

11 public void a f i s e a z aDe s c r i e r e ( ) {

12 System . out . p r i n t l n ( " T i t lu ␣ c a r t i i ␣ e s t e : ␣ "+this . t i t l u+" , ␣ i a r ␣ autoru l ␣ e s t e : ␣ "+this . autor ) ;

13 }

14

15 //metoda ca lcu l eazaReducere e s t e implementata in sub l c l a s a

16 public double ca l cu l eazaReducere ( int procent ){

17 System . out . p r i n t l n ( " Calcu leaza ␣ reducere ␣din ␣Carte . . . " ) ;

18 return 0 . 0 ;

19 }

20 }

1 public c l a s s RamaFoto extends Produs{

2 private int lungime , la t ime ;

3

4 public RamaFoto(double pretUnitar , int lungime , int l a t ime ) {

5 super ( pretUnitar ) ;

6 this . lungime = lungime ;

7 this . l a t ime = lat ime ;

8 }

9

10 //metoda a f i s e a z aDe s c r i e r e e s t e implementata in sub l c l a s a

11 public void a f i s e a z aDe s c r i e r e ( ) {

12 System . out . p r i n t l n ( " Lungimea␣ ramei ␣ e s t e : ␣ "+this . lungime+" , ␣ i a r ␣ lat imea ␣ e s t e : ␣ "+this . l a t ime ) ;

13 }

14

15 //metoda ca lcu l eazaReducere e s t e implementata in sub l c l a s a

16 public double ca l cu l eazaReducere ( int procent ){

17 System . out . p r i n t l n ( " Calcu leaza ␣ reducere ␣ in ␣RamaFoto␣ in ␣ f un c t i e ␣de␣ lat ime ␣ s i ␣ lungime . . . " ) ;

18 return 0 . 0 ;

19 }

20 }

Clasa TestProdus creează un vector de obiecte de tipul Produs şi calculează preţul total al

tuturor produselor declarate. Cum un obiect dintr-o clasă abstractă nu poate fi instanţiat cu tipul

clasei abstracte, se instanţiază cu tipul subclaselor, în acest caz Carte şi RamaFoto.1 public c l a s s TestProdus {

2 public s t a t i c void main ( St r ing [ ] a rgs ) {

3 Produs [ ] l i s t aProdus e = new Produs [ 4 ] ;

4 for ( int i =0; i<l i s t aProdus e . l ength ; i++){

5 i f ( i % 2 == 0){ //daca i e s t e par atunc i se c reeaza un ob i e c t de t i p u l Carte

6 l i s t aProdus e [ i ] = new Carte ( 12 . 3 , " Fundatia ␣ "+i , " I saac ␣Asimov " ) ;

7 } e l s e { //daca i e s t e impar atunc i se c reeaza un ob i e c t de t i p u l RamaFoto

8 l i s t aProdus e [ i ] = new RamaFoto ( 5 . 5 , 20− i , 15− i ) ;

9 }

10 }

11 double pretTota l = 0 . 0 ;

12 for ( int i =0; i<l i s t aProdus e . l ength ; i++){

13 //putem avea acces l a metoda getPretUnitar ( ) pentru ca aceas ta se a f l a in c l a s a par in t e .

14 double pretProdusOr ig ina l = l i s t aProdus e [ i ] . getPretUnitar ( ) ;

15 double reducere = l i s t aProdus e [ i ] . ca l cu l eazaReducere ( i ) ;

16 pretTota l += pretProdusOr ig ina l − reducere ;

17 l i s t aProdus e [ i ] . a f i s e a z aDe s c r i e r e ( ) ;

18 }

19 System . out . p r i n t l n ( " Pretu l ␣ t o t a l ␣ a l ␣ produse lo r ␣ e s t e : ␣ "+pretTota l ) ;

8

Page 28: Laborator JAVA IESC UNITBV

20 }

21 }

D. Interfeţe

Avem interfaţa IPersoana în care se află definiţia unei metode.1 public interface IPersoana {

2 public St r ing returneazaNumePersoana ( ) ;

3 }

Interfaţa IStudent moşteneşte interfaţa IPersoana, implicit şi metoda unică a acesteia.1 public interface IStudent extends IPersoana{

2 public boolean v e r i f i c a S t u d e n t I n t e g r a l i s t ( ) ;

3 }

Clasa Student implementează interfaţa IStudent, deci implementează atât metodele acesteia, cât

şi pe cele ale interfeţei pe care IStudent o moşteneşte.1 public c l a s s Student implements IStudent {

2 St r ing nume ;

3 double medieNote ;

4

5 public Student ( St r ing nume , double medieNote ){

6 this . nume = nume ;

7 this . medieNote = medieNote ;

8 }

9

10 // se implementeaza metoda din IStudent

11 public boolean v e r i f i c a S t u d e n t I n t e g r a l i s t ( ) {

12 i f ( this . medieNote >= 5){

13 return true ;

14 }

15 return f a l s e ;

16 }

17

18 // se implementeaza metoda mostenita de IStudent din IPersoana

19 public St r ing returneazaNumePersoana ( ) {

20 return this . nume ;

21 }

22 }

Clasa TestStudent creează un obiect de tipul Student şi verifică dacă studentul este integralist

sau nu, afişând un mesaj corespunzător.1 public c l a s s TestStudent {

2 public s t a t i c void main ( St r ing [ ] a rgs ) {

3 Student student = new Student ( " Ionescu ␣Radu" , 6 . 3 ) ;

4 i f ( student . v e r i f i c a S t u d e n t I n t e g r a l i s t ( ) )

5 System . out . p r i n t l n ( student . returneazaNumePersoana ( )+" ␣ e s t e ␣ i n t e g r a l i s t " ) ;

6 e l s e

9

Page 29: Laborator JAVA IESC UNITBV

7 System . out . p r i n t l n ( student . returneazaNumePersoana ( )+" ␣nu␣ e s t e ␣ i n t e g r a l i s t " ) ;

8 }

9 }

III. TEMĂ

1. Folosind conceptul de clase şi metode abstracte creaţi o aplicaţie care calculează pentru un

cub şi pentru o sfera:

• aria totala;

• volumul;

• centrul de greutate.

Pentru acestea veţi avea nevoie de:

• cub (reprezentat de 8 puncte);

• sferă (reprezentată de 2 puncte: centrul şi un punct de pe margine);

• punct (reprezentat de cele 3 coordonate în spatiu: x, y şi z);

• metoda care calculează distanţa dintre 2 puncte aflate în spaţiu. Aceasta este necesară

pentru aflarea lungimii unei laturi.

10

Page 30: Laborator JAVA IESC UNITBV

Laborator Nr. 5:

Structuri de date 1

Intocmit de: Dobrinas Alexandra

Indrumator: Asist. Drd. Danciu Gabriel

October 28, 2011

Page 31: Laborator JAVA IESC UNITBV

I. NOTIUNI TEORETICE

A. Array

Un sir de date sau un array este o structura ce contine valori multiple de acelasi tip de data. Lungimeaunui sir de date se stabileste la crearea array-ului si va fi fixa pe ıntreaga existenta a acestuia. De regula,primul element se afla pe pozitia 0, iar ultimul pe pozitia n− 1, unde n reprezinta numarul de elemente dinsir.

1. Declararea unui sir de date

In Java, declararea unui array se face astfel:

tip_de_date [] nume_sir;

unde, tip de date reprezinta tipul de date atribuit sirului (int, float, char, String, sau orice tip referinta),iar nume sir reprezinta numele variabilei ın care se stocheaza sirul.

Odata ce sirul de date a fost declarat, acesta se poate instantia. Pentru instatiere se foloseste operatorulnew.

De exemplu, pentru un sir de date de tipul int, cu 3 elemente, declararea si instantierea acestuia se faceastfel:

int [] s;s = new int[3];

sau:

int [] s=new int[3]

Setarea valorilor pentru elementele sirului s creat, se face astfel:

s[0]=14;s[1]=2;s[2]=12;

sau, elementelor li se pot atribui valori ınca de la instantiere:

int[] s = {14,2,12};

Pentru atribuirea de valori ale unui sir, se pot folosii si instructiunile repetitive. De exemplu, ın cazul Incare se citeste un sir de la tastatura, atribuirea valorilor se poate face astfel:

1 BufferReader s td in = new BufferReader (new InputStreamReader ( System . in ) ) ;2 int [ ] s = new int [ 5 ] ;3 for ( int i =0; i <5; i++)4 {5 s [ i ]= In t ege r . pa r s e In t ( s td in . readLine ( ) ) ;6 }

Declararea unui array de un tip de date referinta se face ın acelasi mod ca si pentru sirurile de tipul dedate primitive. Doar ca un astfel de sir va avea ca elemente obiectele unei clase. Astfel ca, daca se da o clasacu numele Country, un sir de elemente din aceasta clasa se declara astfel:

1 c lass Country2 {3 St r ing name ;4 long populat ion ;5 }67 public c lass CountryDemo {8 public stat ic void main ( St r ing [ ] args )9 {

10

2

Page 32: Laborator JAVA IESC UNITBV

11 Country [ ] s i r = new Country [ 2 ] ;12 s i r [ 0 ] . name = ” I t a l i a ” ;13 s i r [ 0 ] . populat ion = 600000000000 l ;1415 s i r [ 1 ] . name = ”Franta” ;16 s i r [ 1 ] . populat ion = 650000000000 l ;17 }18 }

2. Declararea sirurilor multidimensionale

Deoarece un sir de date poate contine referinte catre alte obiecte, este posibil ca un sir sa contina referintesi catre alte siruri. In acest caz, se spune ca se folosesc siruri multidimensionale. Cele mai comune sirurimultimensionale sunt matricile. Exemplu de sir multidimensional:

int matrix[][] = new int[3][2];matrix[0][1] = 12;

In acest caz se da un sir bidimensional, astfel: 3 siruri ın care sunt retinute siruri de cate doua elementede tip int. Accesarea elementelor unui astfel de sir se face prin precizarea tuturor indicilor (ın cazul acestasunt 2 indici).

Nu este obligatoriu ca toate subsirurile sa aiba aceeasi dimensiune. In exemplul urmator este prezentatun sir multidimensional ın care subsirurile au dimensiuni diferite:

1 f loat s i r [ ] [ ] = new f loat [ 4 ] [ ] ;23 s i r [ 0 ] = new f loat [ 5 ] ;4 s i r [ 1 ] = new f loat [ ] { 2 . 3 f , 5 , 6 . 7 f , 1 1} ;5 s i r [ 2 ] = new f loat [ ]{ 1 f , 4 . 2 f , 7 f , 4 . 1 f , 10 f , 9 f } ;6 s i r [ 3 ] = new f loat [ 2 0 ] ;

B. Clasa Vector

Clasa Vector face parte din pachetul java.util si reprezinta o clasa speciala pentru lucrul cu sirurile deelemente. Cele mai uzuale metode folosite pentru declararea si crearea unui astfel de sir sunt:

Vector v = new Vector();//sauVector v = new Vector(5);//se creeaza un vector de 5 elemente

3

Page 33: Laborator JAVA IESC UNITBV

1. Metode si operatii specifice clasei V ector

Deoarece manipularea elementelor unui sir este o operatie ce necesita multa munca, clasa V ector aredefinite o serie de metode si operatii ce pot fi de folos:

Metoda Operatia specifica

add() Adauga un element intr-un vector.

addAll() Adauga o colectie de elemente intr-un vector.

addElement() asemenea metodei add().

capacity() Returneaza capacitatea adica marimea sirului intern.

clear() sterge toate elementele unui vector.

clone() Creeaza o clona a vectorului.

contains() Verifica daca un vector contine un element.

containsAll() Verifica daca un vector contine o colectie.

copyInto() Copiaza elementele unui vector intr-un array.

elementAt() Returneaza elementul de la pozitia specificata.

elements() Returneaza un obiect al vectorului care permite vizitarea tuturor cheilor vectorului.

ensureCapacity() Verifica si se asigura ca marimea buffer-ului intern sa fie de o anumita marime.

equals() verifica egalitatea cu un obiect.

firstElement() returneaza primul element.

get() returneaza un element de la o anumita pozitie.

indexOf() cauta prima aparitie a unui element in sir.

insertElementAt() Insereaza un element in sir.

isEmpty() verifica daca un vector este gol.

iterator() returneaza un iterator, adica un obiect ce permite vizitarea elementelor din sir.

lastElement() Returneaza ultimul element din sir.

lastIndexOf() Cauta pozitia ultimului element din sir care este egal cu obiectul specificat.

listIterator() Returneaza un obiect care permite ca toate elementele sa fie vizitate secvential.

remove() Sterge un anumit element din vector.

removeAll() Sterge toate elementele specificate in colectia data ca parametru.

removeAllElements() Sterge toate elementele din sir si seteaza marimea acestui cu zero.

set() Schimba un element de la o anumita pozitie.

setElementAt() Acelasi lucru ca si set.

setSize() modifica marimea buffer-ului intern.

size() returneaza numarul de elemente din sir.

subList() returneaza o sectiune din sir.

toArray() returneaza elementele vectorului ca array.

trimToSize() taie o portiune din sir, astfel ca el sa ramana de marimea specificata.

C. Clasa Stack

Stiva este o structura de date de tipul LIFO (Last In, First Out).Clasa Stack este considerata a fi ,,copilul” clasei V ector. ınsa are definite o serie de operatii specifice

stivelor.

• Adaugarea elementelor.

Aceasta operatiune se face prin metoda push():

4

Page 34: Laborator JAVA IESC UNITBV

public Object push(Object element)

• Stergerea unui element Aceasta operatiune se va face prin apelul functiei pop():

public Object pop()

• Verificare daca stiva este goala

public boolean empty()

• Preluarea elementului din varful stivei

public Object peek()

• Cautarea unui element ın stiva

public int search(Object element)

Exemplu de utilizare a clasei Stack:

1 import java . u t i l . Stack ;2 public c lass St iva3 {4 public stat ic void main ( St r ing args [ ] )5 {6 Stack s = new Stack ( ) ;7 s . push ( ”Primul element ” ) ;8 s . push ( ”Al do i l e a element ” ) ;9 s . push ( ”Al t r e i l e a element ” ) ;

10 System . out . p r i n t l n ( ”Next : ” + s . peek ( ) ) ;1112 s . push ( ”Al pat ru l ea element ” ) ;13 System . out . p r i n t l n ( s . pop ( ) ) ;14 s . push ( ”Al c i n c i l e a element ” ) ;15 s . push ( ”Al s a s e l e a element ” ) ;16 System . out . p r i n t l n ( s ) ;1718 int count = s . search ( ”Al do i l e a element ” ) ;19 while ( count != −1 && count > 1)20 {21 s . pop ( ) ;22 count−−;23 }2425 System . out . p r i n t l n ( s . pop ( ) ) ;2627 System . out . p r i n t l n ( s . empty ( ) ) ;28 System . out . p r i n t l n ( s ) ;29 }30 }

II. TEME DE LABORATOR

1. Se considera un sir de elemente ce contine n numere reale. Se spune ca doua elemente ale sale formeazao ,,pereche ın dezordine” daca sunt ındeplinite simultan conditiile:

• i < j

• a[i] > a[j], unde1 ≤ i < n si 1 < j ≤ n

Sa se creeze un program care afiseaza perechile ın dezordine din sir si numarul lor. Exemplu: Pentrun=4 si sirul (1, 13,2,4), se va afisa: 13 2 13 4 2

2. Se considera doua tablouri bidimensionale de dimensiuni identice (nxm). Sa se afiseze transpusamatricei suma. Transpusa unei matrice se obtine prin schimbarea liniilor cu coloanele.

3. Determinati suma maxima care se poate forma cu m numere distincte dintr-un vector ce contine nvalori ıntregi. Daca sirul contine mai putin de m valori distincte se va afisa mesajul Imposibil. Pentrurezolvarea problemei se va folosi clasa V ector.

4. Folosind o stiva, realizati si afisati programul dumneavoastra dintr-o zi, pe ore. Eliminati actiunile pecare le efectuati pana la ora 14 si afisati ceea ce urmeaza sa faceti la ora 15.

5

Page 35: Laborator JAVA IESC UNITBV

Laborator Nr. 5:

Structuri de date 2

Intocmit de: Dobrinas Alexandra

Indrumator: Asist. Drd. Danciu Gabriel

November 3, 2011

Page 36: Laborator JAVA IESC UNITBV

I. NOTIUNI TEORETICE

A. Liste

Lista reprezinta cea mai simpla structura de date ınlantuita. Se folosesc doua tipuri de liste:

• liste simplu ınlantuite;

• liste dublu ınlantuite;

B. Liste simplu ınlantuite

Pot fi definite ca fiind o secventa de obiecte alocate dinamic, ın fiecare obiect se pastranduse atat informatiautila cat si o referinta catre succesorul sau din lista. Exista o multitudine de moduri prin care se poateimplementa aceasta structura de date,ınsa cel mai utilizat mod este prin definirea unei clase cu doi membri,unul ın care se retine informaıia utila si unul In care se retine adresa urmatorului element din lista.

1 public c lass LinkedList {23 int data ;4 LinkedList next ;56 public LinkedList ( ) {78 data = 0 ;9 next = null ;

10 }1112 }

Se observa ca membrul next este de acelasi tip de date ca si clasa, acesta pentru ca urmatorul element dinlista este tot de acest tip de date. Pe langa acesti membri se mai pot adauga si altii care sa contina diverseinformatii, ın functie de aplicatia care cere utilizarea unei astfel de structuri.

Urmatorul exemplu ilustreaza crearea si afisarea unei liste simplu ınlantuite. Initial a fost creat un ele-ment cu ajutorul constructorului, informaatia din acest element a primit valoarea 23, iar pentru creareaurmatorului element s-a instantiat membrul next, s.a.m.d. Aceasta operatie poate fi numita ,,alipireaurmatorului element de elementul curent”. Pentru a parcurge lista se foloseste un iterator.

1 c lass LinkedListDemo {2 public stat ic void main ( St r ing args [ ] )3 {4 LinkedList l i s t = new LinkedList ( ) ;5 l i s t . data =23;6 l i s t . next = new LinkedList ( ) ;7 l i s t . next . data = 10 ;8 l i s t . next . next = new LinkedList ( ) ;9 l i s t . next . next . data = 49 ;

1011 // parcurgerea l i s t e i de l a primul element1213 LinkedList i t e r a t o r = l i s t ;14 do15 {16 System . out . p r i n t l n ( i t e r a t o r . data ) ;17 }18 while ( ( i t e r a t o r = i t e r a t o r . next ) !=null ) ;1920 }21 }

Un alt mod de folosire al listelor ınlantuite este prin declararea si retinerea primului element din lista:

1 c lass LinkedList2 {23 int data ;4 LinkedList2 next ;5 LinkedList2 head ;67 public LinkedList2 ( ) {89 head = this ;

10 next = null ;11 data =0;12 }1314 public LinkedList2 ( LinkedList2 head ) {1516 this . head = head ;

2

Page 37: Laborator JAVA IESC UNITBV

17 next = null ;18 data =0;19 }20 }212223 // ////////////////////////////242526 c lass LinkedList2Demo {2728 public stat ic void main ( St r ing args [ ] ) {2930 LinkedList2 l i s t = new LinkedList2 ( ) ;31 l i s t . head = l i s t ;32 l i s t . data =23;33 l i s t . next = new LinkedList2 ( l i s t ) ;34 l i s t . next . data = 10 ;35 l i s t . next . next = new LinkedList2 ( l i s t ) ;36 l i s t . next . next . data = 49 ;3738 // parcurgerea l i s t e i de l a primul element39 while ( l i s t . next !=null ) {4041 System . out . p r i n t l n ( l i s t . data ) ;42 l i s t = l i s t . next ;43 }4445 System . out . p r i n t l n ( l i s t . data ) ;46 l i s t = l i s t . head ;4748 while ( l i s t . next !=null ) {4950 System . out . p r i n t l n ( l i s t . data ) ;51 l i s t = l i s t . next ;52 }53 System . out . p r i n t l n ( l i s t . data ) ;54 }55 }

Se observa ca prin retinerea primunul element al listei se poate ajunge mult mai repede si mai usor laprimul element din lista. De asemenea, se poate observa ca acest mod de construire al unei liste nu esteeficient, deoarece, ın cazul unei liste cu sute sau chiar mii de elemente adaugarea noilor elemente va fiimposibil de realizat. De aceea, adaugarea unui element nou precum si stergerea unui element sunt operatiispecifice pentru lucrul cu liste alaturi de modificarea informatiei utile, modificarea legaturii dintre elemente,cautarea unui element ın liste, aflarea pozitiei unui element.

C. Liste dublu ınlantuite

In cazul ın care se doreste parcurgerea listei si ın celalalt sens (si nu doar de la predecesor la succesor),avem lista dublu ınlantuita. Aceasta pastreaz conceptele listei simplu ınlantuite, cu specificarea ca fiecareelement al listei mai contine o referinta si catre elementul precedent. Un mod de declararea al unei astfel deliste este urmatorul:

1 public c lass Nod {23 private Nod next ;4 private Nod prev ;5 private int data ;67 public Nod( int data , Nod next ,Nod prev )8 {9 this . data = data ;

10 this . next = next ;11 this . prev = prev ;12 }13 }

Operatile specifice lister simplu ınlantuite se mentin si pentru listele dublu, doar ca trebuie sa se tina contsi de legatura prev.

D. Framework -ul Java pentru Colectii

Java pune la dispozitia utilizatorilor o serie de interfete si clase ce pot fi folosite pentru crearea si utilizareadiferitelor colectii de date. Printre acestea amintim:

• interfata Collection - are definite metode pentru o serie de operatii ce se aplica unei colectii (detaliiaici)

3

Page 38: Laborator JAVA IESC UNITBV

• interfata Iterator - iteratorul este acel obiect ce permite parcurgerea colectiilor (detalii aici)

• interfata List - interfata ce implementeaza Collection. Exista doua clase ce implementeaza aceastainterfata: ArrayList si LinkedList. Interfata List ofera posibilitatea de a lucra ordonat, deci permitepastrarea secventiala a elementelor dintr-o colectie (detalii aici)

• clasa ArrayList - clasa este echivalentul clasei Vector, dar sub forma unei colectii. Un ArrayList esteo colectie de elemente indexate ıntr-o anumita ordine, dar nu neaparat sortate. (detalii)

• clasa LinkedList - aceasta este implementarea listei dublu ınlantuite. (detalii)

E. Multimi - Interfata Set

Interfata Set reprezinta un grup de elemente fara duplicate. Nu exista o conditie anume ce impune acestlucru, ci implementarile din clasele Set, sunt cele care impun aceasta conditie. Interfata Set deriva dinCollections, deci va implementa aceleasi metode ca si aceasta interfata. Un element, aflat deja ın multime,nu mai poate fi modificat. API-ul interfetei se poate gasii aici

F. Clasa HashSet

Face parte din interfata Set si are ca operatii specifice urmatoarele:

• adaugarea elementelor;

• stergerea elementelor;

• verificare daca lista este goala;

• verificare daca un anumit obiect este continut tn lista;

Un exemplu de utilizare al clasei HashSet este urmatorul:

1 import java . u t i l . ArrayList ;2 c lass Point {34 public int x ;5 public int y ;67 public Point ( int x , int y) {89 this . x = x ;

10 this . y = y ;11 }1213 public boolean equa l s ( Object o ) {1415 i f ( ! ( o instanceof Point ) )16 return fa l se ;17 Point pt = ( Point ) o ;18 return ( ( pt . x == this . x ) && ( pt . y==this . y ) ) ;19 }2021 public int hashCode ( ) {2223 return 17∗ this . x +23∗ this . y+43;24 }2526 public Str ing toSt r ing ( ) {27 return ”x = ” +x+ ” y = ” +y + ” id = ”+ hashCode ( )+ ”\n” ;28 }29 }3031 // ///////////////////3233 public c lass Multimi34 {35 public stat ic void main ( St r ing args [ ] ) {3637 Set s e t = new HashSet ( ) ;3839 // Adaug in multime40 s e t . add (new Point (1 ,2 ) ) ;41 s e t . add (new Point (2 ,1 ) ) ;42 s e t . add ( ”c” ) ;43

4

Page 39: Laborator JAVA IESC UNITBV

44 // Sterg un element din multime45 s e t . remove ( ”c” ) ;4647 //Marimea unei multimi48 int s i z e = se t . s i z e ( ) ;49 System . out . p r i n t l n ( s i z e ) ;5051 // Adaug un element ce e x i s t a deja52 s e t . add (new Point (1 ,2 ) ) ;5354 // fa ra a avea insa e f e c t55 s i z e = se t . s i z e ( ) ;56 System . out . p r i n t l n ( s i z e ) ;5758 // Ver i f i cam daca un element e s t e deja in multime59 boolean b = se t . conta ins (new Point (2 ,1 ) ) ; // true60 System . out . p r i n t l n (b) ;6162 b = se t . conta ins ( ”c” ) ; // f a l s e63 System . out . p r i n t l n (b) ;6465 // Parcurgem multimea66 I t e r a t o r i t = se t . i t e r a t o r ( ) ;67 while ( i t . hasNext ( ) ) {68 // s i af isam e lemente l e69 Object element = i t . next ( ) ;70 System . out . p r i n t l n ( element ) ;71 }72 }73 }

II. TEME DE LABORATOR

1. Editati, compilati si lansati ın executie aplicatile prezentate la I B.

2. Creati o lista dublu ınlantuita si afisati-o.

3. Editati, compilati si lansati ın executie aplicatile prezentate la I F.

4. Se da o clasa de numere complexe. Folosind clasa HashSet creati o lista ın care sa se retina numerecomplexe. Adaugati minim 5 astfel de numere si realizati un meniu prin care sa se rezolve urmatoarelecerinte:

• Afisati dimensiunea listei.

• Verificati daca un numar citit exista ın lista. Daca nu exista, adaugati-l si afisati noua lungime alistei.

• Eliminati un numar din lista.

• Afisati suma numerelor din lista.

• Afisati elementele listei.

5

Page 40: Laborator JAVA IESC UNITBV

Laborator 7:

Tratarea excepţiilor în Java

Întocmit de: Adina Neculai

Îndrumător: Asist. Drd. Gabriel Danciu

13 noiembrie 2011

Page 41: Laborator JAVA IESC UNITBV

I. NOŢIUNI TEORETICE

A. Ce este o excepţie?

O excepţie este un eveniment care apare în execuţia unui program şi care întrerupe evoluţia

normală a acestuia.

Încercarea de a soluţiona aceste excepţii folosind metode clasice duce la creşterea semnificativă

a complexităţii codului, ceea ce afectează, în mod indirect, corectitudinea codului şi claritatea

acestuia. De aceea, cei care au creat limbajul Java s-au gândit la un sistem de tratare a excepţiilor

ce permite programatorului:

• tratarea excepţiilor la un nivel superior celui în care apar;

• propagarea excepţiilor la nivelele superioare în mod ierarhic;

• tratarea unitară a excepţiilor de acelaşi tip.

B. Ierarhia excepţiilor

Pentru a crea un obiect excepţie, Java pune la dispoziţia programatorului o ierarhie de clase,

aflată în pachetul java.lang, ierarhie ce poate fi observată în imaginea de mai jos.

Figura 1: Ierarhia simplificată a claselor de tip excepţie din pachetul java.lang

2

Page 42: Laborator JAVA IESC UNITBV

După cum se poate observa din figura de mai sus, clasa Throwable are doi descendenţi: clasa

Error şi clasa Exception. Nici una nu adaugă metode suplimentare, dar au fost introduse în acest

fel pentru a delimita două tipuri fundamentale de excepţii ce pot apărea într-o aplicaţie Java.

Clasa Error corespunde excepţiilor ce nu mai pot fi recuperate de către programator. Apariţia

unei astfel de excepţii înseamnă că a apărut o eroare deosebit de gravă şi aceasta determină ter-

minarea programului. Deşi este datoria programatorului să arunce şi să trateze excepţiile apărute,

excepţiile de tipul Error nu trebuie tratate în acest fel. Ele sunt utilizate de maşina virtuală Java

(JVM).

Clasa Exception este, de fapt, cea utilizată efectiv de programator în procesul de tratare a ex-

cepţiilor. Atât această clasă cât şi descendenţii ei se ocupă de excepţii ce pot fi rezolvate de către

program, fără oprirea acestuia.

Există o mare varietate de clase derivate din Exception care pot fi utilizate. Lista completă se

află aici.

C. Aruncarea unei excepţii

Aruncarea unei excepţii se face cu ajutorul cuvântului cheie throw în felul următor:

throw <obiectExceptie>

sau

throw new <clasaExceptie>(”Mesaj”)

unde <obiectExceptie> şi new <clasaExceptie>(”Mesaj”) sunt instanţe ale clasei Throwable sau

ale unei clase derivate din aceasta.

O metodă poate arunca mai multe excepţii, însă prin aruncarea unei excepţii se iese din metodă

fără a mai executa instrucţiunile care urmau. În cazul în care o metodă aruncă o excepţie, fie prin

throw, fie prin apelul unei alte metode, fără a avea o secvenţă try - catch de prindere, atunci această

metodă trebuie să specifice clar acest lucru.

public void <numeMetoda> throws <classException1>, <classException2>, . . . {

. . .

throw <obExceptie1>

. . .

throw <obExceptie2>

3

Page 43: Laborator JAVA IESC UNITBV

. . .

}

D. Prinderea unei excepţii

O dată ce o excepţie a fost aruncată, ea trebuie prinsă. Acest lucru se poate realiza cu ajutorul

unui bloc try-catch, a cărui formă generală este prezentată mai jos:

try{

//cod ce poate arunca o exceptie

}

catch(<classExcept1> <idExcept1>){

//handler exceptie de tip <classExcept1>

}

catch(<classExcept2> <idExcept2>){

//handler exceptie de tip <classExcept2>

}

. . .

finally{

//secventa de cod executata oricum

}

După cum se poate observa, structura de prinderere a excepţiilor poate fi delimitată în trei blocuri:

• try

Secvenţa de cod din acest bloc poate arunca, în anumite condiţii, excepţii. În cazul în care se

aruncă o exepţie, execuţia secvenţei din blocul try se întrerupe şi se declanşează procedura

de tratare a excepţiei. În caz contrar, secvenţa de cod din interiorul blocului se execută în

întregime, controlul fiind predat primei instrucţiuni de dupa blocul try-catch.

• catch

Numite şi handlere de excepţii, blocurile catch tratează excepţiile. În momentul în care

apare o excepţie în blocul try, se parcurge lista blocurilor catch în ordinea în care apar în

codul sursă. În cazul în care excepţia corespunde unui bloc catch, se execută secvenţa de

4

Page 44: Laborator JAVA IESC UNITBV

cod care corespunde blocului respectiv şi căutarea ia sfârşit, considerându-se că excepţia a

fost rezolvată. După cum se poate observa, pot exista mai multe blocuri catch, acest lucru

subliniind faptul că se pot trata excepţii de mai multe tipuri. Important este ca acestea să

fie introduse în ordinea copil - părinte pentru că blocurile catch se parcurg secvenţial.

• finally

Blocul finally cuprinde secvenţa de cod care se execută în final, indiferent dacă a apărut o

situaţie de excepţie sau nu.

Este obligatoriu ca blocul try să fie urmat de cel puţin un bloc catch sau finally.

E. Crearea propriilor excepţii

În dezvoltarea unei aplicaţii Java pot exista cazuri în care excepţiile apărute să nu poată fi

tratate de clasele de excepţie deja existente în pachetele Java (java.util, java.io, java.net). Astfel,

dezvoltatorii de aplicaţii sunt nevoiţi să-şi creeze propriile clase de excepţie. Acest lucru se poate

realiza foarte uşor şi anume, creând clase care extind clasa Throwable sau clase descendente ale

acesteia. Se recomandă, dintre subclasele lui Throwable, să se extindă clasa Exception. Clasa Error

este specifică erorilor grave, care duc la terminarea execuţiei programului, şi este puţin probabil să

avem nevoie de ea.

II. PREZENTAREA LUCRĂRII DE LABORATOR

A. Exemple de programe ce demonstrează lucrul cu excepţiile

1. Programul următor conţine funcţia main() care apelează metoda metoda1() având ca para-

metru un număr întreg. Funcţia metoda1() va arunca o excepţie în cazul în care parametru

trimis este diferit de 0, altfel funcţia se va executa până la capăt. Observaţi ce se afişează

pentru i=0 şi pentru i=1; când se execută funcţia metoda1() până la capăt şi când nu. De

asemenea, observaţi şi prezenţa blocului finally.1 public c l a s s TestExceptions1 {

2 public s t a t i c void main ( St r ing [ ] a rgs ) {

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

4 try {

5 System . out . p r i n t l n ( " \n␣Caz␣ "+i ) ;

5

Page 45: Laborator JAVA IESC UNITBV

6 // apa r i t i a e x c e p t i e i se r e a l i z e a z a pr in ape lu l metodei metoda1

7 metoda1 ( i ) ;

8 System . out . p r i n t l n ( " \n␣ S f a r s i t ␣ caz ␣ "+i ) ;

9 } catch ( Exception ex ) {

10 // t r a t a r e a e x c e p t i e i i n t a l n i t e in metoda1

11 // ape la r ea f u n c t i e i getMessage ( ) a c l a s e i Exception

12 System . out . p r i n t l n ( "A␣aparut ␣o␣ exc ep t i e . ␣Mesajul ␣ e i ␣ e s t e : ␣ "+ex . getMessage ( ) ) ;

13 } f i n a l l y {

14 System . out . p r i n t l n ( " Se␣ executa ␣ b l o cu l ␣ f i n a l l y " ) ;

15 }

16 }

17 }

18

19 //metoda1 s p e c i f i c a pr in in t e rmed iu l cuvantu lu i che i e " throws " ce t i p u r i de e x c e p t i i arunca

20 private s t a t i c void metoda1 ( int i ) throws Exception {

21 System . out . p r i n t l n ( "Am␣ i n t r a t ␣ in ␣metoda1 " ) ;

22 i f ( i != 0){

23 // aruncarea e x c e p t i e i de t i p u l Exception

24 throw new Exception ( " ex c ep t i e ␣ din ␣metoda1 " ) ;

25 }

26 System . out . p r i n t l n ( "Am␣ i e s i t ␣ din ␣metoda1 " ) ;

27 }

28 }

2. Acest program conţine funcţia main() care apelează funcţia metoda1(), care, la rândul ei ape-

lează funcţia metoda2() ce poate arunca o excepţie. Observaţi că ambele funcţii (metoda1()

şi metoda2()) specifică ce tip de excepţie aruncă (Throwable). Deşi blocul try-catch are mai

multe blocuri catch, excepţia apărută este tratată de blocul corespunzător acesteia, adică

Throwable. Acestă clasă conţine diverse metode care pot ajuta programatorul în localizarea

excepţiei. Despre acestea puteţi citi aici.1 public c l a s s TestExceptions2 {

2 public s t a t i c void main ( St r ing [ ] a rgs ) {

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

4 try {

5 System . out . p r i n t l n ( " \n␣Caz␣ " + i ) ;

6 metoda1 ( i ) ;

7 System . out . p r i n t l n ( " \n␣ S f a r s i t ␣ caz ␣ " + i ) ;

8 } catch ( Exception ex ) {

9 System . out

10 . p r i n t l n ( "A␣aparut ␣o␣ exc ep t i e ␣Exception . ␣Mesajul ␣ e i ␣ e s t e : ␣ "

11 + ex . getMessage ( ) ) ;

12 } catch ( Throwable exTh) {

13 System . out . p r i n t l n ( "A␣aparut ␣o␣ exc ep t i e ␣Throwable␣ in ␣main " ) ;

14 /∗ ape la r ea metodei pr intStackTrace ( ) a c l a s e i Throwable care a f i s e a za , conform

p r i n c i p i u l u i unei s t i v e LIFO ,

15 i n f o rma t i i despre l o c a t i i l e parcurse de exc ep t i e ∗/

16 exTh . pr intStackTrace ( System . out ) ;

17 } f i n a l l y {

18 System . out . p r i n t l n ( " Se␣ executa ␣ b l o cu l ␣ f i n a l l y ␣din ␣main " ) ;

19 }

20 }

21 }

6

Page 46: Laborator JAVA IESC UNITBV

22

23 private s t a t i c void metoda1 ( int i ) throws Throwable {

24 System . out . p r i n t l n ( "Am␣ i n t r a t ␣ in ␣metoda1 " ) ;

25 metoda2 ( i ) ;

26 System . out . p r i n t l n ( "Am␣ i e s i t ␣ din ␣metoda1 " ) ;

27 }

28

29 private s t a t i c void metoda2 ( int i ) throws Throwable {

30 System . out . p r i n t l n ( "Am␣ i n t r a t ␣ in ␣metoda2 " ) ;

31 i f ( i != 0) {

32 throw new Throwable ( " ex c ep t i e ␣ din ␣metoda2 " ) ;

33 }

34 System . out . p r i n t l n ( "Am␣ i e s i t ␣ din ␣metoda2 " ) ;

35 }

36 }

3. Programul următor este unul didactic întrucât aruncă clase de excepţie descendente ale clasei

RuntimeException. Nu este obligatoriu ca acest gen de excepţii să fie ”prinse” (tratate), dar

exemplul a fost introdus pentru o mai bună înţelegere a mecanismului de aruncare/prindere

a excepţiilor.

După cum se poate observa la o primă rulare a programului, va fi prinsă prima excepţie,

NumberFormatException. Comentaţi, respectiv decomentaţi, secvenţe de cod din program,

astfel încât să obţineţi, pe rând, toate excepţiile tratate.

De asemenea, programul conţine o metodă callException() ce primeşte ca parametru un tip

de dată excepţie. Aceasta apelează câteva dintre metodele implementate de clasele de tip

excepţie. Metodele respective au rolul de a oferi mai multe informaţii despre locaţia şi tipul

de excepţie apărut.1 public c l a s s TestExceptions3 {

2 public s t a t i c void main ( St r ing [ ] a rgs ) {

3 try {

4 System . out . p r i n t l n ( " \n␣Number␣Format␣Exception " ) ;

5 St r ing s t r 1 = " 123 r " ;

6 In t ege r n = Int ege r . pa r s e In t ( s t r 1 ) ;

7

8 System . out . p r i n t l n ( " \n␣ArrayIndexOutOfBoundsException " ) ;

9 int s i r [ ] = { 1 , 2 , 3 , 4 } ;

10 s i r [ 6 ] = 3 ;

11

12 System . out . p r i n t l n ( " \n␣StringIndexOutOfBoundsException " ) ;

13 St r ing s t r 2 = " abcde " ;

14 char c1 = s t r 2 . charAt (−1) ;

15

16 System . out . p r i n t l n ( " \n␣Nul lPo interExcept ion " ) ;

17 St r ing s t r 3 = null ;

18 System . out . p r i n t l n ( s t r 3 . l ength ( ) ) ;

19

20 System . out . p r i n t l n ( " \n␣ArithmeticExcept ion " ) ;

7

Page 47: Laborator JAVA IESC UNITBV

21 int n2 = 12/0;

22

23 } catch ( NumberFormatException nfex ) {

24 System . out . p r i n t l n ( " Tratare ␣ exc ep t i e ␣NumberFormatException . . . " ) ;

25 ca l lExcept i on ( nfex ) ;

26 } catch ( ArrayIndexOutOfBoundsException arrayEx ) {

27 System . out . p r i n t l n ( " Tratare ␣ exc ep t i e ␣ArrayIndexOutOfBoundsException . . . " ) ;

28 ca l lExcept i on ( arrayEx ) ;

29 } catch ( StringIndexOutOfBoundsException strEx ) {

30 System . out . p r i n t l n ( " Tratare ␣ exc ep t i e ␣StringIndexOutOfBoundsException . . . " ) ;

31 ca l lExcept i on ( strEx ) ; ;

32 } catch ( Nul lPo interExcept ion nullEx ) {

33 System . out . p r i n t l n ( " Tratare ␣ exc ep t i e ␣Nul lPo interExcept ion . . . " ) ;

34 ca l lExcept i on ( nullEx ) ;

35 }catch ( ArithmeticExcept ion aEx){

36 System . out . p r i n t l n ( " Tratare ␣ exc ep t i e ␣ArithmeticExcept ion . . . " ) ;

37 ca l lExcept i on (aEx) ;

38 }

39 }

40

41 private s t a t i c void ca l lExcept i on ( RuntimeException r tex ){

42 System . out . p r i n t l n ( " Mesajul ␣ standard ␣ a l ␣ e x c e p t i e i : ␣ " ) ;

43 System . out . p r i n t l n ( r t ex ) ;

44 System . out . p r i n t l n ( " Mesajul ␣ e x c e p t i e i : ␣ " ) ;

45 System . out . p r i n t l n ( r t ex . getMessage ( ) ) ;

46 System . out . p r i n t l n ( " Mesajul ␣ l o c a l : ␣ " ) ;

47 System . out . p r i n t l n ( r t ex . getLoca l i zedMessage ( ) ) ;

48 System . out . p r i n t l n ( " \nStack␣ t ra c e : ␣ " ) ;

49 r tex . pr intStackTrace ( System . out ) ;

50 }

51 }

B. Crearea propriilor excepţii

Crearea propriilor excepţii se face prind crearea unei clase obişnuite, dar care moşteneşte clasa

Exception. Clasa următoare face exact acest lucru. IncompatibleMatrixException conţine doi con-

structori, unul fără parametri şi unul cu un parametru şi care apelează constructorul clasei de

bază.1 public c l a s s IncompatibleMatr ixExcept ion extends Exception{

2

3 public IncompatibleMatr ixExcept ion ( ) {

4 }

5

6 public IncompatibleMatr ixExcept ion ( St r ing message ) {

7 super ( message ) ;

8 }

9 }

Clasa prezentata mai jos, declară două matrici de dimensiuni diferite şi se încearcă înmulţirea

acestora. Metoda multiplyMatr() este apelată în cadrul unui bloc try şi verifică dacă două matrici

8

Page 48: Laborator JAVA IESC UNITBV

sunt compatibile. În cazul în care numărul de coloane ale primei matrici este diferit de numărul de

linii ale celei de-a doua, atunci se aruncă excepţia creată anterior, IncompatibleMatrixException.1 public c l a s s TestMatrixException {

2 public s t a t i c void main ( St r ing [ ] a rgs ) {

3 int [ ] [ ] matr1 , matr2 ;

4 matr1 = new int [ 2 ] [ 3 ] ;

5 matr2 = new int [ 4 ] [ 4 ] ;

6

7 try{

8 multiplyMatr (matr1 , matr2 ) ;

9 }catch ( IncompatibleMatr ixExcept ion imEx){

10 System . out . p r i n t l n ( " Mesajul ␣ e s t e : ␣ "+imEx . getMessage ( ) ) ;

11 imEx . pr intStackTrace ( System . out ) ;

12 }

13 }

14

15 private s t a t i c void multiplyMatr ( int [ ] [ ] matr1 , int [ ] [ ] matr2 ) throws IncompatibleMatr ixExcept ion{

16 i f (matr1 [ 0 ] . l ength != matr2 . l ength ){

17 throw new IncompatibleMatr ixExcept ion ( " mat r i c i ␣ incompat ib i l e ␣pt␣ inmu l t i r e " ) ;

18 }

19 //cod de s t i na t pt inmu l t i r ea ma t r i c i l o r

20 }

21

22 }

III. TEMĂ

1. Rulaţi toate programele prezentate ca exemplu în secţiunea II.

2. Realizaţi un program în care să se testeze captarea şi tratarea excepţiilor generate la calcu-

larea a cel puţin 10 funcţii matematice din clasa Math aflată în pachetul java.lang. Folosiţi

blocuri de catch specifice pentru fiecare funcţie în parte.

9

Page 49: Laborator JAVA IESC UNITBV

Laborator Nr. 8:

Fluxuri Java

Intocmit de: Dobrinas Alexandra

Indrumator: Asist. Drd. Danciu Gabriel

November 15, 2011

Page 50: Laborator JAVA IESC UNITBV

I. NOTIUNI TEORETICE

Fluxurile Java pun la dispozitie modalitatea prin care o aplicatie permite citirea unor informatii care segasesc pe o sursa externa, respectiv trimiterea unor informatii catre o destinatie externa. Informatia sepoate gasi oriunde: ıntr-un fisier pe disc, ın retea, ın memorie sau ın alt program si poate fi de orice tip:date primitive, obiecte, imagini, sunete, etc. Mai mult, prin fluxuri este posibila comunicarea ıntre douasau mai multe fire de executie ale aceleiasi aplicatii. Fluxurile sunt secvente de octeti. Indiferent de tipulinformatiilor, citirea/scrierea lor de pe un mediu extern, respectiv pe un mediu extern respecta urmatoriialgoritmi:

• Citirea:

deschide canal comunicatie;cat timp (mai sunt informatii) {citeste informatie;}inchide canal comunicatie;

• Scrierea:

deschide canal comunicatiecat timp (mai sunt informatii) {scrie informatie;}inchide canal comunicatie;

A. Fluxuri pentru lucrul cu fisiere

Fluxurile pentru lucrul cu fisiere sunt cele mai usor de ınteles. Clasele care implementeaza aceste fluxurisunt urmatoarele:

FileReader caractere

FileWriter caractere

FileInputStream octeti

FileOutputStream octeti

Constructorii acestor clase accepta ca argument un obiect prin care se specifica fisierul folosit. Acestapoate fi un sir de caractere, un obiect de tip File sau un obiect de tip FileDescriptor.

Constructorii clasei FileReader (vezi si API):

public FileReader( String fileName ) throws FileNotFoundExceptionpublic FileReader( File file ) throws FileNotFoundExceptionpublic FileReader( FileDescriptor fd )

Constructorii clasei FileWriter (vezi si API):

public FileWriter( String fileName ) throws IOExceptionpublic FileWriter( File file ) throws IOExceptionpublic FileWriter( FileDescriptor fd )public FileWriter( String fileName, boolean append ) throws IOException

Constructorii clasei FileOutputStream (vezi si API):

2

Page 51: Laborator JAVA IESC UNITBV

FileOutputStream(File file) throws FileNotFoundExceptionFileOutputStream(File file, boolean append) throws FileNotFoundExceptionFileOutputStream(FileDescriptor fd)FileOutputStream(String name) throws FileNotFoundExceptionFileOutputStream(String name, boolean append) throws FileNotFoundException

Constructorii clasei FileInputStream (vezi si API):

InputStreamReader(InputStream in)InputStreamReader(InputStream in, Charset cs)InputStreamReader(InputStream in, CharsetDecoder dec)InputStreamReader(InputStream in, String charsetName) throws UnsupportedEncodingException

Cei mai uzuali constructori sunt cei care primesc ca argument numele fisierului. Acestia pot provocaexceptii de tipul FileNotFoundException ın cazul ın care fisierul cu numele specificat nu exista. Din acestmotiv orice creare a unui flux de acest tip trebuie facuta tntr-un bloc try....catch sau metoda ın care suntcreate fluxurile respective trebuie sa arunce exceptii de tipul FileNotFoundException sau de tipul superclaseiIOException.

Urmatoarele programe copiaza continutul unui fisier ıntr-un alt fisier.

1 import java . i o . ∗ ;2 public c lass Copy1 {3 public stat ic void main ( St r ing [ ] args ) throws IOException {45 Fi leReader in = new Fi leReader ( ” in . txt ” ) ;6 F i l eWr i te r out = new Fi l eWr i te r ( ”out . txt ” ) ;78 int c ;9 while ( ( c = in . read ( ) ) != −1)

10 out . wr i te ( c ) ;1112 in . c l o s e ( ) ;13 out . c l o s e ( ) ;14 }15 }

Se observa ca metoda main arunca exceptii de tipul IOException, deci nu este necesara folosirea blocurilortry....catch. Pentru citirea si scrierea din\ın fisiere s-au folosit clasele FileReader sitextitFileWriter

In urmatorul exemplu este exemplificat modul de lucru cu clasele FileInputStream si FileOutputStream,precum si folosirea blocurilor try...catch.

1 import java . i o . ∗ ;2 public c lass Copy2 {3 public stat ic void main ( St r ing args [ ] ) {45 Fi leInputStream in ;6 FileOutputStream out ;78 int ok ;9 try {

10 in = new FileInputStream ( args [ 0 ] ) ;11 try {12 out = new13 FileOutputStream ( args [ 1 ] ) ;14 ok = 0 ;1516 while ( ok != −1) {17 try {18 ok = in . read ( ) ;19 out . wr i t e ( ok ) ;20 System . out . p r in t ( ( char ) ok ) ;21 }22 catch ( IOException e ) {23 System . out . p r i n t l n ( e . getMessage ( ) ) ;24 System . ex i t (1) ;25 }2627 }28 }29 catch ( IOException e ) {30 System . out . p r i n t l n ( e . getMessage ( ) ) ;31 System . ex i t (1) ;32 }33 }34 catch ( FileNotFoundException e ) {35 System . out . p r i n t l n ( e . getMessage ( ) ) ;36 System . ex i t (1) ;37 }38 }39 }

3

Page 52: Laborator JAVA IESC UNITBV

Se recomanda folosirea claselor FileReader si FileWriter atunci cand se citesc sau se scriu siruri de carac-tere. Pentru citirea sirurilor de octeti(de exemplu pentru imagini) se vor folosii clasele FileOutputStream siFileInputStream.

B. Citirea si scrierea cu ajutorul buffer-elor

Sunt folosite pentru a introduce o zona tampon tn procesul de scriere/citire a informatiilor, reducandastfel numarul de accese la dispozitivul ce reprezinta sursa originala de date. Sunt mult mai eficiente decatfluxurile fara buffer si din acest motiv se recomanda folosirea lor ori de cate ori este posibil.

Clasele pentru citirea/scrierea cu zona tampon sunt:

BufferedReader caractere

BufferedWriter caractere

BufferedInputStream octeti

BufferedOutputStream octeti

Clasele BufferedReader si BufferedInputStream citesc tn avans date si le memoreaza sntr-o zona tampon.Atunci cand se executa o operatie read(), octetul citit va fi preluat din buffer. In cazul ın care buffer-uleste gol citirea se face direct din flux si, odata cu citirea octetului, vor fi memorati ın buffer si octetii care ıiurmeaza. Similar, se lucreaza si cu clasele BufferedWriter si BufferedOutputStream.

Fluxurile de citire/scriere cu buffer sunt fluxuri de procesare si sunt folosite prin suprapunere cu altefluxuri.

Exemplu de folosire a zonei tampon pentru realizarea citirii din fisier:

BufferedInputStream out = new BufferedInputStream(new FileInputStream("out.dat"), 1024)

Constructorii clasei BufferedReader sunt:

BufferedReader( Reader in )BufferedReader( Reader in, int dim_buffer )

Constructorii clasei BufferedWriter sunt:

BufferedWriter( Writer out )BufferedWriter( Writer out, int dim_buffer )

Constructorii clasei BufferedInputStream sunt:

BufferedInputStream( InputStream in )BufferedInputStream( InputStream in, int dim_buffer )

Constructorii clasei BufferedOutputStream sunt:

BufferedOutputStream( OutputStream out )BufferedOutputStream( OutputStream out, int dim_buffer )

In cazul constructorilor ın care dimensiunea buffer-ului nu este specificata, aceasta primeate valoarea im-plicita de 512 octeti.

Metodele acestor clase sunt cele uzuale de tipul read si write (vezi API Reader, API Writer). Pe langaacestea, clasele pentru scriere prin buffer mai au si metoda flush care goleste explicit zona tampon chiardaca aceasta nu este plina.

Exemplu pentru folosirea zonelor tampon:

1 Buf feredWriter out = new BufferedWriter (new Fi l eWr i te r ( ”out . dat” ) , 1024) ; //am crea t un f l ux cu bu f f e r de 1024o c t e t i

2 for ( int i =0; i <1024; i++)3 out . wr i te ( i ) ; // bu f f e r u l nu e s t e p l i n −> in f i s i e r nu s−a s c r i s nimic4 out . f l u s h ( ) ; // bu f f e r u l e s t e g o l i t −> dat e l e se s c r i u in f i s i e r

4

Page 53: Laborator JAVA IESC UNITBV

C. Intrari/Iesiri formatate

Orice program Java are:

• o intrare standard;

• o iesire standard;

• o iesire standard pentru erori;

In general intrarea standard este tastatura, iar iesirea standard este ecranul. Intrarea si iesirea standardsunt de fapt, obiecte pre-create ce descriu fluxuri de date pentru citirea respectiv scrierea la dispozitivelestandard ale sistemului. Aceste obiecte sunt definite publice ın clasa System si sunt:

Variabila Semnificatie Tip flux

System.in flux standard de intrare InputStream

System.out flux standard de iesire PrintStream

System.err flux standard pentru afisarea erorilor PrintStream

Fluxul standard de iesire se foloseste pentru afisarea datelor pe ecran, ın modul consola: Sys-tem.out.println(”mesaj”). Fluxul standard pentru afisarea erorilor se foloseste similar:

catch (IOException e) {System.err.println("Eroare de intrare/iesire!")}

Fluxurile de iesire pot fi folosite, asadar fara probleme deoarece tipul lor este PrintStream, clasa primitivapentru scrierea efectiva a datelor. In schimb, fluxul standard de intrare System.out, de tip InputStream careeste o clasa abstracta, deci pentru a-l putea utiliza va trebui sa-l folosim ımpreuna cu un flux de procesarea datelor sau cu orice alt flux ce permite citirea efectiva a datelor.

Uzual, se foloseste metoda readLine pentru citirea datelor de la tastatura si din acest motiv vom folosiintrarea standard ımpreuna cu o clasa de procesare care implementeaza metoda readLine. Exemplul tipiceste:

BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));System.out.print("Introduceti o linie:");String linie = stdin.readLine()System.out.println(linie);

Exemplu: un program care afiseaza liniile introduse de la tastatura

1 import java . i o . ∗ ;2 public c lass Af i s a r e {34 public stat ic void main ( St r ing [ ] args ) {56 BufferedReader s td in = new BufferedReader (new InputStreamReader ( System . in ) ) ;7 St r ing s ;8 try {9 while ( ( s = std in . readLine ( ) ) . l ength ( ) != 0)

10 System . out . p r i n t l n ( s ) ; //Programul se opre s t e cu o l i n i e vida11 }12 catch ( IOException e ) {13 e . pr intStackTrace ( ) ;14 }15 }16 }

Se observa ca metoda readLine poate provoca exceptii de tipul IOException.

5

Page 54: Laborator JAVA IESC UNITBV

II. TEME DE LABORATOR

1. Intr-un fisier se regasesc pe prima linie dimensiunile nxm ale unei matrice, iar pe urmatoarele liniielementele matricei corespunzatoare dimensiunilor date. Sa se citeasca de la tastatura ınca o matricede dimensiune mxn si sa se scrie ıntr-un alt fisier produsul celor doua matrici.(Se vor folosi claseleFileWriter, FileReader, iar citirea de la tastatura se va face folosind clasa BufferedReader)

2. Sa se citeasca de la tastatura un user si o parola. Acestea se vor compara cu ınregistrarile existente ınfisierul parole.txt. Daca user-ul si parola se regasesc printre acestea (pe aceeasi linie), se va afisa mesajul”acces permis”, daca se regaseste doar user-ul, iar parola este gresita se va afisa ”parola gresita” si seva mai cere introducerea parolei ınca o data, dar nu mai mult de 3 ori, daca se atinge acest prag se vaafisa mesajul ”cont blocat”. In caz contrar se reia procesul de introduce a datelor, dar nu mai multde 5 ori. Daca se atinge limita de 5 intrari se va afisa mesajul ”Nu ai cont. Inregistreaza-te.” (Se vorfolosi clasele FileInputStream si FileOutputStream.)Exemplu de date in fisierul parole.txt:user usergigi parolaMeauser1 parola1

3. Intr-un fisier numit clienti.txt sunt memorate date despre clientii unui magazin virtual. Pe fiecare liniese retine numele, prenumele si varsta clientilor. Se cere sa se afiseze numarul si lista clientilor majorisi numarul clientilor minori.

!!! Pentru toate problemele se vor folosii mecanisme de aruncare a exceptilor.

6

Page 55: Laborator JAVA IESC UNITBV

Laborator 9:

Fire de execuţie

Întocmit de: Adina Neculai

Îndrumător: Asist. Drd. Gabriel Danciu

20 noiembrie 2011

Page 56: Laborator JAVA IESC UNITBV

I. NOŢIUNI TEORETICE

A. Ce este un fir de execuţie?

Înainte de a defini conceptul de fir de execuţie sau thread, ne vom opri asupra conceptului

de multitasking. Acesta se referă la capacitatea unui computer de a executa mai multe programe

(task-uri, procese) în acelaşi timp. Având în vedere această noţiune, putem defini conceptul de

multithreading care se referă la execuţia mai multor secvenţe de cod în acelaşi timp, în cadrul

aceluiaşi program. O astfel de secvenţă de cod se numeşte fir de execuţie sau thread.

Un thread se execută în contextul unui program şi nu poate fi tratat decât în cadrul unui

program. Exemplele prezentate până acum au dispus de un sigur fir de execuţie, adică de o singură

structură secvenţială de instrucţiuni.

B. Lucrul cu fire de execuţie

Limbajul Java pune la dispoziţia programatorului, in pachetul java.lang, două clase şi o interfaţă

pentru lucrul cu thread-uri:

• clasa Thread: lucru cu thread-uri ca entităţi separate;

• clasa ThreadGroup: crearea unor grupuri de thread-uri în vederea tratării acestora în mod

unitar;

• interfaţa Runnable: lucru cu thread-uri ca entităţi separate.

1. Crearea unui thread derivând clasa Thread

Operaţiile următoare reprezintă numărul minim de paşi ce trebuie îndepliniţi pentru lucrul cu

un thread creat prin moştenirea clasei Thread:

1. crearea unei clase obişnuite care moşteneşte clasa Thread.

class MyThread extends Thread{

}

2

Page 57: Laborator JAVA IESC UNITBV

2. suprascrierea metodei public void run() a clasei Thread în clasa derivată, MyThread. Instruc-

ţiunile din această metodă trebuie să implementeze ceea ce se doreşte ca thread-ul să facă.

Aceasta poate apela alte metode, folosi alte clase şi declara variabile ca orice metodă.Metoda

run() este apelată atunci când se execută un thread.

Pentru a înţelege mai bine se face o paralelă cu metodamain. Aceasta care este apelată atunci

când se execută o aplicaţie Java. Mai mult, atunci când JVM este pornită, se porneşte o

dată cu ea un thread care apelează metoda main.

3. instanţierea unui obiect thread prin intermediul operatorului new;

MyThread obThread = new MyThread();

4. pornirea thread-ului instanţiat prin apelul metodei start() moştenită din clasa Thread.

obThread.start();

Urmăriţi un exemplu de lucru cu thread-uri prin derivarea clasei Thread în secţiunea IIA.

2. Crearea unui thread implementând interfaţa Runnable

Operaţiile care trebuie îndeplinite pentru a putea crea un thread prin implementarea interfeţei

Runnable sunt următorele:

1. crearea unei clase care să implementeze interfaţa Runnable.

class MyRunnable implements Runnable {

}

2. clasa care implementează interfaţa Runnable trebuie să suprascrie toate metodele definite

în aceasta, dar cum interfaţa conţine doar metoda run(), ea este singura metodă ce trebuie

suprascrisă. Metoda run() implementează ceea ce se doreşte ca thread-ul să facă.

3. se instanţiază un obiect al clasei create utilizând operatorul new.

MyRunnable myRunnableObj = new MyRunnable();

4. se instanţiază un obiect al clasei Thread utilizând un constructor ce are ca şi parametru un

obiect de tipul clasei care implementează interfaţa Runnable.

Thread thread = new Thread(myRunnableObj);

3

Page 58: Laborator JAVA IESC UNITBV

5. se porneşte thread-ul.

thread.start();

Pentru o mai bună înţelegere urmăriţi exemplul prezentat în secţiunea II B.

3. Clasa Thread vs interfaţa Runnable

Clasa Thread defineşte o serie de metode ce pot fi suprascrise de clasa ce derivă din Thread.

Singura care trebuie suprascrisă obligatoriu este run(). Însă, această condiţie se impune şi in cazul

clasei care implementează interfaţa Runnable. Aşadar, dacă nu se doreşte suprascrierea altor me-

tode din Thread, atunci este mai bine să folosim a doua metodă.

Mai mult, cum în Java nu este permisă moştenirea multiplă, creare unui thread prin implementa-

rea interfeţei Runnable devine un avantaj pentru că acel thread poate să moştenească funcţionalităţi

definite în alte clase Java.

C. Controlul unui fir de execuţie

Un thread se poate afla la un moment dat într-una din stările următoare: nou creat, în execuţie,

blocat, terminat.

Clasa Thread conţine o serie de metode ce controlează execuţia unui thread. Iată câteva dintre

cele mai importante:Nume metodă Descriere

String getName() se obţine numele thread-ului

int getPriority() se obţine prioritatea thread-ului

boolean isAlive() determină faptul că un thread mai este în execuţie sau nu

void join() forţează un thread să aştepte terminarea altuia

void run() entry point pentru un thread

static void sleep(long millis) suspendă execuţia unui thread pentru millis milisecunde

void start() începe execuţia unui fir printr-un apel run()

void stop() opreşte execuţia unui thread

Pentru mai multe informaţii despre metodele clasei Thread consultaţi API-ul clasei.

4

Page 59: Laborator JAVA IESC UNITBV

D. Priorităţi

Aparent thread-urile se execută simultan, dar la un moment dat doar un singur thread are

acces la resursele de sistem. Fiecare thread obţine o perioadă de timp în care are acces la resurse,

accesul făcându-se în mod organizat de către un planificator. Una dintre regulile pe care se bazează

planificatorul o reprezintă mecanismul de priorităţi.

Având în vedere cele spuse mai sus, fiecărui thread i se asociază un nivel de prioritate (un număr

întreg). Cu cât acest nivel este mai mare cu atât thread-ul va avea prioritate mai mare la resurse.

Dacă totuşi mai multe thread-uri au acelaşi nivel de prioritate, mecanismul de priorităţi dă dreptul

de execuţie fiecăruia printr-un algoritm circular.

Lucrul cu priorităţi este exemplificat în secţiunea IID.

E. Sincronizarea firelor de execuţie

Există cazuri în care mai multe thread-uri accesează aceeaşi resursă aparent în acelaşi timp.

Pentru a evita astfel de situaţii, care pot crea confuzie, limbajul Java oferă conceptul de monitor.

Acest lucru se realizează prin declararea unor metode, blocuri de cod ale unui obiect synchronized.

Modificatorul synchronized permite unui singur thread accesul, la un moment dat, la acele metode

sau blocuri de cod ale obiectului. Aşadar, dacă un thread apeleză o metodă synchronized a unui

obiect, un alt thread nu are acces la ea până când primul thread nu a terminat-o de executat.

Exemplul este prezentat în secţiunea II E.

II. PREZENTAREA LUCRĂRII DE LABORATOR

A. Crearea unui thread derivând clasa Thread

Exemplul este destul de simplu şi nu necesită explicaţii suplimentare o dată ce au fost urmăriţi

paşii din secţiunea IB 1.1 public c l a s s MyThread extends Thread{

2 private int countDown = 10 ;

3

4 public void run ( ) {

5 System . out . p r i n t l n ( " \ t ␣ begin ␣run␣method . . . " ) ;

6 while ( countDown >=0){

7 System . out . p r i n t l n ( " \ t\ t ␣ Steps ␣ l e t f t ␣ to ␣do : ␣ "+countDown) ;

5

Page 60: Laborator JAVA IESC UNITBV

8 countDown−−;

9 }

10 System . out . p r i n t l n ( " \ t ␣end␣run␣method ! " ) ;

11 }

12 }

1 public c l a s s DemoThread {

2

3 public s t a t i c void main ( St r ing [ ] a rgs ) {

4 System . out . p r i n t l n ( " begin ␣main . . . " ) ;

5 MyThread obThread = new MyThread ( ) ;

6 System . out . p r i n t l n ( " s t a r t ␣ the ␣ thread " ) ;

7 obThread . s t a r t ( ) ;

8 System . out . p r i n t l n ( " s t i l l ␣ in ␣main . . . " ) ;

9 }

10

11 }

Un singur lucru pare să fie curios: apariţia mesajului ”still in main...” imediat după mesajul

”start the thread”. Acest lucru se întâmplă din cauza faptului că metoda main are propriul său fir

de execuţie în care rulează. Prin apelul metodei start() a thread-ului se cere maşinii virtuale Java

crearea şi pornirea unui nou thread. Din acest moment JVM preia controlul execuţiei programului

creând contextul necesar unui thread şi în acest context se apelează metoda run(). Ca urmare se

iese imediat din metoda start().

B. Crearea unui thread implementând interfaţa Runnable

Exemplul prezentat mai jos este puţin mai complex în sensul că profităm de avantajele imple-

mentării unei interfeţe, putând totuşi moşteni orice altă clasă.1 public c l a s s Display {

2 public void printMessage ( St r ing message ){

3 System . out . p r i n t l n ( message ) ;

4 }

5 }

Clasa MyRunnable moşteneşte clasa Display, dar beneficiază de proprietăţile unei clase de tip

thread prin implementarea interfeţei Runnable. Unele dintre îmbunătăţirile ce sunt aduse progra-

mului sunt mutarea instanţierii thread-ului (se trimite ca parametru obiectul curent, deci un obiect

de tipul MyRunnable) şi pornirea acestuia în constructorul clasei MyRunnable.1 public c l a s s MyRunnable extends Display implements Runnable {

2 private int countDown = 10 ;

3 private Thread thread ;

4

5 public MyRunnable ( ) {

6

Page 61: Laborator JAVA IESC UNITBV

6 thread = new Thread ( this ) ;

7 System . out . p r i n t l n ( " s t a r t ␣ the ␣ thread " ) ;

8 thread . s t a r t ( ) ;

9 }

10

11 public void run ( ) {

12 printMessage ( " \ t ␣ begin ␣run␣method . . . " ) ;

13 while ( countDown >= 0) {

14 printMessage ( " \ t\ t ␣ Steps ␣ l e t f t ␣ to ␣do : ␣ " + countDown) ;

15 countDown−−;

16 }

17 printMessage ( " \ t ␣end␣run␣method ! " ) ;

18 }

19 }

Clasa DemoRunnable instanţiază un obiect de tipul MyRunnable. Astfel se apelează construc-

torul unde se creează şi se porneşte thread-ul.1 public c l a s s DemoRunnable {

2 public s t a t i c void main ( St r ing [ ] a rgs ) {

3 System . out . p r i n t l n ( " begin ␣main . . . " ) ;

4 MyRunnable myRunnableObj = new MyRunnable ( ) ;

5 System . out . p r i n t l n ( " s t i l l ␣ in ␣main . . . " ) ;

6 }

7 }

C. Controlul unui fir de execuţie

Exemplul următor prezintă modul de utilizare al metodelor clasei Thread.

Clasa MyThread moşteneşte clasa Thread şi creează un constructor cu un parametru ce apelează

constructorul clasei de bază. Metoda run() este identică cu cea din exemplele anterioare.1 public c l a s s MyThread extends Thread{

2 private int countDown = 5 ;

3

4 public MyThread( St r ing name){

5 super (name) ;

6 }

7

8 public void run ( ) {

9 System . out . p r i n t l n ( " \ t ␣ begin ␣run␣method . . . " ) ;

10 while ( countDown >=0){

11 System . out . p r i n t l n ( " \ t\ t ␣ Steps ␣ l e t f t ␣ to ␣do : ␣ "+countDown) ;

12 countDown−−;

13 }

14 System . out . p r i n t l n ( " \ t ␣end␣run␣method ! " ) ;

15 }

16 }

Clasa DemoThread creează două thread-uri. Pe primul îl porneşte şi îl suspendă pentru 4000

de milisecunde. Observaţi starea în care se află thread-ul după suspendarea temporară a acestuia

7

Page 62: Laborator JAVA IESC UNITBV

(apelul metodei isAlive()). Apoi, se porneşte thread-ul al doilea şi se blochează resursele acestuia

până când se reia execuţia lui (apelul metodei resume()). Observaţi starea thread-ului după apelul

metodei suspend().

În cele din urmă, se forţează blocarea thread-ului principal până când myThread2 işi termină

execuţia (linia de cod 29).1 public c l a s s DemoThread {

2 public s t a t i c void main ( St r ing [ ] a rgs ) throws Inter ruptedExcept ion {

3 System . out . p r i n t l n ( " begin ␣main␣ thread . . . " ) ;

4 MyThread myThread1 = new MyThread( " thread ␣1 " ) ;

5 myThread1 . s t a r t ( ) ;

6 System . out . p r i n t l n (myThread1 . getName ( ) ) ;

7 try {

8 myThread1 . s l e ep (4000) ;

9 } catch ( Inter ruptedExcept ion e ) {

10 e . pr intStackTrace ( ) ;

11 }

12 i f (myThread1 . i sA l i v e ( ) ) {

13 System . out . p r i n t l n (myThread1 . getName ( )+" ␣ i s ␣ a l i v e ! " ) ;

14 } e l s e{

15 System . out . p r i n t l n (myThread1 . getName ( )+" ␣ i s ␣ terminated ! " ) ;

16 }

17

18 MyThread myThread2 = new MyThread( " thread ␣2 " ) ;

19 System . out . p r i n t l n (myThread2 . getName ( ) ) ;

20 myThread2 . s t a r t ( ) ;

21 myThread1 . suspend ( ) ;

22 i f (myThread2 . i sA l i v e ( ) ) {

23 System . out . p r i n t l n (myThread2 . getName ( )+" ␣ i s ␣ a l i v e ! " ) ;

24 } e l s e{

25 System . out . p r i n t l n (myThread2 . getName ( )+" ␣ i s ␣ terminated ! " ) ;

26 }

27

28 System . out . p r i n t l n ( " be f o r e ␣main␣ thread ␣ s l e e p s " ) ;

29 Thread . s l e ep (2000) ;

30 System . out . p r i n t l n ( " a f t e r ␣main␣ thread ␣has␣ s l e p t " ) ;

31

32 myThread2 . s l e ep (2000) ;

33 myThread2 . resume ( ) ;

34 try {

35 myThread2 . j o i n ( ) ;

36 } catch ( Inter ruptedExcept ion e ) {

37 e . pr intStackTrace ( ) ;

38 }

39 myThread2 . s l e ep (1000) ;

40 System . out . p r i n t l n ( " end␣main␣ thread ! ! ! " ) ;

41 }

42 }

8

Page 63: Laborator JAVA IESC UNITBV

D. Priorităţi

Clasa PriorityThread implementează interfaţa Runnable şi are un constructor cu un parametru

ce setează nivelul de prioritate al thread-ului şi care instanţiază un obiect de tip thread, prezent

ca atribut al clasei. Metoda run() apelează metoda toString() a clasei Thread cât timp atributul

countDown este mai mare ca 0.1 public c l a s s Prior i tyThread implements Runnable {

2 private int countDown = 5 ;

3 private int p r i o r i t y ;

4 public Thread thread ;

5

6 public Prior i tyThread ( int p r i o r i t y ) {

7 this . p r i o r i t y = p r i o r i t y ;

8 thread = new Thread ( this ) ;

9 }

10

11 public void run ( ) {

12 thread . s e tP r i o r i t y ( p r i o r i t y ) ;

13 System . out . p r i n t l n ( " \ t ␣ begin ␣run␣method . . . " ) ;

14 while ( countDown >=0){

15 System . out . p r i n t l n ( thread . t oS t r ing ( )+" ␣countDown : ␣ "+countDown) ;

16 countDown−−;

17 }

18 System . out . p r i n t l n ( " \ t ␣end␣run␣method ! " ) ;

19 }

20 }

Clasa DemoPriority creează două obiecte de tipul PriorityThread cu parametri declaraţi ca

şi constante în clasa Thread. Se porneşte execuţia acestora şi thread-ul principal este obligat să

aştepte terminarea execuţiei celor două thread-uri anterioare înainte de a deveni inactiv.

Observaţi ordinea în care se pornesc thread-urile şi ordinea în care se execută.1 public c l a s s DemoPriority {

2 public s t a t i c void main ( St r ing [ ] a rgs ) {

3 System . out . p r i n t l n ( " begin ␣main␣ thread . . . " ) ;

4 Pr ior i tyThread threadMin = new Prior i tyThread (Thread .MIN_PRIORITY) ;

5 Pr ior i tyThread threadMax = new Prior i tyThread (Thread .MAX_PRIORITY) ;

6 threadMin . thread . s t a r t ( ) ;

7 threadMax . thread . s t a r t ( ) ;

8 try{

9 threadMax . thread . j o i n ( ) ;

10 threadMin . thread . j o i n ( ) ;

11 }catch ( Inter ruptedExcept ion e ) {

12 System . out . p r i n t l n ( " i n t e r rupt ed ␣ except ion " ) ;

13 }

14 System . out . p r i n t l n ( " end␣main␣ thread ! ! ! " ) ;

15 }

16 }

9

Page 64: Laborator JAVA IESC UNITBV

E. Sincronizarea firelor de execuţie

Clasa MySynchronized are un constructor cu doi parametri. Unul este de tip String şi reprezintă

numele thread-ului, iar cel de-al doilea este un număr întreg. Constructorul este cel care instanţiază

thread-ul şi tot el este cel care îl porneşte.

Observaţi cele două metode care folosesc modificatorul synchronized. Prima metodă îl foloseşte

ca modificator al funcţiei, iar ce-a de-a doua metodă, cea între comentarii, îl foloseşte ca şi bloc.

Important de reţinut este că în varianta bloc synchronized se aplică doar pe obiecte.1 public c l a s s MySynchronized implements Runnable{

2 private int count ;

3 private Thread thread ;

4

5 public MySynchronized ( St r ing name , int count ){

6 this . count = count ;

7 thread = new Thread ( this , name) ;

8 thread . s t a r t ( ) ;

9 }

10

11 public synchronized int add ( ) {

12 count++;

13 try{

14 Thread . s l e ep (1000) ;

15 }catch ( Inter ruptedExcept ion e ) {

16 System . out . p r i n t l n ( "main␣ thread ␣ in t e r rupt ed " ) ;

17 }

18 ++count ;

19 return count ;

20 }

21

22 /∗ pub l i c i n t add ( ) {

23 synchronized ( thread ) {

24 count++;

25 try {

26 Thread . s l e ep (1000) ;

27 } catch ( Inter ruptedExcept ion e ) {

28 System . out . p r i n t l n ( " main thread in t e r rupt ed " ) ;

29 }

30 ++count ;

31 return count ;

32 }

33 }∗/

34

35 public void run ( ) {

36 System . out . p r i n t l n ( thread . getName ( ) + " ␣ s t a r t i n g . " ) ;

37 System . out . p r i n t l n ( " \ t ␣ the ␣numer␣ o f ␣ "+thread . getName ( )+" ␣ i s : ␣ "+add ( ) ) ;

38 System . out . p r i n t l n ( thread . getName ( ) + " ␣ terminat ing . " ) ;

39 }

40 }

Clasa DemoSynchronized creează două obiecte de tipul MySynchronized.1 public c l a s s DemoSynchronized {

10

Page 65: Laborator JAVA IESC UNITBV

2 public s t a t i c void main ( St r ing [ ] a rgs ) {

3 System . out . p r i n t l n ( " begin ␣main␣ thread . . . " ) ;

4 MySynchronized thread1 = new MySynchronized ( " thread1 " ,1) ;

5 MySynchronized thread2MySyncronized = new MySynchronized ( " thread2 " ,2) ;

6 System . out . p r i n t l n ( " begin ␣main␣ thread . . . " ) ;

7 }

8 }

III. TEMĂ

1. Realizaţi un program care creează cel puţin două fire de execuţie ce calculează produsul

elementelor aceluiaşi vector. Elementele vectorului se vor citi din fişierul in.txt, iar rezultatul

se va afişa într-un alt fişier, out.txt. Cerinţe de implementare:

• pentru calculul produsului folosiţi synchronized (ori modificatorul de acces ori ca bloc);

• pentru implementarea thread-urilor puteţi folosi oricare dintre cele două metode pre-

zentate în laborator;

• atât pentru lucrul cu fişiere cât şi pentru lucrul cu thread-uri se vor folosi mecanisme

de tratare a excepţiilor.

11

Page 66: Laborator JAVA IESC UNITBV

Laborator Nr. 10:

Interfete grafice ın Java

Intocmit de: Dobrinas Alexandra

Indrumator: Asist. Drd. Danciu Gabriel

November 30, 2011

Page 67: Laborator JAVA IESC UNITBV

I. NOTIUNI TEORETICE

Interfata grafica, - GUI, este un termen cu ınteles larg care se refera la toate tipurile de comunicare dintreun program si utilizatorii sai. Aceasta este o particularizare a interfetei cu utilizatorul - UI, prin care seıntelege interactiune dintre un program si utilizatorii sai. Asadar, UI se refera nu numai la ceea ce utilizatorulvede pe ecran ci si la toate mecanismele de comunicare ıntre acesta si program.

Limbajul Java pune la dispozitie numeroase clase pentru implementarea diverselor functionalitati UI, ınsaın continuare sunt prezentate acelea care permit realizarea unei intefete grafice cu utilizatorul (GUI).

Biblioteca de clase care ofera servicii grafice se numeste java.awt, AWT fiind prescurtarea de la Abstract

Window Toolkit. In principiu, crearea unei aplicatii grafice presupune urmatoarele:

• Crearea unei suprafete de afisare (cum ar fi o fereastra) pe care vor fi asezate obiectele grafice careservesc la comunicarea cu utilizatorul (butoane, controale de editare, texte, etc);

• Crearea si asezarea obiectelor grafice pe suprafata de afisare ın poziıiile corespunzatoare;

• Definirea unor actiuni care trebuie sa se execute ın momentul cand utilizatorul interactioneaza cuobiectele grafice ale aplicatiei;

• ,,Ascultarea” evenimentelor generate de obiecte ın momentul interactiunii cu utilizatorul si executareaactiunilor corespunzatoare asa cum au fost ele definite.

Printr-o componenta grafica se ıntelege un obiect care are o reprezentare grafica ce poate fi afisata peecran si care poate interactiona cu utilizatorul. Exemple de componente sunt ferestrele, butoanele, bare dedefilare, etc. In general, toate componentele sunt definte de clase proprii ce se gasesc ın pachetul java.awt.Vezi API aici.

Crearea obiectelor grafice nu realizeaza automat si afisarea lor pe ecran. Mai ıntai ele trebuie aaezate peo suprafata de afisare, care poate fi o fereastra sau suprafata unui applet, si vor deveni vizibile ın momentulın care suprafata pe care sunt afisate va fi vizibila.

In general, toate componentele sunt definte de clase proprii ce se gasesc ın pachetul java.awt, clasaComponent este o superclasa abstracta a tuturor acestor clase. Ierarhia acestor clase este sumarizata ındiagrama de mai jos.

Din cauza modului de imlementare a meniurilor pe diferite sisteme de operare, acestea nu au putut fiintegrate ca obiecte de tip Component. Superclasa cu ajutorul careia se pot crea meniuri este MenuComponent,iar subclasele sale sunt:

2

Page 68: Laborator JAVA IESC UNITBV

A. Suprafete de afisare

Suprafata pe care se aseaza obiectele grafice se numeste suprafata de afisare sau container si reprezintao instanta a unei clase obtinuta prin extensia superclasei Container. O parte din ierarhia a carei radacinaeste Container este prezentata ın figura de mai jos:

Componentele adaugate sunt memorate ıntr-o lista, iar pozitiile lor din aceasta lista vor defini ordineade transpunere a acestora ın cadrul containerului. Daca nu este specificat niciun index la adaugarea uneicomponente, atunci ea va fi adaugata pe ultima pozitie a listei.

1. Adaugarea unei componente

Clasa Container pune la dispozitie metoda add pentru adaugarea unei componente pe o suprafata deafisare. O componenta nu poate apartine decat unui singur container, ceea ce ınseamna ca pentru a mutaun obiect dintr-un container ın altul trebuie sa-l eliminam mai ıntai de pe containerul initial. Eliminareaunei componente de pe un container se face cu metoda remove.

Exemplu de butoane adaugate ıntr-un container:

1 import java . awt . ∗ ;2 public c lass Test1 {3 public stat ic void main ( St r ing args [ ] ) {45 // c r e e z conta iner−ul − ob i e c t de t i p frame6 Frame f = new Frame( ”O f e r e a s t r a ” ) ;78 // s e t e z modul de dipunere a ob . pe supra fa ta f e r e s t r e i9 f . setLayout (new FlowLayout ( ) ) ;

1011 // c r e e z c e l e doua butoane12 Button b1 = new Button ( ”OK” ) ;13 Button b2 = new Button ( ”Cancel ” ) ;1415 //adaug primul buton pe supra fa ta f e r e s t r e i16 f . add (b1 ) ;17 f . pack ( ) ;1819 //adaug a l d o i l e buton pe supra fa ta f e r e s t r e i20 f . add (b2 ) ;21 f . pack ( ) ;2223 // a f i s e z f e r e a s t r a ( o fac v i z i b i l a )24 f . show ( ) ;25 }26 }

3

Page 69: Laborator JAVA IESC UNITBV

2. Gestionarea pozitionarii componentelor ıntr-un container

Un gestionar de pozisionare layout manager este un obiect care controleaza dimensiunea si aranjarea(pozitia) componentelor unui container. Asadar, modul de aranjare a componentelor pe o suprafata de afisarenu este o caracteristica a clasei Container. Fiecare obiect de tip Container, sau o extensie a lui (Applet,Frame, Panel) are asociat un obiect care se ocupa cu dispunerea componentelor pe suprafata sa. Toateclasele care instantiaza obiecte pentru gestionarea pozitionarii implementeaza interfata LayoutManager. Lainstantierea unui container se creeaza implicit un gestionar de pozitionare asociat acestuia. De exemplu,pentru o fereastra (un obiect de tip Window sau o subclasa a sa) gestionarul implict este de tip BorderLayout,ın timp ce pentru un container de tip Panel este o instanta a clasei FlowLayout.

Cei mai utilizati gestionari din pachetul java.awt sunt:

• FlowLayout

• BorderLayout

• GridLayout

• CardLayout

• GridBagLayout

Detalii despre modul de utilizare a gestionarilor de pozitionare se gasesc aici.

B. Gruparea componentelor (Clasa Panel)

Plasarea componentelor direct pe suprafata de afisare poate deveni incomoda ın cazul ın care avem multeobiecte grafice. Din acest motiv se recomanda gruparea obiectelor grafice ınrudite ca functii astfel ıncat saputem fi siguri ca, indiferent de gestionarul de pozitionare al suprafetei de afisare, ele se vor gasi ımpreuna.Gruparea componentelor se face folosind panel-uri.

Un panel este cel mai simplu model de container. El nu are o reprezentare vizibila, rolul sau fiind de a oferio suprafata de afisare pentru componente grafice, inclusiv pentru alte panel-uri. Clasa care instantiaza acesteobiecte este Panel, extensie a superclasei Container. Pentru a aranja corespunzator componentele grupateıntr-un panel, acestuia i se poate specifica un gestionar de pozitionare anume, folosind metoda setLayout.Gestionarul implicit pentru containerele de tip Panel este FlowLayout.

Asadar, o aranjare eficienta a componentelor unei ferestre ınseamna:

• gruparea componentelor ,,ınfratite” (care nu trebuie sa fie despartie de gestionarul de pozitionare alferestrei) ın panel-uri;

• aranjarea componentelor unui panel, prin specificarea acestuia a unui gestionar de pozitionare core-spunzator;

• aranjarea panel-urilor pe suprafata ferestrei, prin specificarea gestionarului de pozitionare al ferestrei.

Exemplu

1 import java . awt . ∗ ;2 public c lass Test2 {3 public stat ic void main ( St r ing args [ ] ) {4 Frame f = new Frame( ”Panel ” ) ;56 Panel panel = new Panel ( ) ;7 panel . setLayout (new FlowLayout ( ) ) ;8 panel . add (new Label ( ”Text : ” ) ) ;9 panel . add (new TextField ( ”” , 20) ) ;

10 panel . add (new Button ( ”Reset ” ) ) ;1112 f . add ( panel , BorderLayout .NORTH) ;13 f . add (new Button ( ”OK” ) , BorderLayout .EAST) ;14 f . add (new Button ( ”Cancel ” ) , BorderLayout .WEST) ;15 f . pack ( ) ;1617 f . show ( ) ;18 }19 }

4

Page 70: Laborator JAVA IESC UNITBV

C. Componente grafice

Unele dintre cele mai utilizate componente grafice sunt: etichetele, butoanele, campurile de text, listelederulante, etc. O lista completa a claselor cu ajutorul carora se definesc componentele grafice, precum siproprietatile lor se gaseste aici.

1. Clasa Label

Un obiect de tip Label (eticheta) reprezinta o componenta pentru plasarea unui text pe o suprafata deafiaare. O eticheta este formata dintr-o singura linie de text static ce nu poate fi modificat de catre utilizator,dar poate fi modificat din program. Exemplu: Cinci etichete si adaugate ıntr-un container.

1 import java . awt . ∗ ;23 public c lass TestLabel {4 public stat ic void main ( St r ing args [ ] ) {5 Frame f = new Frame( ”TestLabel ” ) ;6 f . setLayout (new BorderLayout ( ) ) ;78 Label nord , sud , est , vest , centru ;9 nord = new Label ( ”Nord” , Label .CENTER) ;

10 sud = new Label ( ”Sud” , Label .CENTER) ;11 e s t = new Label ( ”Est” , Label .RIGHT) ;12 vest = new Label ( ”Vest” , Label .LEFT) ;13 centru = new Label ( ”Centru” , Label .CENTER) ;14 centru . setBackground ( Color . ye l low ) ;15 centru . setFont (new Font ( ” Ar ia l ” , Font .BOLD, 14) ) ;1617 f . add ( nord , BorderLayout .NORTH) ;18 f . add ( sud , BorderLayout .SOUTH) ;19 f . add ( est , BorderLayout .EAST) ;20 f . add ( vest , BorderLayout .WEST) ;21 f . add ( centru , BorderLayout .CENTER) ;22 f . pack ( ) ;2324 f . show ( ) ;25 }26 }

2. Clasa Button

Un obiect de tip Button se foloseste pentru plasarea unui buton etichetat pe o suprafata de afisare.Exemplu: Doua butoane adaugate pe o fereastra;

1 import java . awt . ∗ ;23 public c lass TestButton {4 public stat ic void main ( St r ing args [ ] ) {5 Frame f = new Frame( ”Button” ) ;6 f . setLayout (new FlowLayout ( ) ) ;7 f . s e t S i z e (200 , 200) ;89 Button b1 = new Button ( ”OK” ) ;

10 b1 . setBounds (30 , 30 , 50 , 70) ;11 b1 . setFont (new Font ( ” Ar ia l ” , Font .BOLD, 14) ) ;12 b1 . setBackground ( java . awt . Color . orange ) ;13 f . add (b1 ) ;1415 Button b2 = new Button ( ”Cancel ” ) ;16 b2 . setBounds (100 , 30 , 70 , 50) ;17 b2 . setForeground ( java . awt . Color . blue ) ;18 f . add (b2 ) ;19 f . pack ( ) ;20 f . show ( ) ;2122 }23 }

3. Clasa Checkbox

Un obiect de tip Checkbox reprezinta o componenta care are doua stari : selectata sau neselectata. Estefolosit pentru a prelua anumite optiuni de la utilizator.

5

Page 71: Laborator JAVA IESC UNITBV

1 import java . awt . ∗ ;23 public c lass TestCheckBox {4 public stat ic void main ( St r ing args [ ] ) {5 Frame f = new Frame( ”CheckBox” ) ;6 f . setLayout (new GridLayout (5 , 1) ) ;7 f . s e t S i z e (200 , 200) ;89 Label l ab e l 1 = new Label ( ” Ing r ed i en t e Pizza : ” , Label .CENTER) ;

10 l ab e l 1 . setBackground ( Color . orange ) ;11 Label l ab e l 2 = new Label ( ”” ) ;12 l ab e l 2 . setBackground ( Color . l ightGray ) ;1314 Checkbox cbx1 = new Checkbox ( ” cascava l ” ) ;15 Checkbox cbx2 = new Checkbox ( ” sunca” ) ;16 Checkbox cbx3 = new Checkbox ( ” a rde i ” ) ;1718 f . add ( l ab e l 1 ) ;19 f . add ( l ab e l 2 ) ;20 f . add ( cbx1 ) ;21 f . add ( cbx2 ) ;22 f . add ( cbx3 ) ;2324 f . pack ( ) ;25 f . show ( ) ;2627 }28 }

4. Clasa Choice

Un obiect de tip Choice defineste o lista de optiuni din care utilizatorul poate selecta una singura. La unmoment dat, din ıntreaga lista doar o singura optiune este vizibila, cea selectata ın momentul curent.

1 import java . awt . ∗ ;23 public c lass Choice {4 public stat ic void main ( St r ing args [ ] ) {5 Frame f = new Frame( ”Choice ” ) ;6 f . setLayout (new GridLayout (4 , 1) ) ;7 f . s e t S i z e (200 , 200) ;89 Label label = new Label ( ” A l ege t i cu loarea ” ) ;

10 label . setBackground ( Color . red ) ;1112 Choice c u l o r i = new Choice ( ) ;13 c u l o r i . add ( ”Rosu” ) ;14 c u l o r i . add ( ”Verde” ) ;15 c u l o r i . add ( ”Albastru ” ) ;16 c u l o r i . s e l e c t ( ”Rosu” ) ;1718 f . add ( label ) ;19 f . add ( c u l o r i ) ;2021 f . pack ( ) ;22 f . show ( ) ;2324 }25 }

5. Clasa TextField

Un obiect de tip TextField defineste un control de editare a textului pe o singura linie. Este util pentruinterogarea utilizatorului asupra unor valori.

1 import java . awt . ∗ ;23 public c lass TestText {4 public stat ic void main ( St r ing args [ ] ) {5 Frame f = new Frame( ”Text” ) ;6 f . setLayout (new GridLayout (3 , 1) ) ;7 f . s e t S i z e (200 , 200) ;8 f . setBackground ( Color . l ightGray ) ;9

10 TextFie ld nume = new TextField ( ”” , 30) ;11 TextFie ld paro la = new TextField ( ”” , 10) ;12 paro la . setEchoChar ( ’∗ ’ ) ;1314 Panel p1 = new Panel ( ) ;15 p1 . setLayout (new FlowLayout ( FlowLayout .LEFT) ) ;16 p1 . add (new Label ( ”Nume: ” ) ) ;17 p1 . add (nume) ;1819 Panel p2 = new Panel ( ) ;20 p2 . setLayout (new FlowLayout ( FlowLayout .LEFT) ) ;

6

Page 72: Laborator JAVA IESC UNITBV

21 p2 . add (new Label ( ”Parola : ” ) ) ;22 p2 . add ( paro la ) ;2324 Label acces = new Label ( ” In t r oduc e t i numele s i paro la ! ” , Label .CENTER) ;25 f . add (p1 ) ;26 f . add (p2 ) ;27 f . add ( acces ) ;2829 f . pack ( ) ;30 f . show ( ) ;3132 }33 }

II. TEMA

1. Compilati si rulati aplicatile prezentate. Modificati programele astfel ıncat sa se puna ın evidenta toatetipurile de ,,aranjare” a componentele pe container.

2. Realizati un program, pe o anumita tema, ın care sa utilizati cat mai multe diintre componentele cepot fi adaugate pe un container. Folositi cel putin o componenta care nu a fost prezentata ın acestlaborator(vedeti API-ul.)

3. Realizati o interfata pentru un calculator. Vezi calculatorul din Windows. Container-ul va trebui sacontina butoanele pentru cifre, butoanele pentru operatii aritmetice, ,,fereastra” pentru afisare, precumsi alte butoane necesare efectuarii calculelor aritmetice..

7

Page 73: Laborator JAVA IESC UNITBV

Laborator 11:

Evenimente generate de componente AWT

Întocmit de: Adina Neculai

Îndrumător: Asist. Drd. Gabriel Danciu

4 decembrie 2011

Page 74: Laborator JAVA IESC UNITBV

I. NOŢIUNI TEORETICE

Unei componente grafice îi este asociată:

• o formă (ceea ce este afişat pe ecran);

• o serie de evenimente la care poate răspunde (mişcări de mouse, apăsare de taste);

• un model obiectual de responsabil cu prelucrarea evenimentului (ceea ce face componenta

propriu-zis).

A. Ce este un eveniment?

La acţiunea utilizatorului asupra unei componente grafice, JVM generează aşa numitele eve-

nimente. Evenimentul este de fapt o instanţă a unei clase Java, instanţă care conţine o serie de

informaţii despre acţiune.

B. Modelul de evenimente

Modelul de lucru cu evenimente prezentat în această documentaţie (modelul jdk1.1) conţine

o sursă, care poate genera un eveniment, şi unul sau mai mulţi delegaţi. Sursa poate fi oricare

dintre componentele grafice. Delegaţii, numiţi şi handleri, sunt cei responsabili de răspunsul la

eveniment (cei care prelucrează informaţia provenită de la eveniment). Mai mult, ei sunt definiţi

de programator şi datorită acestui model de implementare a evenimentelor, pot fi orice ce clasă ce

implementează o interfaţă corespunzătoare evenimentului respectiv. Pe lângă implementarea clasei

delegat, programatorul este responsabil de asocierea acesteia cu sursa de evenimente. Această

asociere se poate face printr-o metodă a sursei (a componentei grafice), metodă dependentă de

tipul delegatului ce trebuie conectat.

2

Page 75: Laborator JAVA IESC UNITBV

Figura 1: Modelul de evenimente jdk1.1

C. Tipuri de evenimente

Diferite surse (componente grafice) pot genera diferite tipuri de evenimente.

• ActionEvent: indică dacă a avut loc o acţiune definită de o componentă;

• ComponentEvent: clasa rădăcină a evenimentelor; indică dacă o componentă şi-a modificat

dimensiunea, vizibilitatea sau dacă a fost mutată;

• ContainerEvent: specifică dacă s-a modificat conţinutul unui container în urma adăugării

sau eliminării unei componente;

• KeyEvent: precizează dacă s-a apăsat sau nu o tastă;

• MouseEvent: precizează dacă a avut loc o acţiune de genul apasarea unei taste a mouse-ului,

şamd.;

• MouseMotionEvent: precizează dacă a avut loc o acţiune de genul mişcare de mouse;

• WindowEvent: eveniment generat în momentul în care s-a deschis/inchis, activat/dezactivat

o fereastră.

3

Page 76: Laborator JAVA IESC UNITBV

Pentru a răspunde unui eveniment este necesară crearea unuia sau mai multor handlere de

eveniment (delegaţi) şi asocierea lor cu componenta corespunzătoare. Pentru crearea unui handler

e nevoie de implementarea unei anumite interfeţe (în funcţie de tipul evenimentului) într-o anumită

clasă. Asocierea handler - componentă se face prin intermediul unor metode ale clasei Component,

în funcţie de tipul evenimentului.

Componentă grafică Interfaţă Metode de asociere handler - componentă

Component ComponentListener addComponentListener(ComponentListener l)

KeyListener addKeyListener(KeyListener l)

MouseListener addMouseListener(MouseListener l)

MouseMotionListener addMouseMotionListener(MouseMotionListener l)

Button ActionListener addActionListener(ActionListener l)

CheckBox ItemListener addItemListener(ItemListener l)

Choice

List ActionListener addActionListener(ActionListener l)

ItemListener addItemListener(ItemListener l)

ComponentListener cele de la clasa Component

TextField ActionListener addActionListener(ActionListener l)

TextListener addTextListener(TextListener l)

ComponentListener cele de la clasa Component

Window ComponentListener cele de la clasa Component

Frame ContainerListener addContainerListener(ContainerListener l)

Dialog WindowListener addWindowListener(WindowListener l)

FileDialog

MenuItem ActionListener addActionListener(ActionListener l)

Menu

PopupMenu

4

Page 77: Laborator JAVA IESC UNITBV

Interfaţă Metode ce trebuie implementate

ActionListener actionPerformed(ActionEvent e)

ComponentListener componentResized(ComponentEvent e)

componentMoved(ComponentEvent e)

componentShown(ComponentEvent e)

componentHidden(ComponentEvent e)

MouseListener mouseClicked(MouseEvent e)

mousePressed(MouseEvent e)

mouseReleased(MouseEvent e)

mouseEntered(MouseEvent e)

mouseExited(MouseEvent e)

MouseMotionListener mouseDragged(MouseMotionEvent e)

mouseMoved(MouseMotionEvent e)

KeyListener keyTyped(KeyEvent e)

keyPressed(KeyEvent e)

keyReleased(KeyEvent e)

WindowListener windowOpened(WindowEvent e)

windowClosed(WindowEvent e)

windowActivated(WindowEvent e)

etc.

D. Componenta FileDialog

Clasa FileDialog este o clasă derivată din clasa Dialog, iar aceasta din urmă derivată din clasa

Window. FileDialog este aşadar o fereastră, fereastră utilizată pentru selecţia unui fişier. Aceasta

afişează un arbore ce reprezintă structura ierarhică a directoarelor şi fişierelor şi permite utilizato-

rului căutarea în această structură şi selecţia unui fişier.

Există două tipuri de ferestre FileDialog: fereastră de tipul load şi una de tipul save. Primul

tip permite doar selecţia unui fişier existent, pe când al doilea tip oferă şi posibilitatea creării unui

fişier nou. O dată un fişier selectat, fereastra se închide automat.

5

Page 78: Laborator JAVA IESC UNITBV

Pentru a şti mai multe despre această clasă se recomandă citirea API-ului.

E. Componente AWT de lucru cu meniuri

Clasa MenuBar este utilizată pentru a crea o bară de meniuri. Această bară de meniuri poate

fi asociată doar unei ferestre grafice de tipul Frame utilizând metoda setMenuBar(MeniuBar mb)

a clasei Frame. O bară de meniuri este utilizată ca şi cadru în care se adaugă componente de tip

Menu. API-ul clasei se află aici.

Clasa MenuItem reprezintă clasa ce implementeză un meniu. La selecţia unui meniu acesta

generează un eveniment de tipul ActionEvent care poate fi preluat de un handler de tipul Action-

Listener. API-ul clasei se află aici.

Clasa Menu este derivată din MenuItem şi este componenta ce oferă posibilitatea creării unei

structuri verticale de meniuri. În plus faţă de clasa MenuItem, clasa Menu poate crea o componentă

cadru în care se pot adăug alte meniuri (componente de tip MenuItem). API-ul clasei se află aici.

Clasa MenuShortcut nu reprezintă o componentă grafică, dar este corelată lucrului cu me-

niuri. Aceasta este utilizată pentru a asocia unei componente de tip MenuItem o combinaţie de

taste. API-ul clasei se află aici.

II. PREZENTAREA LUCRĂRII DE LABORATOR

A. Evenimentul ActionEvent

Componenta Button creează imaginea unui buton asupra căruia se poate acţiona prin apăsare

(cu ajutorul mouse-ului sau a tastaturii). La ”apăsarea” acestui tip de componentă se va genera un

eveniment de tipul ActionEvent care poate fi tratat de programator printr-un handler înregistrat

la această componentă. Handler-ul în acest caz este reprezentat de clasa MyButtonListener.

După instanţierea unui obiect de acest tip, programatorul trebuie să asocieze respectivul obiect

instanţiat cu componenta Button (addActionListener()). Observaţi că înaintea acestui pas, com-

ponentei Button i s-a setat un şir care va fi înscris în obiectul eveniment de tip ActionEvent ce se

generează când se apasă butonul. Acest lucru a fost realizat prin apelarea metodei setActionCom-

mand().1 import java . awt . ∗ ;

6

Page 79: Laborator JAVA IESC UNITBV

2 import java . awt . event . Act ionL i s t ene r ;

3

4 public c l a s s TestButton {

5

6 public s t a t i c void main ( St r ing [ ] a rgs ) {

7 Frame f = new Frame( " Fereas t ra ␣Buton " ) ;

8 f . setLayout (new FlowLayout ( ) ) ;

9

10 Button b = new Button ( " Bonjour " ) ;

11 f . add (b) ;

12 b . setActionCommand ( " Bonjour " ) ;

13

14 Act ionL i s t ener a c t i onL i s t en e r = new MyButtonListener ( ) ;

15 b . addAct ionListener ( a c t i onL i s t en e r ) ;

16

17 b = new Button ( "Good␣Day" ) ;

18 f . add (b) ;

19 b . addAct ionListener ( a c t i onL i s t en e r ) ;

20

21 b = new Button ( " Aurevoir " ) ;

22 f . add (b) ;

23 b . setActionCommand ( " Exit " ) ;

24 b . addAct ionListener ( a c t i onL i s t en e r ) ;

25

26 f . pack ( ) ;

27 f . s e tV i s i b l e ( true ) ;

28 }

29 }

Pentru crearea handler-ului sau delegatului acestui eveniment, programatorul trebuie să imple-

menteze interfaţa ActionListener într-o clasă (MyButtonListener). Metoda ce trebuie suprascrisă

în acest caz este actionPerformed(). De asemenea, observaţi folosirea metodei getActionCommand

care returnează informaţia setată în clasa TestButton.1 import java . awt . event . ∗ ;

2

3 public c l a s s MyButtonListener implements Act ionL i s t ene r {

4 public void act ionPerformed ( ActionEvent ae ) {

5 St r ing s = ae . getActionCommand ( ) ;

6 i f ( s . equa l s ( " Exit " ) ) {

7 System . e x i t (0 ) ;

8 } e l s e i f ( s . equa l s ( " Bonjour " ) ) {

9 System . out . p r i n t l n ( "Good␣Morning " ) ;

10 } e l s e {

11 System . out . p r i n t l n ( s + " ␣ c l i c k ed " ) ;

12 }

13 }

14 }

7

Page 80: Laborator JAVA IESC UNITBV

B. Evenimentul KeyEvent

Clasa următoare creeză o etichetă şi o componentă de tip text pe care le adaugă într-o fereastră.

La apasarea oricărei taste se declansează un eveniment de tipul KeyEvent. Evenimentul este

tratat de către handler-ul MyKeyListener şi a fost asociat componentei de tip text prin intermediul

metodei addKeyListener().1 import java . awt . ∗ ;

2 import java . awt . event . KeyListener ;

3

4 public c l a s s TestKey {

5

6 public s t a t i c void main ( St r ing [ ] a rgs ) {

7 Frame f = new Frame( " Fereas t ra ␣keyEvent " ) ;

8

9 Label label = new Label ( " S c r i e : ␣ " ) ;

10 TextFie ld tx tF i e l d = new TextFie ld (20) ;

11 KeyListener keyL i s t ene r = new MyKeyListener ( ) ;

12 tx tF i e l d . addKeyListener ( keyL i s t ene r ) ;

13

14 f . add ( txtF ie ld , BorderLayout .CENTER) ;

15 f . add ( label , BorderLayout .NORTH) ;

16

17 f . pack ( ) ;

18 f . s e tV i s i b l e ( true ) ;

19 }

20 }

Întrucât handler-ul implementează interfaţa KeyListener trebuie să-i suprascrie toate metodele.

S-a scris cod doar pentru metoda keyPressed() care se va apela doar în momentul apăsării unei

taste.1 import java . awt . event . ∗ ;

2

3 public c l a s s MyKeyListener implements KeyListener {

4

5 @Override

6 public void keyPressed (KeyEvent keyEvent ) {

7 char i = keyEvent . getKeyChar ( ) ;

8 St r ing s t r = Character . t oS t r ing ( i ) ;

9 System . out . p r i n t l n ( "Key␣ pres sed : ␣ "+ s t r ) ;

10

11 }

12

13 @Override

14 public void keyReleased (KeyEvent arg0 ) {}

15 @Override

16 public void keyTyped (KeyEvent arg0 ) {}

17 }

8

Page 81: Laborator JAVA IESC UNITBV

C. Evenimentul MouseEvent

Exemplul de mai jos crează două etichete şi un buton. La apăsarea butonului se va afişa în

consolă suma numerelor conţinute de etichete.1 import java . awt . ∗ ;

2 import java . awt . event . ∗ ;

3

4 public c l a s s TestMouseClick {

5 public s t a t i c void main ( St r ing [ ] a rgs ) {

6 Frame f = new Frame( " Fereas t ra ␣mouse␣ c l i c k " ) ;

7

8 Label labelY = new Label ( " 2 " ) ;

9 f . add ( labelY , BorderLayout .NORTH) ;

10 Label labelX = new Label ( " 1 " ) ;

11 f . add ( labelX , BorderLayout .CENTER) ;

12

13 Button button = new Button ( " Cl i ck ␣Me" ) ;

14 MouseListener mouseListener = new MyMouseListener ( labelX , labelY ) ;

15 button . addMouseListener ( mouseListener ) ;

16 f . add ( button , BorderLayout .SOUTH) ;

17

18 f . pack ( ) ;

19 f . s e tV i s i b l e ( true ) ;

20 }

21 }

Clasa handler se numeşte MyMouseListener şi suprascrie toate metodele interfeţei MouseListe-

ner, dar scrie cod efectiv doar pentru metoda care se declanşează în momentul apăsării unei taste

a mouse-ului. Această metodă preia informaţiile conţinute de etichetele transmise ca parametru la

instanţierea handler-ului şi afişează în consolă.1 import java . awt . Label ;

2 import java . awt . event . ∗ ;

3

4 public c l a s s MyMouseListener implements MouseListener {

5 Label labelX , labe lY ;

6

7 public MyMouseListener ( Label x , Label y ){

8 this . labe lX = x ;

9 this . labe lY = y ;

10 }

11

12 @Override

13 public void mouseClicked (MouseEvent mouseEvent ) {

14 int x = Int ege r . pa r s e In t ( labelX . getText ( ) ) ;

15 int y = Int ege r . pa r s e In t ( labelY . getText ( ) ) ;

16 System . out . p r i n t l n (x+" ␣+␣ "+y+" ␣=␣ "+(x+y) ) ;

17 }

18

19 @Override

20 public void mouseEntered (MouseEvent arg0 ) {}

21 @Override

22 public void mouseExited (MouseEvent arg0 ) {}

9

Page 82: Laborator JAVA IESC UNITBV

23 @Override

24 public void mousePressed (MouseEvent arg0 ) {}

25 @Override

26 public void mouseReleased (MouseEvent arg0 ) {}

27 }

D. Componenta FileDialog

La pornirea aplicaţiei se va deschide o fereastră FileDialog de tipul load cu numele ”Choose a

file”. Structura de directoare din care se porneşte este ”D:\”.1 import java . awt . ∗ ;

2

3 public c l a s s TestF i l eD ia log {

4 public s t a t i c void main ( St r ing [ ] a rgs ) {

5 Frame frame = new Frame( " Test ␣ f i l eD i a l o g " ) ;

6 F i l eD ia l og f i l eD i a l o g = new Fi l eD ia l og ( frame , " Choose␣a␣ f i l e " , F i l eD ia l og .LOAD) ;

7 f i l eD i a l o g . s e tD i r e c t o ry ( "D:\\ " ) ;

8 frame . addWindowListener (new MyFi leDia logLis tener ( f i l eD i a l o g ) ) ;

9 frame . s e tV i s i b l e ( true ) ;

10 }

11 }

În urma implementării interfeţei WindowListener trebuie suprascrise o sumedenie de metode

(vezi al doilea tabel din sectiunea IC). Cum exemplul are scris cod doar pentru metoda windowO-

pened() care se va apela în momentul în care se deschide fereastra, dorim să nu mai suprascriem

toate celelalte metode asa cum au fost definite in exemplele anterioare. Astfel că se moşteneşte

clasa WindowAdapter. Clase de tipul Adapter există pentru fiecare eveniment în parte.1 import java . awt . F i l eD ia l og ;

2 import java . awt . event . ∗ ;

3 /∗am f o l o s i t c l a s a WindowAdapter pentru a sup r a s c r i e doar anumite metode s i nu toate cum am f i f o s t

4 o b l i g a t i daca implementam i n t e r f a t a WindowListener∗/

5 public c l a s s MyFi leDia logLis tener extends WindowAdapter {

6 F i l eD ia l og f i l eD i a l o g ;

7

8 public MyFi leDia logLis tener ( F i l eD ia l og f i l eD i a l o g ) {

9 this . f i l eD i a l o g = f i l eD i a l o g ;

10 }

11

12 @Override

13 public void windowOpened (WindowEvent e ) {

14 f i l eD i a l o g . s e tV i s i b l e ( true ) ;

15 St r ing f i leName = f i l eD i a l o g . g e tF i l e ( ) ;

16 i f ( f i leName == null )

17 System . out . p r i n t l n ( "You␣ canc e l l e d ␣ the ␣ cho i c e " ) ;

18 e l s e

19 System . out . p r i n t l n ( "You␣ chose ␣ " + fi leName ) ;

20 }

21 }

10

Page 83: Laborator JAVA IESC UNITBV

E. Componente AWT de lucru cu meniuri

Clasa de mai jos realizează o bara de meniuri care conţine elementele următoare: File cu sub-

meniul format din: Open, Exit şi Edit cu submeniul format din Undo. Atât Exit cât şi Undo au şi

un shortcut creat cu clasa MenuShortcut. Explicaţiile suplimentare le aveţi trecute în comentariu.1 import java . awt . ∗ ;

2 import java . awt . event . ∗ ;

3

4 public c l a s s TestMenu {

5 public s t a t i c void main ( St r ing [ ] a rgs ) {

6 Frame frame = new Frame( "Meniu " ) ;

7 // se s e t eaza dimendiunea f e r e s t r e i

8 frame . s e t S i z e (100 , 100) ;

9

10 //s−a c r ea t s i s−a adaugat o bara de meniuri in f e r e a s t r a

11 MenuBar myMenuBar = new MenuBar ( ) ;

12 frame . setMenuBar (myMenuBar) ;

13

14 // se c reeaza componente Menu care se adauga in bara de meniuri

15 Menu myFileMenu = new Menu( " F i l e " ) ;

16 Menu myEditMenu = new Menu( " Edit " ) ;

17 myMenuBar . add (myFileMenu ) ;

18 myMenuBar . add (myEditMenu) ;

19

20 // se c reeaza ob i e c t e de t i p u l MenuItem

21 MenuItem myFileOpenMenuItem = new MenuItem( "Open . . . " ) ;

22 /∗ se f o l o s e s t e c l a s a MenuShortcut pt c r ea r ea unei combinat i i de t a s t e pt acce sa r ea

23 componentei MenuItem Exit ∗/

24 MenuItem myFileExitMenuItem = new MenuItem( " Exit " , new MenuShortcut (

25 KeyEvent .VK_X) ) ;

26 MenuItem myEditUndoMenuItem = new MenuItem( "Undo" , new MenuShortcut (

27 KeyEvent .VK_Z) ) ;

28

29 // se adauga f i e c a r e componente MenuItem in componenta Menu corespunzatoare

30 myFileMenu . add (myFileOpenMenuItem ) ;

31 myFileMenu . addSeparator ( ) ;

32 myFileMenu . add (myFileExitMenuItem ) ;

33 myEditMenu . add (myEditUndoMenuItem) ;

34

35 // se s e t eaza i n f o rma t i i l e ce vor f i t ransmise handler−u lu i o data cu dec l ansa rea evenimentulu i

36 myFileOpenMenuItem . setActionCommand ( " open " ) ;

37 myFileExitMenuItem . setActionCommand ( " e x i t " ) ;

38 myEditUndoMenuItem . setActionCommand ( " undo " ) ;

39

40 // se a soc i a za componentele g r a f i c e cu handler−ul MyActionListener

41 Act ionL i s t ener a c t i onL i s t n e r = new MyActionListener ( ) ;

42 myFileOpenMenuItem . addAct ionListener ( a c t i onL i s t n e r ) ;

43 myFileExitMenuItem . addAct ionListener ( a c t i onL i s t n e r ) ;

44 myEditUndoMenuItem . addAct ionListener ( a c t i onL i s t n e r ) ;

45

46 frame . s e tV i s i b l e ( true ) ;

47 }

48 }

11

Page 84: Laborator JAVA IESC UNITBV

Clasa handler MyActionListener :1 import java . awt . event . ∗ ;

2

3 public c l a s s MyActionListener implements Act ionL i s t ene r {

4

5 @Override

6 public void act ionPerformed ( ActionEvent e ) {

7 St r ing cmd = e . getActionCommand ( ) ;

8 i f (cmd . equa l s ( " open " ) ) {

9 System . out . p r i n t l n ( " open " ) ;

10 } e l s e i f (cmd . equa l s ( " e x i t " ) ) {

11 System . e x i t (0 ) ;

12 } e l s e i f (cmd . equa l s ( " undo " ) ) {

13 System . out . p r i n t l n ( " undo " ) ;

14 }

15 }

16 }

III. TEMĂ

1. Continuaţi exerciţiul 3 din Laborator10.pdf în felul următor:

• Implementaţi funcţionalităţile calculatorului (operaţiile aritmetice specificate). Calcu-

latorul va efectua operaţiile atât la apasarea butoanelor cu ajutorul mouse-ului cât şi

la apăsarea tastelor corespunzătoare de pe tastatură.

• Pe lângă cerinţele de implementare ale interfeţei specificate în laboratorul anterior,

adăugaţi o bară de meniu asemănătoare cu cea a calculatorului din Windows. (File:

Exit Ctrl+X; Edit: Copy Ctrl+C, Paste Ctrl+V).

Pentru nota 10 implementaţi şi funcţionalităţile meniului.

12

Page 85: Laborator JAVA IESC UNITBV

Laborator 12:

Interfeţe grafice în Java

Componente Swing

Întocmit de: Adina Neculai

Îndrumător: Asist. Drd. Gabriel Danciu

11 decembrie 2011

Page 86: Laborator JAVA IESC UNITBV

I. NOŢIUNI TEORETICE

Swing este o librărie a limbajului Java, librărie ce este considerată o extensie a lui AWT. Swing

conţine componente noi şi îmbunătăţite care sporesc funcţionalitatea şi înfăţişarea GUI-ului în

Java. Pachetul din care vom lua componentele necesare se numeşte javax.swing.

Câteva dintre caracteristicile care au fost adăugate în acest pachet sunt următoarele:

• S-au introdus componente diverse cum ar fi: tabele, arbori, slider-e, bare de progres, com-

ponente text;

• componentele Swing au tooltip-uri plasate deasupra lor. Un tooltip este o fereastră de tipul

popup care apare temporar deasupra unei componente atunci când cursorul mouse-ului se

află pe componenta respectivă. Acestea sunt utilizate pentru a oferi mai multe informaţii

despre componenta în cauză.

Priviţi în imaginea următoare relaţia dintre clasele pachetului awt şi clasele pachetului swing:

Figura 1: Ierarhia claselor Swing şi relaţia cu clasele AWT

2

Page 87: Laborator JAVA IESC UNITBV

Având în vedere faptul că librăria Swing a fost construită peste AWT, paşii ce trebuie urmaţi

pentru a realiza o aplicaţie grafică în Java rămân aceiaşi:

• Crearea unei suprafeţe de afişare pe care vor fi aşezate componentele grafice (butoane, con-

troale de editare, texte, etc);

• Crearea şi aşezarea obiectelor grafice pe suprafaţa de afişare în poziţiile corespunzătoare;

• Definirea unor acţiuni care trebuie să se execute în momentul când utilizatorul interacţionează

cu obiectele grafice ale aplicaţiei;

• ”Ascultarea” evenimentelor generate de obiecte în momentul interacţiunii cu utilizatorul şi

executarea acţiunilor corespunzătoare aşa cum au fost ele definite.

A. Componente grafice Swing

Cele mai folosite componente grafice sunt reprezentate în figura următoare:

Figura 2: Ierarhia componentelor Swing

3

Page 88: Laborator JAVA IESC UNITBV

B. Componente meniu în Swing

Bara de meniu poate fi creată cu ajutorul clasei JMenuBar care permite adăugarea compo-

nentelor de tipul JMenu pentru a construi meniul propriu-zis.

JMenu este o fereastră popup care conţine componente JMenuItem şi care este afişată atunci

când utilizatorul selectează o componentă JMenuBar. În plus, o componentă JMenu poate conţine

JSeparator.

Clasa JMenuItem realizează de fapt un buton din lista care se afişează utilizatorului atunci

când acesta selectează o componentă JMenu. Clasele sale copil sunt: JCheckBoxMenuItem, JMenu,

JRadioButtonMenuItem. De ce şi JMenu? Pentru că un JMenu poate conţine ca JMenuItem un

submeniu. Nu consider necesar explicarea componentelor JCheckBoxMenuItem, JRadioButtonMe-

nuItem. Urmăriţi exemplul prezentat în secţiunea IID.

II. PREZENTAREA LUCRĂRII DE LABORATOR

A. Componenta JLabel

Exemplul de mai jos creează o multitudine de etichete Swing, aranjându-le în moduri diferite.

Ce se poate observa este că, spre deosebire de etichetele AWT, cele Swing pot introduce şi imagini

pe lângă textul propriu-zis. De asemenea, se vor folosi aceiaşi gestionari de poziţie din pachetul

AWT. În acest caz avem FlowLayout.

Imaginile se vor adăuga cu ajutorul clasei ImageIcon al cărei constructor conţine ca şi parametru

un String ce reprezintă calea către imaginea dorită.

Metoda makeLabel() returnează un obiect JLabel, obiect instanţiat cu şirul de caractere ”Smile”

concatenat cu numărul etichetei, iar al doilea parametru reprezintă obiectul imagine. Tot în metoda

makeLabel se setează poziţia şirului de caractere pe verticală şi pe orizontală cu ajutorul unor

numere întregi primite ca parametru. Aceste numere întregi sunt de fapt constante ale clasei

JLabel.1 import java . awt . ∗ ;

2 import javax . swing . ∗ ;

3

4 public c l a s s LableExample {

5 public s t a t i c Icon icon = new ImageIcon ( " r e s u r s e / smi l e . g i f " ) ;

6

7 public s t a t i c void main ( St r ing [ ] a rgs ) {

4

Page 89: Laborator JAVA IESC UNITBV

8 JFrame frame = new JFrame ( " Label ␣Example " ) ;

9 frame . s e t S i z e (350 , 200) ;

10 frame . setLayout (new FlowLayout ( ) ) ;

11

12 JLabel [ ] l a b e l s = new JLabel [ 9 ] ;

13 l a b e l s [ 0 ] = makeLabel ( JLabel .TOP, JLabel .LEFT, 0) ;

14 l a b e l s [ 1 ] = makeLabel ( JLabel .TOP, JLabel .CENTER, 1) ;

15 l a b e l s [ 2 ] = makeLabel ( JLabel .TOP, JLabel .RIGHT, 2) ;

16 l a b e l s [ 3 ] = makeLabel ( JLabel .CENTER, JLabel .LEFT, 3) ;

17 l a b e l s [ 4 ] = makeLabel ( JLabel .CENTER, JLabel .CENTER, 4) ;

18 l a b e l s [ 5 ] = makeLabel ( JLabel .CENTER, JLabel .RIGHT, 5) ;

19 l a b e l s [ 6 ] = makeLabel ( JLabel .BOTTOM, JLabel .LEFT, 6) ;

20 l a b e l s [ 7 ] = makeLabel ( JLabel .BOTTOM, JLabel .CENTER, 7) ;

21 l a b e l s [ 8 ] = makeLabel ( JLabel .BOTTOM, JLabel .RIGHT, 8) ;

22

23 // dezac t iveaza e t i c h e t a 0

24 l a b e l s [ 0 ] . setEnabled ( f a l s e ) ;

25

26 // se dezac t iveaza e t i c h e t a 1 . In ace s t caz , se s e t eaza a l t a imagine

27 l a b e l s [ 1 ] . setEnabled ( f a l s e ) ;

28 l a b e l s [ 1 ] . s e tD i sab l ed I con (new ImageIcon ( " r e s u r s e /no . g i f " ) ) ;

29

30 // modi f i ca d i s t an ta i n t r e imagine s i t ext l a e t i c h e t e l e 2 s i 3

31 l a b e l s [ 2 ] . setIconTextGap (15) ;

32 l a b e l s [ 3 ] . setIconTextGap (0) ;

33

34 // se adauga e t i c h e t e l e in f e r e a s t r a

35 for ( int i = 0 ; i < 9 ; i++) {

36 frame . add ( l a b e l s [ i ] ) ;

37 }

38

39 frame . s e tV i s i b l e ( true ) ;

40 }

41

42 public s t a t i c JLabel makeLabel ( int vert , int hor iz , int contor ) {

43 JLabel l = new JLabel ( " Smile ␣ " + contor , icon , SwingConstants .CENTER) ;

44 l . s e tVe r t i c a lTex tPo s i t i on ( ver t ) ;

45 l . s e tHor i zonta lTextPos i t i on ( ho r i z ) ;

46 l . setBorder ( BorderFactory . c reateLineBorder ( Color . blue ) ) ;

47 return l ;

48 }

49 }

B. Componentele JTextField şi JTextPassword

Componentele text au fost îmbunătăţite în pachetul Swing. Dacă în pachetul AWT nu era

permisă crearea unui câmp text în care să se seteze poziţionarea scrisului, iată că JTextField face

posibil acest lucru (linia de cod 15 şi 19).1 import javax . swing . ∗ ;

2 import java . awt . ∗ ;

3

4 public c l a s s TextFieldExample {

5

Page 90: Laborator JAVA IESC UNITBV

5

6 public s t a t i c void main ( St r ing [ ] a rgs ) {

7 JFrame frame = new JFrame ( " TextFie ld ␣Example " ) ;

8

9 JLabel lastNameLabel = new JLabel ( " Last ␣Name" , SwingConstants .LEFT) ;

10 JLabel f i r stNameLabel = new JLabel ( " F i r s t ␣Name" , SwingConstants .CENTER) ;

11 JLabel passwordLabel = new JLabel ( " Password " , SwingConstants .RIGHT) ;

12

13 JTextField lastNameTF = new JTextFie ld (15) ;

14 lastNameTF . setFont (new Font ( " bold " , Font .BOLD, 12) ) ;

15 lastNameTF . setHor izonta lAl ignment ( JTextFie ld .RIGHT) ;

16

17 JTextField firstNameTF = new JTextFie ld ( ) ;

18 firstNameTF . setFont (new Font ( " i t a l i c " , Font . ITALIC , 13) ) ;

19 firstNameTF . setHor izonta lAl ignment ( JTextField .CENTER) ;

20

21 JPasswordField passwordTF = new JPasswordField ( ) ;

22

23 JPanel p = new JPanel ( ) ;

24 p . setLayout (new GridLayout (3 , 1) ) ;

25

26 p . add ( lastNameLabel ) ;

27 p . add ( lastNameTF) ;

28 p . add ( f i rstNameLabel ) ;

29 p . add ( firstNameTF ) ;

30 p . add ( passwordLabel ) ;

31 p . add ( passwordTF ) ;

32

33 frame . add (p) ;

34

35 frame . pack ( ) ;

36 frame . s e tV i s i b l e ( true ) ;

37 }

38 }

C. Componenta JButton

Exemplul prezentat mai jos afişează într-o fereastră trei butoane. Primul conţine doar text, cel

de-al doilea conţine doar o imagine, iar cel de-al treilea conţine şi text şi o imagine. Toate cele trei

butoane au fost create cu ajutorul clasei JButton.

Mai mult, numele apărut pe cel de-al treilea buton are subliniată prima literă, iar la combinaţia

de taste ALT şi prima literă butonul este selectat. Acest lucru este posibil datorită metodei setM-

nemonic() a clasei JButton care primeşte ca parametru prima literă a numelui de pe buton. Astfel

butonul răspunde atât la click-urile de mouse cât şi la combinaţia ALT+prima literă.

Observaţi ce se afişează atunci când plasaţi mouse-ul deasupra butoanelor. Depistaţi liniile de

cod care realizează acest lucru.

6

Page 91: Laborator JAVA IESC UNITBV

1 import java . awt . ∗ ;

2 import javax . swing . ∗ ;

3

4 public c l a s s ButtonExample {

5

6 public s t a t i c void main ( St r ing args [ ] ) {

7 JFrame frame = new JFrame ( " JButton␣Example " ) ;

8 frame . s e t S i z e (300 , 100) ;

9

10 JPanel panel = new JPanel ( ) ;

11 panel . setLayout (new FlowLayout ( FlowLayout .LEFT) ) ;

12

13 JButton cutButton = new JButton ( "Cut " ) ;

14 cutButton . setToolTipText ( " Tool t ip : ␣buton␣ cut " ) ;

15 JButton copyButton = new JButton (new ImageIcon ( " r e s u r s e /copy . g i f " ) ) ;

16 copyButton . setToolTipText ( " Too l t ip : ␣buton␣copy " ) ;

17

18 St r ing buttonName = " Paste " ;

19 St r ing icon = " r e su r s e / paste . g i f " ;

20 f i n a l char key = buttonName . charAt (0) ;

21 JButton pasteButton = new JButton (buttonName , new ImageIcon ( i con ) ) ;

22 pasteButton . setMnemonic ( key ) ;

23 pasteButton . setToolTipText ( " Too l t ip : ␣buton␣ paste " ) ;

24

25 panel . add ( cutButton ) ;

26 panel . add ( copyButton ) ;

27 panel . add ( pasteButton ) ;

28

29 frame . add ( panel , BorderLayout .NORTH) ;

30

31 frame . s e tV i s i b l e ( true ) ;

32 }

33 }

D. Componente Meniu

Clasa MenuExample afişează o fereastră ce conţine o bară de meniu cu două componente meniu.

Prima componentă meniu mai conţine, însă, alte obiecte meniu şi un submeniu.

În acest exemplu, meniul este afişat pe verticală datorită metodei setLayout() care este apelată

de către componenta JMenuBar cu parametrul GridLayout în linia de cod 19.

Observaţi că asemenea componentelor JButton şi JLabel, şi JMenuItem poate conţine imagini.

De asemenea, meniul prezintă separatori între componentele diferite ale unui JMenu (liniile de cod

36, 50 şi 58).1 import java . awt . GridLayout ;

2 import javax . swing . ∗ ;

3

4 public c l a s s MenuExample {

5

7

Page 92: Laborator JAVA IESC UNITBV

6 public s t a t i c void main ( St r ing s [ ] ) {

7 JFrame frame ;

8 JMenuBar menuBar ;

9 JMenu menu , submenu ;

10 JMenuItem menuItem ;

11 JRadioButtonMenuItem rbMenuItem ;

12 JCheckBoxMenuItem cbMenuItem ;

13

14 frame = new JFrame ( "Menu␣example " ) ;

15 frame . s e t S i z e (200 , 200) ;

16

17 // se c reeaza bara de meniu

18 menuBar = new JMenuBar ( ) ;

19 menuBar . setLayout (new GridLayout (2 , 1 ) ) ;

20

21 // se c on s t r u i e s t e primul meniu

22 menu = new JMenu( "Un␣Meniu " ) ;

23 menuBar . add (menu) ;

24

25 //un grup de componente JMenuItems

26 menuItem = new JMenuItem( "Doar␣ text " ) ;

27 menu . add (menuItem) ;

28

29 menuItem = new JMenuItem( " S i ␣ text ␣ s i ␣ imagine " , new ImageIcon ( " r e s u r s e / r o l l i n g . g i f " ) ) ;

30 menu . add (menuItem) ;

31

32 menuItem = new JMenuItem(new ImageIcon ( " r e s u r s e / r o l l i n g . g i f " ) ) ;

33 menu . add (menuItem) ;

34

35 // un grup de componente radio−buton

36 menu . addSeparator ( ) ; //adauga l a s f a r s i t u l grupu lu i de componente an t e r i o a r e o l i n i e o r i z on ta l a ,

cons ide ra ta separa to r

37 ButtonGroup group = new ButtonGroup ( ) ;

38

39 rbMenuItem = new JRadioButtonMenuItem ( " o␣componenta␣ radio−button " ) ;

40 rbMenuItem . s e t S e l e c t e d ( true ) ;

41 // butonul rad io se adauga grupu lu i s i meniului

42 group . add ( rbMenuItem ) ;

43 menu . add ( rbMenuItem ) ;

44

45 rbMenuItem = new JRadioButtonMenuItem ( " a l t a ␣componenta␣ radio−buton " ) ;

46 group . add ( rbMenuItem ) ;

47 menu . add ( rbMenuItem ) ;

48

49 // un grup de componente check−box

50 menu . addSeparator ( ) ;

51 cbMenuItem = new JCheckBoxMenuItem( " o␣componenta␣check−box " ) ;

52 menu . add ( cbMenuItem) ;

53

54 cbMenuItem = new JCheckBoxMenuItem( " a l t a ␣componenta␣check−box " ) ;

55 menu . add ( cbMenuItem) ;

56

57 // un submeniu

58 menu . addSeparator ( ) ;

59 submenu = new JMenu( " Submeniu " ) ;

60

61 menuItem = new JMenuItem( " a l t ␣ ob i e c t ␣ in ␣submeniu " ) ;

62 submenu . add (menuItem) ;

63

8

Page 93: Laborator JAVA IESC UNITBV

64 menu . add ( submenu ) ;

65

66 // se c on s t r u i e s t e a l d o i l e a meniu ce se adauga in bara de meniu

67 menu = new JMenu( " Alt ␣Meniu " ) ;

68 menuItem = new JMenuItem( " ob i e c t ␣ in ␣Alt ␣Meniu " ) ;

69 menu . add (menuItem) ;

70 menuBar . add (menu) ;

71

72 // se ataseaza f e r e s t r e i bara de meniu

73 frame . setJMenuBar (menuBar ) ;

74

75 frame . pack ( ) ;

76 frame . s e tV i s i b l e ( true ) ;

77 }

78 }

III. TEMĂ

1. Realizaţi cerinţele 2 şi 3 din Laborator10.pdf. Folosiţi componente din pachetul javax.swing.

Consultaţi figura din secţiunea IA şi API-ul.

9

Page 94: Laborator JAVA IESC UNITBV

Laborator Nr. 13:

Evenimente generate de Componente SWING

Intocmit de: Dobrinas Alexandra

Indrumator: Asist. Drd. Danciu Gabriel

January 8, 2012

Page 95: Laborator JAVA IESC UNITBV

I. NOTIUNI TEORETICE

Asa cum este precizat si ın Laboratorul 11, un eveniment reprezinta o instanta a unei clase Java, instantacare contine o serie de informatii despre actiunea utilizatorului asupra unei componente grafice. Un ,,eveni-ment” poate fi ınteles, aici, ca un eveniment asincron, independent de evolutia programului si al carui momentde producere nu poate fi prevazut la scrierea codului. Evenimentele cele mai des ıntalnite sunt:

• apasarea unei taste;

• actionarea unui buton de mouse;

• deplasarea cursorului peste anumite zone;

Pentru gestionarea unui eveniment sunt implicati trei participanti:

• sursa evenimentului - obiectul a carui stare se modifica;

• obiectul eveniment - reprezinta evenimentul ın sine;

• event listener - obiectul ce trebuie anuntat despre modificarea ce se produce;

A. Aparitia si tratarea evenimentelor

La fel ca si ın AWT, si ın SWING sunt folositi delegati - handleri pentru prelucrarea informatiei provenitade la eveniment, precum si ascultatori - listeneri pentru tratarea evenimentelor. Ceea ce se ıntampla laaparitia unui eveniment este ilustrat ın figura de mai jos:

Se apeleaza un ascultator atunci cand utilizatorul interactioneaza cu interfata, ceea ce provoaca un eveni-ment. Desi evenimentele provin de obicei din interfata utilizator, ele pot avea si alte surse: conexiunea lainternet, window manager, timer, etc. In functie de ce anume a declansat aparitia unui eveniment existainterfete care se folosesc pentru prelucrarea sa:

2

Page 96: Laborator JAVA IESC UNITBV

Asocierea dintre componenta si handler se face cu ajutorul interfetelor Listener astfel:

Componenta Interfata Metode asociate

JButton

JTextField ActionListener actionPerformed(ActionEvent e)

JMenuItem

JSlider ChangeListener stateChanged(ChangeEvent e)

JCheckBox ItemListenerr itemstateChanged()

key keyPressed()

on KeyListener keyReleased()

component keyTyped()

mouseClicked()

mouse mouseEntered()

on MouseListener mouseExited()

component mousePressed()

mouseReleased()

mouse on MouseMotionListener() mouseMoved())

component mouseDragged()

JFrame WindowListener() windowClosing(WindowEvent e)

II. PREZENTAREA LUCRARII DE LABORATOR

Pentru prelucrarea evenimentelor generate de butoane trebuie folosit un handler care sa implementezeinterfata Listener corespunzatoare actiunii ce se monitorizeaza.

A. Interfata ActionListener

Evenimentele care se prelucreaza cu ajutorul metodelor suprascrise din aceasta interfata sunt evenimentelecare se genereaza la folosirea butonelor, a meniurilor etc. Pentru prelucrarea acestor evenimente trebuie sase utilizeze o clasa handler (aici HandlerButoane) ce implementeaza interfata ActionListener, si suprascriemetoda actionPerformed(ActionEvent e).

1 import javax . swing . ∗ ;2 import javax . swing . border . ∗ ;

3

Page 97: Laborator JAVA IESC UNITBV

3 import java . awt . ∗ ;4 import java . awt . event . ∗ ;56 c lass HandlerButoane implements Act ionL i s t ener {78 private int nrCl ick = 0 ;9 private int i nd i ceCu loare = 0 ;

10 f ina l private Color c u l o r i [ ] = {Color .LIGHT GRAY, Color .RED, Color .ORANGE, Color .PINK } ;1112 public void act ionPerformed ( ActionEvent e ) {1314 JButton butonApasat = ( JButton ) e . getSource ( ) ;1516 // in f un c t i e de denumirea evenimentulu i generat de buton se implementeaza o anumita act iune :1718 // pentru butonul ” contor ”19 i f ( butonApasat . getActionCommand ( ) . equa l s ( ” contor ” ) ) {20 nrCl ick++;21 butonApasat . setText ( ”Apasat : ” + nrCl ick ) ;22 }2324 // pentru butonul ” cu loa re ”25 i f ( butonApasat . getActionCommand ( ) . equa l s ( ” cu loa re ” ) ) {26 ind i ceCu loare++;27 i f ( ind i ceCu loare == cu l o r i . l ength )28 ind i ceCu loare = 0 ;29 butonApasat . setBackground ( c u l o r i [ ind i ceCu loare ] ) ;30 }3132 // pentru butonul ” ex i t ”33 i f ( butonApasat . getActionCommand ( ) . equa l s ( ” ex i t ” ) ) {34 System . ex i t (0) ;35 }36 }37 }

1 public c lass TestButoane extends JFrame {23 public stat ic void main ( St r ing args [ ] ) {4 TestButoane app = new TestButoane ( ) ;56 // c rea rea propriu−z i s a a butoane lor7 JButton butonulNumara = new JButton ( ”Apasa : 0” ) ;8 butonulNumara . setActionCommand ( ” contor ” ) ;9 butonulNumara . setAlignmentX (Component .CENTER ALIGNMENT) ;

1011 JButton butonulCulor i = new JButton ( ”Schimba cu loarea ” ) ;12 butonulCulor i . setActionCommand ( ” cu loa re ” ) ;13 butonulCulor i . setAlignmentX (Component .CENTER ALIGNMENT) ;1415 JButton butonulExit = new JButton ( ”Exit ” ) ;16 butonulExit . setActionCommand ( ” ex i t ” ) ;17 butonulExit . setAlignmentX (Component .CENTER ALIGNMENT) ;181920 // s e ta r ea de l i s t e n e r i pentru f i e c a r e buton in parte21 butonulNumara . addAct ionListener (new ButtonHandler ( ) ) ;22 butonulCulor i . addAct ionListener (new ButtonHandler ( ) ) ;23 butonulExit . addAct ionListener (new ButtonHandler ( ) ) ;242526 // adaugarea butoane lor in Panel27 JPanel panou = new JPanel ( ) ;28 panou . setLayout (new BoxLayout ( panou , BoxLayout . Y AXIS) ) ;2930 panou . add ( butonulNumara ) ;31 panou . add (Box . createRig idArea (new Dimension (0 , 10) ) ) ;32 panou . add ( butonulCulor i ) ;33 panou . add (Box . createRig idArea (new Dimension (0 , 10) ) ) ;34 panou . add ( butonulExit ) ;35 panou . setBorder ( BorderFactory . createEmptyBorder (20 , 20 , 20 , 20) ) ;3637 app . getContentPane ( ) . add ( panou ) ;38 app . pack ( ) ;39 app . se tDe fau l tCloseOperat ion ( JFrame .EXIT ON CLOSE) ;40 app . show ( ) ;41 }42 }

B. Interfata KeyListener

Pentru evenimentele generate cu ajutorul tastaturii trebuie sa se utilizeze o clasa han-dler (aici KeyHandler) ce implementeaza interfata KeyListener, si suprascrie metodelekeyPressed(), keyReleased(), keyTyped(). Nu este obligatoriu sa se implementeze toate metodele dacaaplicatia nu necesita acest lucru.

1 import java . awt . event . ∗ ;23 public c lass KeyHandler implements KeyListener {4

4

Page 98: Laborator JAVA IESC UNITBV

5 @Override6 public void keyPressed (KeyEvent keyEvent ) {7 char i = keyEvent . getKeyChar ( ) ;8 St r ing s t r = Character . t oS t r ing ( i ) ;9 System . out . p r i n t l n ( ”Key pressed : ”+ s t r ) ;

1011 }1213 @Override14 public void keyReleased (KeyEvent arg0 ) {}15 @Override16 public void keyTyped (KeyEvent arg0 ) {}17 }

1 mport java . awt . ∗ ;2 import javax . swing . ∗ ;34 public c lass TestKey {56 public stat ic void main ( St r ing [ ] args ) {7 JFrame f = new JFrame ( ” Fereas t ra keyEvent ” ) ;8 f . setLayout (new FlowLayout ( ) ) ;9

10 JLabel label = new JLabel ( ” S c r i e : ” ) ;11 JTextField tx tF i e l d = new JTextField (20) ;121314 KeyHandler keyH = new Keyhandler ( ) ;15 tx tF i e l d . addKeyListener ( keyH ) ;1617 f . add ( label ) ;18 f . add ( tx tF i e l d ) ;192021 f . pack ( ) ;22 f . s e tV i s i b l e ( true ) ;23 }24 }

C. Interfata MouseListener

Evenimentele generate de mouse, clasa handler trebuie sa implementeze interfata MouseListener si sasuprascrie metodele: mouseClicked(),mouseEntered(), mouseExited(), mousePressed(), mouseReleased().la fel ca si la evenimentele pentru taste, daca nu se cere utilizarea tuturor metodelor, nu este necesaraimplemetarea lor.

12 import java . awt . event . ∗ ;3 import javax . swing . ∗ ;456 public c lass MyMouseListener implements MouseListener {78 JLabel labelX , labelY ;9 public MyKeyListener ( JLabel x , JLabel y )

10 {11 this . labelX = x ;12 this . labelY = y ;13 }141516 @Override17 public void mouseClicked (MouseEvent e ) {18 int x = Intege r . pa r s e In t ( labelX . getText ( ) ) ;19 int y = Intege r . pa r s e In t ( labelY . getText ( ) ) ;20 System . out . p r i n t l n ( x+” + ”+y+” = ”+(x+y ) ) ;212223 }2425 @Override26 public void mouseEntered (MouseEvent e ) {27 // TODO Auto−generated method stub2829 }3031 @Override32 public void mouseExited (MouseEvent e ) {33 // TODO Auto−generated method stub3435 }3637 @Override38 public void mousePressed (MouseEvent e ) {39 // TODO Auto−generated method stub4041 }4243 @Override44 public void mouseReleased (MouseEvent e ) {

5

Page 99: Laborator JAVA IESC UNITBV

45 // TODO Auto−generated method stub4647 }4849 }

1 import java . awt . ∗ ;2 import javax . swing . ∗ ; ;34 public c lass TestMouse {5 public stat ic void main ( St r ing [ ] args ) {6 Frame f = new Frame ( ” Fereas t ra mouse c l i c k ” ) ;78 JLabel labelY = new JLabel ( ”2” ) ;9 f . add ( labelY , BorderLayout .NORTH) ;

10 JLabel labelX = new JLabel ( ”1” ) ;11 f . add ( labelX , BorderLayout .CENTER) ;1213 JButton button = new JButton ( ” Cl ick Me” ) ;14 MyMouseListener mouseListener = new MyMouseListener ( labelX , labelY ) ;15 button . addMouseListener ( mouseListener ) ;16 f . add ( button , BorderLayout .SOUTH) ;1718 f . pack ( ) ;19 f . s e tV i s i b l e ( true ) ;20 }21 }

D. Interfata WindowListener

Se foloseste pentru evenimentele care au loc la deschiderea, ınchiderea unei ferestre sau ın momentul ıncare o fereastra este sau nu activa. Spre deosebire de celelalte interfete, pentru aceasta trebuie suprascrisetoate metodele:

Metoda Descriere

windowActivated(WindowEvent e) se apeleaza cand fereastra devine activa

windowClosed(WindowEvent e) se apeleaza la ınchiderea ferestrei

windowClosing(WindowEvent e) se apeleaza in momentul ın care se ıncearca ınchiderea ferestrei

windowDeactivated(WindowEvent e) se apeleaza cand fereastra nu mai este activa

windowDeiconified(WindowEvent e) se apeleaza cand fereastra isi modifica starea

din minimize(din taskbar) ın starea normala (pe ecran)

windowIconified(WindowEvent e) se apeleaza cand fereastra isi modifica starea

din starea normala (de pe ecran) ın minimize (ın taskbar)

windowOpened(WindowEvent e) se apeleaza cand fereastra devine vizibila

In cazul ın care se doresc efectuarea unor operatii pentru anumite evenimente clasa handler poate extindeclasa WindowAdapter si astfel vor putea fi suprascrise doar metodele dorite.

1 import java . awt . ∗ ;2 import javax . swing . ∗ ;345 public c lass TestWindow {6 public stat ic void main ( St r ing [ ] args ) {78 JFrame f = new JFrame ( ” t e s t ” ) ;9 f . s e t S i z e (150 , 150) ;

1011 f . addWindowListener (new MyWindowListener ( ) ) ;12 f . s e tV i s i b l e ( true ) ;13 }14 }

1 import java . awt . ∗ ;2 import java . awt . event . ∗ ;345 public c lass MyWindowListener extends WindowAdapter {67 public void windowClosing (WindowEvent event ) {8 System . out . p r i n t l n ( ”Eveniment pe f e r e s t r e ” ) ;9 System . ex i t (0) ;

10 }11 }

6

Page 100: Laborator JAVA IESC UNITBV

E. Tratarea evenimentelor pentru meniuri

Tratarea evenimentelor pentru meniuri ın Swing se face ın mod similar cu tratarea evenimentelor pentrumeniuri din AWT.

1 import java . awt . ∗ ;2 import java . awt . event . Act ionL i s t ener ;34 import javax . swing . ∗ ;56 public c lass TestMeniuri {7 public stat ic void main ( St r ing [ ] args ) {89 JFrame frame = new JFrame ( ”Meniu ” ) ;

1011 frame . s e t S i z e (100 , 100) ;121314 JMenuBar myMenuBar = new JMenuBar ( ) ;15 myMenuBar . setLayout (new GridLayout ( 1 , 2 ) ) ;16 frame . setJMenuBar (myMenuBar ) ;171819 JMenu myFileMenu = new JMenu( ” F i l e ” ) ;20 JMenu myEditMenu = new JMenu( ” Edit ” ) ;21 myMenuBar . add (myFileMenu ) ;22 myMenuBar . add (myEditMenu) ;232425 JMenuItem myFileOpenMenuItem = new JMenuItem( ”Open . . . ” ) ;2627 JMenuItem myFileExitMenuItem = new JMenuItem( ” Exit ” ) ;28 JMenuItem myEditUndoMenuItem = new JMenuItem( ”Undo” ) ;293031 myFileMenu . add (myFileOpenMenuItem ) ;32 myFileMenu . addSeparator ( ) ;33 myFileMenu . add (myFileExitMenuItem ) ;34 myEditMenu . add (myEditUndoMenuItem) ;353637 myFileOpenMenuItem . setActionCommand ( ” open ” ) ;38 myFileExitMenuItem . setActionCommand ( ” ex i t ” ) ;39 myEditUndoMenuItem . setActionCommand ( ” undo ” ) ;404142 Act ionL i s t ener a c t i onL i s tn e r = new MyMenuListener ( ) ;43 myFileOpenMenuItem . addAct ionListener ( a c t i onL i s tn e r ) ;44 myFileExitMenuItem . addAct ionListener ( a c t i onL i s tn e r ) ;45 myEditUndoMenuItem . addAct ionListener ( a c t i onL i s tn e r ) ;4647 frame . s e tV i s i b l e ( true ) ;48 }49 }

1 import java . awt . event . ∗ ;23 public c lass MyMenuListener implements Act ionL i s t ener {45 @Override6 public void act ionPerformed ( ActionEvent e ) {7 St r ing cmd = e . getActionCommand ( ) ;89 i f (cmd . equa l s ( ” open ” ) ) {

10 System . out . p r i n t l n ( ” open ” ) ;11 }12 else13 i f (cmd . equa l s ( ” ex i t ” ) ) {14 System . out . p r i n t l n ( ” ex i t ” ) ;15 System . ex i t ( 0 ) ;1617 }18 else19 i f (cmd . equa l s ( ” undo ” ) ) {20 System . out . p r i n t l n ( ” undo ” ) ;21 }22 }23 }

III. TEMA

Adaugati evenimente pentru calculatorul realizat ın SWING.

7