Sunteți pe pagina 1din 296

Tudor Sorin

Vlad Tudor (Huţanu)

JAVA

L&S Info-mat
Copyright 2005-2018  Editura L&S INFO-MAT

ISBN: 978-973-7658-03-6
Această carte în format electronic este protejată de legea
dreptului de autor. Toate drepturile asupra acestei lucrǎri aparţin
editurii L&S INFO-MAT. Reproducerea integralǎ sau parţialǎ a textului
din aceastǎ carte este posibilǎ doar cu acordul în scris al editurii
L&S INFO-MAT.

După confirmarea plății, fiecare carte poate fi descărcată de maximum 5 ori şi este
disponibilă 30 de zile.

Drepturi de autor / Copyright. Fiecare PDF este securizat în 28 de zone cu


watermark invizibil (id comandă, e-mail) pentru a nu putea fi distribuit pe alte
căi virtuale. Sistemul este unul complex şi se detectează automat persoana care a
redistribuit cartea ilegal.

Redistribuirea ilegală este pedepsită de lege!


Mulțumim!

Adresa: Str. Stânjeneilor nr. 6,


Sector 4, Bucureşti

E-mail: office@ls-infomat.ro
www.ls-infomat.ro
www.manuale-de-informatica.ro
Biblioteca Digitală de Informatică “Tudor Sorin”
www.infobits.ro
Laboratorul Virtual de Informatică şi TIC
http://lab.infobits.ro
Cuprins
Capitolul 1. Java, primele noţiuni.......................................... 11
1.1. Instalarea mediului de programare ........................................ 12
1.2. Primul program ..................................................................... 14
1.3. Conceptul de Maşină Virtuală Java (JVM)................................. 15
1.4. Tipuri de aplicaţii Java ........................................................... 16
1.5. Comentarii ............................................................................ 17
1.6. Afişarea şirurilor de caractere ................................................ 17
1.7. Programe care se găsesc în alte folder-e ............................... 17

Capitolul 2. Tipuri şi operaţii de date ........................................ 19


2.1. Tipuri de date ........................................................................ 20
2.1.1. Tipurile de date primitive ....................................................... 20
2.1.2. Tipul referinţă ........................................................................ 22
2.1.3. Observaţii importante ............................................................ 22
2.2. Operatori ............................................................................... 23
2.2.1. Operatori aritmetici ................................................................ 23
2.2.2. Operatori relaţionali ............................................................... 25
2.2.3. Operatori de egalitate ............................................................ 25
2.2.4. Operatori de incrementare şi decrementare ........................... 25
2.2.5. Operatori logici ...................................................................... 26
2.2.6. Operatori logici pe biţi ........................................................... 27
2.2.7. Operatori de atribuire ............................................................ 28
2.2.8. Operatori condiţional ............................................................. 30
2.2.9. Operatori de conversie explicită ............................................. 31
2.2.10. Prioritatea (precedenţa) operatorilor .................................... 31
2.3. Instrucţiuni ............................................................................ 32
2.4. Masive ................................................................................... 38
2.5. Citirea datelor de la tastatură ................................................ 43
2.6. Probleme rezolvate ................................................................ 45
Probleme propuse ........................................................................ 49
Răspunsuri ................................................................................... 55
6 Cuprins

Capitolul 3. Metode ..................................................................... 57


3.1. Generalităţi ............................................................................ 58
3.2. Structura unei metode şi apelul ei .......................................... 59
3.3. Transmiterea parametrilor ..................................................... 61
3.4. Despre variabile ..................................................................... 63
3.5. Exemple de utilizare ale metodelor ........................................ 64
3.5.1. Exemple elementare............................................................... 64
3.5.2. Un exemplu de backtracking n Java ...................................... 67
3.6. Metode recursive ................................................................... 68
3.7. Exemple de utilizare a metodelor recursive.............................. 70
3.7.1. Exemple elementare............................................................... 70
3.7.2. Backtracking ............................................................. 71
3.8 Supra ncărcarea metodelor ..................................................... 73
Probleme propuse ........................................................................ 74
Răspunsuri ................................................................................... 79

Capitolul 4. Clase – primele noţiuni, exemple ........................... 80


4.1. Ce este o clasă ? .................................................................... 81
4.2. Constructori .......................................................................... 83
4.3. Date membru statice şi metode statice .................................. 84
4.4. Cuvântul cheie this .............................................................. 85
4.5. Referinţe către obiecte ........................................................... 85
4.6. Masive de obiecte .................................................................. 87
4.7. Aplicaţii ale noţiunilor prezentate............................................ 88
4.7.1. Lucrul cu numere raţionale...................................................... 89
4.7.2. Lucrul cu mulţimi de numere naturale ..................................... 92
4.8. Garbage Collector ........................................................... 96
4.9. Cum sunt memorate clasele ? ................................................ 96
4.10. Pachete................................................................................ 98
4.11. Clase interioare ................................................................. 101
4.12. O problemă de terminologie .............................................. 102
Probleme propuse ...................................................................... 103
Răspunsuri ................................................................................. 106
Bazele programării în Java 7

Capitolul 5. Studiul unor clase ale limbajului Java ............... 110


5.1. Clasa Math .......................................................................... 111
5.2. Clasa String ...................................................................... 112
5.2.1. Constructorii şi lungimea unui şir de caractere ................... 112
5.2.2. Compararea şirurilor de caractere ....................................... 113
5.2.3. Subşiruri ............................................................................. 114
5.2.4. ş ..................................... 115
5.2.5. Parametrii metodei main() ................................................ 116
5.2.6. Aplicaţii............................................................................... 117
5.3. Clasa StringTokenizer ...................................................... 119
5.4. Clase nfăşurătoare .............................................................. 120
5.5. Lucrul cu numere mari ......................................................... 123
Probleme propuse ...................................................................... 125
Indicaţii / rezolvări ..................................................................... 128

Capitolul 6. Extinderea claselor .......................................... 131


6.1. Noţiuni generale .................................................................. 132
6.2. Un exemplu de extindere al unei clase ................................. 134
6.3. O modalitate de simulare a extinderii multiple ................... 138
6.4. Referinţe către obiectele superclaselor şi referinţe către
obiectele subclaselor .................................................................. 139
Probleme propuse ...................................................................... 142
Indicaţii / rezolvări ..................................................................... 144

Capitolul 7. Noţiuni avansate de programare orientată pe


obiecte .............................................................................. 147
7.1. Polimorfism ......................................................................... 148
7.2. Un exemplu de polimorfism................................................. 150
7.3. Clase abstracte.................................................................... 152
7.4. Un exemplu de clasă abstractă ............................................ 153
7.5. Interfeţe .............................................................................. 155
7.6. Aplicaţii ale interfeţelor ....................................................... 158
7.7. Modificatori ......................................................................... 161
8 Cuprins

Probleme propuse ...................................................................... 165


Răspunsuri ................................................................................. 167

Capitolul 8. Excepţii ........................................................... 169


8.1. Noţiunea de excepţie ........................................................... 170
8.2. Mecanismul de tratare a excepţiilor ..................................... 170
8.3. Metodele care pot returna, n caz de excepţii, obiecte ale unor
alte clase .................................................................................... 176
8.4. Exemple de tratare a excepţiilor .......................................... 177
Probleme propuse ...................................................................... 178
Răspunsuri ................................................................................. 179

Capitolul 9. Alte clase esenţiale în Java ............................... 181


9.1. Clasa Vector ....................................................................... 182
9.2. Fişiere ................................................................................. 184
9.2.1. Noţiunea de flux ................................................................. 184
9.2.2. Fluxuri de octeţi .................................................................. 184
9.2.3. Fluxuri de caractere ............................................................ 186
9.2.4. Intrări de la tastatură .......................................................... 188
9.3 Fire de execuţie. ................................................................... 188
Probleme propuse ...................................................................... 190
Răspunsuri ................................................................................. 191

Capitolul 10. Iniţiere în programarea vizuală ...................... 193


10.1. Prima fereastră .................................................................. 194
10.2. Mecanismul prin care se ataşează componente ferestrei. Clasa
Container ................................................................................. 195
10.3. Un mecanism prin care butoanele răspund evenimentului de
“apăsare” .................................................................................... 197
10.4. Clasa JComponent ............................................................. 198
10.5. Clasa ToolKit .................................................................. 200
10.6. Poziţionarea componentelor .............................................. 200
10.6.1. Poziţionarea absolută ........................................................ 201
Bazele programării în Java 9

10.6.2. Gestionarul de poziţionare FlowLayout ........................... 201


10.6.3. Gestionarul de poziţionare GridLayout ........................... 203
10.6.4. Gestionarul de poziţionare BorderLayout ........................ 204
10.6.5. Gestionarul GridBagLayout ............................................. 205
10.6.6. Gestionarul CardLayout ................................................... 207
10.7. Studiul principalelor componente ...................................... 208
10.7.1. Componente de tip JButton ............................................. 208
10.7.2. Componente de tip JLabel ............................................... 209
10.7.3. Componente de tip JPanel ............................................... 210
10.7.4. Componente de tip JTextField ....................................... 211
10.7.5. Componente de tip JComboBox ......................................... 214
10.7.6. Componente de tip JCheckBox şi JRadioButton şi
gruparea lor .................................................................................. 215
10.7.7. Meniuri ............................................................................. 218
10.7.8. Cutii (casete) de dialog predefinite .................................... 221
10.7.8.1. Cutii de dialog de intrare....................................... 222
10.7.8.2. Cutii de dialog pentru afişarea mesajelor .............. 222
10.7.8.3. Cutii de dialog de confirmare ................................ 223
10.7.8.4. Cutii de dialog cu opţiuni ...................................... 223
10.7.9. Componente de tip JTextArea ........................................... 225
10.7.10. Componente de tip JProgressBar ..................................... 227
10.7.11. Componente de tip JSpinner ........................................... 228
10.7.12. Cutii de tip Open / Save ................................................ 231
10.7.13. Componente de tip JColorChooser ............................. 235
10.7.14. Componente de tip JToolBar ....................................... 237
10.7.15. Componente de tip JTable ........................................... 238
10.8. Mai mult despre clasa Container ..................................... 242
10.9. Cutii de dialog ................................................................... 246
10.10. Clasa Graphics .............................................................. 250
10.10.1. Afişarea imaginilor .......................................................... 250
10.10.2. Cum scriem ? .................................................................. 251
10.10.3. Cum desenăm ?............................................................... 252
10.11. Clasa Graphics2D .......................................................... 254
10 Cuprins

10.11.1. Cum desenăm ?............................................................... 254


10.11.2. Stabilirea modului de trasare a liniilor ............................. 256
10.11.3. Gradient .......................................................................... 257
10.11.4. Clasa BufferedImage .................................................... 259
10.11.5. Texturi ............................................................................ 260
10.11.6. Dreptunghiuri 3D ............................................................ 262
10.11.7. Spaţiul de coordonate al utilizatorului ............................ 263
10.12. Evenimente ...................................................................... 265
10.12.1. Generalităţi ..................................................................... 265
10.12.2. Evenimente de tip Action ......................................... 265
10.12.3. Evenimente de tip MouseEvent ............................... 267
10.12.4. Focus, evenimente de tip FocusEvent .................... 271
10.12.6. Evenimemente de selectare a item-ilor ........................... 273
10.12.7. Evenimemente pentru fereastră ...................................... 274
10.13. Animarea imaginilor ........................................................ 276
Probleme propuse ...................................................................... 278
Indicaţii ...................................................................................... 281

Capitolul 11. Applet-uri ..................................................... 285


11.1. Generalităţi ........................................................................ 286
11.2. Crearea şi executarea applet-urilor ................................... 286
11.3. Arhive Java şi atributele elementului APPLET ...................... 287
11.4. Redefinirea unor metode ale applet-ului ........................... 289
11.5. Afişarea imaginilor. Clasa URL ........................................... 290
11.6. Redarea sunetelor ............................................................. 291
11.7. Exemple de applet-uri....................................................... 292
CAPITOLUL 1

Java, primele noţiuni

Din cuprins:
Instalarea mediului de programare
Primul program
Maşina Virtuală Java
Tipuri de aplicaţii
Comentarii
Afişarea şirurilor de caractere
Programe care se găsesc în alte folder-e
12 Bazele programării în Java

1.1. Instalarea mediului de programare


Pentru a lucra \n Java, utiliz`m soft-ul pus la dispozi]ie de
firma Sun, creatoarea limbajului. Mai precis, utiliz`m Java 2
Platform, Standard Edition (J2SE), v1.4.2, Software
Development Kit (SDK).

|n cele ce urmeaz`, consider`m c` lucr`m sub sistemul de operare


Windows 2000 [i calculatorul are acces la Internet.

A. |ncepem prin a download-a softul. Adresa este: http:\\java.sun.com.


Evident, vom alege o versiune recent` pentru Windows. |n continuare,
instal`m soft-ul download-at. De exemplu, eu l-am instalat \n
c:\j2sdk1.4.2_04.

 Poate p@n` la apari]ia acestei c`r]i ve]i g`si versiuni mai noi.
B. Pentru c` soft-ul pus la dispozi]ie de firma Sun lucreaz` prin comenzi
date de la tastatur` (ca \n MS-DOS, un sistem de operare mai vechi, creat
de Microsoft) va trebui s` folosim un program, numit CMD.exe, care
simuleaz` sistemul de operare amintit. Programul se g`se[te \n folder-ul
WINNT. Identifica]i-l cu Search. El creeaz` o fereastr` prin care
se pot da comenzi MS-DOS.
C. Pentru a utiliza cu u[urin]` acest WINNT, vom crea pe
Desktop un shortcut c`tre el (vede]i al`turat).
D. Va trebui ca fereastra
CMD s` fie deschis` \n
subfolder-ul bin, al folder-ului
care con]ine softul download-
at [i instalat. Executa]i click
cu butonul drept al mouse-
ului [i selecta]i Properties.
La apari]ia cutiei de dialog
al`turate, intoduce]i calea
folder-ul amintit \n edit-ul
Start in.

Dac` shortcut-ul a fost creat


corect, atunci c@nd executa]i
dublu click pe el va ap`rea
fereastra al`turat`, de unde
vom da comenzi de la
tastatur`.
Capitolul 1. Java, primele noţiuni 13

E. |ntruc@t \n perioada de ini]iere programele noastre se vor g`si


\n folder-ul bin, pentru a lucra mai u[or, este recomandabil s`
cre`m pe Desktop [i un shortcut c`tre acest folder.

F. De[i de la instalare, mediul Java ar trebui, implicit, s` lucreze \n


folder-ul bin, este bine ca dvs. s`-l seta]i corespunz`tor. |n acest scop,
vom folosi variabila de sistem CLASSPATH (calea c`tre clase) care este
ini]ializat` cu respectiva cale. Pentru aceasta, vom respecta urm`torii pa[i:

1. Din meniul Start, apela]i Settings, Control Panel [i System.


2. Va ap`rea o cutie de dialog \n care selecta]i Advanced [i
Environment Variables...

3. |n cutia de dialog de mai jos, ap`sa]i New.

4. |n cutia de dialog al`turat`,


introduce]i numele variabilei de
sistem (CLASSPATH) apoi calea
c`tre folder-ul bin. Aten]ie!
Calea trebuie s` corespund`
locului unde ave]i instalat
mediul Java pe calculatorul dv.
Apoi, ap`sa]i OK!
14 Bazele programării în Java

1.2. Primul program


De acum, putem scrie primul program. Trebuie s` [tim c`
mediul Java, pus la dispozi]ie de firma Sun, nu ne ofer` un
editor de text. Din acest motiv, textul program va fi introdus cu
ajutorul NOTEPAD-ului, dar va trebui s` fim aten]i ca extensia
fi[ierului text astfel ob]inut s` fie .java.

 Nu uita]i: pentru \nceput, fi[ierul text care con]ine programul


trebuie s` se g`seasc` \n folder-ul bin.

Pentru a introduce [i rula un program, vom respecta pa[ii urm`tori:


A. Vom deschide shortcut-ul c`tre bin din meniul flotant, vom alege New [i
Text Document, apoi schimb`m numele fi[ierului \n prima.java. Fi[ierul
cu acest nume va fi deschis din meniul flotant asociat, cu Open with...
[i Notepad. Apoi, se introduce programul de mai jos, care afi[eaz` mesajul
Acesta este primul program Java [i salv`m programul:

class prima {
public static void main(String[] args) {
System.out.println("Acesta este primul program Java");}
}

 Este obligatoriu ca numele clasei s` coincid` cu numele fi[ierului. |n


exemplu, clasa se nume[te prima, iar fi[ierul este prima.java.
 Este obligatoriu ca extensia fi[ierului text s` fie .java !

B. Din fereastra CMD, apel`m compilatorul Java prin comanda:

javac prima.java

|n urma acestei comenzi, se va crea fi[ierul prima.class. Acest fi[ier


con]ine programul compilat. Verifica]i existen]a lui \n bin!

C. Pentru a executa programul astfel compilat, vom da comanda:


java prima
Iat` cum arat` acum fereastra CMD:
Capitolul 1. Java, primele noţiuni 15

Dac` a]i reu[it s` rula]i acest prim program, a]i f`cut un pas

 important. |nseamn` c` a]i instalat corect mediul [i de acum pute]i


lucra lini[it. Sunt mul]i cei care se \mpotmolesc \n acest punct [i,
din acest motiv, renun]`…

S` arunc`m o privire asupra programului:

 Orice program este inclus \ntr-o clas`. No]iunea de clas` apar]ine


program`rii orientate pe obiecte [i va fi explicat` pe larg \n aceast`
carte. |n exemplu, clasa se nume[te prima.
 A[a cum am precizat, numele clasei trebuie s` coincid` cu numele
fi[ierului text surs` (cel creat cu NOTEPAD), numai c` acesta din urm`
trebuie s` aib` extensia .java.
 Orice program are o metod` (func]ie main()) [i executarea sa \ncepe
cu instruc]iunile acestei metode.
 |n exemplu, programul afi[eaz` un [ir de caractere. Instruc]iunea
(apelul de metod`) care afi[eaz` acest [ir de caractere este
system.out.println(). Dup` afi[are, cursorul sare pe r@ndul
urm`tor.
 |n Java, \n locul termenului consacrat “func]ie”, vom folosi pe acela de
metod`.
 Este obligatoriu ca metoda main() s` con]in` anumi]i parametri de
intrare: String[] args. Asupra semnifica]iei acestor parametri revenim
\n capitolele urm`toare.
 Elementele public [i static sunt modificatori. Prezen]a lor \n
antetul metodei main() este obligatorie. {i asupra lor vom reveni.
 void este tipul metodei main(). Semnifica]ia este cea din C++, adic`
metoda nu returneaz` nici o valoare.
 |n Java, se face distinc]ie \ntre literele mari [i cele mici. De exemplu,
Mama si mama sunt identificatori diferi]i.

1.3. Conceptul de Maşină Virtuală Java (JVM)


Una dintre cerin]ele care au stat la baza cre`rii
limbajului Java a fost aceea de a ob]ine un limbaj
portabil. Aceasta \nseamn` c` un program scris pe un
anumit calculator, pe care ruleaz` un anumit sistem de
operare, s` poat` rula f`r` modific`ri [i pe un alt
calculator, pe care ruleaz` alt sistem de operare. De exemplu, s` se poate
scrie un program care s` fie rulat pe Windows [i pe Linux.
16 Bazele programării în Java

Pentru a rezolva aceast` problem`, cei de la Sun au recurs la


urm`torul procedeu:

 Fiecare utilizator al unui sistem de operare poate download-a mediul


specific acelui sistem de operare. De aceasta v-a]i convins atunci
c@nd a]i download-at mediul pentru Windows.

 Mediul specific pentru un anumit sistem de operare con]ine un


compilator special creat pentru el. El preia programul din fi[ierul surs`
[i “\l traduce” \ntr-un cod anume, numit byte-code. Compilatorul este
programul javac, iar fi[ierul compilat are extensia .class.

 Programele \n byte-code sunt rulate pe a[a numita Ma[in` Virtual`


Java (JVM). Ma[ina virtual` Java este un suport soft care trebuie s`
fie instalat pe calculatoarele care ruleaz` astfel de fi[iere. C@nd a]i
instalat mediul Java, implicit a]i instalat [i ma[ina virtual` java. De
altfel, ma[ina virtual` Java poate fi instalat` [i \n absen]a mediului de
dezvoltare Java.

 Un fi[ier \n byte-code (extensia .class) poate fi rulat pe orice


calculator, indiferent de sistemul de operare pe care-l are, dac` are
instalat` ma[ina virtual` Java. Practic, se ia prima instruc]iune din
fi[ierul byte-code, este tradus` \n instruc]iuni ale calculatorului pe care
ruleaz` aplica]ia [i acestea din urm` sunt executate; se ia o a doua
instruc]iune din byte-code carte se traduce [i se ruleaz`, [.a.m.d.

 Se poate observa c` Java are [i un compilator care traduce sursa \n


byte-code (javac.exe) dar [i un interpreter care traduce [i execut`
fiecare instruc]iune din byte-code \n instruc]iuni ale calculatorului pe
care se execut` aplica]ia.

Datorit` faptului c` Java este \nzestrat cu interpreter (ia o


instruc]iune, o traduce [i o execut`, apoi alt` instruc]iune, o traduce
[i o execut`...), programele se execut` mai lent. Acest fapt este
compensat de procesoarele din ce \n ce mai performante, dar [i de
performan]ele interpreterului.

1.4. Tipuri de aplicaţii Java


|n Java exist` trei tipuri de aplica]ii:

1. Aplica]ii de sine st`t`toare (stand-alone). Acestea sunt precum


aplica]iile studiate \n Pascal sau C++: se ruleaz` pe un anumit calculator.
2. Aplica]ii care se ruleaz` pe partea de client (applet-uri). Un applet
este alc`tuit dintr-unul sau mai multe fi[iere cu extensia .class [i este
utilizat \n cadrul paginilor web. Practic, el este ata[at textului HTML, la fel
Capitolul 1. Java, primele noţiuni 17

cum se ata[eaz` o imagine, iar fi[ierele care-l alc`tuiesc se transfer` pe


site. El este adus pe calculatorul clientului atunci c@nd se apeleaz` pagina
respectiv` [i este executat prin intermediul browser-ului.
3. Aplica]ii care se execut` pe partea de server (servlet-uri).

! |n aceast` carte sunt tratate doar aplica]iile din primele dou` tipuri.

1.5. Comentarii
|n Java, se pot pune comentarii oriunde dorim, la fel ca [i \n C++.
Ele sunt de dou` feluri:

1. Comentariile la nivel de linie: // tot ce urmeaz` dup` ele, pe linia


celor dou` caractere, este considerat comentariu.
2. Comentarii pe mai multe linii se g`sesc \ntre /* [i */.

class prima { // un comentariu


public static void main(String[] args) {
/* Acesta
este alt comentariu */
System.out.println("Acesta este primul program Java");}
}

1.6. Afişarea şirurilor de caractere


Pentru afi[area datelor vom utiliza dou` metode:
1. System.out.print( sir_de_caractere);
2. System.out.println(sir_de_caractere);

Ambele metode afi[eaz` [irul de caractere c`utat. Diferen]a dintre ele


este dat` de faptul c` dup` afi[are, \n cazul System.out.print(),
cursorul r`m@ne pe r@ndul curent (dup` ultimul caracter scris), iar \n cazul
System.out.println(), dup` ce s-a scris [irul de caractere, cursorul
trece pe linia urm`toare.

1.7. Programe care se găsesc în alte folder-e


Nu este obligatoriu ca programele s` se g`sesc` \n
folder-ul bin. Exist` posibilitatea ca programele Java s` se
re]in` [i \n alte folder-e. S` vedem cum!

Crea]i un folder pe C:\, numit TestJava. Muta]i acolo fi[ierul


prima.java, prezentat \n primul paragraf.
18 Bazele programării în Java

Pentru a-l compila, da]i comanda urm`toare, unde a]i scris [i calea
c`tre fi[ier:

javac c:\testjava\prima.java

Pentru a-l rula, da]i comanda urm`toare, unde parametrul –classpath


spune programului java.exe unde g`se[te fi[ierul cu extensia .class.

java –classpath c:\testjava prima

De altfel, parametrul classpath poate fi pus [i \n variabila de mediu


CLASSPATH, a[a cum am ar`tat. Mai mult, calea se poate scrie \n
continuarea celei existente, a[a cum vede]i mai jos:

|n acest caz, la apelul programului Java nu mai este necesar s` d`m


parametrul -classpath.

Aten]ie: dac` set`m calea ca mai sus, cu ajutorul variabilei de mediu


CLASSPATH, fi[ierul cu extensia .class se caut` \n fiecare cale

 trecut`, \n ordinea \n care au fost trecute c`ile. De exemplu, mai \nt@i


fi[ierul cu extensia .class este c`utat \n bin [i apoi este c`utat \n
TestJava. Aceasta \nseamn` c` dac` \l avem \n ambele locuri, este
executat cel aflat \n bin.
CAPITOLUL 2

Manipularea datelor

Din cuprins:
Tipuri de date
Operatori
Instrucţiuni
Masive
Citirea datelor de la tastatură
Probleme rezolvate
Probleme propuse
20 Bazele programării în Java

2.1. Tipuri de date


|n teoria clasic` a limbajelor de programare, prin tip de date se
\n]elege:
 o mul]ime de valori;
 o regul` prin care aceste valori se codific`;
 o mul]ime de opera]ii definite pe mul]imea valorilor.

Limbajul Java extinde no]iunea de tip de date, la aceea de tip. Aici


se lucreaz` cu clase, care descriu \ntr-o unic` structur` at@t date c@t [i
metode (func]ii). Obiectele sunt instan]ieri ale claselor, deci fiecare obiect
con]ine at@t date c@t [i metode. Asupra acestor probleme vom reveni, dar
re]ine]i faptul c`, \n Java, prin tip vom \n]elege o clas`, iar un obiect are
un anumit tip dac` rezult` ca instan]iere a unei clase.

Totu[i, limbajul Java utilizeaz` [i tipuri \n sens clasic, vezi prima


defini]ie. Pentru a nu se crea confuzii, aceste tipuri se numesc tipuri
primitive. Astfel, avem tipuri de date primitive [i tipuri referin]`.

2.1.1. Tipurile de date primitive


a) Tipuri \ntregi

Tip Octe]i Numere \ntregi din intervalul


ocupa]i
byte 1 [-128,127]
short 2 [-32768,32768]
int 4 [-2147483648, +2147483647]
long 8 [-9223372036854775808,9223372036854775807]

Exemple:
Declar`m [i afi[`m mai multe variabile de tip \ntreg:
short t=32767;
byte z=-128, x=15;
int a=100000;
System.out.println(t);
System.out.println(z);
System.out.println(x);
System.out.println(a);
Capitolul 2. Tipuri şi operaţii de date 21

b) Tipuri reale

Tip Octe]i ocupa]i Modulul valorilor \ntre


float 4 [3.410-38, 3.41038]
double 8 [1.710-308,1.710308]

Pentru ini]ializarea tipurilor reale se folosesc literali.


Exemple:
Pentru tipul real float, literalii trebuie urma]i \n mod obligatoriu
de litera f. Excep]ie fac literalii care reprezint` valori \ntregi.

1. float a=3,b=2.5f,c=-7,d=3E2f,g=-2.4E-2f; Valorile cu care am


ini]ializat variabilele sunt: 3, 2, 2.5, -7, 3102, -2.410-2.
Acelea[i valori se folosesc pentru a ini]ializa variabile de tip double:
2. double a=3,b=2.5,c=-7,d=3E2,g=-2.4E-2;

c) Tipul char

O variabil` de tipul char re]ine un caracter. |n Pascal, C/C++,


caracterele sunt re]inute prin utilizarea codului ASCII. |n Java, codul utilizat
pentru memorarea caracterelor este Unicode [i, \n acest cod, un caracter
ocup` 2 octe]i.

Exemplu: mai jos pute]i observa declara]ia a trei variabile de tip char:

char a='m', b='\u006d', c=109;


System.out.println(a); System.out.println(b); System.out.println(c);

Toate variabilele re]in caracterul m. Prima dat` caracterul este declarat


\n mod clasic, a doua oar` este declarat prin codul s`u \n hexa [i a treia
oar` este declarat \n zecimal. Cele afirmate sunt probate prin afi[are, pentru
c` se afi[eaz` de trei ori m.

Caracterele se pot declara sub form` de coduri escape:

Caracter Semnifica]ie
\\ backslash
\n newline
\' apostrof
\” ghilimele
\r carriage return
\t tab
\f salt la pagin` nou`
22 Bazele programării în Java

Exemple:
1. char a='\''; am declarat caracterul apostrof. Dac` am \ncerca s`
declar`m acest caracter prin char a='''; primim eroare de sintax`.
2. char b='\n'; am declarat caracterul newline. Dac` se afi[eaz`
acest caracter, cursorul sare pe linia urm`toare.
3. char c='\\'; am declarat caracterul backslash. Dac` am \ncerca s`
declar`m acest caracter prin char a='\'; primim eroare de sintax`.

d) Tipul boolean

O variabil` de acest tip poate re]ine la un moment dat, una din cele
dou` valori: false (fals) sau true (adev`rat).

Exemplu: se declar`, se ini]ializeaz` [i se afi[eaz` con]inutul unei variabile


de tip boolean:
boolean c=true;
System.out.println(c);

 Metodele System.out.print() [i System.out.println()


permit afi[area tuturor tipurilor primitive.

2.1.2. Tipul referinţă


O variabil` de tip referin]` re]ine o referin]` (adres`) c`tre un obiect.
Cu ajutorul referin]ei, putem accesa datele membru [i metodele obiectului.
Numele tipului unei astfel de variabile coincide cu numele clasei. Cum
obiectele sunt instan]eri ale claselor [i cum putem proiecta o infinitate de
clase, \nseamn` c` exist` o infinitate de de tipuri referin]`. Prin abuz de
limbaj, vom spune despre o variabil` care poate re]ine o referin]` c`tre un
anumit obiect. c` este de tip referin]`. Orice variabil` de tip referin]` poate
re]ine valoarea null. Ea are semnifica]ia de “nici o referin]`”.

2.1.3. Observaţii importante


A[a cum am ar`tat, cu ajutorul celor dou` metode,

System.out.print() [i System.out.println(),

putem afi[a con]inuturile variabilelor de un tip primitiv. Mai avem de precizat


dou` lucruri esen]iale:

a. Dac` \n corpul unei metode, \n exemplu main(), se g`se[te


o variabil` neini]ializat` [i se \ncearc` afi[area con]inutului pe
Capitolul 2. Tipuri şi operaţii de date 23

care \l are, tentativa este sanc]ionat` prin eroare de sintax`.


Vede]i mai jos:
int i;
System.out.println(i);

b. Avem posibilitatea de a afi[a mai multe variabile pe aceea[i


linie. Aceasta se ob]ine prin convertirea con]inutului variabilelor
\n [iruri de caractere [i concatenarea [irurilor cu ajutorul
operatorului +. Vede]i exemplul de mai jos care afi[eaz` pe o
linie a=2 b=4.5:
int a=2; float b=4.5f;
System.out.println("a="+a+" b="+b);

2.2. Operatori
|n acest paragraf vor fi prezenta]i operatorii utiliza]i \n Java.

2.2.1. Operatori aritmetici


Exist` urm`torii operatori aritmetici:
 - minus (unar, adic` ac]ioneaz` asupra unui singur operand);
 + plus (unar);
 + (binar), pentru adunare;
 - (binar), pentru sc`dere;
 * (binar), are semnifica]ia de \nmul]ire;
 / (binar), pentru \mp`r]ire;
 % (binar) restul \mp`r]irii \ntregi.

 Observa]ii:
1. Operatorul '/' (\mp`r]ire) ac]ioneaz` \n mod diferit \n func]ie de
operanzi:
a) dac` ambii sunt de tip \ntreg, rezultatul este \ntreg [i are
semnifica]ia de \mp`r]ire \ntreag`. Cu toate acestea, rezultatul
este corect (din punct de vedere matematic) numai dac` valorile
care se \mpart sunt pozitive.
b) dac` cel pu]in un operand este de unul din tipurile reale
rezultatul este real (se efectueaz` \mp`r]irea obi[nuit`).
2. Operatorul '%' ac]ioneaz` numai asupra operanzilor de tip \ntreg.
Rezultatul ob]inut este corect din punct de vedere matematic
numai dac` ambii operanzi sunt numere naturale.
24 Bazele programării în Java

3. |n cazul \n care se \mpart dou` valori \ntregi se procedeaz`


astfel:
 se face \mp`r]irea \ntreag` a celor dou` valori care sunt
considerate \n modul;
 semnul c@tului se stabile[te dup` regula semnelor (+ cu +
rezultat +, + cu -, rezultat -), etc.
 |n cazul operatorului '%', se face \mp`r]irea ca anterior (se
ob]ine C), iar restul se o]ine dup` formula R=D-|C.
 Se pot utiliza oric@te perechi de paranteze rotunde, pentru a
impune ca anumite opera]ii s` se fac` prioritar.
Exemple:

1. Fie declara]ia: int a=10;. Atunci expresia 4*a/3 este de tip int [i la
evaluare se ob]ine 13. S-a \nmul]it 4 cu con]inutul variabilei a (10) [i s-a
ob]inut 40. Apoi, 40/3=13 (a fost efectuat` \mp`r]irea \ntreag`). |n acelea[i
condi]ii, expresia 4*(a/3) are ca rezultat num`rul 12. La \nceput s-a
efectuat a/3 [i s-a ob]inut 3, apoi 4*3=12. Iat` un exemplu \n care se
observ` faptul c` una este o expresie la matematic`, [i alta \n Java.
2. Fie declara]ia: float a=10;. Expresia 4*(a/3) are rezultatul 13.3333,
la fel ca expresia 4*a/3. De aceast` dat`, s-a efectuat \mp`r]irea a dou`
numere reale.
3. Fie declara]ia: int a= -10;. Atunci expresia a%3 are ca rezultat
num`rul -1.
4. Fie declara]ia: int a=-10;. Atunci expresia a*-3 are ca rezultat 30.
5. Fie declara]iile: int a=10; char b=2; float c=5;. Atunci expresia:
a+b+c are rezultatul 17.0.

|n exemple, apare o problem` foarte important`: care este tipul


rezultatului, \n cazul \n care o expresie aritmetic` are operanzi de mai
multe tipuri? Problema de mai sus se nume[te problema conversiilor
aritmetice implicite (dup` cum vom vedea, conversiile se pot face [i
explicit).
Regula general` este: se converte[te unul din operanzi c`tre tipul
celuilalt (mai cuprinz`tor). De exemplu, dac` unul din operanzi este de tip
int, iar cel`lalt de tip float, rezultatul va fi de tip float.


F`r` o conversie prealabil`, operatorii aritmetici nu ac]ioneaz` asupra
variabilelor de tip char. De exemplu, secven]a char x=’1’; x=x+1;
este eronat` din punct de vedere sintactic.
Capitolul 2. Tipuri şi operaţii de date 25

2.2.2. Operatori relaţionali


|n Java exist` urm`torii operatori rela]ionali:
 < (mai mic);
 <= (mai mic sau egal);
 > (mai mare);
 >= (mai mare sau egal).
|ntruc@t \n Java exist` valorile logice true [i false, rezultatul unei
opera]ii logice este una dintre aceste valori.
Exemple:
1. 3>5 - expresia ia valoarea false;
2. 3<5 - expresia ia valoarea true;
3. 3+7>=11-1 - expresia ia valoarea true (este posibil s` scriem astfel
de expresii, \ntruc@t operatorii rela]ionali au o prioritate mai mic` dec@t
operatorul aditiv).

2.2.3. Operatori de egalitate


Ace[tia sunt:
 == pentru egalitate;
 != pentru inegalitate.
Ca [i operatorii rela]ionali, expresiile de acest tip returneaz` 0 sau 1 -
\n func]ie de modul \n care este respectat` sau nu egalitatea (inegalitatea).
Exemple:
1. 3==3, rezultat true;
2. 3!=3 rezultat false;

2.2.4. Operatorii de incrementare şi decrementare


Ace[ti operatori sunt unari [i au rolul de a incrementa (adun` 1) sau
decrementa (scad 1) con]inutul unei variabile. Operatorii sunt:
 ++ pentru incrementare;
 -- pentru decrementare.
Operatorii pot fi prefixa]i (aplica]i \n fa]a operandului) sau postfixa]i
(aplica]i dup` operand). Exemplu: fie a o variabil` de tip int.
Operatorul de incrementare prefixat aplicat variabilei a este ++a;
Operatorul de incrementare postfixat aplicat variabilei a este a++;
Operatorul de decrementare prefixat aplicat variabilei a este --a;
Operatorul de decrementare postfixat aplicat variabilei a este a--.
26 Bazele programării în Java

Care este diferen]a \ntre efectul unui operator aplicat prefixat sau
postfixat? S` ne g@ndim la faptul c` pot fi expresii care con]in [i al]i
operatori \n afara celor de incrementare (decrementare).

 Dac` operatorul este prefixat, variabila este incrementat` (decrementat`)


\nainte ca valoarea re]inut` de ea s` intre \n calcul.

 Dac` operatorul este postfixat, variabila este incrementat` (decrementat`)


dup` ce valoarea re]inut` de ea intr` \n calcul.
Exemple:
1. Fie a o variabil` de tip int care re]ine valoarea 1. |n urma evalu`rii
expresiei 1+a++ se ob]ine valoarea 2, dar dup` evaluare, a va re]ine
valoarea 2 (variabila a fost incrementat` dup` ce valoarea re]inut` de ea a
intrat \n calcul).
2. La fel ca \n cazul anterior, expresia 1-++a produce valoarea -1 (vari-
abila a fost \nt@i incrementat`, s-a ob]inut 2, apoi s-a efectuat 1-2).
3. Expresia 1+++a este eronat` sintactic. S-a considerat c` operatorul de
incrementare este aplicat postfixat pentru 1 [i nu prefixat pentru a. Aplicarea
unui operator de acest tip se poate face pentru o variabil`.
4. Dac` a [i b sunt variabile de tip int care re]in valorile 1 [i 3, atunci
expresia a++*b++ produce valoarea 3, dar dup` evaluare cele dou`
variabile re]in 2 [i 4.
5. |n acelea[i condi]ii, expresia ++a*++b produce valoarea 8, iar dup`
evaluare a [i b re]in 2 [i 4 (ca \n cazul anterior).
! Ac]iunea operatorului de decrementare este similar` celei de incrementare,
cu diferen]a c` se scade 1 din con]inutul variabilei.

2.2.5. Operatori logici


Exist` trei tipuri de operatori logici care ac]ioneaz` asupra datelor de
tip boolean:

 ! negare logic`;
 && [i logic;
 || sau logic.

Ace[ti operatori se aplic` oric`rei variabile [i constante de tip logic.


Operatorul negare logic` ac]ioneaz` astfel: dac` operandul este o
valoare true, rezultatul este false, altfel rezultatul este true.
Operatorul [i logic (binar) ac]ioneaz` astfel: dac` ambii operanzi sunt
true rezultatul este true, altfel el este false.
Capitolul 2. Tipuri şi operaţii de date 27

Operatorul sau logic (binar) ac]ioneaz` astfel: dac` cel pu]in unul din
operanzi este true, rezultatul este true, altfel rezultatul este false.
Exemple: \n condi]iile: boolean a=true, b=false;
1. !a returneaz` false;
2. a||b returneaz` true;
3. a&&b returneaz` false;
Operatorii logici binari garanteaz` modul \n care se trateaz` operanzii
- \nt@i cel din st@nga, apoi (dac` este cazul) cei din dreapta. Astfel, dac`
operandul din st@nga este true, operatorul sau logic nu mai ac]ioneaz`
asupra operandului din dreapta (este clar c` rezultatul este true). Tot a[a,
dac` operandul din st@nga este false, operatorul [i logic nu mai evalueaz`
operandul din dreapta (oricum rezultatul este false). Observa]ia este foarte
important` pentru cazul \n care al doilea argument este func]ie (metod`) de
tip boolean.

2.2.6. Operatori logici pe biţi


Limbajul Java este dotat cu un set de operatori care permit accesul la
bit. Ace[tia sunt:
 <<, >>, >>> operatori de deplasare;
 & [i pe bi]i;
 | sau pe bi]i;
 ^ sau exclusiv pe bi]i;
 ~ negare pe bi]i (operator unar).

Ace[ti operatori ac]ioneaz` numai asupra operanzilor de tip \ntreg.

Operatorul << este binar. El are rolul de a deplasa c`tre st@nga con]inutul
tuturor bi]ilor operandului din st@nga sa, cu un num`r de pozi]ii egal cu
valoarea re]inut` de al doilea operand. Pozi]iile r`mase libere (\n dreapta)
vor re]ine valoarea 0. Dac` al doilea operand re]ine valoarea m, o astfel de
deplasare este echivalent` cu \nmul]irea cu 2m (evident, dac` m este mai
mic dec@t num`rul de bi]i rezervat primului operand).

Operatorul >> este binar. El are rolul de a deplasa c`tre dreapta con]inutul
tuturor bi]ilor operandului din st@nga cu un num`r de pozi]ii egal cu
valoarea re]inut` de al doilea operand. Aten]ie: \n pozi]iile din st@nga,
r`mase libere dup` deplasare, se copiaz` con]inutul bitului de semn (acesta
re]ine 1 \n cazul numerelor negative [i 0, \n cazul numerelor pozitive).
Dac` operandul din st@nga este un \ntreg pozitiv, pozi]iile r`mase libere (\n
st@nga) vor re]ine valoarea 0. |n cazul \ntregilor pozitivi, dac` al doilea
28 Bazele programării în Java

operand re]ine valoarea m, o astfel de deplasare este echivalent` cu


\mp`r]irea \ntreag` cu 2m.

Operatorul >>> ac]ioneaz` la fel ca [i operatorul >>, dar diferen]a este dat`
de faptul c` pozi]iile r`mase libere din dreapta vor re]ine 0.

Aten]ie: operatorii de deplasare sunt utiliza]i doar pentru evaluarea

 expresiilor, operanzii, chiar dac` sunt variabile, r`m@n nemodifica]i!


Desigur, valorile astfel ob]inute pot fi atribuite. Aceasta \nseamn`, de
fapt, acces la bit.
|n cazul operatorilor binari &, ^, |, rezultatul se ob]ine aplic@nd
pentru fiecare pereche de bi]i afla]i pe aceea[i pozi]ie regulile din tabelul
urm`tor:
OP1 OP2 OP1&OP2 OP1^OP2 OP1|OP2
0 0 0 0 0
1 0 0 1 1
0 1 0 1 1
1 1 1 0 1

Operatorul ~ (negare pe bi]i) are rolul de a inversa con]inutul bi]ilor


(dac` un bit con]ine 0 va con]ine 1 [i invers).
Exemple: dac` a este de tip int [i re]ine 3, iar b este de acela[i tip [i
re]ine 1 atunci:
1. a&b returneaz` 1;
2. a|b returneaz` 3;
3. a^b returneaz` 2;
4. a<<2 returneaz` 6;
5. a>>1 returneaz` 1;
6. ~a returneaz` -4.

2.2.7. Operatori de atribuire


|n Java atribuirea este operator, dar dup` cum vom vedea, este [i
instruc]iune. |n plus, avem mai mul]i operatori de atribuire. Operatorul '=' se
folose[te \ntr-o expresie de forma:
v=expresie
Aici, v este o variabil`.
Capitolul 2. Tipuri şi operaţii de date 29

Principiul de executare este urm`torul:


 se evalueaz` expresia;
 varibilei v i se atribuie valoarea ob]inut` (dac` este cazul se
efectueaz` conversia respectiv`).

Se pot efectua [i atribuiri multiple de forma:


v=v1=v2=.......=vn=expresie,
unde v, v1........vn sunt variabile.
|n acest caz, principiul de executare este urm`torul:

 se evalueaz` expresia;
 valoarea ob]inut` este atribuit` variabilei vn (eventual convertit` -
dac` este cazul);
 con]inutul variabilei vn este atribuit variabilei vn-1 (eventual se
efectueaz` conversia necesar`);
 . . .
 con]inutul variabilei v1 este atribuit variabilei v (eventual se
efectueaz` conversia necesar`).

Acest operator se asociaz` de la dreapta la st@nga. Ce am prezentat


anterior eviden]iaz` acest lucru.

Pentru atribuiri se mai pot utiliza [i operatorii: *=, /=, %=, +=, -=,
<<=, >>=, &>, ^=, |=.

O atribuire de forma: v op=expresie, are acela[i rezultat ca

v=v op expresie
(diferen]a este c` \n primul caz se genereaz` un cod ma[in` eficient).

Observa]ie! Am v`zut faptul c` atribuirea este operator care figureaz`


\ntr-o expresie. Ca orice expresie, aceasta are o valoare rezultat` \n
urma evalu`rii. |n cazul atribuirilor, valoarea rezultat` este valoarea
atribuit` variabilei care este prima din st@nga, (\ntr-un [ir de atribuiri,
eventual dup` conversie).
Exemple:
1. Fie declara]iile: int a=5, b=3; float c;. |n urma atribuirii c=a/b, c
va con]ine valoarea real` 1.0. Este normal s` fie a[a \ntruc@t expresia a/b
este de tip int (se efectueaz` \mp`r]irea \ntreag` [i se ob]ine 1), apoi
aceast` valoare este atribuit` variabilei c (dup` ce este convertit`).
30 Bazele programării în Java

2. Fie declara]iile: int a,b; float c; [i expresia c=a=b=1. Dup`


evaluare, a re]ine 1, b re]ine 1, c re]ine 1.0, iar valoarea rezultat` \n
urma evalu`rii este 1.0 (real`).
3. Fie declara]ia: int a=3; [i expresia a*=2. |n urma evalu`rii, a re]ine
valoarea 6, iar expresia va produce valoarea de tip int 6.


Observa]ie foarte important`! Sunt permise doar atribuiri \n care tipul
variabilei c`reia i se atribuie con]intul unei variabile de alt tip, con]ine,
printre valorile permise, cele ale tipului variabilei care este atribuit`.

Exemple:

1. Fie declara]iile: long a=2; int b=3;


a=b; //corect
b=a; //incorect

2) Fie declara]iile: char a=2; int b=3;


b=a; //corect
a=b; //incorect
3) Fie declara]iile: float a=2; int b=3;
a=b; //corect
b=a; //incorect
4) Fie declara]iile: float a=2; double b=3;
b=a; //corect
a=b; //incorect


Dup` cum observa]i, aici apare o diferen]` fa]` de C/C++. Java, ca
[i Pascal-ul, \ncearc` s` te fereasc` de erori ascunse, rezultate \n
urma conversiilor implicite.

2.2.8. Operatorul condiţional


Se folose[te \n expresii de genul:
exp1?exp2:exp3
Cerin]a este ca exp1 s` fie de tipul boolean. Principiul de executare
este urm`torul:

 se evalueaz` exp1;
 dac` aceasta produce true, se evalueaz` exp2 [i exp3 este
ignorat` (nu se evalueaz`);
 altfel, se evalueaz` exp3 [i exp2 este ignorat`.
Capitolul 2. Tipuri şi operaţii de date 31

|n ansamblu, expresia este de tipul lui exp2 sau exp3 [i produce


valoarea exp2 sau exp3 (\n func]ie de cea care se evalueaz`).
Exemple:
1. Variabila c ia valoarea 5 (valoarea maxim`).
int a=1, b=5, c;
c=a>b?a:b;

2. Se afiseaz` valoarea 5.
int a=1, b=5, c;
System.out.println(a>b?a:b);
3. Variabila h ia valoarea 9. Aici se observ` c` nu este obligatoriu ca
exp2 [i exp3 s` aib` acela[i tip:
int a=1, b=5; float d=9,h;
h=a>b?a:d;

2.2.9. Operatorul de conversie explicită


De multe ori, vrem ca unul sau mai mul]i operanzi s` intre \n calcul
converti]i a[a cum dorim (nu implicit). Pentru aceasta, \naintea operandului
se trece \ntre paranteze tipul s`u.

Exemple:

1) Variabila a ia valoarea 9. Iat` c`, desi implicit conversia nu poate fi


realizat`, \n acest mod s-a efectuat f`r` probleme.
int a=1; double d=9.6;
a=(int)d;

2) Se afi[eaz` 0.5. Iat` c`, de[i, operanzii sunt \ntregi [i rezultatul ar


trebui s` fie 0, prin utilizarea operatorului de conversie explicit` se ob]ine
rezultatul corect.
int a=3, b=6;
System.out.println((float) a/b);

2.2.10. Prioritatea (precedenţa) operatorilor


Operatorii au o anumit` prioritate (preceden]`). Mai jos, sunt prezenta]i
operatorii \n ordinea descresc`toare a priorit`]ii.

1) (), . , []
2) ++, --, +(unar),–(unar),!, new, operatorul de conversie
explicit`
3) *, /; %
32 Bazele programării în Java

4) +, - (privi]i ca operatori binari)


5) <<, >>,>>>
6) <, <=,>,>=
7) ==, !=
8) &
9) ^
10) |
11) &&
12) ||
13) ?:
14) =, +=, etc (operatori de atribuire)

2.3. Instrucţiuni
1. Instruc]iunea vid`. Instruc]iunea nu face nimic, dar are sens \n
programul Java, dup` cum va rezulta din studiul altor instruc]iuni.
Instruc]iunea vid` se marcheaz` prin ;.

2. Instruc]iunea compus`. Se utilizeaz` atunci c@nd se dore[te ca mai


multe instruc]iuni s` fie considerate ca o singur` instruc]iune. Mai jos, pute]i
observa o instruc]iune compus` care subordoneaz` mai multe instruc]iuni
vide.

{
;
;
;
}

3. Instruc]iunile de incrementare [i decrementare. Se utilizeaz` pentru


a incrementa sau decrementa o anumit` variabil`.
Exemple:
a++; ++a; a--; --a;

Exist` o diferen]` \ntre operatorii de incrementare (decrementare) [i


instruc]iunea de incrementare (decrementare). Instruc]iunea de

 incrementare (decrementare) con]ine numai un operator de


incrementare (decrementare), dar de exemplu, b=++a+1 este o
instruc]iune (atribuire, vezi mai jos) care con]ine [i un operator de
incrementare.

4. Instruc]iunea de atribuire. Con]ine o expresie prin care unei variabile i


se atribuie o alt` expresie (aflat` \n dreapta operatorului de atribuire).
Capitolul 2. Tipuri şi operaţii de date 33

Exemple:
a) int a, b=6;
a=b+5; // dup` atribuire a re]ine 11.
b) int a, b=6;
a=++b+5; // dup` atribuire a re]ine 12.
c) int a=1, b=6;
a+=b; // dup` atribuire a re]ine 7.
d) a=b=c=1; // a, b, c sunt de tip int.

Iat` o atribuire multipl`. Ini]ial, c ia valoarea 1, apoi b=c, atunci b=1,


apoi a=b, deci a=1. Dup` atribuire a, b, [i c re]in 1.

 Observa]ii:
 Nu sunt permise atribuiri de genul: ++a=b+5;
 Exist` o diferen]` \ntre operatorul de atribuire [i instruc]iunea de
atribuire. De exemplu, a=b=c=1 este o instruc]iune de atribuire, dar
con]ine 3 operatori (de atribuire). Practic, o instruc]iune de atribuire
con]ine cel pu]in un operator de atribuire.

5. Instruc]iunea if. Are dou` forme:

Forma 1.
if (expresie de tip boolean) instruc]iune1 else instruc]iune2

Principiul de executare este urm`torul:

 se evalueaz` expresia;
 dac` valoarea produs` de aceasta este true, se execut`
instruc]iune1;
 dac` valoarea produs` este false se execut` instruc]iune2.

Forma 2.
if (expresie de tip boolean) instruc]iune

Principiul de executare este urm`torul:

 se evalueaz` expresia;
 dac` valoarea produs` de aceasta este true, se execut`
instruc]iunea subordonat`, altfel se trece la cea urm`toare.

Exemple: a) Se afi[eaz` cea mai mare valoare dintre valorile re]inute de


variabilele a [i b:
if (a>b) System.out.println(a);
34 Bazele programării în Java

else System.out.println(b);
b) Se rezolv` ecua]ia ax+b=0, unde pentru valorile lui a [i b sunt re]inute
variabilele cu acela[i nume.
if (a!=0)
{ x=-b/a;
System.out.println(x); }
else
if (b==0) System.out.println("infinitate de solutii");
else System.out.println("nu are solutie");

6. Instruc]iunea while. Forma general` este:

while (expresie de tip boolean) instruc]iune

Principiul de executare este urm`torul:

 Se evalueaz` expresia;
 Dac` valoarea produs` de aceasta este true, se execut`
instruc]iunea subordonat`, apoi se revine la evaluarea expresiei,
altfel se trece la instruc]iunea urm`toare.

Exemple:

a) Pentru n>0, num`r natural, s` se calculeze suma cifrelor sale (pentru


n=213, se va afi[a 6):
int n=213,s=0;
while (n!=0)
{ s+=n%10;
n/=10;
}
System.out.println(s);

b) Pentru n, num`r natural, s` se afi[eze num`rul ob]inut prin inversarea


cifrelor sale (pentru n=213, se va afi[a 312):
while (n!=0)
{ ninv=ninv*10+n%10;
n=n/10; }
System.out.println(ninv);

7. Instruc]iunea do while. Forma general` a acestei instruc]iuni este


urm`toarea:
do
instruc]iune
while(expresie);

Principiul de executare este urm`torul:


Capitolul 2. Tipuri şi operaţii de date 35

 Se execut` instruc]iunea subordonat`;


 Se evalueaz` expresia. |n cazul \n care valoarea produs` la
evaluare este false, execu]ia instruc]iunii do while se termin`,
altfel se trece la pasul anterior..

 Observa]ie: secven]a se execut` cel pu]in o dat`, dup` care se pune


problema dac` s` se repete sau nu (prin evaluarea expresiei logice).

Exemple:

a) Se d` un num`r natural n, mai mare sau egal cu 1. S` se calculeze


suma primelor n numere naturale nenule.

int n=10,s=0,i=1;
do
{ s=s+i;
i=i+1;
} while (i<=n);
System.out.println(s);

b) Se d` un num`r natural n, mai mare sau egal cu 1. S` se


descompun` n \n factori primi.

int n=115,i=2,fm;
do
{
fm=0;
while (n%i==0)
{ fm++;
n/=i;
}
if (fm!=0) System.out.println(i+" la puterea "+fm);
i++;
}while (n!=1);

8. Instruc]iunea for are forma general`:

for(expresieini]ializare;expresietest;expresieincrementare) instruc]iune

Dup` cum se vede, \ntre paranteze se g`sesc 3 expresii:

 Expresieinitializare se folose[te de regul` pentru ini]ializarea variabilei de


ciclare. Este de remarcat faptul c` \n cadrul acestei expresii (cu rol
special) este posibil chiar s` declar`m variabila de ciclare (cu valoare
ini]ial`).
 Expresietest este de tip boolean [i se folose[te pentru a testa dac`
se execut` instruc]iunea subordonat` - dac` expresia produce la
36 Bazele programării în Java

evaluare true, instruc]iunea subordonat` for se execut`.


 Expresieincrementare se folose[te pentru incremenatarea variabilei de
ciclare.

Principiul de executare:

P1. Se evalueaz` expresieini]ializare (un caz special este când aceasta


con]ine [i declara]ia variabilei de ciclare);
P2. Se evalueaz` expresiatest. |n cazul \n care aceasta produce true,
se execut` instruc]iunea subordonat` for; apoi se trece la P3, altfel
se trece la instruc]iunea urm`toare (se termin` execu]ia instruc]iunii
for).
P3. Se evalueaz` expresia de incrementare [i se revine la P2.

Toate expresiile pot fi vide. |n concluzie, expresiile de mai sus au

 rolul precizat \n mod normal - dar nu obligatoriu [i nici restrictiv. De


exemplu, dac` expresietest este vid`, se execut` un ciclu infinit.
for(;;) instruc]iune.

Exemple:

a) Se afi[eaz` numerele, 10, 9,..1, fiecare pe c@te un r@nd. Observa]i


faptul c` variabila i a fost declarat` \n cadrul ciclului for.

for (int i=10;i>=1;i--) System.out.println(i);

b) Se afi[eaz` alfabetul, de la „a‟ la „z‟ [i pentru fiecare caracter se


afi[eaz` [i codul s`u.
for (char c='a';c<='z';c++)
System.out.println(c+" "+(int)c);

c) Se calculeaz` suma S  1  1  2  1  2  3  ...  1  2  ...  n


int i,s=0,p=1,n=3;
for(i=1;i<=n;i++)
{ p*=i;//p=p*i;
s+=p; //s=s+p;
}
System.out.println(s);

9. Instruc]iunea break.

Are rolul de a for]a iesirea dintr-un ciclu. |n cazul \n care exist` cicluri
imbricate (un ciclu in interiorul altui ciclu), for]eaz` doar ie[irea din primul
ciclu (vezi secven]a urm`toare, unde for-ul dup` j se execut` doar pentru
j=1). Se folos[te pentru instruc]iunile for, while, do while [i, \n
Capitolul 2. Tipuri şi operaţii de date 37

particular, pentru switch (cazul va fi studiat separat). Analiza]i secven]a de


mai jos:
for (int i=1;i<=4;i++) Se afi[eaz`
for (int j=1;j<=4;j++)
if (j==2) break; 1 1
else System.out.println(i+" "+j); 2 1
3 1
4 1

10. Instruc]iunea continue; este folosit` \n cazul ciclurilor (for,


while, do while) [i are rolul de a determina ca, dup` executarea ei, s`
se sar` direct la testul condi]iei de continuare. Astfel, se ignor` instruc]iunile
care \i urmeaz` \n secven]a care se repet`.

Exemplu: secven]a urm`toare afi[eaz`. 1, 3. 4. Dac` i ia valoarea 2,


atunci, se execut` continue [i se sare peste apelul metodei de afi[are.

for (int i=1;i<=4;i++)


{ if (i==2) continue;
System.out.println (i);}

11. Instruc]iunea switch are forma particular`:


switch (expresie)

case exp1: secven]` instruc]iuni1; break;
case exp2: secven]` instruc]iuni2; break;
.................................
case expn: secven]` instruc]iunin; break;
[default: secven]` instruc]iunin+1];

unde:
 expresie are semnifica]ia: expresie de tip \ntreg (sau char).;
 expi : sunt expresii constante de tip \ntreg (sau char);
 instruc]iunii reprezint` o secven]` oarecare de instruc]iuni.

Principiul de executare:

 se evalueaz` expresia;

 dac` aceasta produce o valoare egal` cu cea produs` de


expi, se execut`, \n ordine, instruc]iunii [i se trece la
instruc]iunea urm`toare, altfel se execut` numai secven]a
instruc]iunin+1.

 Observa]ie. Alternativa default este facultativ`. |n absen]`, \n cazul \n


care nu exist` coinciden]` de valori, se trece la instruc]iunea urm`toare.
38 Bazele programării în Java

Exemplu: Secven]a care urmeaz` probeaz` instruc]iunea switch. |n


exemplu se afi[eaz` 1:
int i =1;
switch(i)
{
case 1: System.out.println(1);break;
case 2: System.out.println(2);break;
default: System.out.println("altceva");
}

 Observa]ie. Am prezentat o form` simplificat` a instruc]iunii switch, mai


precis, cea corespunz`toare program`rii structurate. |n absen]a
instruc]iunii break, \n cazul \n care exist` egalitate \ntre expresie [i
expi se execut` secven]a corespunz`toare [i, pe r@nd, toate secven]ele
care urmeaz`, [.a.m.d.

Exemplu: secven]a care urmeaz` afi[eaz`: 2, altceva.

int i =2;
switch(i)
{
case 1: System.out.println(1);
case 2: System.out.println(2);
default: System.out.println("altceva");
}


|n forma general`, instruc]iunea switch are rolul de a stabli mai
multe puncte de intrare \ntr-o secven]` de instruc]iuni, \n func]ie de
valoarea pe care o re]ine expresie.

12. Instruc]iunea apel metod` (func]ie) va fi tratatat` la momentul


potrivit. Pentru moment, putem da ca exemplu de astfel de instruc]iune doar
System.out.print() sau System.out.println().

13. Instruc]iunea de declarare a variabilelor. P@n` \n prezent, am


\nt@lnit-o de multe ori. Ea poate fi plasat` oriunde \n corpul unei metode
(func]ii).
Exemplu: int x=2,y.

2.4. Masive
|n Java exist` un mecanism excep]ional de lucru cu masive (vectori,
matrice, etc).
Din motive didactice, pentru \nceput, vom prezenta declararea
masivelor \n doi pa[i:
Capitolul 2. Tipuri şi operaţii de date 39

Pasul 1. Se declar` o variabil` care poate re]ine o referin]` (adres`) c`tre


vector, matrice, etc.
Exemple:
a) int[] V; am declarat o variabil` referin]` c`tre un vector cu
componente de tip int. O declara]ie echivalent` poate fi f`cut` prin:
int V[];.
b) int[][] Mat; am declarat o variabil` referin]` c`tre o matrice cu
componente de tip int.
c) float[] V, V1; am declarat dou` variabile referin]` c`tre vectori,
numite V, respectiv V1. Ambii vectori au componente de tip float.
d) float Mat[][],Mat1[][]; am declarat dou` variabile de tip referin]`
c`tre matrice. Cele dou` variabile se numesc Mat [i Mat1.

Pasul 2. Aloc`m spa]iu \n memorie pentru masiv (vector matrice). Adresa


vectorului va fi re]inut` \n variabila V.
Exemple:
a) V=new int[4];. Am alocat spa]iu \n memorie pentru un vector cu 4
componente de tip int (practic am creat vectorul). Referin]a c`tre el va fi
re]inut` \n V, [i, pornind de la aceast` variabil` putem accesa V.
b) Mat=new int [4][3];. Am alocat spa]iu \n memorie pentru o matrice cu
4 linii [i 3 coloane cu componente de tip int.
 Prima component` a unui vector are indicele 0, a doua indicele 1
[.a.m.d. Tot a[a, liniile unei matrice se numeroteaz` \ncep@nd cu 0,
coloanele unei matrice se numeroteaz` \ncep@nd cu 0.
 O component` a unui vector se adreseaz` porind de la referin]` [i
scriind indicele \ntre paranteze drepte (exemplu V[3]) o component`
a unei matrice se adreseaz` pornind de la referin]` si scriind \ntre
paranteze p`trate fiecare din cei doi indici (exemplu Mat [2][1]).
Exemple:
a) |n secven]a urm`toare se creeaz` un vector, se ini]ializeaz` fiecare
component` a lui [i se afi[eaz`.
int[] V; // sau int V[];
V=new int[4]; int i;
for (i=0;i<4;i++) V[i]=i+1;
for (i=0;i<4;i++) System.out.println(V[i]);

Schema al`turat` reflect`


modul \n care arat` V 1 2 3 4
vectorul, dup` ce i-am 0 1 2 3
ini]ializat componentele. referin]a
40 Bazele programării în Java

 Vectorii se pot declara [i a[a cum se vede mai jos, gata ini]ializa]i.
|n urma unei astfel de declara]ii se poate lucra direct cu ei, exact ca
anterior.
int[] V={1,2,3,4}; int i;
for (i=0;i<4;i++) V[i]=i+1;
for (i=0;i<4;i++) System.out.println(V[i]);

b) |n secven]a urm`toare se creeaz` o matrice, se ini]ializeaz` fiecare


component` a ei [i se afi[eaz`.

int[][] Mat;
int i,j;
Mat=new int [4][3];
for (i=0;i<4;i++)
for (j=0;j<3;j++) Mat[i][j]=i+j;
for (i=0;i<4;i++)
{ for (j=0;j<3;j++)
System.out.print(Mat[i][j]+" ");
System.out.println();
}

 Ca [i vectorii, matricele se pot declara [i a[a cum se vede mai jos,


gata ini]ializate. |n urma unei astfel de declara]ii se poate lucra direct
cu ele, exact ca anterior.
int[][] Mat={{1,2,3,4},{3,4,5,6}};
int i,j;
for (i=0;i<2;i++)
{ for (j=0;j<3;j++)
System.out.print(Mat[i][j]+" ");
System.out.println();
}

 Declararea unui masiv se poate face [i \ntr-un singur pas, ca mai jos:

float[] V=new float[4];

 De vreme ce numele masivului (V, Mat, \n exemplele date) re]ine o


referin]` c`tre masiv, \nseamn` c` unei astfel de variabile i se poate
atribui o referin]` c`tre alt masiv, ceea ce este echivalent cu faptul c`
atribuirea “func]ioneaz`” \n cazul masivelor ca \n cazul variabilelor de
unul din tipurile de date primitive. Totu[i, exist` o diferen]` esen]ial`:
se atribuie doar referin]a, nu con]inutul masivului, care r`m@ne
nemodificat. Masivul care nu mai este referit va fi [ters, automat (f`r`
ca, \n acest scop, s` fie scris` o secven]` special`).
Capitolul 2. Tipuri şi operaţii de date 41

Exemplu: Avem doi vectori, V [i V1. Cei doi vectori sunt crea]i [i ini]ializa]i.
Dup` aceasta, se interschimb` referin]ele c`tre cei doi vectori [i, \n vederea
prob`rii opera]iilor efectuate se afi[eaz`.

float[] V=new float[4], V1=new float[3], Man; int i;


for (i=0;i<4;i++) V[i]=i+1;
for (i=0;i<3;i++) V1[i]=9;
Man=V1; V1=V; V=Man;
for (i=0;i<4;i++) System.out.println(V1[i]);
for (i=0;i<3;i++) System.out.println(V[i]);

Grafic, interschimbarea de mai sus se poate prezenta astfel:


 Dup` crearea [i ini]ializarea celor doi vectori:

V 1 2 3 4
0 1 2 3

V1 9 9 9
11 0 1 2
 1
Man=V1;

V 1 2 3 4
0 1 2 3

V1 9 9 9
11 0 1 2
1
Man

 V1=V;
V 1 2 3 4
0 1 2 3

V1 9 9 9
11 0 1 2
1
Man

 V=Man;

V 1 2 3 4
0 1 2 3

V1 9 9 9
11 0 1 2
1
42 Bazele programării în Java

 O alt` utilizare de excep]ie a acestui mecanism este aceea prin care


se declar` un masiv exact cu num`rul de componente dorit [i nu un
num`r de componente mare, care se presupune c` indiferent de
intrare, nu poate fi dep`[it (ca \n Pascal, C/C++). Aceasta conduce
la economie de memorie.
int n;
// se citeste n;
V=new int [n];

 De[i din punct de vedere teoretic nu se poate explica \n acest


moment, num`rul de componente ale unui vector (masiv
unidimensional) este returnat de data membru (vom \nv`]a despre
date membru) length, apelat` ca mai jos. |n urma execut`rii acestei
secven]e se afi[eaz` 10.
int[] vector=new int[10];
System.out.println(vector.length);

 O matrice poate fi privit` ([i, de fapt asta [i este) ca un vector de


vectori. Fie declara]ia int Mat[][]=new int [4][5]. Putem spune
c` avem un vector cu 4 componente. Fiecare component` este la
r@ndul ei, un vector cu 5 componente. Atunci, length, aplicat`
matricei, re]ine 4, [i aplicat`, de exemplu, componentei de indice 2
returneaz` 5. La executarea secven]ei de mai jos se afi[eaz` 4 [i 5.
int Mat[][]=new int [4][5];
System.out.println(Mat.length);
System.out.println(Mat[2].length);

 |n cazul matricelor (sau, \n general, masivelor de dimensiune mai


mare sau egal` cu 2) exist` posibilitatea ca liniile s` aib` lungime
diferit`. Cu alte cuvinte, o component` a vectorului de vectori
(matricea) poate avea un num`r de componente, alt` component`, alt
num`r de componente. |n secven]a urm`toare am declarat o matrice
cu 2 linii. Prima linie are 3 componente, a doua linie are dou`
componente. |n final, se afi[eaz` con]inutul unui element al matricei.
int Mat[][]=new int [2][];
Mat[0]=new int[3]; Mat[1]=new int[2];
Mat[0][0]=1; Mat[0][1]=2;Mat[1][0]=3;
System.out.println(Mat[0][1]);

 V` da]i seama c@t` economie de memorie se face?


Aplica]ie: secven]a urm`toare creeaz`, ini]ializeaz` [i afi[eaz` o matrice
triunghiular`. Al`turat pute]i observa rezulatul rul`rii. Este ceva faptul c`
pentru a re]ine o matrice triunghiular` se re]ine exact at@t c@t este necesar!
int[] vector=new int[10];
int Mat[][]=new int [4][]; int i, j, k=1;
for (i=0;i<4;i++)
{ Mat[i]=new int[i+1]; // declararea este instructiune
Capitolul 2. Tipuri şi operaţii de date 43

for (j=0;j<=i;j++)Mat[i][j]=k++; }
for (i=0;i<4;i++)
{ for (j=0;j<Mat[i].length;j++)
System.out.print(Mat[i][j]);
System.out.println();
}

2.5. Citirea datelor de la tastatură


Limbajul Java con]ine o mul]ime de facilit`]i, dar pentru \ncep`tori
exist` o real` dificultate \n a citi date de la tastatur`. Pentru aceast`
opera]ie este necesar s` cunoa[tem o serie de clase. Ca s` le \n]elegem,
sunt necesare cuno[tin]e avansate de Java. {i nu putem a[tepta p@n`
atunci, pentru c` este relativ dificil s` prezin]i materia, mai ales la nivel de
liceu, f`r` a putea citi ceva de la tastatur`. Pentru a rezolva aceast`
problem`, am recurs, ca de altfel [i \n alte cursuri de Java, la prezentarea
unei clase prin care s` putem realiza citirea de la tastaur`.
Clasa respectiv`, o prezent`m acum [i \n cele ce urmeaz`, nu ne
vom referi dec@t la utilizarea ei. Ulterior, vom prezenta modul \n care a fost
realizat` clasa precum [i multe alte cuno[tin]e privind opera]iile de
intrare/ie[ire. Iat` clasa pe care o vom folosi (se nume[te cin):
import java.io.*;
import java.util.*;
class cin {
static InputStreamReader f = new InputStreamReader (System.in);
static BufferedReader tamp=new BufferedReader(f);
static String linie() {
try { return tamp.readLine();}
catch (IOException e) {return ("Eroare");}
}
static String Token(){
StringTokenizer v=new StringTokenizer(linie());
if (v.hasMoreTokens())return v.nextToken();
else return"";}
}

Textul de mai sus \l vom introducem \n fi[ierul cin.java. Apoi, \l


compil`m cu javac cin.java. |n urma compil`rii rezult` fi[ierul
cin.class. Acest fi[ier va fi utilizat de orice program care utilizeaz` o
metod` din clasa cin. Dac` fi[ierele cin.java [i cin.class se vor
g`si \n folder-ul bin, atunci, f`r` nici o problem`, utiliz`m aceste metode
ca [i cum ar fi ale limbajului Java (practic, orice program care apeleaz`
clasele respective le g`seste \n bin).

 Metoda linie() are rolul de a citi \ntreaga linie pe care utilizatorul o


introduce de la tastatur`. Rezultatul este de tip referin]` la String,
adic` referin]` c`tre [irul de caractere citit.
44 Bazele programării în Java

Exemplu: programul urm`tor cite[te [i afi[eaz` o linie introdus` de la


tastatur`:
class prima {
public static void main(String[] args) {
String l=cin.linie();
System.out.println(l);}
}
Putem considera c` un [ir de caractere con]ine unul sau mai multe
token-uri (unita]i lexicale). De exemplu. [irul “Ionel are 100 de lei noi”
con]ine 6 token-uri (“Ionel”, “are”, “100”, “de”, “lei”, “noi”). Dup`
cum observa]i, token-urile sunt separate printr-unul sau mai multe spa]ii
albe.
 Metoda Token() cite[te primul token de pe linia introdus` de la
tastatur` [i-l returneaz`.
Exemplu: \n programul urm`tor se cite[te [i se afi[eaz` un token. Dac`
se tasteaz` [irul “Un token”, se afi[eaz` token-ul “Un”. Re]ine]i: metoda
returneaz` numai primul token !
class prima {
public static void main(String[] args) {
String t=cin.Token();
System.out.println(t); }
}

 Dac` dorim s` citim numai un caracter, vom utiliza metoda


charAt(nr), care retuneaz` caracterul aflat pe pozi]ia nr a [irului de
caractere. Aten]ie: primul caracter al [irului are indicele 0.

Exemplu: \n programul urm`tor se cite[te [i se afi[eaz` un caracter.


Observa]i modul de de utilizare al metodei charAt().
class prima {
public static void main(String[] args) {
String l=cin.linie();
char c=l.charAt(0);
System.out.println(c);
}
}

 Dac` dorim s` citim numere, putem folosi tot metoda Token(). |n


acest caz este sarcina noastr` s` convertim rezultatul c`tre tipul dorit.
|n acest caz, vom utiliza metode ale unor clase, numite \nf`[ur`toare,
clase care vor fi studiate la momentul potrivit.
 Metoda Integer.parseInt(sir) returneaz` [irul convertit c`tre int.

Exemplu: Se citesc dou` numere naturale a [i b [i se afi[eaz` suma lor:


class prima {
public static void main(String[] args) {
Capitolul 2. Tipuri şi operaţii de date 45

System.out.print("a=");
int a=Integer.parseInt(cin.Token());
System.out.print("b=");
int b=Integer.parseInt(cin.Token());
System.out.println(a+b);}
}
 Metoda Long.parseLong(sir) returneaz` [irul convertit c`tre long.

Exemplu: \n secven]a urm`toare, se citesc dou` numere naturale mai mari


a [i b [i se afi[eaz` suma lor:
long a=Long.parseLong(cin.Token());
long b=Long.parseLong(cin.Token());
System.out.println(a+b);

 Metoda Float.parseFloat(sir) returneaz` [irul convertit c`tre


float.

Exemplu: \n secven]a urm`toare, se citesc dou` numere reale a [i b [i se


afi[eaz` suma lor:
float a=Float.parseFloat(cin.Token());
float b=Float.parseFloat(cin.Token());
System.out.println(a+b);

 Metoda Double.parseDouble(sir) returneaz` [irul convertit c`tre


float.

Exemplu: \n secven]a urm`toare, se citesc dou` numere reale a [i b [i se


afi[eaz` suma lor:
double a=Double.parseDouble(cin.Token());
double b=Double.parseDouble(cin.Token());
System.out.println(a+b);

Nu trebuie s` v` \ngrijora]i c` nu a]i \n]eles toate no]iunile

 prezentate. Pentru moment, lua]i-le ca atare. Toate vor fi studiate \n


am`nunt. Pentru moment, s` ne mul]umim cu faptul c` putem citi [i
afi[a un [ir de caractere.

2.6. Probleme rezolvate


|ntruc@t cunoa[tem deja operatorii [i instruc]iunile [i putem citi date cu
ajutorul clasei cin, de acum putem s` scriem mici programe. Toate
instruc]iunile se vor g`si \n main().

1. Se citesc dou` numere reale. Se cere s` se afi[eze num`rul cel mai


mare dintre ele (calculul maximului).

class prima {
46 Bazele programării în Java

public static void main(String[] args) {


System.out.print("a=");
double a=Double.parseDouble(cin.Token());
System.out.print("b=");
double b=Double.parseDouble(cin.Token());
if (a>b)System.out.println(a);
else System.out.println(b);
}
}
2. S` se rezolve ecua]ia ax+b=0 (a,b). Numerele a [i b se citesc de
la tastatur`.
class prima {
public static void main(String[] args) {
System.out.print("a=");
double a=Double.parseDouble(cin.Token());
System.out.print("b=");
double b=Double.parseDouble(cin.Token());
if (a==0)
if (b==0) System.out.println("infinitate de solutii");
else System.out.println("nu are solutie");
else System.out.println(-b/a);
}
}

3. Se cite[te n, num`r natural mai mare dec@t 0. S` se calculeze


1+2+...n.

class prima {
public static void main(String[] args) {
System.out.print("n=");
int i,s=0,n=Integer.parseInt(cin.Token());
for (i=1;i<=n;i++) s+=i;
System.out.println("Suma este " +s);
}
}

 Observa]i modul \n care se afi[eaz`, mai \nt@i, [irul “n=”, si apoi se


a[teapt` introducerea lui n.
 Prin expresia: "Suma este " +s se converte[te mai \nt@i tipul int
c`tre String (obiect care re]ine un [ir de caractere), apoi cele dou`
se concateneaz`. |n final, se afi[eaz` [irul astfel ob]inut.

 Aceasta \nseamn` c` pentru a converti o valoare numeric`, a, c`tre


[ir, se poate face [irul sum` \ntre [irul vid [i a: “”+a. De re]inut!

4. Se cite[te n, num`r natural. Se cere s` se calculeze suma cifrelor lui.


De exemplu, dac` se cite[te 124 se va afi[a 7. De acum, vom scrie
numai metoda main().

public static void main(String[] args) {


Capitolul 2. Tipuri şi operaţii de date 47

System.out.print("n=");
int s=0,n=Integer.parseInt(cin.Token());
while (n!=0)
{ s+=n%10;
n=n/10;}
System.out.println("Suma cifrelor este " +s);
}

5. Se cite[te n, num`r natural. Se cere s` se afi[eze num`rul ob]inut prin


inversarea cifrelor sale. De exemplu, dac` se cite[te 123, se va afi[a 321.

public static void main(String[] args) {


System.out.print("n=");
int n=Integer.parseInt(cin.Token()), ninv=0;
while (n!=0)
{ ninv=ninv*10+n%10;
n=n/10;
}
System.out.println("Numarul este " +ninv);
}

6. Se cite[te n num`r natural. S` se afi[eze descompunerea sa \n factori


primi.
public static void main(String[] args) {
System.out.print("n=");
int n=Integer.parseInt(cin.Token()),i=2, fm;
do
{ fm=0;
while (n%i==0)
{ fm++;
n/=i;}
if (fm!=0) System.out.println(i+" la puterea "+fm);
i++;
} while (n!=1);
}

7. Se cite[te n [i un vector cu n componente numere \ntregi. S` se


afi[eze con]inutul componentelor vectorului.

public static void main(String[] args) {


System.out.print("n=");
int n=Integer.parseInt(cin.Token()),i;
int V[]=new int[n];
for (i=0;i<n;i++)
{ System.out.print("V["+i+"]=");
V[i]=Integer.parseInt(cin.Token()); }
for (i=0;i<n;i++) System.out.println(V[i]);
}

 Observa]i faptul c` vectorul are exact n componente [i nu a fost


necesar ca acesta s` fie dimensionat de la \nceput cu un num`r de
componente presupus maxim.
48 Bazele programării în Java

8. Se cite[te n [i un vector cu n componente numere reale. S` se afi[eze


valoarea maxim` con]inut` de vector.
public static void main(String[] args) {
System.out.print("n=");
int n=Integer.parseInt(cin.Token()),i;
double V[]=new double[n];
for (i=0;i<n;i++)
{ System.out.print("V["+i+"]=");
V[i]=Double.parseDouble(cin.Token());
}
double max=V[0];
for (i=1;i<n;i++)
if (max<V[i]) max=V[i];
System.out.println("Valoarea maxima gasita="+max);
}

9. Se cite[te n [i un vector cu n componente numere reale. S` se afi[eze


con]inutul componentelor vectorului sortate cresc`tor. Se va utiliza metoda
bulelor.
public static void main(String[] args) {
System.out.print("n=");
int n=Integer.parseInt(cin.Token()),i;
double man; boolean gasit;
double V[]=new double[n];
for (i=0;i<n;i++)
{ System.out.print("V["+i+"]=");
V[i]=Double.parseDouble(cin.Token());}
do
{ gasit=false;
for (i=0;i<n-1;i++)
if (V[i]>V[i+1])
{ man=V[i];
V[i]=V[i+1];
V[i+1]=man;
gasit=true;}
} while (gasit==true);
for (i=0;i<n;i++) System.out.println(V[i]);
}

10. Interclasare. Se citesc m numere reale sortate cresc`tor. De asemenea,


se citesc n numere reale sortate cresc`tor. Se cere s` se afi[eze cele m+n
valori \n ordine cresc`toare.
public static void main(String[] args) {
System.out.print("m=");
int m=Integer.parseInt(cin.Token()),i,j;
double A[]=new double[m];
for (i=0;i<m;i++)
{ System.out.print("A["+i+"]=");
A[i]=Double.parseDouble(cin.Token());}
System.out.print("n=");
Capitolul 2. Tipuri şi operaţii de date 49

int n=Integer.parseInt(cin.Token());
double B[]=new double[n];
for (j=0;j<n;j++)
{ System.out.print("B["+j+"]=");
B[j]=Double.parseDouble(cin.Token());
}
int k=0;
double C[]=new double[m+n];
i=j=0;
while (i<m && j<n)
if (A[i]<B[j]) C[k++]=A[i++];
else C[k++]=B[j++];
if (i<m) for (j=i;j<m;j++) C[k++]=A[j];
else for (i=j;i<n;i++) C[k++]=B[i];
for (i=0;i<k;i++) System.out.println(C[i]);
}

11. S` se citeasc` [i s` se afi[eze o matrice cu m linii [i n coloane,


unde fiecare element re]ine un num`r \ntreg.
public static void main(String[] args) {
System.out.print("m=");
int m=Integer.parseInt(cin.Token()),i,j;
System.out.print("n=");
int n=Integer.parseInt(cin.Token());
int A[][]=new int[m][n];
for (i=0;i<m;i++)
for (j=0;j<n;j++)
{ System.out.print("A["+i+","+j+"]=");
A[i][j]=Integer.parseInt(cin.Token());
}
for (i=0;i<m;i++)
{ for (j=0;j<n;j++) System.out.print(A[i][j]+" ");
System.out.println();
}
}

12. Mai jos pute]i observa o secven]` simpl` prin care se pot inversa
liniile i [i j ale unei matrice cu n linii [i m coloane (i,j<n).
int Man[];
Man=A[i]; A[i]=A[j]; A[j]=Man;
50 Bazele programării în Java

Probleme propuse
1. Ce se va afi[a \n urma execut`rii secven]elor urm`toare?

1.1)
int x=3; a) 3;
x=~x; b) 4;
System.out.println(x); c)-3;
d)-4.

1.2)
int x=5; a) 0;
x=x<<3; b) 2;
System.out.println(x); c) 40;
d) 5.

1.3)

int x=5; a) 0;
x=x>>1; b) 2;
System.out.println(x); c) 5;
d) 1.
1.4) System.out.println(7>10); a) eroare de execuţie;
b) 7>10;
c) false;
e) true.

1.5) float x=1/2; a) 0;


System.out.println(x); b) 0.5;
c) Eroare;
d) 1/2.

1.6) System.out.print(-15/4); a) -3 -3;


System.out.print(“ “); b) -4 2;
System.out.print(-15%4); c) -4 -2;
d) eroare.

2. Fie x [i y dou` variabile logice. S` se demonstreze rela]iile de mai jos


(de Morgan):

a) !(x || y)=!x && !y.


b) !(x && y)=!x || !y.

3. Evalua]i expresiile urm`toare, preciz@nd rezultatul:

a) x+1.5, unde x este o variabil` \ntreag` ce con]ine num`rul 7;


b) x<=4, unde x este o variabil` \ntreag` ce con]ine num`rul 4;
c) a+1>3, unde a este o variabil` real` care con]ine num`rul 3;
Capitolul 2. Tipuri şi operaţii de date 51

d) 6/2;
e) x/y+y/x unde x [i y sunt variabile \ntregi care con]in, 1 respectiv 6;
f) x<3 || x>6 (unde x este o variabil` real` care re]ine 7);
g) x<3 && x>6 (la fel ca mai sus);

4. Fie x o variabil` de tip int. Pentru ce valori ale lui x expresia:


x+7==8*x ia valoarea true?

5. La fel ca mai sus, numai c` expresia este: 2*x+3==6.

6. Consider`m long a=3; char b=2; Care este valoarea produs` de


expresia a+b, [i care este tipul rezultatului?
a) Nu se poate aduna con]inutul unei variabile de tip char cu acela al
unei variabile numerice. Compilatorul furnizeaz` eroare de sintax` la
compilare;
b) Rezultatul este 5 [i este de tip char;
c) Rezultatul este 5 [i este de tip long.

7. Consider`m int a=-10,b=3; Care sunt valorile produse de expresiile


a/b [i a%b ?
a) -3,33333...3 [i 2;
b) -3 [i -1;
c) -4 [i 2.

8. Consider`m int a=2; Care este valoarea rezultat` \n urma evalu`rii


expresiei 1/(2*a)?
a) 0.25;
b) Operatorul "/" ac]ioneaz` numai asupra variabilelor de un tip real.
Avem eroare de sintax`.
c) 0.

9. Consider`m int a=2,b=5; Care este valoarea rezultat` \n urma


evalu`rii expresiei a+3<=b+2?
a) true;
b) false;
c) Este obligatoriu s` folosim paranteze, pentru c` altfel nu se poate
face evaluarea.

10. Consider`m int a=5,b=5; Care este valoarea rezultat` \n urma


evalu`rii expresiei a++/++b?
a) 1; b) 0,833333; c) 0.
52 Bazele programării în Java

11. Avem int a=5,b=3; Care este valoarea rezultat` \n urma evalu`rii
expresiei a&b+a|b+a^b?
a) 11; b) nedecidabil; c) 21.

12. Consider`m int a=0,b=3; Care este valoarea rezultat` \n urma


evalu`rii expresiei a+=b+1?
a) |n partea st@ng` a unei atribuiri trebuie s` figureze o singur` variabil`
[i nu o expresie;
b) 4;
c) c) 3.

13. Consider`m int a=0,b=3; Care este valoarea rezultat` \n urma


evalu`rii expresiei a=1=b?
a) Eroare de sintax`;
b) 3;
c) true.
14. Dac` x [i y sunt de tip int, ce valori trebuie s` re]in` pentru ca
expresia (x | y)==(x ^ y ) s` produc` valoarea true?
a) 3 3; b) 3 5; c) 4 7; d) 4 2.
15. Dac` x este de tip int, care dintre expresiile de mai jos produce
valoarea 0, indiferent de con]inutul variabilei x?

a) x & x; b) x | x; c) x ^ x; d) x | !x.

16. Dac` x este de tip int, rezolva]i ecua]ia: (x & x)==x.

17. Dac` x este de tip int, rezolva]i ecua]ia: (x ^ x)==x.

18. Dac` x [i y sunt de tip int, rezolva]i ecua]ia:


(x ^ x ^ y)==y.
19. Dac` x este de tip int, rezolva]i ecua]ia: (x | ~x)==x.

20. Care este func]ia evaluat` de expresia de mai jos (x este real)?
x<2?x-1:x*x
21. Care este valoarea pe care o re]ine variabila rez dup` executarea
secven]ei de mai jos?
int k,rez;
k=4; rez=3+k/5;

a) 3; b) secven]a este gre[it`; c) 4.


Capitolul 2. Tipuri şi operaţii de date 53

22. Care dintre secven]ele de mai jos este corect` din punct de vedere
sintactic?
a) k=4; b) k=4; c) k=4;
if (k>=0); if(k>=0) if k>=0;
else; then; else;
else;

23. Care va fi valoarea variabilei s dup` executarea secven]ei?


int i,s=0;
for (i=1;i<=10;i++)
{ i=i/10;
s+=i;}

a) 0; b) 10; c) Secven]a cicleaz`; d) 1.

24. Ce se \nt@mpl` dac` se ruleaz` secven]a urm`toare?


int a=1,b=6;
while (a!=b)
{ a++;
b--;}
System.out.println(a);

a) secven]a cicleaz`; b) se afi[eaz` 3;


c) secven]a con]ine erori de sintax`;
d) nici una din variantele de mai sus nu este adev`rat`.
25. Ce se \nt@mpl` dac` se ruleaz` secven]a urm`toare?
int x=3;
while (x!=x*x) x=x/2;
System.out.println(x);
a) secven]a cicleaz`; b) se afi[eaz` 1; c) se afi[eaz` 0;
d) nici una dintre variantele de mai sus nu este adev`rat`.

Testele de la 26 la 29 se refer` la programul urm`tor:


int x=3;
do
{ x--; x*=2;}
while (x!=10);

26. De c@te ori se execut` secven]a subordonat` instruc]iunii do?


a) o dat` b) de dou` ori c) de trei ori d) secven]a cicleaz`

27. |nlocui]i cele dou` atribuiri subordonate instruc]iunii do cu una singur`,


astfel \nc@t programele ob]inute s` fie echivalente.
54 Bazele programării în Java

28. Dac` valoarea ini]ial` a lui x este 5 (x=5), care trebuie s` fie condi]ia
de continuare ( while (x=?) ) astfel \nc@t atribuirile subordonate lui do s`
se execute exact de 4 ori?
a) 10 b) 8 c) 50 d)28

29. Pentru care dintre valorile ini]iale ale lui x (de mai jos) programul nu
cicleaz`?
a) 0 b) 1 c) 2 d) 4

30. Care dintre atribuirile de mai jos \nlocuieste secven]a celor trei atribuiri:
x:=x-1; x:=2*x; x:=x+1;
a) x:=2*x-1 b) x:=2*x-3 c) x:=2*x+1 d) x:=2*x

31. S` se scrie un program care rezolv` ecua]ia ax2+bx+c=0, unde:


(a,b,c  ).

32. S` se calculeze valoarea func]iei F, definit` pe mul]imea numerelor


reale, pentru un x citit:

33. Se citesc n numere reale. S` se afi[eze valoarea minim` citit`.


34. Se cite[te un [ir de numere \ntregi p@n` la \nt@lnirea num`rului 0. S`
se calculeze media aritmetic` a numerelor din [ir.
35. Citim un [ir de numere \ntregi, la fel ca la problema precedent`. S`
se calculeze suma dintre primul num`r, al treilea, al cincilea,... [i produsul
dintre al doilea, al patrulea,... etc.
36. Se cite[te n, num`r natural. S` se calculeze expresiile de mai jos
(programe separate):
1 1 1
E1  1    ...  2 ;
2 2 32 n
1 2 n
E2    ...  ;
23 3 4 ( n  1)( n  2)
1 1 1
E3  1    ...  , unde n! 1  2  ...  n.
1! 2! n!

37. Se cite[te o succesiune de cifre 1 [i 0, prima fiind 1. Aceasta are


semnifica]ia unui num`r \n baza 2. S` se afi[eze num`rul \n baza 10.
Capitolul 2. Tipuri şi operaţii de date 55

38. Se consider` [irul definit astfel (FIBONACCI).

1, dacã n  1 sau n  2


u (n)  
u ( n  1)  u ( n  2), altfel

Se cite[te o valoare natural` a>0. S` se calculeze u(a).


39. Se consider` [irul definit la problema anterioar`. S` se afi[eze num`rul
de termeni care sunt strict mai mici dec@t o valoare citit`.
40. Se cite[te un num`r natural. C@te cifre con]ine?
41. Se cite[te un num`r natural cu 5 cifre. Afi[a]i num`rul format dup`
eliminarea cifrei din mijloc.
42. Un num`r se nume[te perfect dac` este egal cu suma divizorilor s`i
(exclusiv el). Exemplu: 6=1+2+3. Afi[a]i toate numerele perfecte mai mici
dec@t o valoare dat`.
43. Afi[a]i toate numerele naturale mai mici dec@t o valoare dat`, care sunt
egale cu suma p`tratelor cifrelor lor.
44. Afi[a]i primele n perechi de numere prime care sunt consecutive \n
mul]imea numerelor impare. Exemplu: (3,5), (5,7).
45. Se cite[te un num`r natural par. S` se descompun` \n sum` de
numere prime (conjectura GOLDBACH).
46. Se cite[te un vector cu n componente, numere naturale. S` se afi[eze
cel mai mare num`r ra]ional subunitar \n care num`r`torul [i numitorul fac
parte din mul]imea valorilor citite. Exemplu: dac` am citit valorile 1 2 3 se
afi[eaz` 2/3.
47. Acela[i enun] ca la problema anterioar`, numai c` se cere s` se
afi[eze cel mai mic num`r ra]ional supraunitar.
48. Se cite[te un vector cu n componente numere naturale. Se cere s` se
ob]in` toate permut`rile circulare la dreapta.
Exemplu: dac` n=4, si vectorul este 1 2 3 4, permut`rile circulare sunt:
1 2 3 4, 4 1 2 3, 3 4 1 2, 2 3 4 1.
Observa]i faptul c`, de fiecare dat`, ultimul element trece pe prima pozi]ie,
iar restul elementelor sunt deplasate la dreapta cu o pozi]ie.
49. Se dau n numere ra]ionale, re]inute \n doi vectori a [i b. Astfel,
num`r`torul primului num`r este a[1], numitorul s`u este b[1], etc.
Programul va decide dac` numerele date sunt distincte. |n cazul \n care
r`spunsul este afirmativ, programul va afi[a DA, altfel va afi[a NU [i o
pereche de numere egale.
56 Bazele programării în Java

50. Se dau n numere ra]ionale distincte, re]inute \n doi vectori a [i b [i m


numere ra]ionale distincte re]inute \n vectorii c [i d. Se consider` c` cele n
numere alc`tuiesc o mul]ime X [i cele m numere alc`tuiesc o mul]ime Y. Se
cere s` se afi[eze:
a) XY;
b) XY;
c) X-Y.
Observa]ie: pentru fiecare cerin]` se va face un program.

Răspunsuri:
1.1 d), 1.2 c), 1.3 b) 1.4 c) 1.5 a) 1.6 a) 4. x=1. 5. x
6. c) 7. b) 8. c) 9. a) 10. c) 11. a) 12. b) 13. a) 14. d)
15. c) 16. Orice num`r care poate fi re]inut de tipul int; 17. x=0;
18. Orice x [i y care pot fi re]inute de tipul int.; 19. x=-1;
20. f(x) x-1 daca x<2, x*x altfel; 21. a) 22. a) 23. c) 24. a)
25. b) 26. c) 27. x=2*(x-1); 28. c); 29. d); 30. a).
CAPITOLUL 3

Metode

Din cuprins:
Generalităţi
Structura unei metode şi apelul ei
Transmiterea parametrilor
Despre variabile
Exemple de utilizare ale metodelor
Metode recursive - exemple
Supraîncărcarea metodelor
Probleme propuse
58 Bazele programării în Java

3.1. Generalităţi
|n Java se lucreaz` orientat spre obiect (prin programare orientat` pe
obiecte). Din ra]iuni didactice, vom \ncerca s` prezent`m lucrurile pornind de
la ceea ce [tim deja, dac` am lucrat, c@t de c@t, \ntr-un alt limbaj de
programare. Mai precis, vom \nv`]a s` lucr`m cu variabile (date membru)
[i func]ii (metode) ata[ate clasei care con]ine main(). Aceasta ne permite
s` exers`m utilizarea subprogramelor \n Java, f`r` a ne complica de la
\nceput cu mecanismele specifice program`rii pe obiecte. Acest fapt este
important pentru c` nu are sens ca absolut orice problem` s` fie rezolvat`
prin mecanismele program`rii orierntate pe obiecte.

 |n Java, exist` posibiltatea de a declara variabile vizibile la nivel de


clas`, a[a cum se vede \n programul de mai jos, unde se citesc
con]inuturile numerice a dou` astfel de variabile [i se afi[eaz` suma
lor. Ca s` respect`m terminologia consacrat`, le vom numi date
membru (ale clasei care con]ine main()). Pentru moment, pentru a
putea lucra ca acest mod este obligatoriu ca datele membru s` fie
precedate de modificatorul static. Justific`rile celor prezentate acum
vor fi date ulterior.
public class Clasa1 {
static int a,b;
public static void main(String[] args) {
a=Integer.parseInt(cin.Token());
b=Integer.parseInt(cin.Token());
System.out.println(a+b);}
}

 Orice dat` membru (variabil`) a clasei este ini]ializat` automat, la


pornirea programului. Astfel, datele numerice sunt ini]ializate cu 0,
datele de tip boolean cu false, datele de tip caracter cu caracterul
de cod 0, datele de tip referin]` cu null (nu con]in nici o adres`).
Cele afirmate pot fi verificate cu programul urm`tor, dar caracterul de
cod 0 nu este afi[abil.

class prima {
static int a; static float b;
static char c; static boolean d;
public static void main(String[] args) {
System.out.println(a+" "+b+" "+c+" "+d);}
}

 |n Java, nu vom mai folosi termenul de func]ie, ci un altul, specific


program`rii orientate pe obiecte, numit metod`. Aceasta \nseamn` c`
atunci c@nd spunem metod`, vom \n]elege c` vorbim despre o func]ie
(subprogram). Justificarea termenului va fi f`cut` \n capitolul urm`tor.
Orice metod` ata[at` clasei de baz` va fi precedat` de modificatorul
Capitolul 3. Metode 59

static. Deocamdat`, re]inem acest lucru \n mod mecanic. Motiva]ia


va fi dat`, ca [i \n cazul precedent, \n capitolul urm`tor.

Exemplu de metod`:

1. Metoda test() are rolul de a afi[a un mesaj. Observa]i modul \n care


am apelat-o din main():
public class Clasa1 {
static void test()
{ System.out.println("eu sunt o metoda");}

public static void main(String[] args) {


test();
}
}

3.2. Structura unei metode şi apelul ei


|n esen]`, o metod` este alc`tuit` din:

 Antet - acesta con]ine mai multe informa]ii importante necesare


compilatorului, numele netodei, lista parametrilor formali, tipul metodei [i,
eventual, modificatori.
 Corpul metodei - acesta cuprinde instruc]iunile metodei.

Exemplu: mai jos, pute]i observa metoda suma() ce are rolul de a calcula
suma a dou` numere naturale. |n schema ata[at`, pute]i identifica
elementele constitutive ale ei:

Modificator Tipul Numele Lista


metodei metodei parametrilor
formali

static int suma(int x, int y)


{ return x+y;
}
Corpul
metodei

 Numele metodei – se utilizeaz` pentru a o identifica atunci c@nd


metoda este apelat`.
 Lista parametrilor formali - parametrii formali sunt valorile pe care
metoda le prime[te la apel. |n exemplu, lista este format` din doi
parametri formali, x [i y, ambii de tipul int.
60 Bazele programării în Java

 Tipul metodei – sau altfel spus, precizeaz` natura rezultatului. |n


exemplu, metoda returneaz` o valoare \ntreag` (de tip int), dar
pot fi metode de alt tip, cum ar fi float double, etc. Exist` [i
metode care nu returneaz` nimic, caz \n care tipul metodei este
void.
 Corpul metodei – este sub forma unei instruc]iuni compuse. |n
exemplu, acesta con]ine o singur` instruc]iune, return, prin care
se calculeaz` [i se returneaz` suma parametrilor formali.
 Modificator – static

Mai jos pute]i observa modul \n care se apeleaz` metoda suma():


public class Clasa1 {
static int suma(int x, int y)
{return x+y;}
public static void main(String[] args) {
System.out.println(suma(2,3));
int x=2, y=5;
System.out.println(suma(x,y));
System.out.println(suma(3,y));}
}

Prin suma(2,3) se apeleaz` metoda suma(), unde x=2, [i y=3. Metoda


returneaz` suma parametrilor (5) [i valoarea este afi[at`. Faptul c` apelul
metodei este scris direct \n metoda System.out.println(), \nseamn` c`
metoda este, \n expresia din System.out.println(), evaluat` ca o
valoare (\n exemplu, de tip int). Prin suma(x,y), se apeleaz` metoda
suma(), unde parametrii sunt valorile variabilelor x [i y (2 [i 5).
 Metodele care sunt de orice alt tip \n afara tipului void, trebuie s`
returneze o valoare din tipul respectiv. Returnarea valorii se face prin
utilizarea instruc]iunii return. |n exemplu, metoda suma() prin
return x+y; returneaz` suma celor doi parametrii primi]i.
Mai jos pute]i observa modul \n care se apeleaz` o metod` de tip void:
public class Clasa1 {
static void met()
{ System.out.println("Eu sunt o metoda de tip void"); }
public static void main(String[] args) {
met(); }
}

 O metod` se apeleaz` printr-o instruc]iune de apel. Un exemplu de


astfel de instruc]iune de apel este apelul de mai sus: met(). Sunt
permise [i apeluri de genul suma(x,y), de[i nu \ntotdeauna au sens.
De asemenea, se pot utiliza expresii prin care se apeleaz` o metod`:
de exemplu, System.out,println(1+suma(2,3)), unde expresia
este: 1+suma(2,3).
Capitolul 3. Metode 61

 Parametrii care figuraz` \n apelul unei metode se numesc parametri


efectivi. De exemplu, \n apelul suma(2,3), parametrii efectivi sunt
valorile 2 [i 3. |n apelul suma(x,y) parametrii efectivi sunt
con]inuturile variabilelor x [i y.
 Metodele se pot apela una pe alta, indiferent de pozi]ia pe care o
ocup` defini]ia lor \n cadrul clasei. |n exemplul de mai jos, metoda
met1() apeleaz` metoda met(), de[i aceasta din urm` este definit`,
\n cadrul clasei, dup` ea.
class prima {
static void met1()
{ System.out.println("Met1");
met();}
static void met()
{ System.out.println("Met");}
public static void main(String[] args) {
met1();}
}

3.3. Transmiterea parametrilor


A[a cum am ar`tat, parametrii care se g`sesc \n antetul metodei se
numesc parametri formali, iar cei care se g`sesc \n instruc]iunea de apel se
numesc parametri efectivi.
|ntre parametrii formali [i cei efectivi trebuie s` existe o anumit`
concordan]`, care este descris` prin regulile urm`toare:
 Num`rul parametrilor formali trebuie s` coincid` cu num`rul
parametrilor efectivi.
 Tipul parametrilor formali trebuie s` coincid` cu tipul parametrilor
efectivi sau tipul parametrilor efectivi s` poat` fi convertit implicit (ca
\n cazul atribuirii) c`tre tipul parametrilor formali la fel ca \n cazul
atribuirii.
 Nu este obligatoriu ca numele parametrilor formali s` coincid` cu
numele parametrilor efectivi.

Exemple pentru metoda static int suma(int x, int y):


a) prin apelul suma(1,2) se apeleaz` metoda suma() cu dou` valori de
tip int, 2 [i 3. |n acest caz, num`rul parametrilor formali este 2 [i
num`rul parametrilor efectivi este tot 2.
b) prin apelul suma('1',3) am apelat metoda suma() cu doi parametri:
unul de tip char, altul de tip int. Apelul este corect pentru c` o variabil`,
constant`, de tip char poate fi converit` c`tre tipul int (la fel ca la
atribuiri).
62 Bazele programării în Java

c) dac` x, de exemplu, este tipul long, atunci apelul suma(x,y) nu este


un apel corect pentru c` nu sunt permise conversiile de la long la int.
La fel, nu este permis apelul de float la int, etc.
d) parametrii efectivi pot fi expresii, ca \n apelul suma(2-3,3+4), unde se
returneaz` 6. |n exemplu, se apeleaz` suma(-1,7).
e) parametrii efectivi pot con]ine [i operatorul de conversie explicit`, ca \n
apelul: suma(2,(int)3.7), unde se returneaz` 5.

 |n Java, parametrii se transmit numai prin valoare. Aceasta \nseamn`


c` parametrul efectiv, chiar dac` este variabil`, r@m@ne nemodificat.
Privi]i exemplul urm`tor:

public class Clasa1 {


static void exemplu(double x)
{ x=3.7; }
public static void main(String[] args) {
double x=5; exemplu(x);
System.out.println(x);
}
}

|n main() avem o variabil` x, de tip double, ini]ializat` cu 5.


Apel`m metoda de tip void exemplu(). |n metod`, lui x i se atribuie
alt` valoare (3.7). Dup` executarea metodei, se revine \n main() [i
se afi[eaz` x. Valoarea afi[at` este cea ini]ial`, 5. Con]inutul variabilei
x din main() a r`mas nemodificat. Cum este posibil acest lucru?

 Pentru fiecare parametru formal, metoda apelat` re]ine \n stiv` (o


memorie special`, asupra c`reia vom reveni) un spa]iu. |n mod
practic, se creeaz` o variabil` cu numele parametrului formal.

Prin urmare, metoda exemplu() a creat \n stiv` o variabil` cu


numele x. Acestei variabile i s-a atribuit valoarea 3.7. Variabila x din
main() este cu totul alta. Din acest motiv, con]inutul lui x din
main() r`m@ne nemodificat.
 Am ar`tat faptul c` numele unui masiv este o referin]` c`tre masiv
ce se g`se[te \n memorie. |n acest caz, transmiterea unei referin]e
c`tre un masiv ca parametru al unei metode are ca efect posibilitatea
modific`rii con]inuturilor componentelor masivului.


|ntruc@t masivele con]in [i data membru length, dac` o metod`
prime[te ca parametru o referin]` c`tre masiv , atunci nu mai este
necesar ca, \n alte limbaje de programare, s` transmitem [i num`rul
de componente ale masivului.
Capitolul 3. Metode 63

Exemplu:

Metoda exemplu() calculeaz` suma numerelor re]inute de un vector [i


face ca fiecare component` a vectorului s` re]in` valoarea 1. |n programul
principal se ini]ializeaz` vectorul, apoi se probeaz` efectul metodei.

public class Clasa1 {


static int exemplu(int[] t )
{ int s=0,i;
for (i=0;i<t.length;i++) s+=t[i];
for ( i=0;i<t.length;i++) t[i]=1;
return s;
}
public static void main(String[] args) {
int[] v=new int [5];
int i;
for (i=0;i<5;i++) v[i]=Integer.parseInt(cin.Token());
System.out.println(exemplu(v));
for (i=0;i<v.length;i++) System.out.print(v[i]+" ");
}
}

3.4. Despre variabile


P@n` \n prezent am utilizat trei feluri de variabile:

1. |n corpul metodelor. Aceste variabile se numesc variabile locale.


2. |n antetul metodelor. Si acestea sunt, dup` cum vom vedea, tot
variabile [i se numesc parametri.
3. La nivelul clasei. Acestea se numesc, a[a cum am ar`tat date
membru.

 |n cadrul metodelor, parametrii sunt trata]i precum variabilele locale [i


pot fi accesa]i din orice punct al metodei. De exemplu, dac` avem
metoda static int met(int a) [i o apel`m prin met(2), metoda
va avea o variabil` local` a care va fi ini]ializat` cu 2.


Dac` avem un parametru cu un anumit nume, atunci nu mai este
permis s` declar`m variabile locale cu acest nume. De exemplu,
secven]a urm`toare d` eroare de compilare, pentru c` numele
variabilei locale coincide cu numele parametrului.

static void met(int a)


{ int a=7;
System.out.println(a);
}
64 Bazele programării în Java

 Variabilele locale pot fi accesate din blocul \n care au fost declarate


[i, imediat ce au fost executate instruc]iunile din acel bloc, nu vor mai
exista. De exemplu, \n metoda de mai jos am declarat dou` variabile
locale, ambele cu numele i. Prima este declarat` \n for [i este
recunoscut` de blocul (\n exemplu instruc]iunea) subordonat. Dup`
\ncheierea execu]iei for-ului, aceast` variabil` nu mai exist`, prin
urmare poate fi declarata din nou.
static void met()
{ for (int i=1;i<=3;i++) System.out.println(i);
int i=5;
System.out.println(i);}

 |n cazul \n care avem o data membru cu un anumit nume [i dac`


\ntr-o metod` declarat` cu modificatorul static ([i p@n` acum am
dat numai astfel de exemple) avem o variabil` local` (parametru) cu
acela[i nume, atunci din metod` se poate adresa doar varabila local`
(parametrul). De exemplu, programul de mai jos afi[eaz` 2, adic`
valoarea variabilei locale a [i nu 3, valoarea re]inut` de data membru.
public class Clasa1 {
static int a=3;
public static void main(String[] args) {
int a=2;
System.out.println(a);
}
}

 Parametrii [i variabilele locale sunt memorate \ntr-o structur` special`


de date, numit` stiva. Stiva func]ioneaz` pe principiul LIFO (Last In
First Out) -"ultimul intrat, primul ie[it".

Pentru a \n]elege modul de lucru cu stiva, ne imagin`m un num`r n


de farfurii identice, a[ezate una peste alta (o "stiv`" de farfurii).
Ad`ugarea sau scoaterea unei farfurii se face cu u[urin]`, numai \n
v@rful stivei. Dup` ce am scos toate farfuriile din stiv`, spunem c`
aceasta este vid`. Oric@t ar p`rea de simplu principiul stivei, el are
consecin]e uria[e \n programare. Vede]i recursivitatea!

3.5. Exemple de utilizare ale metodelor

3.5.1. Exemple elementare


1. Se citesc dou` numere \ntregi m [i n. Se cere s` se tip`reasc` cel mai
mare divizor comun [i cel mai mic multiplu comun al lor.

Rezolvare. Presupunem cunoscut algoritmul care determin` cel mai mare


divizor comun pentru dou` numere. Cel mai mic multiplu comun al dou`
Capitolul 3. Metode 65

numere se poate determina \mp`r]ind produsul lor la cel mai mare divizor
comun al lor. Prin urmare, scriem o metod` cmmdc cu doi parametri formali
m [i n, care \ntoarce o valoare \ntreag` - cel mai mare divizor comun al
lor.
public class Clasa1 {
static int cmmdc(int m, int n)
{ while (m!=n)
if (m>n) m-=n;
else n-=m;
return m;}
public static void main(String[] args) {
int m=Integer.parseInt(cin.Token());
int n=Integer.parseInt(cin.Token());
int cm=cmmdc(m,n);
System.out.println(cm);}
}

2. Se citesc dou` numere naturale m<n. Se cere s` se tip`reasc` toate


numerele palindrom aflate \ntre m [i n. Un num`r este palindrom dac` citit
direct [i invers rezultatul este acela[i. Exemplu: 121.

Rezolvare. S` analiz`m problema. Este necesar s` fie testate toate


numerele \ntre m [i n, pentru ca apoi s` fie tip`rite numai cele care
\ndeplinesc condi]ia cerut`. Pentru aceasta, vom scrie o metod` numit`
palin() care are rolul de a testa dac` num`rul este sau nu palindrom.
Evident, metoda trebuie s` fie de tipul boolean.

Care este avantajul scrierii metodei?

Acesta este dat de faptul c`, atunci c@nd scriem metoda, ne


concentr`m exclusiv asupra ei, deci posibilitatea de a gre[i este minim`.
Dac` dispunem de metod`, algoritmul este extrem de simplu: for de la m
la n. |n plus, este posibil ca aceast` metod` s` poat` fi folosit` [i \n alte
cazuri.
public class Clasa1 {
static boolean palin(int i)
{ int isalv=i,iinv=0;
while (i!=0)
{ iinv=iinv*10+i%10;
i=i/10;}
return isalv==iinv;
}
public static void main(String[] args) {
int m=Integer.parseInt(cin.Token());
int n=Integer.parseInt(cin.Token());
for(int i=m;i<n;i++)
if (palin(i)) System.out.println(i);
}
}
66 Bazele programării în Java

3. Superpalindrom. Un num`r natural este palindrom dac` citit de la st@nga


la dreapta [i de la dreapta la st@nga r`m@ne nemodificat. De exemplu,
num`rul 12321 este palindrom. Un num`r natural este superpalindrom dac`
este palindrom at@t el c@t [i p`tratul s`u. Scrie]i un program care listeaz`
toate numerele cu aceast` proprietate aflate \ntre doi intregi a [i b .

Rezolvare. Modul \n care test`m dac` un num`r este palindrom este acum
l`murit. Mai mult, avem [i metoda. Nu trebuie dec@t s` o folosim:
public class Clasa1 {
static boolean palin(int i)
{ int isalv=i,iinv=0;
while (i!=0)
{ iinv=iinv*10+i%10; i=i/10;}
return isalv==iinv;
}
public static void main(String[] args) {
int m=Integer.parseInt(cin.Token());
int n=Integer.parseInt(cin.Token());
for(int i=m;i<n;i++)
if (palin(i))
if (palin(i*i)) System.out.println(i+" "+i*i);
}
}

4. Numere rotunde. Se cite[te n<10000. Se cere s` se afi[eze num`rul


de numere mai mici sau egale cu n care, \n binar, au acela[i num`r de
cifre 0 [i 1. De exemplu, 9 este un astfel de num`r 910=10012.

Rezolvare. Trebuie testate numerele de la 1 la n. Prin urmare folosim


instruc]iunea for cu i de la 1 la n. Acum trebuie testat dac`, \n binar,
fiecare i are tot at@tea cifre 0 c@te cifre 1. Pentru asta folosim o metod`
boolean`, numit` valabil.

public class Clasa1 {


static boolean valabil(int nr)
{ int zero=0,unu=0;
while (nr!=0)
{ if (nr%2!=0) unu++;
else zero++;
nr=nr / 2; }
return zero==unu;
}
public static void main(String[] args) {
int n=Integer.parseInt(cin.Token()),s=0;
for(int i=1;i<=n;i++)
if( valabil(i))s++;
System.out.println(s);
}
}
Capitolul 3. Metode 67

3.5.2. Un exemplu de backtracking în Java


Nu prezent`m aici tehnica backtracking. Este totu[i, o carte dedicat`
limbajului Java [i spa]iul nu ar permite prezentarea integral` a tehnicilor de
programare. Oricum, majoritatea dintre dvs. cunosc deja tehnica, iar dac` nu
o cunoste]i, recomand s` o citi]i din manualele de informatic` pentru liceu.

 Generarea permut`rilor. Se cite[te n, se cere s` se afi[eze toate


permut`rile mul]imii {1,2...n}. Observa]i modul de construc]ie [i
utilizare a metodelor.
public class Clasa1 {
static void Init(int k,int[] st)
{ st[k]=0; }
static boolean Am_Succesor (int n, int k,int[] st)
{ boolean rasp=false;
if (st[k]<n) {
st[k]++;
rasp=true;}
return rasp;}
static boolean E_Valid(int k,int[] st)
{ boolean rasp=true;
for (int i=1;i<k;i++)
if (st[i]==st[k]) rasp=false;
return rasp; }
static boolean Solutie(int k, int n)
{ return k==n;}
static void Tipar(int n, int[] st)
{ for (int i=1;i<=n;i++) System.out.print(st[i]);
System.out.println();}
static void back(int n)
{ boolean AS;
int k=1;
int[] st=new int[n+1];
Init(k,st);
while (k>0)
{ do { } while ((AS=Am_Succesor(n,k,st)) && !E_Valid(k,st));
if (AS)
if (Solutie(k,n)) Tipar(n,st);
else {k++;
Init(k,st);}
else k--; }
}
public static void main(String[] args) {
int n=Integer.parseInt(cin.Token());
back(n);
}
}
68 Bazele programării în Java

 Se puteau folosi date membru pentru n [i st. |n acest caz, am


fi avut mai pu]ini parametri...

3.6. Metode recursive


|n Java, metodele pot fi recursive. Aceasta \nseamn` c` o metod` se
poate autoapela.

Exemplul 1. S` se calculeze recursiv n!. Pentru a scrie o metod` recursiv`


care efectueaz` acela[i calcul, vom porni de la o defini]ie recursiv` a lui n!.
Aceasta este:

1, n0
n!  fact(n)   nN
n  fact(n  1), altfel

De exemplu, pentru a calcula 3!, proced`m astfel:

3!=fact(3)=3fact(2)=32fact(1)=321fact(0)=3211=6.

Metoda recursiv` fact() nu face altceva dec@t s` transcrie defini]ia


recursiv` prezentat` anterior:

public class Clasa1 {


static int fact(int n)
{ if (n==0) return 1;
else return n*fact(n-1);
}
public static void main(String[] args) {
System.out.println(fact(3));
}
}

Care este mecanismul prin care subprogramele se pot autoapela? S`


ne amintim modul \n care subprogramele memoreaz` parametrii transmi[i:

 Pentru memorarea parametrilor, subprogramele folosesc o zon` de


memorie numit` stiv`.

 Stiva este o structur` de date de tip special. Astfel, ultima dat`


introdus` \n stiv` este prima care se poate accesa (scoate din stiva).
Apoi, se acceseaz` iar ultima, dar care \n cazul ini]ial era prima
[.a.m.d.

 Memorarea parametrilor transmi[i se face \n ordinea \n care ace[tia


figureaz` \n antet: de la st@nga la dreapta.
Capitolul 3. Metode 69

|n continuare, prezent`m grafic modul \n care func]ioneaz` recursivitatea


\n cazul metodei fact() a programului anterior. Aceast` metod` nu are
variabile locale, deci \n stiv` se depune doar parametrul n.

La primul apel al metodei fact() se creeaz`


n 3 \n stiv` o variabil` numit` n, care re]ine 3 -
valoarea parametrului formal.

Metoda se autoapeleaz`. De aceast` dat`,


n 2 parametrul n ia valoarea 2. |n stiv` se
creeaz` un nou nivel care re]ine n cu
n 3
valoarea 2.

n 1 Metoda se autoapeleaz`. De aceast` dat`


parametrul n ia valoarea 1. |n stiv` se
n 2 creeaz` un nou nivel, care re]ine n cu
valoarea 1.
n 3

n 0
fact=1
Metoda se autoapeleaz`. Parametrul n ia
valoarea 0. |n stiv` se creeaz` un nou nivel,
n 1 care re]ine n cu valoarea 0. Func]ia ia
n 2 valoarea 1, autoapelul nu mai are loc. Se
revine pe nivelul 3.
n 3

n 1 Pe nivelul 3 se efectueaz` calculul 1*1=1.


fact=1
Se revine apoi pe nivelul 2.
n 2
n 3
n 2 fact=2
Pe nivelul 2 se efectueaz` calculul 2*1=2.
Se revine apoi pe nivelul 1.
n 3

Pe nivelul 1 se efectueaz` calculul 3*2=6.


n 3
Se revine apoi \n main().
fact=6

Aici se afi[eaz` 6, adic` s-a calculat 3!.


70 Bazele programării în Java

3.7. Exemple de utilizare a metodelor recursive

3.7.1. Exemple elementare


1. Se cite[te xZ. Se cere programul pentru calculul func]iei:

 x  1, x  12
F(x)  
F(F(x  2)), x  12
public class Clasa1 {
static int manna (int x)
{ if (x>=12) return x-1;
else return manna(manna(x+2));
}
public static void main(String[] args) {
int n=Integer.parseInt(cin.Token());
System.out.println(manna(n));
}
}

2. Se dau dou` numere naturale, a [i b. Se cere s` se calculeze cel mai


mare divizor comun al lor.

Pentru rezolvare, utiliz`m o defini]ie recursiv` a celui mai mare divizor


comun pentru dou` numere naturale a [i b.

a, ab

cmmdc(a, b)  cmmdc(a  b, b),a  b
cmmdc(a, b  a), a  b

Aceast` defini]ie este transcris` \n metoda recursiv` cmmdc.

public class Clasa1 {


static int cmmdc (int a,int b)
{ if (a==b) return a;
else
if (a>b) return cmmdc(a-b,b);
else return cmmdc(a,b-a);
}
public static void main(String[] args) {
int a=Integer.parseInt(cin.Token());
int b=Integer.parseInt(cin.Token());
System.out.println(cmmdc(a,b));
}
}
Capitolul 3. Metode 71

3. S` se scrie o metod` recursiv` pentru a calcula suma cifrelor unui


num`r natural.

Ideea: se izoleaz` ultima cifr`, iar lui n i se atribuie c@tul \ntreg


dintre vechea valoare [i 10. Aceast` idee folose[te pentru a g`si
o rela]ie de recuren]`, necesar` elabor`rii variantei recursive:

0, n0
S(n)  
n % 10  S(n / 10), altfel

Programul de mai jos, calculeaz` suma utiliz@nd rela]ia prezentat`.


public class Clasa1 {
static int s(int n)
{ if (n==0) return 0;
else return n%10 +s(n/10); }
public static void main(String[] args) {
int n=Integer.parseInt(cin.Token());
System.out.println(s(n)); }
}

4. S` se scrie o metod` recursiv` pentru a transforma un num`r natural n,


din baza 10 în baza k (1<k<10).
S` ne amintim algoritmul clasic de trecere din baza 10 \n baza k.
Num`rul se \mparte la k, se re]ine restul, c@tul se \mparte la k, se re]ine
restul ... p@n` c@nd c@tul este mai mic dec@t \mp`r]itorul. Rezultatul se
ob]ine prin scrierea \n ordine invers` a resturilor ob]inute. Practic, afi[area
restului se face dup` autoapel.
public class Clasa1 {
static void transform(int n,int b)
{ int rest=n%b;
if (n>=b) transform(n/b,b);
System.out.print(rest);}
public static void main(String[] args) {
int n=Integer.parseInt(cin.Token());
int b=Integer.parseInt(cin.Token());
transform(n,b);}
}

3.7.2. Backtracking recursiv


1. Se cite[te n, num`r natural. S` se afi[eze pemut`rile mul]imii
{1,2...n}. Se cere s` se aplice un algoritm de generare recursiv.
72 Bazele programării în Java

Rezolvare. Vom folosi o metod` standard, recursiv` de generare a


permut`rilor. Observa]i faptul c`, de aceast` dat`, st [i n sunt date
membru.
public class Clasa1 {
static int[] st=new int[10];
static int n;
static void init(int k)
{st[k]=0;}
static boolean succesor (int k)
{ if (st[k]<n)
{ st[k]++;
return true;}
else return false;
}
static boolean valid (int k)
{ boolean ev=true;
for (int i=1;i<=k-1;i++)
if (st[k]==st[i]) ev=false;
return ev;
}
static boolean solutie(int k)
{ return k==n+1;}
static void tipar()
{ for (int i=1;i<=n;i++)
System.out.print(st[i]);
System.out.println();
}
static void back(int k)
{ if (solutie(k)) tipar();
else
{ init(k);
while(succesor(k))
if (valid(k)) back(k+1);
}
}
public static void main(String[] args) {
n=Integer.parseInt(cin.Token());
back(1);
}
}

2. Se citesc n [i p, numere naturale. S` se afi[eze toate aranjamentele


de n luate c@te p.

Rezolvare. Singura diferen]` fa]` de algoritmul anterior este c`, de aceast`


dat`, o solu]ie are lungimea p. Aceasta atrage modificarea metodelor
solutie() [i tipar(). |n plus, va trebui sa-l citim [i pe p. |n rest,
programul este acela[i.
public class Clasa1 {
Capitolul 3. Metode 73

static int[] st=new int[10];


static int n,p;
...
static boolean solutie(int k)
{ return k==p+1;}
...
static void tipar()
{ for (int i=1;i<=p;i++)
System.out.print(st[i]);
System.out.println();
}
...
public static void main(String[] args) {
n=Integer.parseInt(cin.Token());
p=Integer.parseInt(cin.Token());
back(1);}
}

3. Se citesc n [i p, numere naturale. S` se afi[eze toate combin`rile de


n luate c@te p.

Rezolvare. Programul este aproape la fel cu programul de generare a


aranjamentelor. Practic, elementele se generaz` \n st \n ordine strict
cresc`toare. Aceasta elimin` [i posibilitatea de generare dubl` a lor ( de
exemplu {2,1}, {1,2}). |n plus, dac` elementele sunt generate \n ordine
strict cresc`toare, dispare condi]ia prin care se verific` dac` sunt distincte
sau nu. Aceasta \nseamn` c` metoda valid() devine inutil`. |n acest caz,
ori determin`m ca metoda valid() s` returneze \ntotdeauna true, p`str@nd
structura metodei back() ca mai jos, ori mai eficient, n-o mai apel`m.
static void init(int k)
{ if (k==0) st[k]=0;
else st[k]=st[k-1];}
static boolean valid (int k)
{ return true; }

3.8. Supraîncărcarea metodelor


 |n Java, metodele pot fi supra\nc`rcate. Aceasta
\nseamn` c` putem avea dou` sau mai multe metode
cu acela[i nume, dar care difer` prin tipul [i/sau
num`rul parametrilor. Privi]i programul de mai jos, care
con]ine dou` metode cu acela[i nume, cu acela[i num`r de parametri
(1), dar de tip diferit (int, respectiv float).
public class Clasa1 {
static void eu_sunt(int n)
{ System.out.println("Parametru de tip int "+ n); }
static void eu_sunt(double n)
{ System.out.println("Parametru de tip double "+n ); }
74 Bazele programării în Java

public static void main(String[] args) {


eu_sunt(3);
eu_sunt(-2.7);
}
}

 Faptul c` metodele pot fi supra\nc`rcate are consecin]e uria[e \n


programare. Dac` \n cazul program`rii clasice (neorientate pe obiecte)
se poate tr`i bine [i f`r` aceast` facilitate, \n cazul program`rii
orientate pe obiecte, aceast` facilitate devine esen]ial`, a[a cum va
rezulta din capitolele urm`toare.

 Un exemplu este chiar metoda println(), at@t de utilizat` p@n` \n


acest moment. Ea afi[eaz` orice i-am transmite ca parametru: o
valoare de tip int, o valoare de tip float, un caracter sau un [ir
de caractere. De fapt, exist` mai multe metode println() care
difer` doar prin tipul parametrului.

Probleme propuse
1. "Numai ultima cifr`". Se citesc n, num`r natural <100, [i n numere
naturale xi, nenule, mai mici ca 30000. Se cere:

 ultima cifr` a num`rului x1  x2 .... xn ;


x x3 ..... xn
 ultima cifr` a num`rului x1 2 .

Exemplu: n=3; x1=11; x2=4; x3=3. Programul tip`re[te:

 8, pentru c` ultima cifr` a sumei 11+4+3 este 8;

 1, pentru c` ultima cifra a lui 1112 este 1.

2. S` se citeasc` dou` matrice [i s` se fac` suma lor. Programul se va


realiza astfel:

 se scrie o metod` de citire a unei matrice cu m linii [i n coloane;


 se scrie o metod` de afi[are a unei matrice cu m linii [i n coloane;
 se scrie o metod` care adun` dou` matrice;
 con]inutul metodei main() rezult` din apelul acestor metode.

3. S` se calculeze coeficien]ii polinomului P(x)=(x+a)n, \n dou` variante:

a) Programul utilizeaz` o metod` care \nmul]e[te un polinom oarecare


de grad k cu polinomul x+a.
Capitolul 3. Metode 75

b) Programul utilizeaz` o metod` care calculeaz` coeficien]ii, a[a cum


rezult` din formula de mai jos (binomul lui Newton):
n
( x  a ) n   Cnk a k x n  k
k 0

4. S` se tip`reasc` toate numerele prime aflate \ntre doi \ntregi citi]i.


Programul va folosi o metod` care returneaz` 1 sau 0 dac` num`rul este
prim sau nu.
5. Scrie]i un program care tip`re[te numerele \ntregi g`site \ntre dou`
valori citite care se divid cu suma cifrelor lor. Programul va utiliza o metod`
care returneaz` suma cifrelor unui num`r \ntreg primit ca parametru.
6. Pentru fiecare metod` de sortare cunoscut`, scrie]i c@te o metod` care
sorteaz` descresc`tor un vector cu componente numere reale.
7. Scrie]i o metod` care interclaseaz` doi vectori sorta]i descresc`tor.
8. Scrie]i o metod` care identific` \ntr-un vector cu numere reale, sortate
cresc`tor, dac` o anumit` valoare este sau nu re]inut` de vector. Metoda
va utiliza algoritmul de c`utare binar`.
9. Un polinom P(X) de grad n, cu coeficien]ii reali este memorat sub
form` de vector (cu n+1) componente. Se cere s` se scrie o metod` care
calculeaz` P(a), unde a este un num`r real citit.
Indica]ie. Se va utiliza schema lui Horner. Exemplu: P(X)=X2+5X+6 Se
cere P(4).
1 5 6
1 9 42
|n r@ndul 2, 1 este coeficientul polinomului. Apoi:
1*4+5=9;
9*4+6=42.
10. Ce afi[eaz` programul urm`tor?
public class Clasa1 {
a) 3
static int f(int x)
{ return x+1;}
b) 4
static void t(int a) c) 5
{ System.out.println(++a);} d) 6
public static void main(String[] args) {
t(f(f(f(1)))); }
}

11. Ce afi[eaz` programul urm`tor?


public class Clasa1 {
static int a; a) 233;
b) 23;
static int f()
c) 32;
{ int a=3;
d) 232
return a;}
76 Bazele programării în Java

static void g()


{ int a=3;
System.out.print(a);}

public static void main(String[] args) {


a=2;
System.out.print(a);;
g();
System.out.print(f());}
}

12. |n programul de mai jos, \nlocui]i cele trei puncte cu una din
secven]ele de mai jos. Pentru care dintre ele programul afi[eaz` produsul
celor dou` numere citite.
public class Clasa1 {
static int a,b,t=0;
static void increment ()
{ t++; }

public static void main(String[] args) {


int i,j;
a=Integer.parseInt(cin.Token());
b=Integer.parseInt(cin.Token());
...
increment()
System.out.println(t);
}
}
a) b)

for (i=1;i<=b;i++) for (i=1;i<=a;i++)


for (j=1;j<=b;j++) for (j=1;j<=b-1;j++)

c) d)

for (i=1;i<=b;i++) for (i=1;i<=b;i++)


for (j=1;j<=a-1;j++) for (j=1;j<=a;j++)

13. Care dintre instruc]iunile de mai jos, \nlocuit` \n program (\n locul
celor 3 stelu]e) nu calculeaz` a2, pentru un num`r natural, a citit?

public class Clasa1 {


static int increment (int x)
{ return x+1; }
static int decrement (int x)
{ return x-1; }
public static void main(String[] args) {
int a=Integer.parseInt(cin.Token());
***}
}
Capitolul 3. Metode 77

a) System.out.println(increment(increment(a)*decrement(a)));
b) System.out.println(increment(a)*decrement(a)+1);
c) System.out.println(1+increment(a)*decrement(a)));

14. Calcula]i recursiv suma a n numere naturale citite.

15. Calcula]i recursiv expresiile:

a) 12+23+...+n(n+1);
b) 1+1/2+...+1/n;
c) 1/(23)+2/(3*4)+...+n/((n+1)(n+2));
k
16. Se citesc n [i k (numere naturale n>k). Calcula]i, recursiv, Cn , prin
k 1
utilizarea formulei de recuren]`: C  C  C . Este eficient?
k k
n n 1 n 1

17. Scrie]i un program iterativ care rezolv` problema anterioar` utiliz@nd


aceea[i formul`.

18. Calcula]i recursiv, Cnk prin utilizarea formulei:

1, k  0;

C nk   n  k  1 k 1
Cn altfel.

 k
19. Se cite[te un num`r natural n. Se cere s` se scrie o metod`
recursiv` care returneaz` cea mai mic` baz` \n care se poate considera n.

20. Scrie]i o metod` boolean` recursiv` care testeaz` dac` un num`r


natural n>1 este prim.

21. Scrie]i o metod` recursiv` care returneaz` suma elementelor pare ale
unui vector citit.
Exemplu: n=4, V=(2,2,5,6). Se returneaz` 10.

22. Scrie]i o metod` recursiv` boolean` prin care se testeaz` dac` un


num`r natural x se reg`se[te \ntre componentele unui vector V cu n
numere naturale.

23. Scrie]i o metod` recursiv` care returneaz`, oglinditul unui num`r natural.
Exemplu: pentru n=123 se returneaz` 321.

24. Scrie]i o metod` recursiv` care descompune \n toate modurile posibile


un num`r natural n \n dou` numere n1 [i n2, n1n2 a c`ror sum` este n.
78 Bazele programării în Java

25. Pentru un vector cu n componente 0 sau 1 care are semnifica]ia de


num`r binar, se cere s` se scrie o metod` recursiv` care afi[eaz` num`rul
\n baza 10.
Exemplu: pentru n=4 [i V=(1011) se va returna 11.

26. Scrie]i o metod` recursiv` care afi[eaz` valoarea unui polinom \n


punctul a. Coeficien]ii polinomului sunt da]i \ntr-un vector. Astfel, pentru
V=(1,2,3) avem polinomul P=x2+2x+3.

27. Fie func]ia definit` pe N*N* Se citesc n [i k. Se cere s` se scrie o


metod` recursiv` care evalueaz` func]ia:
 0, kn

S(n, k)   1, k  1, n
S(n  1, k  1)  kS(n  1, k) 1 k  n

28. Calcula]i func]ia definit` pe N*N:

0, k  0 sau k  n;

F(n, k)  1 k  n;
F(n  1, k  1)  nF(n  1, k) 1  k  n.

29. Calcula]i iterativ [i recursiv cel mai mare divizor pentru dou` numere
naturale m [i n, utiliz@nd algoritmul lui Euclid:
cmmdc(n, m mod n), n0
cmmdc(m, n)  
m, n0
30. Ce se afiseaz` pentru System.out.println(t(12)); ?
static int t(int n)
{ if (n!=0) return 10*t(n/10)+ n%10;
else return 0; }

a) 12; b) 21; c) eroare; d) 0.

31. Ce calculeaz` metoda urm`toare?

static int t(int n)


{ if (n!=0) return (n%2)*n +t(n-1);
else return 0; }

a) suma primelor n numere naturale impare;


b) suma primelor n numere naturale pare;
c) suma numerelor naturale impare strict mai mici dec@t n;
d) suma numerelor naturale impare mai mici sau egale cu n.
Capitolul 3. Metode 79

32. |n metoda de mai jos \nlocui]i linia ... cu una dintre instruc]iunile
urm`toare, astfel \nc@t metoda s`-[i \ncheie execu]ia f`r` eroare pentru
orice valoare admisibil` a argumentului:
static int x(int n)
{ if (n!=0)
{ System.out.println(n);
... }
else return 0;
}

a) return x(n-2); b) return x(n%2);


c) return x(n-1); d) return x(n/2);

33. Dac` metoda este apelat` prin an(4), de c@te ori se autoapeleaz`?

static int an(int n)


{ if (n==0) return 1;
else return 3*an(n-1)+7;
}

a) de 4 ori; b) de 3 ori;
c) de 5 ori; d) depinde de stiv`.

Răspunsuri:
10. c) 11. a) 12. d) 13. c) 30 a) 31. d) 32. d) 33. a)
CAPITOLUL 4

Clase - primele noţiuni,


exemple

Din cuprins:
Ce este o clasă ?
Constructori
Date membru statice şi metode statice
Cuvântul cheie this
Referinţe către obiecte
Masive de obiecte
Aplicaţii ale noţiunilor prezentate
s Garbage Collector
Cum sunt memorate clasele ?
Pachete
Clase interioare
O problemă de terminologie
Probleme propuse
81 Bazele programării în Java

4.1. Ce este o clasă ?


La matematic` v-a]i \nt@lnit cu numere complexe! Ele sunt de forma:
z=x+iy, unde x,y. Prin urmare, pentru fiecare num`r complex ar trebui
s` re]inem dou` valori reale, pentru x [i pentru y. Decidem c` \n acest
caz, pentru a le re]ine, avem nevoie de dou` variabile de tip double.

Privi]i programul de mai jos care con]ine dou` clase: Complex [i test..
class Complex {
// date membru
double x,y;
// metoda
void afis()
{ System.out.println(x+" "+y); }
}
public class test {
public static void main(String[] args) {
// declar un numar complex
Complex z1;
z1= new Complex (); // Complex z1=new Complex();
// Datelor membru li se atribuie valori
z1.x=3;
z1.y=-4.7;
// Afisez datele membru
z1.afis();
}
}

S` analiz`m programul.

Clasa Complex:

1. Clasa con]ine dou` date membru, x [i y, ambele de tip double.


2. Clasa con]ine o metod` care are rolul de a afi[a \ntr-un mod
convenabil datele membru ale clasei.
Clasa test - metoda main()
1. Complex z1;- variabila z1 este de tip Complex. Prin urmare, ea poate
re]ine o referin]` (adres`) c`tre un obiect de tip Complex.
2. z1=new Complex(); - se creeaz` un obiect de tip Complex [i referin]a
c`tre el este re]inut` de z1.
3. z1.x=3; z1.y=-4.7; - datelor membru x [i y ale obiectului a c`rui
referin]` este re]inut` de z1 li se atribuie, respectiv, valorile 3 [i 4.7.
4. z1.afis(); - se afi[eaz` num`rul complex re]inut de obiectul referit
de z1.
Capitolul 4. Clase – primele noţiuni, exemple 82

 Foarte important !

A) La baza program`rii pe obiecte st` no]iunea de clas`. Clasa


incorporeaz` at@t date membru, c@t [i metode. A defini o clas` \nseamn` a
crea un tip (\n sensul extins). Un obiect rezult` ca instan]iere a unei clase.
Obiectul va avea ca tip numele clasei respective. Pentru a putea accesa
datele membru [i metodele clasei respective se utilizeaz` variabile de tip
referin]` c`tre obiectele clasei respective.
B) Odat` definit` clasa, putem crea obiecte de tipul clasei respective. |ntr-o
form` simplificat` (mai precis, \n absen]a unui constructor), crearea unui
obiect de tipul unei clase se face prin construc]ia de mai jos, unde v este
o variabil` referin]` c`tre obiectele clasei respective.
Nume_clasa v=new Nume_Clasa()
C) Un constructor al unei clase este o metod` special` a clasei respective
care are rolul de a aloca \n memorie spa]iul necesar obiectului dar [i de a
ini]ializa datele membru ale acestuia. Orice clas` are un constructor implicit
(adic` o metod` pe care nu a scris-o cel care a creat clasa).
D) Operatorul new are dublu rol:
- apeleaz` contructorul clasei respective;
- returneaz` referin]a (adresa) la care a fost creat obiectul respectiv.

Exemplu: Complex z=new Complex(); - z re]ine o referin]` c`tre obiectul


creat prin new.

z
1 x y
E) Accesul la variabilele interne ale obiectului se realizeaz` prin numele
obiectului, urmat de operatorul „.‟ [i numele variabilei. |n exemplu, Z va
re]ine num`rul x+2i, iar aceste valori vor fi afi[ate,
z1.x=1;
z1.y=2;
System.out.println(z1.x);
System.out.println(z2.y);

F) O clas` poate con]ine una sau mai multe metode. Apelul unei metode
de acest tip se face prin numele variabilei care re]ine referin]a c`tre obiect,
urmat de „.‟ [i de numele metodei. Exemplu: z1.afis();
G) Datele membru ale unei clase sunt ini]ializate implicit cu valoarea 0,
dac` sunt de un tip numeric, sau caracterul de cod 0, dac` sunt de tip
char, sau cu null dac` sunt de tip referin]`.
83 Bazele programării în Java

4.2. Constructori
A[a cum am ar`tat, orice clas` are un constructor implicit. Rolul lui
este de a aloca spa]iu \n memorie pentru obiect. Constructorul este apelat
de operatorul new. Acesta din urm` are [i rolul de a returna referin]a c`tre
obiect, referin]` care este memorat` de o variabil` de tip referin]` c`tre
obiect.

Unei clase i se pot crea proprii constructori, a[a cum rezult` din
exemplul urm`tor, unde clasei prezentate \n paragraful precedent i s-au
ad`ugat doi constructori:
class Complex {
// date membru
double x,y;
// Constructor 1
Complex (double x1)
{ x=x1; }
// Constructor 2
Complex (double x1, double y1)
{ x=x1; y=y1;}
// metoda
void afis()
{ System.out.println(x+" "+y);}
}
public class test {
public static void main(String[] args) {
Complex z1 = new Complex (2,3),z2 =new Complex (1);
z1.afis();
z2.afis();
}
}

Primul constructor are un singur parametru [i se folose[te pentru declara]ii


de numere complexe care au partea imaginar` 0. Al doilea constructor se
utilizeaz` pentru a declara numere complexe cu parte real` [i parte
imaginar`. |n ambele cazuri nu mai este nevoie ca datele membru s` fie
ini]ializate.

 De re]inut:

A) Un constructor nu are tip;


B) Un constructor are \ntotdeauna numele clasei c`reia \i apar]ine;
C) Dac` unei clase i se ata[eaz` un constructor, altul dec@t cel implicit,
atunci nu se mai poate instan]ia un obiect prin utilizarea constructorului
implicit. De exemplu, pentru clasa definit` \n acest paragraf o instruc]iune
de genul Complex z=new Complex() d` eroare de sintax`.
Capitolul 4. Clase – primele noţiuni, exemple 84

D) Unei clase i se pot ata[a mai mul]i constructori, dup` cum a]i v`zut [i
\n exemplu. Ei trebuie s` difere prin num`rul parametrilor [i /sau tipul
parametrilor, cu alte cuvinte, ca [i metodele, acestia sunt supra\nc`rca]i.
E) Constructorul implicit este apelat \n mod transparent (f`r` a scrie o
secven]` special`) de c`tre constructorul propriu.

4.3. Date membru statice şi metode statice


At@t datele membru c@t [i metodele unei clase pot fi statice. Aceasta
\nseamn` c` datele [i metodele declarate statice pot fi apelate, a[a cum
suntem deja obi[nui]i, pornind de la un obiect al clasei respective, dar [i
pornind de la numele clasei, a[a cum observa]i \n exemplul urm`tor.

Clasa Matematica con]ine o dat` membru ini]ializat` (Pi). De


asemenea, ea mai con]ine dou` metode: Patrat() [i Cub() prin care se
calculeaz` x2 [i x3. |n exemplu se calculeaz` [i afi[eaz` aria unui cerc \n
dou` feluri:

 apel@nd data membru [i metoda pornind de la numele clasei


(Matematica);
 apel@nd data membru [i metoda pornind de la numele unui obiect
al clasei Matematica.

class Matematica {
static double Pi=3.1415;
static double Patrat (double x)
{ return x*x; }
static double Cub (double x)
{ return x*x*x; }
}
public class Clasa1 {
public static void main(String[] args) {
int Raza=3;
double Aria=Matematica.Pi*Matematica.Patrat(Raza);
System.out.println(Aria);
//altfel
Matematica ob=new Matematica();
Aria=ob.Pi*ob.Patrat(Raza);
System.out.println(Aria);
}
}

 Foarte important !
A) Datele membru statice [i metodele statice nu sunt memorate de fiecare
obiect al clasei respective. Ele sunt memorate o singur` dat`, \n cadrul
clasei respective.
85 Bazele programării în Java

B) Sunt clase care au date membru [i/sau metode statice [i nestatice.


O clas` indispensabil`, este clasa Math, care este prezentat` \n
aceast` carte. Ea con]ine o mul]ime de metode “matematice” care se
utilizeaz` mult \n orice limbaj de programare. Clasa Matematica, din
exemplu, este construit` pe acelea[i principii ca [i clasa Math.

4.4. Cuvântul cheie this


|n interiorul claselor se poate utiliza cuv@ntul cheie this. Semnifica]ia
sa este: referin]` c`tre obiectul curent. Iat` una dintre aplica]iile sale:

Aplica]ie. Dac` o metod` (sau un constructor) are o variabil` cu un anumit


nume, de exemplu x, [i dac`, clasa are o dat` membru cu acela[i nume,
pentru exemplul nostru tot x, atunci pentru a nu se crea confuzie, data
membru va fi adresat` prin this.x, iar variabila din metod` (sau
constructor) prin x.

Exemplu: pentru clasa Complex din paragraful precedent, cei doi


constructori ar putea fi scri[i [i a[a:
Complex (double x)
{ this.x=x; }
Complex (double x, double y)
{ this.x=x; this.y=y;}

Alte aplica]ii ale cuv@ntului cheie this vor fi prezentate la momentul potrivit.

4.5. Referinţe către obiecte


Metodele pot avea parametri de tip referin]` la obiecte [i pot returna
referin]e c`tre obiecte. Evident, referin]ele sunt transmise prin valoare. Dar,
pornind de la ele, se poate accesa obiectul ca [i c@nd ar fi transmis prin
referin]`.
Exemplu: ad`ug`m clasei Complex metoda Complex adun(Complex z);
Metoda returneaz` o referin]` c`tre un obiect de tip Complex care re]ine
num`rul complex rezultat ca sum` \ntre num`rul re]inut de obiectul curent [i
num`rul complex transmis ca parametru.
class Complex {
double x,y;
Complex (double x)
{ this.x=x; }
Complex (double x, double y)
{ this.x=x; this.y=y;}
Capitolul 4. Clase – primele noţiuni, exemple 86

void afis()
{ System.out.println(x+" "+y);}
Complex adun(Complex z)
{ return new Complex (x+z.x,y+z.y);}
}
public class test {
public static void main(String[] args) {
Complex z1 = new Complex (2,3);
Complex z2 =new Complex(3,4);
Complex z=z1.adun(z2);
z.afis();}
}

Programul afi[eaz` suma numerelor complexe re]inute z1 [i z2 adic`


num`rul complex z=5+7i, afi[at ca: 5 7. Observa]i faptul c` variabila care
re]ine referin]a c`tre obiectul sum` a fost ini]ializat` cu ajutorul metodei
adun() a obiectului z1.

 Clasele pot con]ine variabile de tip referin]` la propriile obiecte


(sau la obiectele altei clase).
Exemplu (lista liniar` simplu \nl`n]uit`): pornind de la aceast` observa]ie,
construim o list` liniar` simplu \nl`n]uit`. Privi]i programul urm`tor care
creeaz` [i afi[eaz` o list` liniar` simplu \nl`n]uit`:
class Nod {
int info;
Nod adr_urm;
}
public class Lista {
static Nod v=null; // nu este obligatotrie ini]ilizarea
static void adaug(int nr)
{ Nod c=new Nod();
c.info=nr;
c.adr_urm=v;
v=c;}
static void afis()
{ Nod c=v;
while (c!=null)
{ System.out.println(c.info);
c=c.adr_urm;}
}
public static void main(String[] args) {
for (int i=1;i<=9;i++) adaug(i);
afis(); }
}

Un nod re]ine o informa]ie oarecare, s-o numim info [i s`


presupunem c` este de tip int [i o referin]` c`tre nodul urm`tor
(adr_urm). Evident, referin]a este c`tre obiecte ale acelea[i clase. Clasa
respectiv` am numit-o Nod.
87 Bazele programării în Java

Clasa care construie[te lista (Lista) con]ine o dat` membru de tip


static de tip referin]` c`tre un obiect al clasei Nod. De asemenea, clasa
con]ine [i dou` metode adaug() [i afis().

 Metoda adaug() are rolul de a ad`uga un nod listei liniare. Ea


prime[te ca argument num`rul care trebuie re]inut de info.
Observa]i cum s-a procedat: s-a creat un nou obiect al clasei Nod,
iar referin]a c`tre el este re]inut` de c. Data membru a acestui
obiect, info, este ini]ializat` cu valoarea primit` ca parametru de
metod`, iar adr_urm cu referin]a c`tre nodul anterior, re]inut` de
v. |n final, v re]ine referin]a c`tre ultimul nod creat. |n acest fel,
lista va re]ine nodurile \n ordinea invers` cre`rii lor. Am preferat
acest algoritm pentru simplitatea lui.
 Metoda afis() listeaz` valorile re]inute de data membru info a
fiec`rui nod.

4.6. Masive de obiecte


|ntrebarea este: se pot crea masive care re]in obiecte? De exemplu,
putem s` cre`m un vector care re]ine obiecte de tipul Complex? R`spunsul
este afirmativ! Elementele unui masiv pot re]ine referin]e c`tre obiecte.
Exemplu: \n programul urm`tor se creeaz` [i se afi[eaz` un
vector cu componente de tip Complex.
class Complex {
double x,y;
Complex (double x)
{ this.x=x; }
Complex (double x, double y)
{ this.x=x; this.y=y;}
void afis()
{ System.out.println(x+" "+y);}
Complex adun(Complex z)
{ return new Complex (x+z.x,y+z.y);}
}
public class test {
public static void main(String[] args) {
Complex[] V=new Complex[3];
for (int i=0;i<3;i++) V[i]=new Complex(i+1,i+2);
for (int i=0;i<3;i++) V[i].afis();
}
}

Pentru a \n]elege modul \n care a fost construit vectorul de obiecte


rezultate ca instan]e ale clasei Complex, analiza]i figura urm`toare:
Capitolul 4. Clase – primele noţiuni, exemple 88

V[0] V[1] V[2]

1 2 afis() 2 3 afis() 3 4 afis()


x y x y x y

Alte exemple:
1) |n secven]a urm`toare, V1 re]ine o referin]` c`tre un vector cu 10
componente care pot re]ine referin]e c`tre obiecte ale clasei Complex.
Se instan]iaz` un obiect al clasei Complex [i referin]a sa este
atribuit` lui V1[2]. Ultimele 3 instruc]iuni au rolul de a proba cele
prezentate.
Complex[] V1 =new Complex[10];
V1[2]=new Complex(10,11);
V1[2].afis();

2) |n secven]a urm`toare, V1 re]ine o referin]` c`tre o matrice cu 8 linii


[i 5 coloane. Fiecare component` a matricei poate re]ine o referin]`
c`tre un obiect al clasei Complex. Se instan]iaz` un obiect al clasei
Complex [i referin]a sa este atribuit` lui V1[2][3].
Complex[][] V1 =new Complex[8][5];
V1[2][3]=new Complex(10,11);
V1[2][3].afis();

3) V1 re]ine o referin]` c`tre o matrice cu 5 linii [i un num`r neprecizat


de coloane. Un element al matricei va re]ine o referin]` c`tre un
obiect al clasei Complex. Linia de indice 3, va avea 6 elemente.
Elementul aflat \n linia de indice 3 [i coloana de indice 4 va re]ine o
referin]` c`tre un obiect al clasei Complex. Apoi, se probeaz`...
Complex[][] V1=new Complex[5][];
V1[3]=new Complex[6];
V1[3][4]=new Complex(100,200);
V1[3][4].afis();

4.7. Aplicaţii ale noţiunilor prezentate


Este momentul s` \nv`]`m s` cre`m clase [i apoi s` le utiliz`m..
|nainte de a prezenta aplica]iile preciz`m c`, dac` lucr`m \n folder-ul bin, a[a
cum am lucrat p@n` acum, putem compila o clas` oarecare f`r` ca ea s`
con]in` metoda main(). Fi[ierul ob]inut (are extensia .class) se va g`si \n
bin. (dac` cel cu extensia .java este tot acolo). Orice alt` clas` care con]ine
89 Bazele programării în Java

main() din bin, poate folosi clasa compilat`, f`r` a o mai declara \ntr-un fel.
De altfel, aceast` problem` va fi tratat` pe larg \n acest capitol.

4.7.1. Lucrul cu numere raţionale

S` se creeze o clas` cu ajutorul c`reia s` se poat` lucra u[or cu


numere ra]ionale. Un num`r ra]ional q este de forma m/n cu m [i n numere
\ntregi [i n diferit de 0.

 Clasa va avea dou` date membru, m [i n, ambele tip int.


 Constructorul clasei este Rational (int m, int n). Obiectul este creat
numai dac` n0. Datorit` faptului c` un num`r ra]ional poate fi re]inut
\n mai multe feluri (de exemplu 2/3=4/6=8/12=) se va re]ine num`rul
simplificat (pentru exemplul dat, m=2 [i n=3, chiar dac` introducem 8 [i
12). Pentru a putea realiza simplificarea frac]iei, m [i n se \mpart la cel
mai mare divizor comun al lor.
 Clasa va dispune de o metod`, static int cmmdc(int m, int n),
apelat` de constructor, prin care se calculeaz` cel mai mare divizor
comun al valorilor re]inute de datele membru m [i n.
 Metoda Rational add(Rational r) creeaz` un obiect al clasei
Rational care este rezultatul adun`rii dintre obiectul curent [i obiectul
a c`rui referin]` a fost primit` ca parametru [i returneaz` referin]a c`tre
el. Faptul c` a fost apelat constructorul cu datele membru ale obiectului
sum`, are ca efect faptul c` obiectul care re]ine suma este deja
simplificat (m [i n au fost \mp`r]ite la cmmdc al lor).
 Metoda Rational sub(Rational r) creeaz` un obiect al clasei
Rational care este rezultatul sc`deriii dintre obiectul curent [i obiectul
a c`rui referin]` a fost primit` ca parametru [i returneaz` referin]a c`tre
el.
 Metoda Rational mul(Rational r) creeaz` un obiect al clasei
Rational care este rezultatul \nmul]irii dintre obiectul curent [i obiectul
a c`rui referin]` a fost primit` ca parametru [i returneaz` referin]a c`tre
el.
 Metoda Rational div(Rational r) creeaz` un obiect al clasei
Rational care este rezultatul \mp`r]irii dintre obiectul curent [i obiectul
a c`rui referin]` a fost primit` ca parametru [i returneaz` referin]a c`tre
el.
 Metoda boolean maiMare (Ratioanal r) compar` obiectul curent cu
obiectul a c`rui referin]` a fost primit` ca parametru [i returneaz` true
dac` obiectul curent este strict mai mare dec@t cel a c`rui referin]` a
fost transmis` ca parametru [i false \n caz contrar.
Capitolul 4. Clase – primele noţiuni, exemple 90

 Metoda boolean maiMic (Ratioanal r) compar` obiectul curent cu


obiectul a c`rui referin]` a fost primit` ca parametru [i returneaz`
true dac` obiectul curent este strict mai mic dec@t cel a c`rui referin]`
a fost transmis` ca parametru [i false \n caz contrar.
 Metoda boolean egal (Ratioanal r) compar` obiectul curent cu
obiectul a c`rui referin]` a fost primit` ca parametru [i returneaz`
true dac` obiectul curent este egal cu cel a c`rui referin]` a fost
transmis` ca parametru [i false \n caz contrar.

Mai jos pute]i observa modul \n care arat` clasa Rational:


class Rational {
int m,n;
static int cmmdc(int m, int n)
{ if (n!=0) return cmmdc(n, m%n);
else return m;}
Rational (int m, int n)
{ if (n!=0)
{ int d=cmmdc(m,n);
this.m=m/d; this.n=n/d;}
else System.out.println("Numitorul este nul");}
Rational add(Rational r)
{ return new Rational (m*r.n+r.m*n, n*r.n); }
Rational sub(Rational r)
{ return new Rational (m*r.n-r.m*n, n*r.n); }
Rational mul(Rational r)
{ return new Rational (m*r.m,n*r.n); }
Rational div(Rational r)
{ if (r.m!=0) return new Rational (m*r.n,n*r.m);
else return new Rational (0,1);}
boolean maiMare(Rational r)
{ return (double) m/n > (double)r.m/r.n; }
boolean maiMic(Rational r)
{ return (double) m/n < (double)r.m/r.n; }
boolean egal(Rational r)
{ return (double) m/n == (double)r.m/r.n; }
}

 |n continuare, ne propunem s` rezolv`m c@teva aplica]ii \n care intervin


numere ra]ionale:

1. Se citesc dou` numere ra]ionale q1 [i q2 (0). Se cere s` se afi[eze


q1+q2, q1-q2, q1*q2, q1/q2. Rezultatele vor fi tot dou` numere ra]ionale.

Rezolvare. Varialbila q3 este de tip referin]` c`tre un obiect al clasei


Rational. Dup` fiecare opera]ie, ea va re]ine referin]a c`tre obiectul rezultat
\n urma opera]iei.
91 Bazele programării în Java

class I {
public static void main(String[] args) {
int m=Integer.parseInt(cin.Token());
int n=Integer.parseInt(cin.Token());
Rational q1=new Rational (m,n);
m=Integer.parseInt(cin.Token());
n=Integer.parseInt(cin.Token());
Rational q2=new Rational (m,n);
Rational q3=q1.add(q2);
System.out.println("Suma="+q3.m+"/"+q3.n );
q3=q1.sub(q2);
System.out.println("Diferenta="+q3.m+"/"+q3.n );
q3=q1.mul(q2);
System.out.println("Produsul="+q3.m+"/"+q3.n );
q3=q1.div(q2);
System.out.println("Catul="+q3.m+"/"+q3.n );
}
}

2. Se citesc k numere ra]ionale. Se cere s` se afi[eze suma lor sub form`


de num`r ra]ional.

Rezolvare. Obiectul s, va re]ine ini]ial o referin]` c`tre un num`r ra]ional nul


(m=0, n=1). Se citesc, pe r@nd, cele k numere ra]ionale. Pentru fiecare num`r
ra]ional citit, se construie[te obiectul suma \ntre s [i obiectul care re]ine
num`rul ra]ional, iar referin]a c`tre el este atribuit` lui s. |n final se afi[eaz`
datele mebru ale obiectului s.
class I {
public static void main(String[] args) {
System.out.print("k=");
int k=Integer.parseInt(cin.Token());
Rational s=new Rational(0,1);
for (int i=0;i<k;i++)
{ System.out.print("m=");
int m=Integer.parseInt(cin.Token());
System.out.print("n=");
int n=Integer.parseInt(cin.Token());
Rational q=new Rational (m,n);
s=s.add(q);
}
System.out.println("Suma="+s.m+"/"+s.n );
}
}

3. Se cite[te un vector cu k componente numere ra]ionale (obiecte ale clasei


Rational). Se cere s` se afi[eze vectorul sortat cresc`tor

Rezolvare. Dup` citirea vectorului vom utiliza metoda de sortare prin


interschimbare. Pentru comparare se utilizeaz` metoda maiMare().
Capitolul 4. Clase – primele noţiuni, exemple 92

class I {
public static void main(String[] args) {
System.out.print("k=");
int k=Integer.parseInt(cin.Token());
Rational [] V=new Rational [k];
for (int i=0;i<k;i++)
{ System.out.print("V["+i+"].m=");
int m=Integer.parseInt(cin.Token());
System.out.print("V["+i+"].n=");
int n=Integer.parseInt(cin.Token());
V[i]=new Rational(m,n);
}
boolean gasit;
Rational man;
do
{ gasit=false;
for (int i=0;i<k-1;i++ )
if (V[i].maiMare(V[i+1]))
{ man=V[i];
V[i]=V[i+1];
V[i+1]=man;
gasit=true;
}
} while (gasit);
for (int i=0;i<k;i++)
System.out.println("V["+i+"].m="+V[i].m+" V["+i+"].n="+V[i].n);
}
}

4.7.2. Lucrul cu mulţimi de numere naturale

S` se creeze o clas` numit` Multime, care s` ne faciliteze lucrul cu


mul]imi de numere naturale. Numerele naturale care pot fi elemente ale
mul]imilor sunt din intervalul [0,999], adic` cel mult 1000 de numere. De
exemplu, o astfel de mul]ime ar fi {1,3,5}.

O mul]ime se re]ine prin vectorul caracteristic. Dac` un num`r apar]ine


mul]imii, componenta respectiv` va re]ine 1, altfel componenta va re]ine 0.
De exemplu, pentru mul]imea dat` ca exemplu, vectorul caracteristic va fi:

0 1 0 1 0 1 0 0
0 1 2 3 4 5 6 999
|n continuare, prezent`m componentele care alc`tuiesc clasa respectiv`:

 caract – referin]` c`tre un vectorul caracteristic.

 int card() – metod` care returneaz` num`rul de elemente al mul]imii


(cardinalul). Practic, num`r` componentele nenule din vectorul
caracteristic.
93 Bazele programării în Java

 boolean ap(int k) – metod` care testeaz` apartenen]a lui k la


mul]ime. Practic, se verific` dac` caract[k] re]ine 1. |n caz de
apartenen]`, metoda returneaz` true, altfel returneaz` false.

 Multime reun(int k) – metod` care returneaz` o referin]` la mul]imea


ob]inut` din reuniunea mul]imii asociate obiectului curent cu elementul k.

 Multime reun(Multime T) – metod` care returneaz` o referin]` la


mul]imea ob]inut` din reuniunea mul]imii asociate obiectului curent cu
mul]imea asociat` obiectului a c`rui referin]` este transmis` ca
parametru. Dup` cum observa]i, avem de fapt, dou` metode cu acela[i
nume (am folosit supra\nc`rcarea metodelor).

 Multime inters(Multime T) – metod` care returneaz` o referin]` la


mul]imea ob]inut` din intersec]ia mul]imii asociate obiectului curent cu
mul]imea asociat` obiectului a c`rui referin]` este transmis` ca
parametru.

 Multime dif(Multime T) – metod` care returneaz` o referin]` la


mul]imea ob]inut` din diferen]a \ntre mul]imea asociat` obiectului curent
[i mul]imea asociat` obiectului a c`rui referin]` este transmis` ca
parametru.

 Multime dif(Multime T) – metod` care returneaz` o referin]` la


mul]imea ob]inut` din diferen]a dintre mul]imea asociat` obiectului curent
[i mul]imea alc`tuit` dintr-un singur element, adic` elementul k transmis
ca parametru.

 boolean inclus(Multime T) – metod` care returneaz` true dac`


mu]imea asociat` obiectului curent este inclus` \n mul]imea a c`rei
referin]` a fost transmis` ca parametru [i false \n caz contrar.

Analiza]i clasa Multime:

class Multime {
byte[] caract=new byte[1000];
int card()
{ int s=0;
for (int i=0;i<1000;i++)
if (caract[i]==1) s++;
return s;}
boolean ap(int k)
{ if (caract[k]==1) return true;
else return false;}
Multime reun (int k)
{ caract[k]=1;
return this;}
Capitolul 4. Clase – primele noţiuni, exemple 94

Multime reun (Multime T)


{ Multime man=new Multime();
for (int i=0;i<1000;i++)
if (caract[i]==1 || T.caract[i]==1) man.caract[i]=1;
return man; }
Multime inters (Multime T)
{ Multime man=new Multime();
for (int i=0;i<1000;i++)
if (caract[i]==1 && T.caract[i]==1) man.caract[i]=1;
return man; }
Multime dif (Multime T)
{ Multime man=new Multime();
for (int i=0;i<1000;i++)
if (caract[i]==1 && T.caract[i]==0) man.caract[i]=1;
return man; }
Multime dif (int k)
{ caract[k]=0;
return this; }
boolean inclus(Multime T)
{ boolean inclus=true;
for (int i=0;i<1000;i++)
if (caract[i]==1 && T.caract[i]==0) inclus=false;
return inclus; }
}

 Exerci]ii de utilizare a clasei Multimi:

1. Se citesc n numere naturale mai mici dec@t 1000. Se cere s` se afi[eze


num`rul numerelor distincte [i numerele propriu-zise. De exemplu, dac` n=4 [i
numerele sunt 5, 6, 5, 6 se va afi[a 2 [i 5, 6.
Rezolvare. Numerele citite sunt ad`ugate (reunite) la o mul]ime ini]ial vide.
Evident, dac` un num`r apare de mai multe ori, el se va g`si \n mul]ime o
singur` dat`. Num`rul de numere distincte va fi dat de num`rul de elemente
al mul]imii (cardinalul ei), iar numerele distincte sunt cele care se reg`sesc \n
mul]ime.
class I {
public static void main(String[] args) {
Multime A= new Multime();
System.out.print("n=");
int n=Integer.parseInt(cin.Token());
for (int i=0;i<n;i++)
A=A.reun(Integer.parseInt(cin.Token()));
System.out.println("Numere distincte "+A.card());
for (int i=0;i<1000;i++)
if (A.ap(i)) System.out.println(i);
}
}
95 Bazele programării în Java

2. Se citesc dou` mul]imi de numere naturale A [i B. Se cere s` se afi[eze


dac` cele dou` mul]imi sunt egale sau nu.

Rezolvare. O metod` de verificare a egalit`]ii a dou` mul]imi, A [i B, este de


a verifica dac` AB [i BA. Desigur, s-ar putea proceda si altfel, prin a
verifica dac` cei doi vectori caracteristici sunt identici.
class I {
public static void main(String[] args) {
Multime A= new Multime();
System.out.print("n=");
int n=Integer.parseInt(cin.Token());
for (int i=0;i<n;i++)
A=A.reun(Integer.parseInt(cin.Token()));
Multime B=new Multime();
System.out.print("m=");
int m=Integer.parseInt(cin.Token());
for (int i=0;i<m;i++)
B=B.reun(Integer.parseInt(cin.Token()));
if (A.inclus(B) && B.inclus(A) ) System.out.println("Egale");
else System.out.println("Diferite");
}
}

3. Se citesc dou` mul]imi de numere naturale A [i B. Se cere s` se afi[eze


dac` cele dou` mul]imi sunt disjuncte (nu au elemente comune) sau nu.
Rezolvare. Dou` mul]imi sunt disjuncte dac` intersec]ia lor este vid`.
Programul este asem`n`tor programului precedent, dar secven]a prin care se
testeaz` dac` mul]imile sunt disjuncte este cea de mai jos.
if (A.inters(B).card()==0) System.out.println("Disjucte");
else System.out.println("Nedisj");

4. Se citesc n mul]imi de numere naturale mai mici dec@t 1000. S` se


memoreze mul]imile \ntr-un vector de mul]imi [i s` se calculeze [i afi[eze
mul]imea care rezult` din reuniunea celor n mul]imi.

Rezolvare. Se creeaz` un vector de mul]imi.


class I {
public static void main(String[] args) {
System.out.print("n=");
int n=Integer.parseInt(cin.Token());
Multime [] V= new Multime[n];
for (int i=0;i<n;i++)
{ V[i]=new Multime();
System.out.print("Multime["+i+"] "+ "nr elem=");
int m=Integer.parseInt(cin.Token());
for (int j=0;j<m;j++)
V[i]=V[i].reun(Integer.parseInt(cin.Token()));
}
Multime R= new Multime();
Capitolul 4. Clase – primele noţiuni, exemple 96

for (int i=0;i<n;i++)


R=R.reun(V[i]);
for (int i=0;i<1000;i++)
if (R.ap(i))System.out.print (i+" ") ;
}
}

4.8. Garbage Collector


Modul \n care se aloc` obiectele a fost prezentat \n acest capitol. Pe
parcursul rul`rii unui program se pot aloca multe obiecte, iar altele devin
inutile, adic` nu mai exist` referin]` c`tre ele. Dac` num`rul obiectelor alocate
este foarte mare, este posibil ca programul s` nu mai dispun` de suficient`
memorie [i, prin urmare, executarea sa s` nu mai poat` continua.

Pentru a rezolva aceast` problem`, programele java con]in o secven]`


(fir de executare), numit` Garbage Collector, care intervine automat (f`r`
ca programul nostru s` con]in` instruc]iuni scrise special \n acest scop) si
elibereaz` memoria ocupat` de obiectele nereferite. Aceasta poate duce,
uneori, la o \ncetinire a execut`rii programelor. Momentul \n care intervine
Garbage Collector nu este stabilit de programator.

4.9. Cum sunt memorate clasele ?


P@n` \n prezent am utilizat, de regul`, programe scrise con]inute \ntr-
un singur fi[ier text surs`, cu extensia .java. [i care se afl` \n subfolder-
ul bin al folder-ului Java Un astfel de text include toate clasele create de
noi. Cunoa[em faptul c` numele unui astfel de fi[ier trebuie s` coincid` cu
numele clasei care con]ine metoda main().

Fie programul de mai jos, care se g`se[te \n fi[ierul surs`


exmp.java. Textul con]ine 3 clase A, B, [i exmp.

class A
{ void tip() { System.out.println("clasa A"); }
}
class B
{ void tip() { System.out.println("clasa B"); }
}
public class exmp {
public static void main(String[] args) {
A x=new A(); x.tip();
B y=new B(); y.tip();
}
}
97 Bazele programării în Java

|n urma compil`rii, fiec`rei clase inclus` \n fi[ierul text \i va


corespunde un fi[ier cu numele clasei respective [i extensia class.

Compil`m exmp prin javac exmp.java. Analiza]i folder-ul bin. |n


urma compil`rii, el va con]ine trei fi[iere A.class, B.class, exmp.class.
Pentru rularea programului vom da comanda java exmp.

 |n acest fel, comunic`m programului java faptul c` fi[ierul care


con]ine clasa exmp con]ine [i metoda main(). Aceasta \nseamn` c`
se [tie de unde trebuie s` \nceap` rularea (care este clasa care
con]ine metoda main()). Mai mult, programul va identifica automat
celelalte clase de care are nevoie (A.class [i B.class) \n folder-ul
bin.

 Modul \n care se re]in clasele are drept consecin]` [i faptul c`, odat`
compilat` o clas`, ea se va g`si \n folder-ul bin [i va putea fi
utilizat` [i de alte programe, care nu con]in \n textul surs` clasa
respectiv` (pe acest principiu am utilizat clasa cin).

 V` da]i seama c` o astfel de modalitate de lucru \n care toate


fi[ierele text, cu extensie java, toate clasele compilate se g`sesc \n
acela[i folder (bin) creeaz` numeroase dezavantaje \n practic`, acolo
unde trebuie s` avem programele memorate separat. Din acest motiv,
trebuie s` prezent`m modul \n care putem memora clasele separat.

Revenim la programul aflat \n fi[ierul text exmp.java. Obseva]i faptul


c` acest program nu utilizeaz` clase definite \n alt` parte. Vom crea un
folder, sa-l numim sursa, \n care am mutat fi[ierul exmp.java (a fost
[ters din bin).. De asemenea, vom mai crea un folder, numit sursac \n
care dorim s` avem programul compilat. Ambele folder-e se g`sesc \n
r`d`cin` (c:\).

Pentru a compila fi[ierul exmp.java aflat \n folder-ul sursa [i pentru


ca rezultatul s` se g`seasc` \n folder-ul sursac, vom apela javac astfel:
javac –d c:\sursac c:\sursa\exmp.java
 –d c:\sursac – specific` folder-ul \n care se va g`si programul
compilat;

 c:\sursa\exmp.java – fi[ierul care con]ine sursa java, dar aici,


cuprinde [i calea c`tre el (este pe c:\, \n folder-ul sursa [i se
nume[te exmp.java).


Dac` am fi apelat javac prin javac c:\sursa\exmp.java, atunci
programul compilat s-ar g`si acolo unde este [i fi[ierul text care
con]ine programul surs` (adic` \n folder-ul sursa).
Capitolul 4. Clase – primele noţiuni, exemple 98

Pentru a rula programul care se g`se[te compilat \n folder-ul sursac,


se apeleaz` java astfel:
java –classpath c:\sursac exmp

 –classpath c:\sursac specific` folder-ul unde se g`se[te


programul compilat;
 exmp – numele clasei care con]ine main().

 Nu uita]i, pute]i folosi variabila de sistem CLASSPATH (vezi


cap. 1) !

4.10. Pachete
Un pachet este alc`tuit dintr-una sau mai multe clase si eventual, unul
sau mai multe subpachete. Perntru moment, vom neglija subpachetele [i vom
considera pachetul alc`tuit exclusiv din clase. Ideea de baz`, care a stat la
elaborarea unui set de reguli de creare [i exploatare a pachetelor, este de a
permite celor ce scriu programe s` utilizeze clasele respective sau numai
unele metode con]inute de aceste clase. Acum, ne propunem s` \nv`]`m s`
cre`m [i s` utiliz`m pachete. Clasele care alc`tuiesc pachetul respectiv se pot
g`si \ntr-unul sau mai multe fi[iere surs`.

Vom porni de la un exemplu, \n care avem dou` clase A [i B. Fiecare


clas` con]ine c@te o metod`.

Pasul 1. Stabilim numele pachetului, |n exemplul nostru, acesta se nume[te


primulPachet.

Pasul 2. Cre`m un folder care va re]ine fi[ierele compilate. |n exemplu, acesta


va fi pe C:\ [i se nume[te Pachete.

Pasul 3. Fi[ierele surs` (cu extensia .java) se grupeaz` \ntr-un folder


oarecare. |n exemplu acesta se va numi Surse [i se va afla pe c:\.

 Pentru a preciza c` o anumit` clas` apar]ine unui pachet, prima linie a


sursei trebuie s` fie package nume_pachet;
 Pentru a avea acces la o clas` din afara ei, trebuie ca respectiva clas` s`
fie public`. Aceasta \nseamn` c` \naintea cuv@ntului cheie class trebuie
s` se g`seasc` modificatorul public.
 Pentru a avea acces la o anumit` metod` a clasei respective, trebuie ca
metoda s` fie public`. |n concluzie [i metodele con]inute \n clasele
respective vor fi precedate de modificatorul public.

|n concluzie, \n C:\Surse vom avea fi[ierele A.java [i B.java de mai jos:


99 Bazele programării în Java

A.java:
package primulPachet;
public class A
{ public void tip() { System.out.println(“clasa A”); }
}

B.java:
package primulPachet;
public class B
{ public void tip() { System.out.println(“clasa B"); }
}

Pasul 4. Compil`m pe r@nd cele dou` clase (-d precizeaz` unde se vor g`si
fi[ierele compilate):

javac -d c:\pachete c:\surse\a.java


javac -d c:\pachete c:\surse\b.java

S` observ`m c`, \n folder-ul pachete s-a creat automat un subfolder care


are numele pachetului (primulPachet Cu asta pachetul este creat.

Urmeaz` s` scriem un program care utilizeaz` clasele pachetului creat.


Fie programul de mai jos, a c`rui surs` se g`se[te \n folder-ul C:\Prog.
Dorim ca programul compilat s` se reg`seasc` \n acela[i folder.
 Dup` cum stim, este obligatoriu ca numele fi[ierului s` coincid` cu numele
clasei care con]ine main(), dar s` aib` extensia .java.

 De asemenea, pentru a preciza c` acest program utilizeaz` pachetul numit


primulPachet, prima linie a proiectului va con]ine clauza import
primulPachet.*;. Iat` programul:

import primulPachet.*;
public class exmp {
public static void main(String[] args) {
System.out.println("Utilizarea primului pachet");
A x=new A(); x.tip();
B y=new B(); y.tip();}
}

Pasul . Compil`m programul, av@nd grij` s` specific`m locul unde g`sesc


clasele. |ntruc@t se dore[te ca programul compilat s` se g`seasc` \n acela[i
loc cu sursa, parametrul -d lipse[te.
javac -classpath c:\pachete C:\prog\exmp.java

Pasul . Comand`m executarea programului. Trebuie s` preciz`m folder-ele


care con]in clasele: c:\prog (pentru exmp.class) [i c:\pachete
(A.class, B.class). C`ile se scriu separate prin ;, f`r` spa]iu \ntre ele.
java -classpath c:\prog;c:\pachete exmp
Capitolul 4. Clase – primele noţiuni, exemple 100

 Important !

1. Clasele care alc`tuiesc pachetul trebuie s` fie publice. De asemenra,


metodele lor, care pot fi apelate de utilizatorii pachetelor trebuie s` fie publice.
2. Fiecare clas` a pachetului trebuie s` se g`seasc` \ntr-un fi[ier text cu
extensia .java [i numele clasei respective. Rezult` de aici c` o clas` trebuie
s` fie singura din fi[ierul respectiv.

S` recapitul`m: am creat un pachet care se nume[te primulPachet. El se


g`se[te \n folder-ul Pachete.

Am ar`tat faptul c` un pachet poate con]ine, pe l@ng` clase [i unul sau


mai multe subpachete. Subpachetele sunt, la r@ndul lor pachete, dar sunt
incluse \ntr-un pachet din considerente de ordonare logic` a claselor.

Pentru a \n]elege modul \n care se creeaz` [i exploateaz` un


subpachet, vom ad`uga pachetului primulPachet un subpachet numit
pachetel, care contine o singur` clas`, C, aflat` \n fi[ierul C.java din bin.
package primulPachet.pachetel; //numele subpachetului
public class C
{ public void tip() {
System.out.println("clasa din structuri.pachetel");}
}

Compil`m clasa cu: javac -d C:\Pachete C.java Automat, \n folder-ul


primulPachet, pe ling` fi[ierele A.class, B.class va ap`rea subfolder-ul
pachetel care con]ine fi[ierul C.class.

Programul urm`tor, aflat \n fi[ierul Inv.java din bin va utiliza subclasa


C din pachetel.
import primulPachet.pachetel.*;
class Inv {
public static void main(String[] args) {
C x=new C();
x.tip();
}
}

Compil`m programul prin: javac -classpath C:\Pachete Inv.java


Dup` aceast` comand` \n bin avem fi[ierul Inv.class (a fost necesar s` se
cunoasc` locul unde este clasa C.

Lansarea \n executare se face cu comanda java -classpath


C:\Pachete;C:\j2sdk1.4.2_04\bin Inv. A doua cale din classpath
este c`tre folder-ul bin (acolo am pe calculatorul meu instalat mediul Java).
Fiecare trece calea pentru locul unde are instalat pe propriul calculator
mediul Java.
101 Bazele programării în Java

 Foarte important !

1. Prin import primulPachet.pachetel.*; -solicit`m s` avem acces la


toate clasele din subpachetul pachetel. Cum acest subpachet nu con]ine
dec@t o clas` (C), am putea scrie:
import primulPachet.pachetel.C;

2. |n acest caz, nu se poate solicita accesul la clasa subpachetului prin


import primulPachet.*;, pentru c` o astfel de solicitare asigur` accesul la
toate clasele pachetului primulPachet, nu [i la toate clasele subpachetelor sale.

4.11. Clase interioare


|n Java exist` posibilitatea ca o clas` s` includ` una sau mai multe
clase. Ca [i datele membru sau metodele unei clase, clasele interne pot fi
statice sau nestatice.

A) Clase nestatice. Acestea se includ \n structura de clas`. Pentru fi


activate, clasa “mam`” va con]ine o referin]` c`tre un obiect al clasei
interne. Prin intermediul acestei referin]e se pot accesa datele membru [i
metodele clasei interne. Vezi exemplul de mai jos, unde referin]a c`tre
obiectul clasei interne este ref. |n acest caz, obiectul clasei “mam`”
con]ine o referin]` c`tre obiectul clasei interne. |n exemplu, se apeleaz`
metoda M1() a clasei “mama” [i metoda M2() a clasei interne. De
asemenea, se afi[eaz` data membru a clasei interne, numit` b.

class A {
I ref=new I();
int a=1;
void M1()
{ System.out.println("a="+a);}
class I {
int b=2;
void M2()
{ System.out.println("Metoda din clasa inclusa");}
}
}

public class C {
public static void main(String[] args) {
A x=new A();
x.M1();
x.ref.M2();
System.out.println(x.ref.b);
}
}
Capitolul 4. Clase – primele noţiuni, exemple 102

B) Clase statice. Mai jos, ave]i un astfel de exemplu. Observa]i modul de


apel al metodelor [i datelor membru:
class A {
int a=1;
void M1()
{ System.out.println("a="+a);}
static class I {
static int b=2;
static void M2()
{ System.out.println("Metoda din clasa inclusa");}
}
}
public class C {
public static void main(String[] args) {
A x=new A();
x.M1();
A.I.M2();
System.out.println(A.I.b);}
}

 Observa]ii:

1. Dac` o clas` con]ine o clas` interioar`, atunci dup` compilare se ob]in


dou` clase (dou` fi[iere cu extensia .class). Prima cu numele clasei (\n
exemplul dat, A.class), a doua cu numele clasei care include o alt` clas`,
urmat de caracterul “$” [i de numele clasei incluse (\n exemplu A$I.class).

2. Pentru clasele interioare nestatice, datele membru [i metodele claselor


interioare se pot accesa [i f`r` a utiliza acea referin]` c`tre clasa interioar`,
ca \n exemplul urm`tor, referitor la programul prezentat la \nceputul acestui
paragraf.
A x=new A();
A.I y= x.new I();
y.M2();

3. Dintr-o clas` interioar` se pot accesa datele membru ale clasei care o
con]ine. Testa]i!

4.12. O problemă de terminologie


Am v`zut c` metodele pot \ntoarce referin]e c`tre obiecte. De
asemenea, parametrii metodelor pot fi de tip referin]` c`tre obiecte. Prin
abuz de limbaj, pentru a nu complica exprimarea, vom spune, uneori, c`
metodele \ntorc obiecte, vom vorbi despre obiectul (obiectele) primite ca
parametru de o metod`. |ns`, acestea trebuie \n]elese ca referin]e c`tre
obiecte.
103 Bazele programării în Java

Probleme propuse
Exerci]iile 1. [i 2. se refer` la clasa de mai jos, care se g`se[te deja
compilat` \n bin:

class a {
int a=1;
int a()
{ int a=2;
return a;}
}

1. Care dintre programele de mai jos este corect din punct de vedere
sintactic?

a) b)
class ex { class ex {
public static void public static void
main(String[] args) { main(String[] args) {
a a=new a();} a x=new a;}
} }

c) d)
class ex { class ex {
public static void public static void
main(String[] args) { main(String[] args) {
x a=new a();} a x=new ();}
} }

2. Fiind dat` x, o variabil` care re]ine o referin]` c`tre un obiect al clasei a,


care dintre instruc]iunile de mai jos afi[eaz` valoarea 2?

a) System.out.println(x.a);
b) System.out.println(x.a.a);
c) System.out.println(x.a());
d) Nici una dintre instruc]iunile de mai sus nu afi[eaz` valoarea 2.

3. Fiind dat` clasa de mai jos, ce afi[eaz` instruc]iunea aflat` \n main():


A.M(3.5)?

class A {
static void M(int x) {System.out.println(1);}
static void M(float x) {System.out.println(2);}
static void M(double x) {System.out.println(3);}
static void M(char x) {System.out.println(4);}
}

a) 1; b) 2; c) 3; d) 4.
Capitolul 4. Clase – primele noţiuni, exemple 104

4. Ce afi[eaz` programul urm`tor?

class A {
int a,b;
A(int a, int b)
{ this.a=a;
this.b=b;}
A (int x) {b=x;}
void Afis() {System.out.print (a+" "+b);}
}
class ex {
public static void main(String[] args) {
A x=new A(3);
x.Afis();
}
}

a) Eroare; b) 3 0; c) 0 0; d) 0 3.

5. Crea]i o clas` numit` Lista, care opereaz` cu liste liniare simplu \nl`n]uite.
Un element al listei liniare simplu \nl`n]uite este descris de clasa Nod:
class Nod
{ Nod adr_urm;
int nr; }

Clasa Lista va con]ine:

 Data membru v - adresa primului nod al listei. |n cazul \n care lista


este nul`, v re]ine null.

 Metoda void adaug (int nr) - adaug` la sf@r[itul listei un nod care
va re]ine valoarea numeric` nr, primit` de metod` ca parametru.

 Metoda void afis() - care afi[eaz` valorile re]inute de noduri.

6. Ad`uga]i clasei Lista o metod` void stergP() care permite [tergerea


primului nod introdus.

7. Ad`uga]i clasei Lista o metod` void stergU() care permite [tergerea


ultimului nod introdus.
8. Ad`uga]i clasei Lista o metod` void adaugI(int nr) care permite ca
la \nceputul listei s` se adauge un nod care s` con]in` valoarea nr, primit`
de metod` ca parametru.
9. Scrie]i un program care creeaz` o list` liniar` simplu \nl`n]uit`. Programul
va utiliza clasa Lista, creat` anterior. Numerele se citesc de la tastatur` [i
se vor g`si \n list` \n ordinea \n care au fost introduse. {irul de numere se
consider` \ncheiat atunci c@nd se cite[te num`rul 0 (acesta nu este introdus
\n list`).
105 Bazele programării în Java

10. La fel ca la problema 9, numai c` elementele se vor g`si \n list` \n


ordinea invers` introducerii lor.
11. Ad`uga]i clasei Lista o metod` void concat(Lista) care s`
concateneze lista curent` cu o alt` list`. Scrie]i un program care o testeaz`.
12. Realiza]i o clas` numit` Stiva, care opereaz` cu stive alocate ca liste
liniare simplu \nl`n]uite. Un element al listei este descris de clasa Nod:

class Nod
{ Nod adr_prec;
int nr; }

Clasa Stiva va con]ine urm`toarele:

 Data membru varf - re]ine adresa ultimului nod introdus \n stiv`.


 Metoda void push(int nr) - adaug` un nod stivei [i acesta va
re]ine valoarea numeric` nr, primit` de metod` ca parametru.
 Metoda int pop() - extrage un nod din stiv` [i returneaz` valoarea
pe care acesta o re]inea. Dac` stiva este vid`, returneaz` -1.

13. Crea]i un folder numit Pac pe c:\. Acest folder va con]ine pachetul
citiri, care include clasa cin.java (cea pe care am utilizat-o de at@tea ori
pentru citirea datelor).
14. Scrie]i un program care cite[te [i afi[eaz` o variabil` \ntreag`. Programul
va utiliza pachetul citiri.
15. Realiza]i un pachet care con]ine clasele Nod [i Stiva, create la
exerci]iul anterior. Pachetul se va numi structuri [i se va g`si \n folder-ul
Pac, creat \n C:\.

16. Prin utilizarea clasei Stiva, scrie]i un program care cite[te n numere
naturale [i le afi[eaz` \n ordinea invers` citirii.

17. Crea]i o clas` numit` Coada, care implementeaz` structura de tip coad`.
Fiecare element al cozii va fi de tip Complex (deci va re]ine un num`r
\ntreg).
.
18. Ad`uga]i pachetului structuri (vezi problema 15) clasa Coada.

19. Scrie]i un program care utilizeaz` clasa Coada din pachetul structuri.
20. Realiza]i un program care creeaz` [i parcurge \n preordine, inordine [i
postordine un arbore binar. Fiecare nod al arborelui re]ine un num`r real.
Datele se citesc de la tastatur`.
21. Crea]i un pachet care con]ine clasele pe care le-a]i utilizat \n programul
precedent.
Capitolul 4. Clase – primele noţiuni, exemple 106

Răspunsuri:
1. a) 2. c) 3. c) o constant` real` care nu se termin` cu f, este
considerat` automat ca fiind de tipul double. Prin urmare, este apelat`
automat metoda cu parametru de tip double.
4. d) Clasa este \nzestrat` cu doi constructori (supra\nc`rca]i). Este apelat
constructorul cu un singur parametru. Data membru a este ini]ializat` implicit
cu 0.

5.
class Lista
{ Nod v;
void adaug(int nr)
{ // daca lista este vida
if (v==null)
{ v=new Nod();
v.nr=nr;
v.adr_urm=null;}
else
// daca lista este nevida, aceasta este parcursa mai
// intai, dupa care se adauga nodul
{ Nod c=v;
while (c.adr_urm!=null) c=c.adr_urm;
c.adr_urm=new Nod();
c.adr_urm.nr=nr;
c.adr_urm.adr_urm=null;}
}
}

6. Nu este nevoie ca memoria ocupat` de nodul [ters s` fie eliberat`. De


aceasta se ocupa Garbage Collector.
void stergP()
{ if (v!=null) v=v.adr_urm; }

7. La fel ca mai sus, nu este nevoie ca memoria ocupat` de nodul [ters s`


fie eliberat`.
void stergU()
{ Nod c=v;
while (c.adr_urm.adr_urm!=null) c=c.adr_urm;
c.adr_urm=null;}

8.
void adaugI(int nr)
{ Nod c=new Nod();
c.nr=nr;
c.adr_urm=v;
v=c;
}
107 Bazele programării în Java

9.
class ex {
public static void main(String[] args) {
Lista l1=new Lista();
int Numar_citit;
do
{ System.out.print("numar_citit=");
Numar_citit=Integer.parseInt(cin.Token());
if (Numar_citit!=0) l1.adaug(Numar_citit);
} while (Numar_citit!=0);
l1.afis();
}
}

10. Identic, numai c`, \n loc de


if (Numar_citit!=0) l1.adaug(Numar_citit);

va fi if (Numar_citit!=0) l1.adaugI(Numar_citit);.

11.
void concat(Lista varf)
{ Nod c=v;
while (c.adr_urm!=null) c=c.adr_urm;
c.adr_urm=varf.v;
}

12.
class Stiva
{ Nod varf;
void push(int nr)
{ Nod c=new Nod();
c.nr=nr;
c.adr_prec=varf;
varf=c;
}
int pop()
{ if (varf!=null)
{ int x=varf.nr;
varf=varf.adr_prec;
return x; }
else return -1;
}
}

13.
Cre`m folder-ul Pac. Fi[ierul cin.java se g`se[te \n bin. |l modific`m
astfel:
- prima linie va con]ine package citiri;
- clasa devine public` [i fiecare metod` a ei tot public`.
Capitolul 4. Clase – primele noţiuni, exemple 108

package citiri;
import java.io.*;
import java.util.*;
public class cin {
...
public static String linie() {
...
public static String Token(){
...
}

Compil`m fi[ierul: javac -d c:\Pac cin.java. Automat, Pac va avea


subfolder-ul citiri, care con]ine cin.class.

14. Programul este cel de mai jos, iar fi[ierul gr.java este \n bin:
import citiri.*;
class gr {
public static void main(String[] args)
{ System.out.print("n=");
int n=Integer.parseInt(cin.Token());
System.out.println(n);}
}

Apoi:
javac -classpath c:\Pac gr.java (am precizat unde este pachetul care
con]ine cin.class).

java -classpath C:\Pac;C:\j2sdk1.4.2_04\bin gr (trebuie precizat


locul unde se g`sesc clasele, iar pe calculatorul la care lucrez mediul Java
este pe C:\j2sdk1.4.2_04)

15. Cele dou` clase trebuie s` fie publice (inclusiv trebuie s` fie publice
metodele push() [i pop(). Pentru aceasta, fiecare clas` trebuie s` se
g`seasc` \ntr-un fi[ier cu extensia .java [i care are numele clasei respective.
Astfel, \n bin avem:

Fi[ierul Nod.java:
package structuri;
public class Nod
{ Nod adr_prec;
int nr; }

Fi[ierul Stiva.java:
package structuri;
public class Stiva
{ Nod varf;
public void push(int nr) {
...
public int pop() {
...
}
109 Bazele programării în Java

Urmeaz` s` compil`m cele dou` fi[iere:


javac -d c:\Pac Nod.java

javac -d c:\Pac -classpath c:\Pac Stiva.java (clasa Stiva utilizeaz`


clasa Nod [i este necesar s` se [tie folder-ul unde o g`se[te, motiv pentru
care avem [i clauza -classpath). Automat, folder-ul Pac va avea ca
subfolder, folder-ul structuri.

16. Programul este cel de mai jos, iar fi[ierul Inv.doc este \n bin:
import structuri.*;
import citiri.*;

class Inv {
public static void main(String[] args)
{
Stiva st=new Stiva();
System.out.print("n=");
int n=Integer.parseInt(cin.Token());
int nr;
for (int i=0;i<n;i++)
{
System.out.print("nr=");
st.push(Integer.parseInt(cin.Token()));
}
do
{
nr=st.pop();
if (nr!=-1) System.out.println(nr);
}while (nr!=-1);
}
}

Se dau comenzile:
javac -classpath c:\Pac Inv.java
java -classpath C:\Pac;C:\j2sdk1.4.2_04\bin gr
CAPITOLUL 5

Studiul unor clase ale


limbajului Java

Din cuprins:
Clasa Math
Clasa String
Clasa StringTokenizer
Clase înfăşurătoare
Lucrul cu numere mari
Probleme propuse
Capitolul 5. Studiul unor clase ale limbajului Java 111

P@n` \n prezent am \nv`]at s` construim [i s` utiliz`m clasele.


Desigur, a fost doar un \nceput, \ntruc@t studiul claselor va continua [i \n
capitolul urm`tor. Totu[i, este foarte important s` cunoa[tem [i s` folosim
clasele mai importante cu care limbajul Java este \nzestrat. Pachetul
java.lang con]ine mai multe clase care alc`tuiesc nucleul aplica]iilor Java.
Din acest motiv, pentru utilizarea lor nu mai este necesar` folosirea
directivei import.

5.1. Clasa Math


Clasa Math face parte din pachetul java.lang [i con]ine mai multe
metode statice prin care se calculeaz` valorile mai multor func]ii clasice din
matematic` (logaritmice, exponen]iale, trigonometrice, etc).

Metoda Ce calculeaz` ?
long abs(long x) modul din x (|x|)
double abs(double x) ...
int abs(int x) ...
float abs(float x) ...
int abs(int x) ...
double acos(double x) arccos(x)
double asin(double x) arcsin(x)
double ceil(double x) cel mai mic \ntreg mai mare
sau egal cu x.
double floor(double x) cel mai mare \ntreg mai mic
sau egal cu x ([x], parte
\ntreag` din x)
double cos(double x) cos(x)
double sin(double x) sin(x)
double tan(double x) tg(x)
double pow(double a, double b) ab
double sqrt(double x) radical(x)
long round(double x) cel mai apropiat \ntreg de x.
int round (float x) ...
double random() num`r aleator (\nt@mpl`tor) \n
[0,1)
double max(double x, double y) max{x,y}
float max(float x, float y) ...
int max(int x, int y) ...
long max(long x, long y) ...
double min(double x, double y) min{x,y}
float min(float x, float y) ...
long min(long x, long y) ...
int min(int x, int y) ...
double exp(double x) ex
112 Bazele programării în Java

double log (double x) logaritm natural (ln(x))


double E constanta e
double PI constanta 

Exemple:
 Math.ceil(2.35) returneaz` 3;
 Math.ceil(-2.35) returneaz` -2;
 Math.floor(2.35) returneaz` 2;
 Math.floor(-2.35) returneaz` -3.
 Math.round(2.35) returneaz` 2.
 Math.round(-2.35) returneaz` -2.
 Math.round(2.55) returneaz` 3.
 Math.round(-2.55) returneaz` -3.
 Math.round(-2.5) returneaz` -2.
 Math.round(2.5) returneaz` 3.

Exemplu: programul de mai jos, afi[eaz` o valoare natural` aleatoare \n


intervalul [1.101]. Math.random() returneaz` o valoare aleatoare \n
intervalul [0,1), Math.random()*100) returneaz` o valoare real` \n
intervalul [0,100), Math.ceil(Math.random()*100) returneaz` o valoare
\ntreag` \n intervalul [0,100], 1+Math.ceil(Math.random()*100)
returneaz` o valoare natural` \n intervalul [1,101].
public static void main(String[] args) {
System.out.println(1+Math.ceil(Math.random()*100)); }

5.2. Clasa String


5.2.1. Constructorii şi lungimea unui şir de caractere
Un obiect al clasei String re]ine un [ir de caractere. P@n` acum am
lucrat cu obiecte ale clasei String, dar acum este momentul ca aceast`
clas` s` fie prezentat` \n mod sistematic. Clasa este \nzestrat` cu doi
constructori:
 String(); - ini]ializeaz` un obiect String care re]ine [irul vid.
Exemplu: secven]a afi[eaz` “un sir”.
String s =new String ();
s="Un sir";
System.out.println(s);

 String (String s); - ini]ializeaz` un obiect String care re]ine un


[ir de caractere dat. Exemplu: secven]a afi[eaz` “un sir”.
String s =new String ("Un sir");
System.out.println(s);
Capitolul 5. Studiul unor clase ale limbajului Java 113

 int length() - \ntoarce num`rul de caractere din [ir. Exemplu:


secven]a de mai jos afi[eaz` 6.
String s =new String ("Un sir");
System.out.println(s.length());

|n Java nu este permis` adresarea unui caracter al [irului prin indice,


pentru exemplul precedent, s[k]. |n schimb, avem metoda de mai jos,
unde primul caracter al [irului are indicele 0, al doilea are indicele 1,
[.a.m.d.

 char charAt(int i) returneaz` caracterul de pe pozi]ia i. Exemplu:


pentru [irul s, din exemplul precedent, instruc]iunea afi[eaz` „n‟.

System.out.println(s.charAt(1));

5.2.2. Compararea şirurilor de caractere


{irurile de caractere re]inute de obiectele clasei String pot fi
comparate din punct de vedere lexicografic (ordinea din dic]ionar). Pentru
aceasta, clasa String con]ine mai multe metode.

 int compareTo (String s) compar` [irul de caractere re]inut de


obiectul curent cu [irul de caractere re]inut s. Metoda returneaz`:
 o valoare negativ`, dac` [irul re]inut de obiectul curent este situat,
\n ordine lexicografic`, \naintea [irului re]inut de obiectul s.
 0, dac` [irurile re]inute de cele dou` obiecte coincid.
 o valoare pozitiv`, dac` [irul re]inut de obiectul curent este situat,
\n ordine lexicografic`, dup` [irul re]inut de obiectul s.

Exemple: secven]a afi[eaz` -2, 0, 2.


String s =new String ("abc");
String s1=new String("cd");
System.out.println(s.compareTo(s1)+ " "
+s.compareTo(s)+" "+s1.compareTo(s));

 int compareToIgnoreCase(String s) – la fel precum


compareTo(), numai c` nu se face diferen]a \ntre literele mari [i
cele mici. Exemplu: secven]a de mai jos afi[eaz` 0.
String s =new String ("AB");
String s1=new String("ab");
System.out.println(s.compareToIgnoreCase("ab"));

 boolean equals(String s) – returneaz` true dac` [irurile de


caractere re]inute de obiectul curent [i cel transmis ca parametru sunt
identice.
114 Bazele programării în Java

 boolean equalsIgnoreCase(String s) – la fel ca mai sus numai c`


nu se face distinc]ie \ntre literele mari [i cele mici.

5.2.3. Subşiruri
Vom \n]elege prin sub[ir al un [ir de caractere, mai multe caractere
consecutive ale acestuia. De exemplu, “text” are ca sub[ir “ex”.

 boolean startsWith(String s) – returneaz` true dac` [irul


re]inut de s precede [irul re]inut de obiectul curent.
 boolean endsWith(String s) – returneaz` true dac` [irul re]inut
s se afl` la sf@r[itul [irului re]inut de obiectul curent.

Exemple pentru startsWidth() [i endsWith(). Secven]a de mai jos


afi[eaz` de dou` ori true:

String s =new String ("123");


String s1=new String("12");
String s3=new String("23");
System.out.println(s.startsWith(s1));
System.out.println(s.endsWith(s3));

 boolean regionMatches(int i1, String s, int i2, int l)


compar` dou` sub[iruri de lungime l. Primul sub[ir este al obiectului
curent [i \ncepe de pe pozi]ia i1, al doilea sub[ir este al [irului s [i
\ncepe pe pozi]ia i2. |n caz de egalitate, metoda returneaz` true,
contrar returneaz` false.
Exemplu: secven]a de mai jos afi[eaz` [irul 567 coincid:
if (s.regionMatches(4, s1, 2, 3))
System.out.println("567 coincid");

 String substring (int index) – metoda returneaz` sub[irul


[irului curent care este \ntre pozi]ia index [i sf@r[itul [irului.
Exemplu: secven]a de mai jos afi[eaz` 456789:
String s =new String ("123456789");
System.out.println(s.substring(3));

 String substring (int index, int sf ) – metoda returneaz`


sub[irul [irului curent care este \ntre pozi]ia index [i sf-1.
Exemplu: secven]a de mai jos afi[eaz` 45:
String s =new String ("123456789");
System.out.println(s.substring(3,5));
Capitolul 5. Studiul unor clase ale limbajului Java 115

 String replace (char c1, char c2) – metoda returneaz` [irul


ob]inut dac` se \nlocuiesc \n [irul re]inut de obiectul curent toate
apari]iile caracterului c1 cu caracterul c2.
Exemplu: secven]a de mai jos afi[eaz` tata:
String s =new String ("mama");
System.out.println(s.replace('m','t'));

 String replaceAll (String s1, String s2) – metoda


returneaz` [irul ob]inut dac` se \nlocuiesc \n [irul re]inut de obiectul
curent toate apari]iile sub[irului s1 cu sub[irul s2.
Exemplu: secven]a de mai jos afi[eaz` *** doi *** doi trei:
String s =new String ("unu doi unu doi trei");
System.out.println(s.replaceAll("unu","***" ));

 String replaceFirst (String s1, String s2) – la fel ca mai


sus, doar c` se \nlocuie[te numai prima apari]ie a sub[irului.
Exemplu: secven]a de mai jos afi[eaz` *** doi unu doi trei:

String s =new String ("unu doi unu doi trei");


System.out.println(s.replaceFirst("unu","***" ));

 String trim() \ntoarce sub[irul [irului re]inut de obiectul curent,


sub[ir ob]inut prin eliminarea spa]iilor (blank-urilor de la \nceput [i de
la sf@r[it).

 int indexOf (String s) returneaz` indicele primei apari]ii a


sub[irului s \n [irul re]inut de obiectul curent. |n cazul \n care s nu
este g`sit ca sub[ir al [irului referit de obiectul curent, metoda
returneaz` -1.

Exemplu: secven]a de mai jos afi[eaz` 4:


String s1=new String("un exemplu");
String s2=new String("xe");
System.out.println(s1.indexOf(s2));

5.2.4. Concatenarea şirurilor de caractere


A[a cum deja [tim, \n Java [irurile de caractere pot fi concatenate cu
ajutorul operatorului +.

Exemple:
1. Secven]a urm`toare afi[eaz` Un sir Alt sir:
String s =new String ("Un sir" );
String s1 = new String(" Alt sir");
116 Bazele programării în Java

s=s+s1;
System.out.println(s);

2. Acela[i lucru este afi[at [i de secven]a de mai jos:


String s =new String ("Un sir "+"Alt sir" );
System.out.println(s);


Dup` cum observa]i, concatenarea [irurilor nu este comutativ`. Aceasta
\nseamn` c` prezint` importan]` ordinea \n care [irurile sunt puse \n
expresie.

 Metoda String concat(String s) returneaz` [irul ob]inut prin


concatenarea [irului re]inut de obiectul curent cu s.

Exemplu: secven]a urm`toare afi[eaz` Un sir Alt sir:


String s =new String ("Un sir ");
String s1 =new String ("Alt sir" );
System.out.println(s.concat(s1));

5.2.5. Parametrii metodei main()

Acum suntem \n m`sur` s` analiz`m parametrii metodei main():


public static void main(String[] args).

Antetul con]ine un vector cu elemente de tip String |n exemplu, numele


vectorului este args.

1. C@te elemente are vectorul? Acest num`r se poate afla u[or, ca la


orice vector: args.length.
2. Unde se introduc [irurile de caractere primite ca parametri de c`tre
main()? Aceste [iruri se introduc pe linia de comand` a programului Java
[i sunt separate prin spa]ii.
Exerci]iu: programul de mai jos calculeaz` suma valorilor introduse ca
parametri. Evident, mai \nt@i acestea sunt convertite c`tre int. Exemple de
utilizare:

a) Dac` apelul este java t 3 4 se va afi[a 7.


b) Dac` apelul este java t 1 2 3 4 se va afi[a 10.
class t {
public static void main(String[] args) {
int s=0;
for (int i=0;i<args.length;i++)
s+=Integer.parseInt(args[i]);
System.out.println("suma argumentelor este ="+s);}
}
Capitolul 5. Studiul unor clase ale limbajului Java 117

5.2.6. Aplicaţii
1. S` se citeasc` de la tastatur` un [ir de caractere, apoi s` se afi[eze.
Rezolvare. Vom utiliza clasa cin (cea pe care am folosit-o [i p@n` acum).
De altfel, clasa cin o vom utiliza pentru toate exerci]iile din acest paragraf.
public static void main(String[] args) {
String s =new String ();
s=cin.linie();
System.out.println(s);
}

2. Se citesc dou` [iruri de caractere. S`


se listeze indicele fiec`rei apari]ii a
primului [ir citit ca sub[ir al celui de-al
doilea [ir citit. Iat` cum arat` execu]ia
programului:
Rezolvare: Ideea este urm`toarea: dup`
ce sub[irul a fost identificat, se afi[eaz` pozi]ia de \nceput, apoi se extrage
din [ir sub[irul de \nceput ce con]ine inclusiv prima apari]ie a sub[irului,
dup` care procedeul se repet` p@n` c@nd sub[irul c`utat nu mai este g`sit.
O problem` aparte este dat` de faptul c` trebuie, de fiecare dat`, s`
afi[`m pozi]ia de \nceput a sub[irului \n [irul ini]ial [i nu \n [irul r`mas. Din
acest motiv, utiliz`m mai multe variabile: poz - pozi]ia de \nceput a
sub[irului \n [irul r`mas; ind - suma lungimilor [irurilor extrase. De fiecare
dat` se va afi[a ca indice de apari]ie a sub[irului, ind+poz.
public static void main(String[] args) {
String subsir =new String (cin.linie());
String sir =new String (cin.linie());
int poz=0, ind=0, lsubs=subsir.length();
while (poz!=-1)
{ poz=sir.indexOf(subsir);
if (poz!=-1)
{ System.out.println(ind+poz);
ind+=poz+lsubs;
sir=sir.substring(poz+lsubs);}
}
}

3. Se citesc dou` [iruri de caractere. S` se afi[eze


[irul format din cel de-al doilea [ir din care au fost
extrase toate apari]iile primului [ir citit. Al`turat
observa]i un exemplu de execu]ie:

Rezolvare: Se identific` prima apari]ie a sub[irului, apoi, prin extragerea


sub[irului, se ob]ine un nou [ir, iar se idendific` prima apari]ie a sub[irului
[.a.m.d. {irul astfel ob]inut se afi[eaz` atunci c@nd nu se mai con]ine nici
o apari]ie a sub[irului citit.
118 Bazele programării în Java

public static void main(String[] args) {


String subsir =new String (cin.linie());
String sir =new String (cin.linie());
int poz=0, ind=0, lsubs=subsir.length();
while (poz!=-1)
{
poz=sir.indexOf(subsir);
if (poz!=-1)
sir=sir.substring(0,poz)+sir.substring(poz+lsubs);
}
System.out.println(sir);
}

4. Se cite[te un [ir de caractere. {irul con]ine mai multe cuvinte separate


de unul sau mai multe blank-uri. Se cere s` se elimine blank-urile de la
\nceputul [i sf@r[itul [irului. De asemenea, se cere ca, \n noul [ir, cuvintele
s` fie separate obligatoriu printr-un singur blank.
Rezolvare. Dup` eliminarea blank-urilor de \nceput [i de sf@r[it sub un for
se identific` primele dou` blank-uri consecutive, unde primul blank are
indicele i. Se elimin` primul dintre ele, apoi valoarea lui i scade cu 1,
pentru ca \n [irul nou format s` se reia c`utarea de la primul blank, cel
neeliminat (nu uita]i, la testul urm`tor valoarea lui i cre[te cu 1, pentru c`
totul se execut` sub for).

public static void main(String[] args) {


String sir =new String (cin.linie());
sir=sir.trim();
for (int i=1;i<=sir.length()-2;i++)
if (sir.charAt(i)==' ' && sir.charAt(i+1)==' ')
{ sir=sir.substring(0,i)+sir.substring(i+1);
i--;
}
System.out.println(sir);
}

5. Se citesc n cuvinte, c@te unul pe linie. Se cere s` se afi[eze cuvintele


\n ordine lexicografic` (ordinea alfabetic`, \nt@lnit` \n dic]ionar).

R`spuns. Vom utiliza un vector de obiecte de tip String. |n rest, este o


sortare obi[nuit`...

public static void main(String[] args) {


System.out.print("n=");
int n=Integer.parseInt(cin.Token());
String [] V=new String [n];
for (int i=0;i<n;i++)
{ System.out.print("Cuvantul["+i+"]=");
V[i]=cin.linie();
}
boolean gasit;
String man;
Capitolul 5. Studiul unor clase ale limbajului Java 119

do
{ gasit=false;
for (int i=0;i<n-1;i++)
if (V[i].compareTo (V[i+1])>0)
{ man=V[i];
V[i]=V[i+1];
V[i+1]=man;
gasit=true;
}
} while (gasit);
for (int i=0;i<n;i++)
System.out.println(V[i]);
}

5.3. Clasa StringTokenizer


Clasa StringTokenizer se g`se[te \n pachetul java.util (vezi
import) [i con]ine c@teva metode care permit extragerea unit`]ilor lexicale
(token-uri) din care este alc`tuit un [ir de caractere. Implicit, acestea se
consider` separate prin caracterele albe ( „ „, „\n‟, „\t‟, „\r‟ „\f‟). Iat` cele
mai importante metode:
 StringTokenizer (String s) – constructor, creeaz` obiectul care
trateaz` [irul de caractere referit de s.
 StringTokenizer (String s, String delim) – constructor,
creeaz` obiectul care trateaz` [irul de caractere referit de s., dar
token-urile sunt separate de caracterele care alc`tuiesc delim.
 boolean hasMoreTokens() – returneaz` true dac` [irul mai
con]ine token-uri necitite [i false \n caz contrar.
 String nextToken() - returneaz` [irul de caractere care alc`tuiesc
urm`torul token (cite[te un token).
 int countTokens(); - returneaz` num`rul de token-uri r`mase necitite
(cu nextToken()).
Exemplu: programul urm`tor cite[te o linie introdus` de la tastatur` (vezi
clasa cin) [i afi[eaz` token-urile \nt@lnite. De exemplu dac` linia introdus`
de la tastatur` este: mama are 350000 lei, se afi[eaz`:
import java.util.*;
mama
class t {
are
public static void main(String[] args) {
350000
String s=new String (cin.linie());
lei
StringTokenizer t=new StringTokenizer(s);
while (t.hasMoreTokens())
System.out.println(t.nextToken()); }
}
120 Bazele programării în Java

5.4. Clase înfăşurătoare int – Integer


short - Short
Pentru fiecare tip primitiv s-a construit c@te long – Long
o clas` \nf`[ur`toare. Un obiect al clasei byte – Byte
\nf`[ur`toare poate re]ine o valoare a tipului char – Character
primitiv. Al`turat, pute]i observa coresponden]a float – Float
double – Double
\ntre numele tipurilor primitive [i numele claselor boolean – Boolean
\nf`[ur`toare.

 Fiecare clas` \nf`[ur`toare este \nzestrat` cu o metod` constructor.

Exemple:
int n=4;
Integer nr=new Integer(n);
Double x=new Double (-12.34);
Character c=new Character ('e');
Boolean este=new Boolean(true);

 Constructorii acestor clase sunt supra\nc`rca]i, \n sensul c` exist` [i


constructori care au ca parametru de intrare referin]e c`tre obiecte de
tip String.

Exemple:
Integer nr=new Integer("10");
Double x=new Double ("-12.34");
Boolean este=new Boolean("true");

 Fiecare clas` \nf`[ur`toare con]ine o metod` care returneaz` valoarea


re]inut` de obiectul instan]iat de ea.

Exemple: se extrag valorile re]inute de obiectele create \n primele exemple:


int n1=nr.intValue();
double x1=x.doubleValue();
char c1=c.charValue();
boolean este1=este.booleanValue();

 Fiecare clas` care re]ine o valoare numeric` con]ine c@te o metod`


static` (aten]ie la apel!) pentru conversia c`tre un tip primitiv a unui
obiect de tip String. Astfel avem:
a) int parseInt(String s); // in Integer
Exemplu: int t=Integer.parseInt("10");
b) parseFloat(String S); // in Float
Exemplu: float b=Float.parseFloat("-12.34");
c) double parseDouble (String s) // in Double
Exemplu: double b=Double.parseDouble("-12.34");
Capitolul 5. Studiul unor clase ale limbajului Java 121

d) parseLong(String s); // in Long


Exemplu: long t=Long.parseLong("1000");
e) parseByte(String s) // in Byte
Exemplu: byte x=Byte.parseByte("12");

 Dac` [irul de caractere nu poate fi convertit c`tre valoarea numeric`


de tipul dorit, se genereaz` o excep]ie \n urma c`reia executarea
programului se \ntrerupe.
 Conversia invers`, de la un tip primitiv c`tre un [ir se poate realiza
u[or, a[a cum am mai \nt@lnit de multe ori concaten@nd un [ir
(eventual vid) cu o valoare numeric`.
Exemplu: secven]a urm`toare afi[eaz` [irul 10:
int i=10;
String s=new String(i+"");
System.out.println(s);

 Clasele \nf`[ur`toare con]in constantele MIN_VALUE [i MAX_VALUE


care re]in cea mai mic` [i cea mai mare valoare a tipului respectiv.
|n cazul variabilelor de un tip real (float, double) MIN_VALUE are
semnifica]ia de cea mai mic` valoare pozitiv` care poate fi re]inut` de
tipul respectiv.

System.out.println(Integer.MIN_VALUE);
System.out.println(Integer.MAX_VALUE);
System.out.println(Double.MIN_VALUE);
System.out.println(Double.MAX_VALUE);

 Clasele \nf`[ur`toare ale tipurilor reale (double, float) con]in


constanta NaN (Not a Number). Valoarea NaN se ob]ine dac`, \ntr-o
expresie de tip real, se \mparte 0 la 0, sau se extrage radical
(indice 2) dintr-o valoare negativ`, sau se aplic` logaritmul unui num`r
negativ etc.
Exemple:

1. Secven]a de mai jos afi[eaz` NaN:


double x=0,y=0,z;
z=x/y;
System.out.println(z);

2. Secven]a de mai jos afi[eaz` NaN:


int x=-2;
System.out.println(Math.sqrt(x));
122 Bazele programării în Java

 Clasele \nf`[ur`toare ale tipurilor reale (double, float) con]in


metodele boolean isNaN (double e), respectiv boolean isNaN
(float e). Cele dou` metode returneaz` true dac` se ob]ine NaN.

Exemple:

1. Secven]a de mai jos afi[eaz`: Ambii operanzi sunt 0:


int x=0; double y=0;
if (Double.isNaN(x/y))
System.out.println("Ambii operanzi sunt 0");

2. Secven]a de mai jos afi[eaz`: Radical dintr-un numar negativ:


if (Double.isNaN(Math.sqrt(x)))
System.out.println("Radical dintr-un numar negativ");

 Compar`rile precum cele de mai jos nu au efect. De exemplu,


secven]a de mai jos nu afi[eaz` nici un mesaj:
if (Math.sqrt(x)==Double.NaN)
System.out.println("Radical din numar negativ");

 Clasele \nf`[ur`toare ale tipurilor reale (double, float) con]in


constantele POSITIVE_INFINITY, NEGATIVE_INFINITY.
Constanta POSITIVE_INFINITY se ob]ine dac`, \ntr-o
expresie de tip real, se \mparte o valoare pozitiv` la 0,
iar constanta NEGATIVE_INFINITY se ob]ine dac`, \ntr-o expresie de
tip real, se \mparte la 0 o valoare negativ`.
double x=2;
System.out.println(x/0);
x=-2;
System.out.println(x/0);


Dac` expresia este de tip \ntreg, atunci se genereaz` o excep]ie
(excep]iile vor fi studiate separat), iar programul este \ntrerupt, ca \n
secven]a de mai jos.

int x=2;
System.out.println(x/0);

 Clasele \nf`[ur`toare ale tipurilor reale (double, float) con]in


metoda boolean` boolean isInfinite (double) (sau float) prin
care se testeaz` dac` s-a ob]inut una din constantele de mai sus.
Exemplu: secven]a de mai jos afi[eaz` Impartire la 0.
double x=2;
if (Double.isInfinite(x/0))
System.out.println("Impartire la 0");
Capitolul 5. Studiul unor clase ale limbajului Java 123

5.5. Lucrul cu numere mari


Prin numere mari vom \n]elege acele valori numerice care dep`[esc
limitele de memorare ale tipurilor primitive. Opera]iile cu astfel de numere
sunt anevoioase prin faptul c` num`rul trebuie memorat pe cifre (\ntr-un
vector). |n Java exist` dou` clase care permit lucrul cu numere mari: clasa
BigInteger [i clasa BigDecimal.

A) Clasa BigInteger lucreaz` cu numere \ntregi mari. Cele mai


importante metode sunt:

 BigInteger(String s) - constructor. Are rolul de a crea un obiect


de tip BigInteger pornind de la un obiect de tip String.
Exemplu: BigInteger n2=new BigInteger("-2");

 String toString(); - are rolul de a converti num`rul re]inut de


obiectul curent c`tre un [ir de caractere.
 BigInteger add (Biginteger n); - adun` la num`rul re]inut de
obiectul curent num`rul re]inut de obiectul transmis ca parametru.
 BigInteger subtract (Biginteger n); - scade din num`rul
re]inut de obiectul curent num`rul re]inut de obiectul transmis ca
parametru.
 BigInteger multiply (Biginteger n); - \nmul]e[te num`rul
re]inut de obiectul curent cu num`rul re]inut de obiectul transmis ca
parametru.
 BigInteger divide (Biginteger n); - \mp`r]ire \ntreag` \ntre
num`rul re]inut de obiectul curent [i num`rul re]inut de obiectul a
c`rui referin]` este re]inut` de n.
 BigInteger remainder (Biginteger n); - returneaz` un obiect
care re]ine restul \mp`r]irii num`rului re]inut de obiectul curent la
num`rul obiectului transmis ca parametru.
 BigInteger pow (BigInteger n); - dac` obiectul curent re]ine m
[i obiectul transmis ca parametru valoarea n, atunci metoda
returneaz` obiectul care re]ine mn.
 BigInteger negate(); - dac` obiectul curent re]ine m atunci
metoda returneaz` obiectul care re]ine -m.
 int signum(); - dac` obiectul curent re]ine m se returneaz`
obiectul care re]ine sgn(m), adic`: -1 dac` m<0, 0 dac` m=0 sau 1
dac` m>0.
124 Bazele programării în Java

 int CompareTo(BigInteger n); - dac` obiectul curent re]ine m,


iar obiectul referit re]ine n, atunci metoda returneaz` -1 dac` m<n, 0
dac` m=n, 1, dac` m>n.

Exemplu: se cere s` se calculeze 21000. Num`rul dep`[e[te cu mult


capacitatea de memorare a tipului long. Prin urmare, vom utiliza clasa
BigInteger:
import java.math.*;
class t {
public static void main(String[] args) {
BigInteger n1=new BigInteger("1");
BigInteger n2=new BigInteger("2");
for (int i=1;i<=1000;i++) n1=n1.multiply(n2);
System.out.println(n1.toString());}
}

B) Clasa BigDecimal - cele mai importante metode sunt:

 BigDecimal(String s) – constructor. Are rolul de a crea un obiect


de tip BigDecimal pornind de la [irul s.
 BigDecimal(BigInteger val) - constructor, creeaz` un obiect
pornind de la un altul de tip BigInteger;
 BigDecimal(double val) – constructor, creeaz` un obiect pornind
de la o valoare de tip double.
 BigDecimal abs() – returneaz` obiectul care re]ine modulul
num`rului re]inut de obiectul curent.
 String toString() – returneaz` num`rul re]inut de obiectul curent
convertit c`tre String.
 BigDecimal add(BigDecimal n) - returneaz` obiectul care re]ine
suma numerelor re]inute de obiectul curent [i cel transmis ca
parametru. Rezultatul va avea num`rul maxim de zecimale pe care le
au cei doi operanzi.
 BigDecimal subtract(BigDecimal n) – returneaz` obiectul care
re]ine valoarea rezultat` din sc`derea numerelor re]inute de cei doi
operanzi (obiectul curent, desc`zut [i obiectul transmis ca parametru,
sc`z`tor). Num`rul de zecimale al rezultatului se ob]ine ca la add.
 BigDecimal multiply(BigDecimal n) – obiectul care re]ine
produsul numerelor re]inute de cei doi operanzi. Num`rul de zecimale
al rezultatului este dat suma numerelor de zecimale ale operanzilor.
 BigDecimal divide(BigDecimal val, int rotunjire) - \mparte
cei doi operanzi. Num`rul de zecimale al rezultatului este egal cu
num`rul de zecimale al de\mp`r]itului.
Capitolul 5. Studiul unor clase ale limbajului Java 125

Exemplu: fie obiectele de mai jos:


BigDecimal n1=new BigDecimal("1.000");
BigDecimal n2=new BigDecimal("3.000000");
n1=n1.divide(n2,0); -n1 re]ine 0.334
n1=n1.divide(n2,1); -n1 re]ine 0.333

 int scale() - returneaz` num`rul zecimalelor ale num`rului re]inut


de obiectul curent.
 BigDecimal setScale(int nrzec) - returneaz` un obiect care
memoreaz` num`rul re]inut de obiectul curent cu nrzec zecimale.
 BigDecimal negate() – returneaz` un obiect care re]ine num`rul
memorat de obiectul curent, dar care a fost negativat.
 int signum() - returneaz` sgn(x) vezi metoda similar` de la
BIgInteger;
 BigDecimal abs() - returneaz` obiectul care re]ine modulul
num`rului memorat de obiectul curent.
 int compareTo(BigDecimal val) – compar` numerele re]inute de
cei doi operanzi. Vezi metoda similar` de la BigInteger.

Probleme propuse
1. Scrie]i un program care s` citeasc` 0<a<b, numere naturale [i s`
afi[eze un num`r aleator \n intervalul [a,b].
2. Scrie]i un program care cite[te x, num`r real, [i n>0, num`r natural [i
calculeaz` P=sin(x)*sin(2x)*...sin(n*x). Se presupune c` x
reprezint` o valoare exprimat` \n radiani.
3. Se cite[te de la tastatur` un [ir de caractere. {irul con]ine cel pu]in 10
caractere. Se cere s` se afi[eze numai primele 10 caractere din [ir.
4. Se cite[te de la tastatur` un [ir de caractere. Dac` [irul are mai mult
de 4 caractere s` se afi[eze numai primele 4, altfel se va afi[a [irul citit.
5. Scrie]i o clas`, numit` Afis, care con]ine metoda String aNum(int
lung, String s) metod` ce are rolul de a \ntoarce sirul re]inut de s, pe
lungimea lung). Dac` num`rul de caractere ale [irului este mai mare dec@t
lung, se \ntoarce sub[irul format din primele lung caractere ale [irului,
altfel se \ntoarce un [ir pe lungimea lung. [ir alc`tuit din caracterele [irului
ini]ial la care se adaug` de un num`r corespunz`tor de blank-uri. Exemple
pentru lung=5:
 {irul: citit “Mihai” - se returneaz` “Mihai”.
126 Bazele programării în Java

 {irul: “tastatura” - se returneaz` “tasta”.


 {irul: “aer” - se returneaz` “aer ”.

 O astfel de metod` este util` pentru afisarea unui [ir de


caractere pe o anumit` lungime.

6. Scrie]i un program care cite[te n, num`r natural [i n [iruri de caractere.


Programul va afi[a pe c@te o linie, primele 5 caractere ale fiec`rui [ir citit.
Dac` [irul are mai pu]in de 5 caractere, se va afi[a [irul, urmat de un
num`r de blank-uri astfel \nc@t lungimea total` afi[at` s` fie de 5 caractere.
7. Ad`uga]i clasei Afis metoda String num(int lung, int v) care
are rolul de a returna [irul de lungime lung, alc`tuit din [irul ob]inut din
convertirea \ntregului v \n [ir [i, \n cazul \n care acest [ir are lungimea mai
mic` dec@t lung, el va fi precedat de un num`r corespunz`tor de blank-uri.
|n situa]ia \n care lungimea [irului ob]inut din conversia num`rului este mai
mare dec@t lung, metoda va returna un mesaj de eroare. Exemple pentru
lung=3.
 Num`rul 125 - se returneaz` “125”.
 Num`rul 1 - se returneaz` “ 1”.
 Sirul: “3152” - se returneaz` "Numarul nu poate fi afisat";
8. Scrie]i un program care cite[te n, num`r natural [i n numere naturale.
Programul va afi[a, pe c@te o linie, fiecare dintre cele n numere naturale
citite. Numerele se vor afi[a pe 5 caractere [i vor fi aliniate la dreapta.
Exemplu: n=3, numerele citite sunt: 12234, 45, 4. Se va afi[a:
12234
45
4

 |n practic`, [irurile alc`tuite din caractere se afi[eaz` aliniate la


st@nga, iar valorile numerice se afi[eaz` aliniate la dreapta.
9. Ad`uga]i clasei Afis metoda String num(int lung, int zec,
double v) care returneaz` [irul rezultat din conversia unui num`r real
(indiferent de num`rul de zecimale). {irul are lungimea lung, num`rul este
afi[at aliniat la dreapta [i va avea zec zecimale. |n ipoteza \n care
num`rul nu poate fi afi[at prin utilizarea a lung caractere, se va returna un
mesaj de eroare.

 Num(5,2,23.3456) returneaz` “23.34”;


 Num(5,2,3.3456) returneaz` “ 3.34”;
 Num(5,2,-9) returneaz` “-9.00”;
 Num(5,2,123) returneaz` “Numarul nu poate fi afisat”.
Capitolul 5. Studiul unor clase ale limbajului Java 127

10. Scrie]i un program care cite[te n, num`r natural [i n numere reale.


Programul va afi[a pe c@te o linie fiecare num`r citit. Numerele se vor afi[a
pe 8 caractere, vor fi aliniate la dreapta [i vor avea obligatoriu dou`
zecimale (indiferent de num`rul de zecimale pe care \l au).

11. S` se creeze o clas` numit` Elev. Un obiect al clasei respective


con]ine numele elevului, nota la matematic`, nota la informatic` [i nota la
englez`. Clasa va con]ine un constructor care cite[te de la tastatur` valorile
respective [i o medod` void afisez(), care afi[eaz` toate datele pe o
linie astfel:

 nume elev pe 20 de caractere, aliniat la st@nga;


 nota la matematic` pe 5 caractere, aliniat` la dreapta;
 nota la informatic` pe 5 caractere, aliniat` la dreapta;
 nota la englez` pe 5 caractere, aliniat` la dreapta;
 media general`, pe 8 caractere, cu dou` zecimale, aliniat` la dreapta.

12. Scrie]i un program care, prin utilizarea clasei Elev, cite[te numele [i
notele pentru n elevi [i le afi[eaz` aliniat, \mpreun` cu media general`.

13. Scrie]i un program care cite[te un [ir introdus de la tastatur`.


Cuvintele din [ir sunt separate printr-unul sau mai multe spa]ii. Se cere s`
se afi[eze [irul ob]inut din cuvintele din [irul ini]ial, dar care, de aceast`
dat`, sunt separate printr-un singur spa]iu.
Exemplu:

se cite[te: mama merge la plimbare


se afi[eaz`: mama merge la plimbare

14. Calcula]i n! pentru 1n1000.

15. Rezolva]i ecua]ia de gradul 1 ax+b=0, unde a si b sunt numere


reale atât de mari c` nu pot fi re]inute de variabile de tip double.

16. Scrie]i un program care calculeaz` ez, cu k zecimale exacte (k se


cite[te de la tastatur`). Calculul se va face prin utilizarea formulelor de mai
jos:
n 1
x 2 x3 xn x
ex  1 x    ...  Rn ( x) Rn ( x )  e
x

2! 3! n! ( n  1)!

Dac`, de exemplu k=30, atunci se va efectua calculul pentru n determinat


astfel \nc@t:
1
Rn ( x ) 
10 30
128 Bazele programării în Java

17. Afla]i prin metoda \njum`t`]irii intervalului r`d`cina real` a ecua]iei


x3+x+1=0. Se cere ca r`d`cina s` fie afi[at` cu primele 50 de zecimale
exacte.

Indicaţii / rezolvări:
1. class prima {
public static void main(String[] args) {
System.out.print("a="); int a=Integer.parseInt(cin.Token());
System.out.print("b="); int b=Integer.parseInt(cin.Token());
System.out.println(a+Math.floor(Math.random()*(b-a+1)));
}
}

3. class prima {
public static void main(String[] args) {
String afis=new String(cin.linie());
System.out.println(afis.substring(0,10));}
}

4. Dac` \ncerca]i programul precedent, pentru un [ir de caractere mai mic


de 10 caractere ve]i primi eroare!
class prima {
public static void main(String[] args) {
String afis=new String(cin.linie());
if (afis.length()>4)
System.out.println(afis.substring(0,4));
else System.out.println(sir);}
}

5. class Afis {
String aNum(int lung, String sir)
{ if (sir.length()>lung)
return sir.substring(0,lung);
else
{ String blank="";
for (int i=1;i<=lung-sir.length();i++) blank=blank+" ";
return sir+blank; }
}
}

6. class prima {
public static void main(String[] args) {
System.out.print("n="); int n=Integer.parseInt(cin.Token());
String[] t=new String [n];
for(int i=0;i<n;i++)
t[i]=cin.linie();
Afis comanda=new Afis();
for(int i=0;i<n;i++)
System.out.println(" "+comanda.aNum(5,t[i])); }
}
Capitolul 5. Studiul unor clase ale limbajului Java 129

7.
String num(int lung, int v)
{ String sir=new String (""+v);
if (sir.length()>lung) return "Numarul nu poate fi afisat";
else
{ while (sir.length()!=lung) sir=" "+sir;
return sir;}
}

8.
class prima {
public static void main(String[] args) {
System.out.print("n="); int n=Integer.parseInt(cin.Token());
Afis comanda=new Afis();
int[] t=new int [n];
for(int i=0;i<n;i++)
t[i]=Integer.parseInt(cin.Token());
for(int i=0;i<n;i++)
System.out.println(comanda.num(5,t[i]));
}
}

9.
String num(int lung, int zec, double v)
{ String sir=new String (""+v);
int indice=sir.indexOf(".");
if (sir.length()-indice-1<zec)
while (sir.length()-indice-1!=zec) sir=sir+"0";
else
sir=sir.substring(0,indice+zec+1);
if (sir.length()>lung) return "Numarul nu poate fi afisat";
else
{ while (sir.length()!=lung) sir=" "+sir; return sir; }
}

10.
class prima {
public static void main(String[] args) {
System.out.print("n="); int n=Integer.parseInt(cin.Token());
Afis comanda=new Afis();
double[] t=new double [n];
for(int i=0;i<n;i++)
t[i]=Double.parseDouble(cin.Token());
for(int i=0;i<n;i++)
System.out.println(comanda.Num(8,2,t[i]));
}
}

11.
class Elev
{ String Nume;
int nota_mate,nota_info,nota_engl;
Elev()
{ System.out.println("Introduceti datele");
System.out.print("Numele elev=");Nume=cin.linie();
130 Bazele programării în Java

System.out.print("Nota mate=");
nota_mate=Integer.parseInt(cin.Token());
System.out.print("Nota info=");
nota_info=Integer.parseInt(cin.Token());
System.out.print("Nota engl=");
nota_engl=Integer.parseInt(cin.Token());
}
void afisez()
{ Afis elv=new Afis();
System.out.print(elv.aNum(20,Nume));
System.out.print(elv.num(5,nota_mate));
System.out.print(elv.num(5,nota_info));
System.out.print(elv.num(5,nota_engl));
double med=(double)(nota_mate+nota_info+nota_engl)/3;
System.out.println(elv.num(8,2,med));}
}
12.
class prima {
public static void main(String[] args) {
System.out.print("n=");int n=Integer.parseInt(cin.Token());
Elev[] tabel=new Elev[n];
for (int i=0;i<n;i++) tabel[i]=new Elev();
for (int i=0;i<n;i++) tabel[i].afisez();}
}
13.
import java.util.*;
class t {
public static void main(String[] args) {
String s=new String (cin.linie());
StringTokenizer t=new StringTokenizer(s);
String sir_corect= new String();
while (t.hasMoreTokens())
sir_corect=sir_corect+t.nextToken()+" ";
sir_corect=sir_corect.trim();
System.out.println(sir_corect);}
}
14.
import java.math.*;
class t {
public static void main(String[] args) {
System.out.print("n=");int n=Integer.parseInt(cin.Token());
BigInteger P=new BigInteger("1"),I=new BigInteger("1"),incr=new
BigInteger("1");
for(int i=1;i<=n;i++)
{ P=P.multiply(I); I=I.add(incr);}
System.out.println(P.toString());}
}

17. Dac` not`m cu f(x)=x3+x+1, avem f(-1)=-1, f(0)=1. Cum


f‟(X)=3x2+1, f este strict cresc`toare [i are o unic` r`d`cin` \n intervalul
(-1,0). Lugimea intervalului este 1. De acum putem aplica metoda
\njum`t`]irii intervalului.
CAPITOLUL 6

Extinderea claselor

Din cuprins:
Un exemplu de extindere al unei clase
O modalitate de simulare a extinderii multiple
Referinţe către obiectele superclaselor, referinţe
către obiectele subclaselor
Probleme propuse
132 Bazele programării în Java

6.1. Noţiuni generale


1. Pornind de la o clas` dat` se poate crea o alt` clas`, care o extinde
(mo[tene[te) pe aceasta. Noua clas` va avea toate datele membru [i
toate metodele clasei de la care s-a pornit, c`rora li se pot ad`uga noi
date membru [i/sau noi metode. |n Java, clasa care este extins` se
nume[te superclas`, iar noua clas` se nume[te subclas`.
Analiza]i exemplul de mai jos:
class C1
{ int x,y; }
class C2 extends C1
{ int z;
void afis()
{ System.out.println(x+" "+ y+" "+z); }
}
public class C {
public static void main(String[] args) {
C2 ref= new C2();
ref.x=3;
ref.y=4;
ref.z=5;
ref.afis();
}
}

Aici s-a extins clasa C1. Ea con]ine dou` date membru x [i y, ambele de
tip int. |n exemplul dat, C1 este superclas`.
Noua clas`, C2, va con]ine datele membru ale clasei C1 (\n exemplu x [i
y) dar [i o nou` dat` membru (z, de tip int). De asemenea, clasa C2
con]ine [i metoda afis(), care are rolul de a afi[a con]inutul datelor
membru ale unui obiect. |n exemplu, clasa c2 este subclas`. Programul
creeaz` un obiect al clasei C2, numit ref, \i ini]ializeaz` datele membru [i
le afi[eaz`.
2. Pentru a marca faptul c` o clas` extinde o alt` clas` se folose[te
cuv@ntul extends (\n exemplu class C2 extends C1 ).
3. Ini]ializarea unui obiect al subclasei are ca efect apelul, \n aceast`
ordine, al constructorului superclasei [i apelul constructorului subclasei. Este
normal s` fie a[a, pentru c` subclasa include datele membru [i metodele
superclasei.
Exemplu: analiza]i programul de mai jos, \n care fiecare clas` con]ine c@te
un constructor. Programul afi[eaz`:
Constructor 1
Constructor 2
Capitolul 6. Extinderea claselor 133

class Unu{
Unu (){ System.out.println("Constructor 1"); }
}
class Doi extends Unu
{ Doi() { System.out.println("Constructor 2"); };
}
public class C {
public static void main(String[] args) {
Doi x=new Doi();
}
}

4. Exist` posibilitatea ca anumite date membru sau metode s` aib` acela[i


nume at@t \n superclas` c@t [i \n subclas`. |n astfel de cazuri, implicit, la
\nt@lnirea numelui datei membru (sau metodei) se apeleaz` data membru
(metoda) a subclasei. |n cazul \n care se dore[te ca s` fie apelat` data
membru (metoda) a superclasei, se utilizeaz` cuv@ntul cheie super. El are
semnifica]ia de obiect curent al superclasei. |n exemplul de mai jos, x este
dat` membru at@t a superclasei c@t [i a subclasei. Exemplu: programul
urm`tor va afi[a 1 2 3.
class C1
{ int x=1,y; }
class C2 extends C1
{ int x;
void afis()
{ System.out.println(super.x+" "+ y+" "+x); }
}
class C{
public static void main(String[] args) {
C2 pt= new C2();
pt.x=3;
pt.y=2;
pt.afis();
}
}

 super nu poate fi folosit \n afara clasei.

5. |n cazul \n care superclasa este \nzestrat` cu un constructor care


prime[te parametri, atunci este obligatoriu ca acesta s` fie apelat de
constructorul subclasei. De ce? A[a cum am ar`tat, constructorul subclasei
apeleaz` automat constructorul superclasei. |n cazul \n care apelul nu este
explicit, este apelat constructorul implicit (f`r` parametri) al superclasei. Or,
am \nv`]at faptul c`, \n condi]iile existen]ei unui constructor cu parametri, nu
mai este posibil s` apel`m constructorul implicit, pentru c` apare eroare.
Mai mult, prima instruc]iune a constructorului subclasei trebuie s` fie apelul
constructorului superclasei. Apelul constructorului superclasei se face prin:
super (lista_parametri).
134 Bazele programării în Java

Exemplu: Analiza]i programul urm`tor, \n care clasa Elev con]ine numele [i


prenumele unui elev, iar clasa Olimpic extinde clasa Elev [i con]ine \n
plus o dat` membru, materia la care elevul este olimpic [i o metod` prin
care se afi[eaz` numele, prenumele elevului [i materia respectiv`.
class Elev
{ String nume, prenume;
Elev (String nume, String prenume)
{ this.nume=new String(nume);
this.prenume=new String(prenume); }
}

class Olimpic extends Elev


{ String materia;
Olimpic(String nume, String prenume, String materia)
{ super(nume,prenume); // apel constructor al superclasei
this.materia=new String(materia);}
void afis()
{ System.out.println(nume+" "+prenume+" "+materia); }
}
public class test {
public static void main(String[] args) {
//primul mod de creare a unui obiect olimpic
Olimpic A=new Olimpic("Pascu", "Marius", "informatica");
//al doilea mod de creare a unui obiect olimpic
String n=new String("Grosu");
String p=new String("Bogdan");
String mat=new String("matematica");
Olimpic B=new Olimpic(n,p,mat); A.afis(); B.afis();
}
}

6. |n Java, o clas` poate extinde (mo[teni) o singur` superclas` . Nu


exist` un mecanism de mo[tenire multipl`, a[a precum exist` \n alte
limbaje. Din acest motiv, ierarhia claselor are o structur` arborescent` .

6.2. Un exemplu de extindere al unei clase


Fie clasa Complex, de mai jos. Ea are dou` date membru, x [i y,
care re]in partea real` [i partea imaginar` a unui num`r complex. De
asemenea, clasa este \nzestrat` cu un constructor [i metoda afis(), care
afi[eaz` num`rul complex re]inut de obiect.
class Complex
{ double x,y;
Complex (double x, double y)
{ this.x=x;
this.y=y;}
void afis()
{System.out.println(x+" "+y);}
}
Capitolul 6. Extinderea claselor 135

Clasa este extins` la o alta, Complex_op, care con]ine [i metode prin care
se efectueaz` opera]iile de mai jos cu numere complexe:

z1  z 2  x 1  i  y1  x 2  i  y 2  x 1  x 2  i  (y1  y 2 ).

z1  z 2  x 1  i  y1  x 2  i  y 2  x 1  x 2  i  (y1  y 2 ).
z1  z 2  x 1  i  y1 x 2  i  y 2   x 1  x 2  y1 y 2  i  (x 1 y 2  x2 y1 ).
z1 x  i  y1  x  i  y1    x 2  i  y 2  x1 x 2  y 1 y 2  i x 2 y1  x1 y 2 
 1  1 
z 2 x2  i  y 2 x2  i  y 2   x2  i  y 2  x 22  y 22

Iat` ce con]ine, \n plus, clasa Complex_op:

 Doi constructori. Primul dintre ei accept` partea real` [i partea


imaginar` a unui num`r complex. Al doilea, accept` numai partea
real` (num`r real inclus, evident, \n mul]imea numerelor complexe).
 Metodele add, sub, mul, div - efectueaz` opera]iile de adunare,
respectiv sc`dere, \nmul]ire, \mp`r]ire a dou` numere complexe. Ele
returneaz` num`rul complex rezultat \n urma opera]iei.
class Complex_op extends Complex
{
Complex_op (double x, double y)
{ super(x,y); }

Complex_op (double x)
{ super(x,0); }

Complex_op add(Complex_op z)
{ Complex_op t=new Complex_op (x+z.x,y+z.y);
return t; }

Complex_op sub(Complex_op z)
{ Complex_op t=new Complex_op (x-z.x,y-z.y);
return t; }

Complex_op mul(Complex_op z)
{ Complex_op t=new Complex_op (x*z.x-y*z.y, x*z.y+z.x*y);
return t; }

Complex_op div(Complex_op z)
{ double num=z.x*z.x+z.y*z.y;
Complex_op t;
if (num!=0)
t=new Complex_op ((x*z.x+y*z.y)/num, (z.x*y-x*z.y)/num);
else t=new Complex_op(0,0);
return t;
}
}
136 Bazele programării în Java

 Exerciţii rezolvate

1. S` se creeze dou` obiecte de tip Complex_op [i s` se afi[eze suma,


diferen]a, produsul [i c@tul lor.
public class test {
public static void main(String[] args) {
// instantiez z si il afisez
Complex_op z=new Complex_op(2,3);
z.afis();
// instantiez z1 si il afisez
Complex_op z1= new Complex_op(10);
z1.afis();
// Afisez suma dintre z si z1
z.add(z1).afis();
// Afisez diferenta dintre z si z1
z.sub(z1).afis();
// Afisez produsul dintre z si z1
z.mul(z1).afis();
// Afisez catul dintre z si z1
z.div(z1).afis();
}
}

2. Se citesc a [i b dou` numere reale care reprezint` partea real` [i


partea complex` a num`rului z=a+b*i [i n, un num`r natural mai mare
sau egal cu 1. Se cere s` se afi[eze zn.
public class test {
public static void main(String[] args) {
System.out.print("a=");
double a=Double.parseDouble(cin.Token());
System.out.print("b=");
double b=Double.parseDouble(cin.Token());
Complex_op z= new Complex_op(a,b);
z.afis();
// initializez produsul cu 1;
Complex_op P= new Complex_op(1);
System.out.print("n=");
int n=Integer.parseInt(cin.Token());
for (int i=0;i<n;i++) P=P.mul(z);
P.afis();
}
}

3. S` se extind` clasa Complex_op, la o alta, numit` Cmpl, care s`


con]in`, \n plus, o metod` prin care returneaz` modulul num`rului complex
[i o alt` metod` boolean` care returneaz` true, \n cazul \n care num`rul
este real (y are valoarea 0).

Rezolvare. |ntruc@t constructorii nu se mo[tenesc, a fost necesar`


rescrierea lor:
Capitolul 6. Extinderea claselor 137

class Cmpl extends Complex_op


{
Cmpl (double x, double y)
{ super(x,y); }
Cmpl (double x)
{ super(x,0); }
double modul()
{ return Math.sqrt(x*x+y*y);}
boolean real()
{ return y==0; }
}

4. Se cite[te un vector de numere complexe. Se cere s` se sorteze


cresc`tor elementele vectorului \n func]ie de modulul lor.

Rezolvare: datorit` faptului c` avem nevoie de modulul numerelor complexe,


vom apela la ultima clas` creat`: Cmpl. Observa]i ierarhia acestor clase: la
baz` este Complex, apoi Complex_op, iar ultima este Cmpl. Programul
utilizeaz` [i metoda Afis(), care apar]ine clasei complex.

public class test {


public static void main(String[] args) {
System.out.print("n=");
int n=Integer.parseInt(cin.Token());
Cmpl[] V=new Cmpl[n];
for (int i=0;i<n;i++)
{
System.out.print("V["+i+"].x=");
double x=Double.parseDouble(cin.Token());
System.out.print ("V["+i+"].y=");
double y=Double.parseDouble(cin.Token());
V[i]=new Cmpl(x,y);
}
boolean gasit;
Cmpl man;
do
{
gasit=false;
for (int i=0;i<n-1;i++)
if (V[i].modul()>V[i+1].modul())
{
man=V[i];
V[i]=V[i+1];
V[i+1]=man;
gasit=true;
}
} while (gasit);
for (int i=0;i<n;i++) V[i].afis();
}
}
138 Bazele programării în Java

6.3. O modalitate de simulare a extinderii multiple


A[a cum deja [ti]i, \n Java o clas` poate extinde (mo[teni) o singur`
clas`. Se poate totu[i, simula mo[tenirea multipl`. Privi]i exemplul urm`tor,
\n care clasa Mosten extinde dou` clase A [i B. Ea va avea datele
membru [i metodele celor dou` clase. Ideea e foarte simpl`:

1. Clasa va re]ine referin]e c`tre obiecte ale claselor pe care le extinde;


2. Pornind de la aceste referin]e se pot accesa datele membru [i metodele
claselor care sunt extinse, dup` cum se poate observa \n exemplu:
class A {
int a=1;
void m1() { System.out.println("a="+a);}
}
class B {
int b=2;
void m2() { System.out.println("b="+b);}
}
class Mosten {
A x=new A();
void m1() { x.m1(); }
B y=new B();
public void m2() { y.m2(); }
}
public class test {
public static void main(String[] args) {
Mosten t=new Mosten();
t.m1();
System.out.println(t.x.a);
t.m2();
System.out.println(t.y.b);
}
}

 Observa]ii:
1. |n fapt, se instan]eaz` 3 obiecte: primul este al clasei A, al doilea este
al clasei B [i al treilea este al clasei Mosten. Accesul la datele membru [i
metodele obiectelor de tip A [i B se face prin referin]ele c`tre acestea,
referin]e con]inute de obiectul de tip Mosten.
2. Accesul la datele membru ale claselor extinse se face pu]in mai greu
(vede]i exemplul de mai sus). Cu toate acestea, problema nu este at@t de
grav`. |n practica OOP, se obi[nuie[te ca datele membru s` fie accesate
numai prin metodele clasei respective. Dezavantajul acestui procedeu este
dat de faptul c`, \n cazul unor clase cu zeci de metode care urmeaz` a fi
“mo[tenite”, trebuie avut` mult` r`bdare pentru a implementa, ca mai sus,
toate metodele.
Capitolul 6. Extinderea claselor 139

6.4. Referinţe către obiectele superclaselor şi


referinţe către obiectele subclaselor
Fie clasele de mai jos, unde clasa Y, extinde clasa X:

class X
{ int k=1;
void met() {System.out.println("Metoda x"); }
}
class Y extends X
{ int v=2;
void metoda() {System.out.println("Metoda y"); }
}

1. O variabil` de tip referin]` c`tre un obiect al superclasei poate re]ine o


referin]` c`tre un obiect al subclasei. |n acest caz, pornind de la referin]`,
se pot accesa numai datele membru [i metodele superclasei, care sunt,
evident, [i ale subclasei.

Exemplu: programul urm`tor afi[eaz` 1 [i Metoda x:

public class test {


public static void main(String[] args) {
X ref=new Y();
System.out.println(ref.k);
ref.met(); }
}

|n aceste condi]ii, fiecare dintre instruc]iunile urm`toare ar produce eroare:

System.out.println(ref.v);
ref.metoda();

2. Totu[i, exist` posibilitatea ca, \n cazul \n care o variabil` de tip referin]`


c`tre superclas` con]ine o referin]` c`tre un obiect al subclasei, pornind de
la ea, cu ajutorul operatorului de conversie explicit`, s` putem accesa
datele membru [i metodele acelui obiect. Vede]i exemplul de mai jos, unde
se afi[eaz` 2 [i Metoda y:

public class test {


public static void main(String[] args) {
X ref=new Y();
Y ref1=(Y)ref;
System.out.println(ref1.v);
ref1.metoda();
}
}
140 Bazele programării în Java

Observa]ie foarte important`: \n cazul \n care o metod`, nu [i o dat`


membru, a superclasei este redefinit` \n subclas`, adic` a fost scris`
o alta cu acela[i nume, atunci este posibil ca prin procedeul de mai
sus, f`r` a utiliza operatorul de conversie explicit`, s` apel`m metoda
subclasei. Acest caz este tratat separat. Vede]i polimorfismul.
3. O variabil` de tip referin]` c`tre un obiect al subclasei, nu poate re]ine
o referin]` c`tre superclas`.
Exemplu: dac` \n program am avea instruc]iunea: Y ref=new X();, ea ar
produce eroare la compilare.
V` pute]i \ntreba, la ce folose[te faptul c` o variabil` de tip referin]` c`tre
un obiect al superclasei poate re]ine [i o referin]` c`tre un obiect al
subclasei? Ideea de baz` este urm`toarea: se poate crea o clas`, care
poate fi extins` de mai multe clase. Aceasta \nseamn` c` o structur`
oarecare (vector, matrice, stiv`, coad`, list` liniar`, etc) cu elemente de tip
referin]` c`tre obiectele superclasei, poate lucra cu referin]e c`tre obiectele
subclaselor. Sau, altfel spus, prin acest procedeu se poate asigura
independen]a structurii fa]` de datele propriu-zise. Ideea este fundamental`
\n OOP.

Exemplu: dorim s` cre`m o structur` de tip stiv` care s` lucreze cu orice


fel de date, dar structura s` r`m@n` aceea[i. |n acest exemplu, nodurile
con]in fie numere \ntregi, fie numere reale.
Rezolvare: Pentru a putea implementa aceast` cerin]` vom considera o
clas`, s-o numim Baza, care are o singur` dat` membru: o variabil` care
poate re]ine referin]e c`tre propriile obiecte. Clasa Int extinde clasa Baza.
Ea are [i data membru x, care re]ine un \ntreg, precum [i un constructor.
Clasa Real extinde [i ea clasa Baza. Ea are [i data membru x, care
re]ine un num`r real, precum [i un constructor.
class Baza
{ Baza adr_prec; }
class Int extends Baza
{ int x;
Int(int x)
{ this.x=x;}
}
class Real extends Baza
{ double x;
Real(double x)
{ this.x=x;}
}

 Observa]ii:
1. Evident c` obiectele clasei Int, precum [i obiectele clasei Real au [i
data membru adr_prec, care este mo[tenit`.
Capitolul 6. Extinderea claselor 141

2. Practic, prin extinderea clasei Baza putem ob]ine orice alte clase ale
c`ror obiecte s` poat` fi memorate de stiv`.
Clasa Stiva con]ine:

 variabila varf - care poate re]ine o referin]` c`tre un obiect al clasei


Baza. Rolul ei este de a memora adresa ultimului nod introdus \n
stiv`.
 metoda void push(Baza Nod) - introduce un nod \n stiv`;
 metoda Baza pop() - are rolul de a extrage un nod din stiv` [i de
a-l returna.
class Stiva
{ Baza varf;
void push(Baza Nod)
{ Nod.adr_prec=varf;
varf=Nod;}
Baza pop()
{ if (varf!=null)
{ Baza x=varf;
varf=varf.adr_prec;
return x; }
else return null;
}
}

|n programul urm`tor se introduc \n stiv` 3 numere \ntregi, dup` care


se extrag [i se afi[eaz`:
class test {
public static void main(String[] args)
{ Stiva st=new Stiva();
st.push(new Int(3));
st.push(new Int(5));
st.push(new Int(6));
Int N;
while ((N=(Int)st.pop())!=null) System.out.println(N.x);
}
}

|n programul urm`tor se introduc \n stiv` 3 numere reale, dup` care


se extrag [i se afi[eaz`:
class test {
public static void main(String[] args)
{ Stiva st=new Stiva();
st.push(new Real(3.2));
st.push(new Real(5.5));
st.push(new Real(6.3));
Real N;
while ( (N=(Real)st.pop())!=null ) System.out.println(N.x);
}
}
142 Bazele programării în Java

Probleme propuse
1. S` se extind` clasa cin. Noua clas` se va numi Cit [i va con]ine
metodele:
static int Intreg() // cite[te [i returneaz` un num`r \ntreg;
static double Real() // cite[te [i returneaz` un num`r real;
static char Caracter() // cite[te [i returneaz` un caracter;
static String Sir() // cite[te [i returneaz` un [ir de caractere.

2. Utiliza]i noua clas` \ntr-un program care cite[te [i afi[eaz` un num`r


\ntreg, unul real [i un caracter.

|ntreb`rile de la 3 la 7 se refer` la cele dou` clase:


class Unu
{ int A=1;}

class Doi extends Unu


{int A=2;}

3. Ce se afi[eaz` \n urma execut`rii secven]ei urm`toare?


Doi x=new Doi();
System.out.println(x.A);

a) 1; b) 2; c) Eroare.

4. Ce se afi[eaz` \n urma execut`rii secven]ei urm`toare?

Unu x=new Doi();


System.out.println(x.A);

a) 1; b) 2; c) Eroare.

5. Ce se afi[eaz` \n urma execut`rii secven]ei urm`toare?

Doi x=new Unu();


System.out.println(x.A);

a) 1; b) 2; c) Eroare.

6. Ce se afi[eaz` \n urma execut`rii secven]ei urm`toare?

Doi x=new doi();


System.out.println(x.super.A);

a) 1; b) 2; c) Eroare.
Capitolul 6. Extinderea claselor 143

7. Scrie]i o secven]` \n main(), care afi[eaz` valorile re]inute de data


membru A a clasei Unu [i data membru A a clasei Doi. Cerin]`
suplimentar`: se va utiliza o singur` dat` operatorul new.

8. Fiind date clasele de mai jos, care este corpul corect al constructorului
clasei Doi?

class Unu
{ int A;
Unu (int A)
{this.A=A; }
}

class Doi extends Unu


{ int B,C;
Doi (int A, int B, int C)
{ ... }
void afis() { System.out.println(A+" "+B+" "+C);}
}

a) b) c) d)
this.B=B; super(A); this.A=A; Nici unul
this.C=C; this.B=B; this.B=B; nu este
super(A); this.C=C; this.C=C;
corect

9. Fiind dat` clasa de mai jos (Baza), scrie]i o clas` (Lista) care
creeaz` o list` liniar` simplu \nl`n]uit` \n care elementele sunt obiectele
clasei Baza. Evident, elementele acestei liste nu au nici o alt` informa]ie, \n
afara celei de adres`.
class Baza { Baza adr_urm;}
Lista va con]ine:
 Baza v; - data membru; re]ine v@rful listei;
 Baza varf() - returneaz` v@rful listei liniare (adresa primului
element);
 void adaug (Baza Nod) - adaug` la sf@r[itul listei un element.

10. Crea]i clasa Int, care s` extind` clasa Baza [i s` con]in` \n plus:

 int val; - dat` membru;


 Int (int val) - constructor;
 int valoare() - returneaz` valoarea re]inut` de val.

11. Scrie]i un program care creeaz` o list` liniar` simplu \nl`n]uit` cu n


elemente (n citit de la tastatur`) de tip Int. Valorile re]inute de obiectele
de tip Int sunt, de asemenea, citite de la tastatur`. Lista va fi construit`
cu ajutorul clasei Lista.
144 Bazele programării în Java

12. Scrie]i un program care creeaz` o list` liniar` simplu \nl`n]uit` cu n


elemente (n citit de la tastatur`) de tip String. {irurile de caractere
re]inute de obiectele de tip Sir sunt, de asemenea, citite de la tastatur`.
Lista va fi construit` cu ajutorul clasei Lista.

13. Scrie]i un program care creeaz` o list` liniar` simplu \nl`n]uit` cu n


elemente (n citit de la tastatur`), obiecte de tip Persoana. Clasa
Persoana va fi construit` de dvs. [i va con]ine numele [i vârsta persoanei.
Lista va fi construit` cu ajutorul clasei Lista.

Indicaţii / răspunsuri:
1. class Cit extends cin
{ static int Intreg()
{ return Integer.parseInt(Token());}
static double Real()
{ return Double.parseDouble(Token());}
static char Caracter()
{ return linie().charAt(0);}
static String Sir()
{return linie();}
}
2. class t {
public static void main(String[] args) {
System.out.print("n=");int n=Cit.Intreg();
System.out.println(n);
System.out.print("x=");double x=Cit.Real();
System.out.println(x);
System.out.print("ch=");char ch=Cit.Caracter();
System.out.print(ch);}
}

3. b) 4. a) 5. c) 6. c)
7. Doi x=new Doi();
Unu y=x;
System.out.println(y.A+" "+x.A);

8. b)
9. class Lista
{ Baza v;
Baza varf()
{ return v;}
void adaug (Baza Nod)
{ Baza c=v;
if (c!=null)
{ while (c.adr_urm!=null) c=c.adr_urm;
c.adr_urm=Nod; }
else v=Nod;
}
}
Capitolul 6. Extinderea claselor 145

10. class Int extends Baza


{ int val;
int (int val)
{ this.val=val;}
int valoare()
{ return val;}
}
11. public class C {
public static void main(String[] args) {
System.out.print("n=");
int n=Integer.parseInt(cin.Token());
Lista l= new Lista();
for (int i=0;i<n;i++)
{ System.out.print("val=");
int val=Integer.parseInt(cin.Token());
Int Nod=new Int(val);
l.adaug(Nod);}
Baza varf=l.varf();
Int Nod=(Int)varf;
while (Nod!=null)
{ System.out.println(Nod.valoare());
Nod=(Int)Nod.adr_urm;}
}
}
12. Rezolv`m problema \n doi pa[i:

a) Construim clasa Sir, care extinde clasa Baza:


class Sir extends Baza
{ String sir;
Sir (String sir)
{ this.sir=sir; }
String valoare()
{ return sir; }
}
b) Scriem programul propriu-zis:
public class C {
public static void main(String[] args) {
System.out.print("n=");
int n=Integer.parseInt(cin.Token());
Lista l= new Lista();
for (int i=0;i<n;i++)
{ System.out.print("val=");
String val=cin.linie();
Sir Nod=new Sir(val);
l.adaug(Nod);}
Baza varf=l.varf();
Sir Nod=(Sir)varf;
while (Nod!=null)
{ System.out.println(Nod.valoare());
Nod=(Sir)Nod.adr_urm; }
}
}
146 Bazele programării în Java

13.

class Persoana extends Baza


{
String nume;
int varsta;
Persoana ()
{
System.out.println("Nume=");
nume=cin.linie();
System.out.println("varsta=");
varsta=Integer.parseInt(cin.Token());
}
String nume()
{ return nume; }
int varsta()
{ return varsta; }
}
public class C {
public static void main(String[] args) {
System.out.print("n=");
int n=Integer.parseInt(cin.Token());
Lista l= new Lista();
for (int i=0;i<n;i++)
{ Persoana Nod=new Persoana();
l.adaug(Nod);
}
Baza varf=l.varf();
Persoana Nod=(Persoana)varf;
while (Nod!=null)
{ System.out.println(Nod.nume() +" "+Nod.varsta());
Nod=(Persoana)Nod.adr_urm;
}
}
}
CAPITOLUL 7

Noţiuni avansate de programare


orientată pe obiecte

Din cuprins:
Polimorfism. Exemple
Clase abstracte. Exemple
Interfeţe. Aplicaţii
Modificatori. Exemple
Probleme propuse
148 Bazele programării în Java

7.1. Polimorfism
Prin polimorfism vom \n]elege posibilitatea ca at@t superclasa, c@t [i
subclasa s` aib` metode cu acela[i nume (metodele pot fi redefinite).

De[i, \n aparen]`, \n]elegerea polimorfismului nu este dificil`, \n


realitate, apar anumite probleme pe care ne propunem s` le rezolv`m \n
acest paragraf. Mai mult, polimorfismul reprezint` unul din punctele cheie ale
program`rii orientate pe obiecte [i este un instrument puternic de
programare.

Fie B o clas` care extinde o clas` A. Prin urmare, toate datele


membru [i metodele clasei A se reg`sesc [i \n clasa B. Am mai \nv`]at
faptul c` o metod` a clasei A poate fi redefinit`, adic`, \n clasa B scriem o
metod` cu acela[i nume (\n exemplu, void tip()). Vom trata dou` cazuri,
cazul \n care metodele sunt nestatice [i cazul \n care metodele sunt statice.

I) Metodele [i datele membru sunt nestatice.

Fie O un obiect al clasei A [i O1 un obiect al clasei B.


Vede]i exemplul urm`tor, al c`rui rezultat \l pute]i observa
al`turat.
class A
{ int i=1;
void tip() { System.out.println("clasa A"); }
}

class B extends A
{ void tip() { System.out.println("clasa B"); }
}

public class test {


public static void main(String[] args) {
// Cazul 1
A O=new A(); O.tip();
// Cazul 2
B O1=new B(); O1.tip();
// Cazul 3
A O2=new B(); O2.tip();
}
}

 |n cazul 1 se apeleaz` metoda tip() a clasei A. Se va afi[a


clasa A [i valoarea 1 (pentru i). Este normal s` fie a[a, obiectul
este al clasei A, referin]a este c`tre un obiect al clasei A.
 |n cazul 2 se apeleaz` metoda tip() a clasei B. Se va afi[a
clasa B [i valoarea 2 (pentru i). Este normal s` fie a[a,
obiectul este al clasei B, referin]a este c`tre un obiect al clasei B.
Capitolul 7. Noţiuni avansate de programare orientată pe obiecte 149

 |n cazul 3, [i acesta este cazul interesant pe care-l studiem \n


acest moment, se va apela metoda tip() a clasei B, prin urmare
se va afi[a clasa B [i valoarea 1 (pentru i). S` observ`m c`
obiectul este al clasei B, dar variabila care re]ine referin]a c`tre el
este o referin]` c`tre obiecte ale clasei A. Cu toate c` a fost
apelat` metoda clasei B, a fost afi[at con]inutul variabilei i a
clasei A

Foarte important: \n cazul unei metode a superclasei, redefinit` \n

 subclas`, dou` elemente prezint` importan]`: tipul variabilei referin]`


(c`tre obiecte ale superclasei sau c`tre obiecte ale subclasei) [i tipul
obiectului creat (al superclasei sau al subclasei). Se disting, astfel
dou` cazuri:
A) tipul referin]ei [i tipul obiectului creat coincid (sunt fie ale superclasei, fie
ale subclasei). |n acest caz este apelat` metoda care este din tipul
comun. De asemenea, se afi[eaz` variabila care apar]ine obiectului de
tip comun. Vezi, mai sus, cazurile 1 [i 2.
B) tipul referin]ei este al superclasei, iar tipul obiectului creat este al
subclasei (invers nu este posibil, a[a cum am ar`tat). |n acest caz,
dac` metoda redefinit` este nestatic`, Java ia \n considerare tipul
obiectului creat [i deci, va fi apelat` metoda subclasei. Vezi, mai sus,
cazul 3. |n schimb, se ob]ine accesul la data membru a superclasei.

II) Metodele [i datele membru sunt statice. Relu`m


problema pentru acest caz. Vede]i programul de mai jos,
iar rezultatul afi[at de el, al`turat. |n cazurile 1 [i 2
comportamentul este acela[i, dar \n cazul 3 este apelat`
metoda superclasei, deci se afi[eaz` clasa A. Observa]i
faptul c`, \n acest caz, comportamentul este diferit.
class A
{ static int i=1;
static void tip() { System.out.println("clasa A"); }
}
class B extends A
{ static int i=2;
static void tip() { System.out.println("clasa B"); }
}
public class test {
public static void main(String[] args)
{ // Cazul 1
System.out.println("Cazul 1");
A O=new A(); O.tip();
System.out.println(O.i);
// Cazul 2
System.out.println("Cazul 2");
B O1=new B(); O1.tip();
System.out.println(O1.i);
150 Bazele programării în Java

// Cazul 3
System.out.println("Cazul 3");
A O2=new B(); O2.tip();
System.out.println(O2.i);
}
}

|n terminologia program`rii orientate pe obiecte ve]i \nt@lni termenul de


legare (static`, dinamic`). Care este semnifica]ia lui? Pornind de la referin]a
c`tre obiect, se apeleaz` o metod` redefinit`. Am v`zut c`, \n unele cazuri
se apeleaz` metoda superclasei, \n altele, se apeleaz` metoda subclasei.
Cu alte cuvinte, se apeleaz` (leag`) o metod` sau alta. Aceasta este
semnifica]ia termenului de legare (adic` apel al unei metode sau alta).

 Legarea este static` dac` \nainte de executarea programului se poate


[ti care metod` este apelat` [i este dinamic` dac` numai \n
momentul execut`rii se decide metoda care va fi apelat`. |n Java
este permis` [i legarea dinamic`.

Privi]i exemplul de mai jos, \n care legarea dinamic` este evident`.


Dac` se introduce 0 se afi[eaz` clasa A, iar dac` se introduce o valoare
diferit` de 0 se afi[eaz` clasa B.
class A
{ int i=1;
void tip() { System.out.println("clasa A"); }
}

class B extends A
{ void tip() { System.out.println("clasa B"); }
}

public class Clasa1 {


public static void main(String[] args) {
A x;
int n=Integer.parseInt(cin.Token());
if (n==0) x=new A();
else x=new B();
x.tip();
}
}

7.2. Un exemplu de polimorfism


S` se creeze o clas` numit` Muncitor. Clasa va con]ine data
membru ore_lucrate [i un constructor prin care acesteia i se atribuie o
valoare. De asemenea, clasa con]ine o metod` nestatic` salariu() prin
care se calculeaz` suma c@[tigat` de acesta (se ob]ine ca produs \ntre
num`rul orelor lucrate [i suma \ncasat` pentru o or` lucrat`, \n exemplu
20000 lei). Dintre muncitori, se selecteaz` [eful de echip`, care are \n
Capitolul 7. Noţiuni avansate de programare orientată pe obiecte 151

subordine mai mul]i muncitori. Se [tie c` [eful de echip` prime[te mai mult
pentru o or` lucrat` (\n exemplu 50.000). Se construie[te clasa
Sef_echipa, care este subclas` a clasei Muncitor. Metoda salariu()
este redefinit`. Dintre [efii de echip`, unii sunt selecta]i pentru a urma o
[coal` de mai[tri. Dup` ce devin mai[tri [i au \n subordine mai mul]i [efi
de echip`. S` se construiasc` clasa Maistru, care are ca superclas` clasa
Sef_echipa. Un maistru prime[te pe or` mai mult dec@t un [ef de echip`
(\n exemplu 100000 lei), deci metoda salariu() este redefinit`. Se cere
s` se scrie un program care cite[te un num`r natural n \ntre 1 [i 3. Dac`
n este 1 se construie[te un obiect al clasei muncitor, dac` n este 2 se
construie[te un obiect al clasei sef_echipa, iar dac` n este 3 se
construie[te un obiect al clasei Maistru. De asemenea, se cite[te num`rul
de ore lucrat de persoana respectiv`. |n final, se va afi[a salariul \ncasat
de persoana citit`.

class Muncitor
{ int ore_lucrate;
Muncitor(int ore_lucrate)
{ this.ore_lucrate=ore_lucrate;}
double salariu()
{ return ore_lucrate*20000;}
}
class Sef_echipa extends Muncitor
{ Sef_echipa(int ore_lucrate)
{ super(ore_lucrate); }
double salariu()
{ return ore_lucrate*50000;}
}
class Maistru extends Sef_echipa
{ Maistru(int ore_lucrate)
{ super(ore_lucrate);}
double salariu()
{ return ore_lucrate * 100000;}
}
public class test {
public static void main(String[] args) {
Muncitor x=null;
int tip=Integer.parseInt(cin.Token());
int ore=Integer.parseInt(cin.Token());

switch (tip)
{ case 1: x=new Muncitor(ore); break;
case 2: x=new Sef_echipa(ore); break;
case 3: x=new Maistru(ore); break; }
System.out.println(x.salariu());
}
}
152 Bazele programării în Java

 Observaţii:
 Exemplul dat se refer` la polimorfism [i la legarea dinamic`. Metoda
salariu este prezent` \n toate cazurile. Este rulat` o metod` sau alta
\n func]ie de valoarea citit`, prin urmare avem legare dinamic`.
 Exist` multe alte metode de rezolvare ale acestei probleme. Judec@nd
dup` problema \n sine, ar rezulta c` utilizarea polimorfismului poate fi
evitat`. A[a este, dar \n cazul programelor complexe (de exemplu \n
programarea vizual`), utilizarea lui se dovede[te extrem de util`.

7.3. Clase abstracte


Limbajul Java pune la dispozi]ia programatorilor un mecanism care se
dovede[te uneori extrem de eficient [i anume clasele abstracte.
O clas` abstract` con]ine date membru (nu \n mod obligatoriu) [i mai
multe metode, dar unele pot fi, la r@ndul lor abstracte. Pentru o metod`
abstract`, \n clas` se trece doar prin antetul ei. Metodele abstracte
urmeaz` s` fie redefinite \n subclase. Orice clas` abstract` trebuie s` fie
precedat` de cuv@ntul cheie abstract [i orice metod` abstract` din cadrul
ei trebuie [i ea s` fie precedat` de acela[i cuv@nt cheie. Clasele abstracte
nu se folosesc direct, adic` nu se instan]iaz` obiecte ale lor, ci se
utilizeaz` doar pentru a fi extinse (sunt prin defini]ie superclase).
Exemplu. |n programul de mai jos clasa Ex este abstract`. Ea con]ine dou`
metode abstracte, afis1() [i afis2(), dar [i o metod` decid(), care \n
func]ie de un parametru apeleaz` una dintre cele dou` metode abstracte.
Pentru a putea folosi clasa Ex, o extindem ob]in@nd astfel clasa Ex1. |n
clasa Ex1, redefinim cele dou` metode. Totu[i, clasa Ex1 nu redefine[te
metoda decid(), deci orice obiect al ei va folosi metoda din clasa
abstract`. Acest mecanism, permite ca \n clasa abstract` s` existe un
anumit “motor” (metod`) care apeleaz` alte metode care urmeaz` a fi
redefinite. Programul de mai jos apeleaz` mai \nt@i Afis 1 [i apoi Afis 2:
abstract class Ex
{ abstract void afis1();
abstract void afis2();
void decid(int b)
{ if (b>0) afis1();
else afis2(); }
}
class Ex1 extends Ex
{ void afis1()
{ System.out.println("Afis 1");}
void afis2()
{ System.out.println("Afis 2");}
}
Capitolul 7. Noţiuni avansate de programare orientată pe obiecte 153

public class test {


public static void main(String[] args) {
Ex1 a=new Ex1();
a.decid(1);
a.decid(-1);
}
}

7.4. Un exemplu de clasă abstractă


Cei care au studiat backtracking \n variant` iterativ`, standardizat`, au
v`zut fapul c` exist` o unic` metod` care apeleaz` mai multe metode care
au acela[i nume, parametri [i acela[i rol. A rezolva o problem` sau alta
\nseamn` a rescrie metodele specifice (init(), succesor(), [.a.m.d.) dar
motorul (metoda back()) r`m@ne aceea[i. De aici [i ideea: o clas`
abstract` (Bkt) va re]ine metoda back(), care nu este abstract`, iar
celelalte metode sunt abstracte. A rezolva o problem` \nseamn` a crea o
subclas` \n care redefinim metodele care o rezolv` (init(), succesor(),
valid(),...) conform cerin]elor problemei.
Programul de mai jos, utilizeaz` clasa bkt, pentru a o extinde \n
vederea rezolv`rii problemei particulare de generare a tuturor permut`rilor
mul]imii {1,2..n}, pentru n citit.
abstract class Bkt
{ int[] st; int n;
abstract void init(int k);
abstract boolean am_Succesor (int k);
abstract boolean e_Valid(int k);
abstract boolean solutie(int k);
abstract void tipar();
void back()
{ boolean AS;
int k=1;
st=new int[n+1];
init(k);
while (k>0)
{ do { } while ((AS=am_Succesor(k)) && !e_Valid(k));
if (AS)
if (solutie(k)) tipar();
else {k++;init(k);}
else k--; }
}
}
class Permut extends Bkt {
Permut (int n)
{ this.n=n;}
void init(int k)
{ st[k]=0; }
154 Bazele programării în Java

boolean am_Succesor (int k)


{ boolean rasp=false;
if (st[k]<n) { st[k]++; rasp=true;}
return rasp;}
boolean e_Valid(int k)
{ boolean rasp=true;
for (int i=1;i<k;i++)
if (st[i]==st[k]) rasp=false;
return rasp; }
boolean solutie(int k)
{ return k==n;}
void tipar()
{ for (int i=1;i<=n;i++) System.out.print(st[i]);
System.out.println();}
}

public class test {


public static void main(String[] args) {
System.out.print("n=");
int n=Integer.parseInt(cin.Token());
Permut x=new Permut(n);
x.back();
}
}

Exerci]iu: se cere s` se rezolve problema celor n dame. Folosind clasele


anterioare [i polimorfismul, problema devine foarte u[oar`. Ob]inem clasa
Dame care extinde clasa Permut. O singur` metod` trebuie redefinit`,
metoda boolean e_Valid(int k).
class Dame extends Permut
{ Dame (int n)
{ super(n); }
boolean e_Valid(int k)
{ boolean rasp=true;
for (int i=1;i<k;i++)
if ((st[i]==st[k]) || (Math.abs(st[k]-st[i])==Math.abs(k-i)) )
rasp=false;
return rasp;
}
}

Iar programul este asem`n`tor celui anterior:


public class test {
public static void main(String[] args) {
System.out.print("n=");
int n=Integer.parseInt(cin.Token());
Bkt x=new Dame(n);
x.back();
}
}
Capitolul 7. Noţiuni avansate de programare orientată pe obiecte 155

7.5. Interfeţe
Prin interfa]` vom \n]elege un proiect de clas`. O interfa]` poate
con]ine doar constante [i antete de metode. Ele sunt acceptate de limbaj [i
se presupune c`, ulterior, interfe]ele vor fi implementate de una sau mai
multe clase. O interfa]` arat` ca o clas`, numai c`, \n locul cuv@ntului
class, se folose[te cuv@ntul interface. Atunci c@nd scriem o clas` care
implementeaz` o anumit` interfa]`, se folose[te cuv@ntul cheie implements,
ca \n exemplul de mai jos. O interfa]` poate fi implementat` de una sau
mai multe clase.

Exemplu: Mai jos, avem o interfa]` numit` InterfA. Interfa]a este


implementat` de dou` clase, A [i B. |n main() prob`m toate acestea prin
crearea a dou` obiecte, unul care instan]iaz` clasa A, altul care instan]iaz`
clasa B. Programul afi[eaz`:
Afis din clasa A=6 5
Afis din clasa B=7 5

iar codul este:


interface InterfA {
int i=5;
void afis();
}
class A implements InterfA{
int i=6;
public void afis()
{ System.out.println("Afis din clasa A="+i+" "+InterfA.i);}
}
class B implements InterfA {
int i=7;
public void afis()
{ System.out.println("Afis din clasa B="+i+" "+InterfA.i);}
}
public class test {
public static void main(String[] args) {
A x=new A(); x.afis(); B y=new B(); y.afis(); }
}

Mai observ`m c`:


 Constantele declarate \n interfa]` (\n exemplu constanta i, cu
valoarea 5) se apeleaz` prin numele interfe]ei, urmat de „.‟ [i de
numele constantei.
 Constantele pot fi redefinite de date membru (\n exemplu de i cu
valoarea 6 [i i cu valoarea 7). At@t constanta c@t [i redefinirile ei
pot fi apelate simultan.
156 Bazele programării în Java

1. O variabil` de tip referin]` c`tre interfa]` poate memora o referin]`


c`tre orice clas` care implementeaz` respectiva interfa]`. Mai mult, legarea
este dinamic`, a[a cum rezult` din exemplul urm`tor.
Exemplu: pentru clasele implementate anterior, se poate ob]ine acela[i efect
dac` main() se scrie astfel:

public static void main(String[] args) {


int tip=Integer.parseInt(cin.Token());
if (tip==1) { interfA x=new A(); x.afis(); }
else { interfA y=new B(); y.afis(); }
}

2. O interfa]` poate extinde mai multe interfe]e. S` observ`m faptul c` o


clas` poate extinde o singur` clas`, dar o interfa]` poate extinde mai multe
interfe]e, ca mai jos:
interface A
{ void metA();}
interface B
{ void metB();}
interface C
{ void metC();}
interface Extinsa extends A,B,C
{ void MetE();}

3. A implementa o interfa]` extins` \nseamn` a implementa toate metodele


interfe]elor care au stat la baza extinderii, plus metodele a c`ror antet se
g`se[te \n interfa]a extins`. |n exemplul urm`tor se implementeaz` clasa
Extinsa:
class Ex implements Extinsa {
public void metA() {System.out.println("metA");}
public void metB() {System.out.println("metB");}
public void metC() {System.out.println("metC");}
public void metE() {System.out.println("metE");}
}
public class test {
public static void main(String[] args) {
Ex x=new Ex();
x.metA(); x.metB(); x.metC(); x.metE(); }
}

4. O clas` poate implementa oric@te interfe]e, ca \n exemplul urm`tor:

interface A
{ void metA();}
interface B
{ void metB();}
interface C
{ void metC();}
Capitolul 7. Noţiuni avansate de programare orientată pe obiecte 157

class Ex implements A,B,C {


public void metA() {System.out.println("metA");}
public void metB() {System.out.println("metB");}
public void metC() {System.out.println("metC");}
}
public class test {
public static void main(String[] args) {
Ex x=new Ex();
x.metA(); x.metB(); x.metC();}
}

5. Cu ajutorul interfe]elor se poate simula mo[tenirea multipl` (se [tie c`


\n Java nu este permis` mo[tenirea multipl`). Exemplu: Avem 3 clase
rezultate \n urma implement`rii a 3 interfe]e. Prin procedeul de mai jos,
clasa Mosten preia metodele celor 3 clase:
interface A
{ void metA();}
class Aclass implements A
{ public void metA() {System.out.println("metA");}
}
interface B
{ void metB();}
class Bclass implements B
{ public void metB() {System.out.println("metB");}
}
interface C
{ void metC();}
class Cclass implements C
{ public void metC() {System.out.println("metC");}
}
class Mosten implements A,B,C {
public void metA() { A x= new Aclass(); x.metA();}
public void metB() { B x= new Bclass(); x.metB();}
public void metC() { C x= new Cclass(); x.metC();}
}
public class test {
public static void main(String[] args) {
Mosten x=new Mosten();
x.metA(); x.metB(); x.metC();}
}

6. Mai mult, se pot mo[teni metode ale claselor care implementeaz` o


aceea[i interfa]`. Privi]i exemplul urm`tor \n care clasa Mosten utilizeaz`, la
un moment dat, o singur` clas` dintre cele 3 (A, B, C) care
implementeaz` interfa]a numit` Interf:
interface Interf
{ void met();}
158 Bazele programării în Java

class A implements Interf


{ public void met() {System.out.println("Metoda din A");}
}
class B implements Interf
{ public void met() {System.out.println("Metoda din B");}
}
class C implements Interf
{ public void met() {System.out.println("Metoda din C");}
}
class Mosten {
Interf x;
Mosten (Interf x) { this.x=x;}
void met() { x.met();}
}
public class test {
public static void main(String[] args) {
Mosten v1=new Mosten(new A()); v1.met();
Mosten v2=new Mosten(new B()); v2.met();
Mosten v3=new Mosten(new C()); v3.met();}
}

7.6. Aplicaţii ale interfeţelor


Vom prezenta c@teva exemple, pur didactice, care s` explice rolul
interfe]elor. Atunci c@nd ve]i studia programarea vizual` v` ve]i convinge de
importan]a lor.
Exemplul 1. |n multe programe se solicit` citirea unui num`r natural.
Aceasta se poate face prin afi[area unui mesaj, apoi urmeaz` citirea
propriu-zis` a acestuia. Pentru a permite ca programul s` r`m@n` aproape
neschimbat atunci c@nd citim un num`r natural \ntr-un fel sau altul, metoda
care cite[te se va g`si \ntr-o interfa]`, care este implementat` diferit de mai
multe clase. |n acest exemplu interfa]a CitScriu con]ine antetul unei
metode de citire a unui num`r natural. Dou` clase, IO1 [i IO2
implementeaz` aceast` interfa]`. Clasa Suma este \nzestrat` cu un
constructor care are ca parametru o referin]` c`tre obiectul care efectueaz`
citirea [i o metod`, afis(), care cite[te dou` numere naturale [i afi[eaz`
suma lor. Rula]i programul [i prin crearea obiectului Suma, cu ajutorul
instruc]iunii: Suma s=new Suma (new IO2());.
interface CitScriu {
int citeste();}
class IO1 implements CitScriu {
public int citeste()
{ System.out.print("Introduceti valoarea ");
return Integer.parseInt(cin.Token());
}
}
Capitolul 7. Noţiuni avansate de programare orientată pe obiecte 159

class IO2 implements CitScriu {


public int citeste()
{ System.out.print("Tastati valoarea dorita ");
return Integer.parseInt(cin.Token());}
}
class Suma {
CitScriu x;
Suma(CitScriu x)
{ this.x=x;}
void afis()
{ int n=x.citeste();
n+=x.citeste();
System.out.println("Suma este "+n);}
}
public class test {
public static void main(String[] args) {
Suma s=new Suma (new IO1());
s.afis();
}
}

Exemplul 2. Uneori creatorul unei clase care utilizeaz` metoda (metodele)


unei interfe]e dore[te s` lase utilizatorilor clasei “pl`cerea” de a implementa
respectivele metode. |ntr-un astfel de caz el furnizeaz` fi[ierul compilat al
clasei respective. Iat`, pentru exemplul anterior, cum arat` clasa Suma:
abstract class Suma implements CitScriu{
void afis()
{ int n=citeste();
n+=citeste();
System.out.println("Suma este "+n);}
}
Cel care utilizeaz` clasa respectiv` va scrie un program precum cel
de mai jos:
class SumaM extends Suma implements CitScriu
{ public int citeste() {
System.out.print("v=");
return Integer.parseInt(cin.Token()); }
}
public class test {
public static void main(String[] args) {
SumaM s=new SumaM (); s.afis(); }
}

Exemplul 3. Prin utilizarea interfe]elor se pot transmite metode (func]ii) ca


parametri. |n exemplu, interfa]a Functia con]ine antetul unei func]ii reale de
parametru real, numit` f. Interfa]a poate fi implementat` de mai multe
clase, unde fiecare clas` define[te func]ia f. Clasa Afis con]ine o variabil`
de tip referin]` c`tre interfa]a Functia, numit` ref. Aceast` variabil` este
utilizat` pentru a memora o referin]` c`tre un obiect al uneia din clasele
160 Bazele programării în Java

care implementeaz` interfa]a, deci c`tre func]ia dorit`. Prin urmare, cu


ajutorul clasei Afis se poate calcula func]ia dorit`. |n exemplu, interfa]a a
fost implementat` de dou` clase, care con]in func]ii diferite: Liniara [i
Patratica. Clasa Afis r`m@ne nemodificat`, indiferent de func]ia pe care
o evalueaz`. Compila]i interfa]a Functia [i clasele Liniara, Patratica [i
Afis.
interface Functia
{ double f(double x);}
class Liniara implements Functia
{ public double f(double x) {return 3*x+1;}
}
class Patratica implements Functia
{ public double f(double x) {return x*x;}
}
class Afis {
Functia ref;
Afis(Functia ref)
{ this.ref=ref;}
public double funct(double x)
{ return ref.f(2); }
}
S` presupunem c` un utilizator dore[te s` afi[eze f(1), f(2)... f(10)
pentru func]ia liniar` 3x+1. Atunci el va scrie programul:

public class test{


public static void main(String[] args) {
Afis a =new Afis(new Liniara());
for (int i=1;i<=10;i++) System.out.println (a.funct(i));
}
}

S` presupunem c` utilizatorul dore[te s` afi[eze f(1), f(2)... f(10)


pentru func]ia x2. Atunci el va scrie programul:
public class test{
public static void main(String[] args) {
Afis a =new Afis(new Patratica());
for (int i=1;i<=10;i++) System.out.println (a.funct(i));
}
}


Observa]ie: mai general, prin utilizarea interfe]elor se transmit de fapt
obiecte rezultate din instan]ieri ale claselor care au implementat
respectiva interfa]`.
Exemplul 4. Nu este de neglijat faptul c` \ntr-o interfa]` se pot defini multe
constante. Urm`ri]i exemplul urm`tor \n care am declarat [i “utilizat”
constante pentru zilele s`pt`m@nii:
Capitolul 7. Noţiuni avansate de programare orientată pe obiecte 161

interface Saptamana {
int Luni=1,Marti=2, Miercuri=3,Joi=4,
Vineri=5, Sambata=6, Duminica=7;
}
class Ziua implements Saptamana {
void ceFac()
{ for (int zi=Luni;zi<=Duminica;zi++)
if (zi>=Marti && zi<=Joi)
System.out.println("Ceva munca");
else
System.out.println("Sarbatoare");
}
}
public class test {
public static void main(String[] args) {
Ziua x=new Ziua();
x.ceFac();}
}

|n practic`, constantele joac` un rol extrem de important asigur@nd o


citire u[oar` [i chiar scriere eficient` a programelor. |n programarea vizual`
ve]i \nt@lni o mul]ime de constante pentru culori, alinieri de text, etc.

7.7. Modificatori
Forma general` prin care o clas` este definit` o pute]i observa mai
jos. Tot ce este trecut \ntre paranteze drepte este op]ional.

[<Modificatori clasa>] class <nume clasa> [extends <nume


clasa>] implements [lista interfete]
{ [...] }
Observ`m c`, p@n` acum, nu am prezentat modificatorii de clas`. Ace[tia
sunt: public, abstract [i final [i se folosesc \n aceast` ordine.

1. Modificatorul public. Dac` este trecut acest modificator, atunci clasa


respectiv` poate fi accesat` de orice cod Java care acceseaz` pachetul \n
care se g`se[te acea clasa. Dac` acest modificator este absent, atunci
clasa poate fi accesat` doar din pachetul \n care se g`se[te (revede]i
crearea pachetelor). Clasele publice trebuie scrise \n fi[iere care le poart`
numele [i au extensia .java.
Observa]ie foarte important`. |n cazul \n care, la crearea clasei, nu se
folose[te clauza package (nu se realizeaz` un pachet), se consider`

 c` respectiva clas` face parte dintr-un pachet f`r` nume. Pachetul


f`r` nume este alc`tuit din totalitatea claselor f`r` clauza package
care se g`sesc \ntr-un folder. Din acest motiv, c@t timp am lucrat
numai cu clase aflate \n folder-ul bin, nu a fost nevoie ca acestea
s` con]in` clauza package.
162 Bazele programării în Java

2. abstract - marcheaz` o clas` abstract` (revede]i clasele abstracte). |n


absen]`, se consider` c` respectiva clas` nu este abstract`.
3. Modificatorul final este trecut atunci c@nd nu se dore[te ca respectiva
clas` s` fie extins` (derivat`, mo[tenit`), caz \n care aceast` opera]ie este
interzis`.
|n rest, am \nv`]at faptul c` o clas` poate extinde o singur` clas`, dar
poate implementa mai multe interfe]e (vede]i: extends, implements).

Pentru definirea datelor membru \n Java avem forma general`:

[<Modificatori>] <tip data>


<Nume data membru1>[=valoare]
[Nume data membru2][=valoare]...

Modificatorii sunt:
1. public – data membru poate fi accesat` de oriunde este accesibil`
(deci [i din afara pachetului) [i poate fi mo[tenit`;
2. protected - data membru poate fi accesat` de codul aflat \n acela[i
pachet [i poate fi mo[tenit`;
3. private - data membru poate fi accesat` numai din clasa \n care se
afl` [i nu este mo[tenit` (sau dac` vre]i, este mo[tenit`, dar nu poate fi
accesat` din clasa care o mo[tene[te, ceea ce este acela[i lucru);
4. modificatorul implicit (package) – are efect \n absen]a modificatorilor de
mai sus. Data poate fi accesat` de cod din acela[i pachet [i poate fi
mo[tenit` numai de clase ale aceluia[i pachet;
5. final – data membru este considerat` constant`, deci nu poate fi
modificat`;
6. static - data membru nu este memorat` de fiecare obiect al clasei
respective (modificatorul a mai fost prezentat).

Modificatorii public, protected, private [i cel implicit (package)


se numesc modificatori de acces. Evident, o defin]ie de dat` membru va
con]ine numai unul din cei trei modificatori sau, in absen]a lor, se consider`
c` avem modificatorul implicit.

Pentru declararea unei metode se utilizeaz` forma general`:


[<Modificatori>] <Tip metoda> <Nume> (<lista parametri>)
[throws <TipClasa1>[<TipClasa2>]...]]<metoda>
Modificatorii sunt prezenta]i mai jos, iar clauza throws va fi studiat` \n
capitolul care trateaz` excep]iile.
1. Modificatorii de acces - au aceea[i semnifica]ie ca la datele membru.
Capitolul 7. Noţiuni avansate de programare orientată pe obiecte 163

2. final - specific` faptul c` \ntr-o clas` derivat`, metoda nu poate fi


redefinit`.
3. static - are ca efect faptul c` metoda nu este re]inut` de fiecare
obiect al clasei respective. Acest modificator a fost prezentat.

 Exemple de utilizare a modificatorilor


1. Modificatorii sunt absen]i. Clasa poate fi accesat` din interiorul
pachetului, poate fi derivat`, data membru i poate fi mo[tenit` ca [i
metoda met(). De asemenea, data membru [i metoda pot fi accesate de
date aflate \n acela[i pachet.
class A
{ int i=2;
void met() {System.out.println(“Test”);}
};

2. Clasa test trebuie s` se g`seasc` \n fi[ierul test.java (deoarece este


public`). Pentru ea nu se pot crea subclase (pentru c` are modificatorul
final). Data membru i este static`, adic` nu se reg`se[te \n fiecare obiect
al clasei respective, iar metoda este nestatic`, deci se reg`se[te \n fiecare
obiect al clasei respective.
public final class test
{ static int i=2;
void met() {System.out.println("Test");}
};
|n aceste condi]ii, defini]ia clasei de mai jos este eronat`, chiar dac` se
g`se[te \n acela[i pachet cu clasa test.
class B extends test {}

3. Fie clasele de mai jos:


class A
{ private int i=2;
void met() {System.out.println("Test");}
void metp() {System.out.println(i);}
};
class B extends A
{ void met1() {System.out.println("Test1");}
}
|n aceste condi]ii, dac` \n clasa de mai jos, aflat` \n acela[i pachet,
se \nlocuiesc cele trei puncte cu instruc]iunile urm`toare atunci:
public class test {
public static void main(String[] args) {
A x=new A();
... }
}
164 Bazele programării în Java

a) System.out.println(x.i); - avem eroare, deoarece i are


modificatorul private, deci nu poate fi accesat din afara clasei;

b) x.met(); - se afi[eaz` Test pentru c` metoda nu este privat`;

c) B y=new B(); y.met1(); - se afi[eaz` Test1;

d) B y=new B(); y.met(); - se afi[eaz` Test;

e) x.metp(); - se afi[eaz` 2. De[i i este privat, el este afi[at de


met() care are acces la datele private ale propriei clase.

4. Fie clasa de mai jos. Atunci:


class A
{ final int i=2;
final void met() {System.out.println("Test");}
void metp() {System.out.println(i);}
}

a) Clasa urm`toare, aflat` \n acela[i pachet, este eronat` pentru c` data


membru i este cu modificatorul final, este deci considerat` constant` [i
prin urmare nu i se poate modifica valoarea:

public class test {


public static void main(String[] args) {
A x=new A();
x.i=4;
}
}

b) Clasa urm`toare, aflat` \n acela[i pachet, este eronat` pentru c` extinde


clasa A [i redefine[te o metod` care con]ine modificatorul final:
class B extends A
{ void met() {System.out.println("Test1");}
}

c) Clasa urm`toare, aflat` \n acela[i pachet, este corect` pentru c`, de[i
extinde clasa A, redefine[te o metod` care nu are modificatorul final:
class B extends A
{ void metp() {System.out.println("Test2");}
}
Capitolul 7. Noţiuni avansate de programare orientată pe obiecte 165

Probleme propuse
Testele de la 1 la 4 se refer` la clasele urm`toare. De fiecare dat`,
instruc]iunea (sau setul de instruc]iuni) la care se refer` \ntrebarea va fi
scris` \n locul liniei lips` (punctat`):

class A
{ int x=1;
void met() {System.out.println("Clasa A");}
}
class B extends A
{ int x=2;
void met() {System.out.println("Clasa B");}
}
class C extends B
{ int x=3;
void met() {System.out.println("Clasa C");}
}

public class test {


public static void main(String[] args) {
...
}
}

1. Ce se afi[eaz` \n urma execut`rii secven]ei:


A x=new B();x.met();

a) Clasa A; b) Clasa B; c) Clasa C; d) EROARE.

2. Ce se tip`re[te \n urma execut`rii secven]ei:


A x=new B(); System.out.println(x.x);

a) 1; b) 2; c) 3; d) EROARE.

3. Ce se afi[eaz` \n urma execut`rii secven]ei:


B x=(A)new B(); x.met();

a) Clasa A; b) Clasa B; c) Clasa C; d) EROARE.

4. Ce se tip`re[te \n urma execut`rii secven]ei:


B x=new C(); x.met();

a) Clasa A; b) Clasa B; c) Clasa C; d) EROARE.


166 Bazele programării în Java

5. Ce afi[eaz` programul de mai jos, dac` n citit este 3?


class Unu
{ int a=1;
void afis()
{System.out.println(a); }
}
class Doi extends Unu
{ int a=2;
void afis()
{ System.out.println(a);}
}
class t {
public static void main(String[] args) {
Unu x;
int n=Integer.parseInt(cin.Token());
if (n==1) x=new Unu();
else x=new Doi();
x.afis();
System.out.println(x.a);
}
}

a) 1 1; b) 2 2; c) 1 2; d) 2 1.

6. Utiliz@nd polimorfismul, scrie]i un program care cite[te un num`r natural


n [i dac` este prim, afi[a]i succesorul s`u \n mul]imea numerelor prime,
dac` este impar (f`r` a fi prim) afi[a]i succesorul s`u \n mul]imea
numerelor impare, iar dac` este par, afi[a]I succesorul s`u \n mul]imea
numerelor pare.
Exemple:
n=7 se afi[eaz` 11;
n=21 se afi[eaz` 23;
n=8 se afi[eaz` 10.

Testele 7 [i 8 se refer` la programul urm`tor:


interface Testare {
int k=1; int f();
}
class Test1 implements Testare
{ int k=2;
public int f() {return Testare.k;}
}
class Test2 implements Testare
{ int k=3;
public int f() {return k;}
}
Capitolul 7. Noţiuni avansate de programare orientată pe obiecte 167

public class test {


public static void main(String[] args) {
System.out.print("n=");
int n=Integer.parseInt(cin.Token());
Testare x;
if (n%2==0) x=new Test1();
else x=new Test2();
System.out.println(x.f()+" "+x.k); }
}

7. Ce se afi[eaz` dac` se introduce valoarea 8?


a) 1 2; b) 1 1; c) 3 3; d) 2 1.
8. Ce se tip`re[te dac` se cite[te valoarea 21?
a) 1 3; b) 2 1; c) 3 3; d) 3 1.
9. Fiind date interfa]a de mai jos [i 3 implement`ri ale ei, se cere s` se
scrie un program care afi[eaz` valoarea celor 3 func]ii con]inute de
implement`ri pentru o valoare citit` de la tastatur`:
interface functie {
int f(int x);
}
class f1 implements functie
{ public int f(int x) { return x*x-x; }
}
class f2 implements functie
{ public int f(int x) { return 8*x-1; }
}
class f3 implements functie
{ public int f(int x) { return 3*x*x-x+10; }
}

10. Pentru k valori citite de la tastatur` scrie]i un program care afi[eaz`


valoarea func]iei g(x), definit` mai jos, unde f1, f2, f3 sunt cele de la
problema anterioar`.
g ( x)  max f1 ( x), f 2 ( x) f 3 ( x)

Răspunsuri:
1. b); 2. a); 3. d); 4. c); 5 d);
6. class Numar
{ int nr;
Numar(int nr) { this.nr=nr;}
int valoare () { return nr;}
boolean impar()
{ if (nr%2==1) return true;
else return false;}
168 Bazele programării în Java

boolean prim ()
{ boolean p=true;
for (int i=2;i<=Math.sqrt(nr);i++)
if (nr%i==0) { p=false;
break;}
return p;
}
int succesor() {return nr+1;}
}
class Par extends Numar
{ Par(int nr)
{ super(nr);}
int succesor() { return nr+2;}
}
class Impar extends Numar
{ Impar(int nr)
{ super(nr);}
int succesor() { return nr+2;}
}
class Prim extends Impar
{ Prim(int nr)
{ super(nr);}
int succesor()
{ Numar val=new Numar(nr+2);
while (!val.prim()) val=new Numar(val.succesor());
return val.valoare();
}
}
public class test {
public static void main(String[] args) {
System.out.print("n=");
int n=Integer.parseInt(cin.Token());
Numar x=new Numar(n);
if (x.prim()) x=new Prim(x.valoare());
else
if (x.impar()) x=new Impar(x.valoare());
else x=new Par(x.valoare());
System.out.println(x.succesor());}
}

7. b); 8. d);
9. public class test {
public static void main(String[] args) {
System.out.print("n=");
int n=Integer.parseInt(cin.Token());
functie f=new f1(); System.out.println(funct(f ,n));
f=new f2(); System.out.println(funct(f ,n));
f=new f3(); System.out.println(funct(f ,n));
}
public static int funct(functie ref, int x)
{ return ref.f(x);}
}
CAPITOLUL 8

try {……………}
Excepţii
catch (ER1 ob1) {……………}
[ catch (ER2 ob2) {…………}
catch (ER3 ob3) {…………}
...
catch (ERn obn) {………} ]
[ finally {……………}]

Din cuprins:
Noţiunea de excepţie
Mecanismul de tratare a excepţiilor
Metode de tratare a excepţiilor
Exemple de tratare a excepţiilor
Probleme propuse
170 Bazele programării în Java

8.1. Noţiunea de excepţie


Prin excep]ie vom \n]elege o situa]ie nedorit` \n care poate ajunge un
program \n timpul rul`rii. Exist` nenum`rate exemple de excep]ii:

 se dore[te citirea unui num`r natural, dar din gre[eal`, utilizatorul


introduce un caracter;
 datele introduse pentru diverse c@mpuri nu sunt \n plaja de valori
admis` pentru c@mpul respectiv;
 un vector are n componente (indicii sunt de la 0 la n-1) [i se
\ncearc`, de exemplu, s` se atribuie o valoare componentei de
indice n;
 se \ncearc` deschiderea unui fi[ier inexistent;
 ...

Pentru a rezolva astfel de situa]ii, \n Java exist` un mecanism extrem


de bine pus la punct (mecanism de tratare a excep]iilor).

8.2. Mecanismul de tratare a excepţiilor


Pentru a prezenta acest mecanism vom porni de la un exemplu
extrem de simplu, at@t de simplu \nc@t ar putea fi tratat f`r` probleme [i \n
absen]a acestuia.

Exemplu: s` se citeasc` [i s` se afi[eze un num`r natural 1n5.

Practic, problema se reduce la citirea unui \ntreg [i afi[area lui. Dar,


\n timpul execut`rii, din gre[eal`, se poate introduce o valoare numeric`
care nu este \ntre aceste valori. Cum proced`m, altfel dec@t \n mod clasic?

Privi]i exemplul urm`tor, \n care, dac` num`rul citit este \ntre 1 [i 5,


acesta este afi[at, altfel se afi[eaz` mesajul 1<=n<=5.
class Eroare extends Exception
{ void afis()
{ System.out.println("1<=n<=5"); }
}
class t {
public static int citesc() throws Eroare
{ int n=Integer.parseInt(cin.Token());
if (n>=1 && n<=5) return n;
else throw new Eroare();
}
Capitolul 8. Excepţii 171

public static void main(String[] args) {


try
{ int numar=citesc();
System.out.println(numar);}
catch (Eroare er) {er.afis();}
}
}

a) Clasa Eroare extinde clasa Exception (este obligatoriu s` fie


precizat` aceast` extensie. Ea con]ine o singur` metod`, void afis(),
care are rolul de a afi[a mesajul de eroare.
b) La sf@r[itul antetului metodei int citesc() se g`se[te cuv@ntul cheie
throws, urmat de numele clasei care trateaz` eroarea respectiv`. Prin
aceasta se anun]` c` respectiva metod` poate \ntoarce fie un \ntreg (\n caz
de introducere reu[it` a datelor, fie o referin]` c`tre un obiect al clasei
Eroare (\n caz de introducere nereu[it` a datelor). Iat`, deci, c` \n acest
caz, metodele pot \ntoarce [i date de alt tip dec@t cel dat de tipul metodei !
Acest aspect este esen]ial. Instruc]iunea throw returneaz` referin]a c`tre un
obiect al clasei Eroare.

c) Utilizarea metodei citesc() se face, \n mod obligatoriu, cu ajutorul


instruc]iunii try (\ncearc`). Secven]a unde poate ap`rea excep]ia, se
g`se[te \n instruc]iunea compus` subordonat` lui try (\n exemplu int
numar=citesc()). Dac` citirea reu[e[te, programul \[i \ncheie execu]ia,
altfel, se verific` dac` obiectul \ntors de metod` este de tip Eroare (vezi
clauza catch). |n caz afirmativ, se execut` metoda afis() a acestui
obiect (er este referin]a c`tre obiect).

|n sintez`, putem afirma:


 clauza throws are rolul de a specifica faptul c` o metod` poate
\ntoarce [i referin]e c`tre obiectele altor clase (dac` extind clasa
Exception). Dac` sunt mai multe clase, atunci numele acestora sunt
separate prin virgul`.
 instruc]iunea throw - returneaz` referin]a c`tre unul din obiectele
claselor trecute dup` clauza throws.
 instruc]iunea try are forma general` (ceea ce este trecut \ntre
paranteze drepte este facultativ):
try { secven]a de instruc]iuni care pot conduce c`tre excep]ii }
catch (ER1 ob1) { secven]a care trateaz` excep]ia cu clasa Er1 }
[ catch (ER2 ob2) { secven]a care trateaz` excep]ia cu clasa Er2 }
catch (ER3 ob3) { secven]a care trateaz` excep]ia cu clasa Er2 }
...
catch (ERn obn) { secven]a care trateaz` excep]ia cu clasa Ern } ]
[ finally { secv. se execut` indiferent dac` a fost eroare sau nu}]
172 Bazele programării în Java

Exemplu: extindem, ce-i drept, \n mod artificial exemplul anterior. Pentru


cele dou` excep]ii (n<1 [i n>5) vom utiliza dou` metode diferite aflate \n
clase diferite (Eroare1 [i Eroare2). |n acest caz metodele sunt de tip
constructor, deci corpurile catch sunt vide.
class Eroare1 extends Exception
{ Eroare1() { System.out.println("1<=n");}
}

class Eroare2 extends Exception


{ Eroare2() { System.out.println("n<=5");}
}

class t {
public static int citesc() throws Eroare1,Eroare2
{ int n=Integer.parseInt(cin.Token());
if (n<1) throw new Eroare1();
else
if (n>5) throw new Eroare2();
else return n;
}

public static void main(String[] args) {


try
{ int numar=citesc();
System.out.println(numar);
}
catch (Eroare1 er1) {}
catch (Eroare2 er2) {}
}
}

1. Una dintre ra]iunile existen]ei unui mecanism de tratare a excep]iilor este


dat` de faptul c`, \n anumite cazuri, excep]ia poate fi tratat` \n mod
corespunz`tor, dup` care secven]a se poate relua (f`r` ca programul s`-[i
\ncheie execu]ia). Revenim asupra exemplului dat, \n care se citesc numere
naturale din intervalul [1,5]. Programul urm`tor cite[te [i afi[eaz` un
vector cu 3 astfel de componente. |n momentul \n care s-a introdus un
num`r gre[it citirea se reia. Programul \[i \ncheie execu]ia atunci c@nd au
fost citite toate cele 3 componente ale vectorului.

class Eroare extends Exception


{ void afis()
{ System.out.println("1<=n<=5");}
}
class e {
public static int citesc() throws Eroare
{ int n=Integer.parseInt(cin.Token());
if (n>=1 && n<=5) return n;
else throw new Eroare();
}
Capitolul 8. Excepţii 173

public static void main(String[] args) {


int[] V=new int[3];
for (int i=0;i<3;i++)
try { V[i]=citesc();}
catch (Eroare er) { er.afis(); i--; }
System.out.println("Am citit");
for (int i=0;i<3;i++)
System.out.print(V[i]+" ");
}
}

2. Dac` clasa care trateaz` excep]ia extinde clasa Exception, atunci este
obligatoriu ca apelul metodei ce poate returna o excep]ie s` se fac` \n
construc]ia try, ca \n exemplul anterior, sau metoda care apeleaz` o astfel
de metod` s` con]in` \n antet clauza throws.
Exemplul 1: dac` \n metoda main() de mai sus, am avea V[]=citesc(),
f`r` construc]ia try, atunci am primi eroare de compilare.

Exemplul 2. citesc() poate fi apelat` ca mai jos, unde metoda main()


con]ine clauza throws. Oricum, \n acest caz, dac` num`rul nu este \n
intervalul [1.5] excep]ia este tratat` printr-un mesaj implicit, \n care se
precizeaz` numele clasei c`reia \i apar]ine obiectul returnat.
public static void main(String[] args) throws Eroare{
System.out.println(citesc());}

Clasa Exception con]ine (printre altele):


 un constructor implicit (f`r` parametru): Exception();
 un constructor cu parametru de tip String: Exception(String
mes);
 o metod` care returneaz` mesajul mes, primit de constructor:
String getMessage().
Exemplu: |n aceste condi]ii, programul din exemplul anterior poate fi scris [i
ca mai jos (mai simplu):
class e {
public static int citesc() throws Exception
{ int n=Integer.parseInt(cin.Token());
if (n>=1 && n<=5) return n;
else throw new Exception("1<=n<=5");
}
public static void main(String[] args) {
int[] V=new int[3];
for (int i=0;i<3;i++)
try { V[i]=citesc();}
catch (Exception er) {i--; System.out.println(er.getMessage());}
System.out.println("Am citit");
for (int i=0;i<3;i++)
System.out.print(V[i]+" "); }
}
174 Bazele programării în Java

Uneori, este deranjant faptul c` instruc]iunea capabil` s` produc` o


excep]ie trebuie pus` automat sub try, iar clasa c`reia \i apar]ine trebuie
s` con]in` clauza throws. Mai mult, chiar \n Java exist` metode care pot
produce excep]ii, dar care pot fi folosite f`r` try. De exemplu, metoda
parseInt a clasei Integer. Privi]i programul urm`tor, \n care dac` [irul
de caractere introdus poate fi convertit c`tre un \ntreg se afi[eaz` num`rul,
altfel programul se termin` cu excep]ie. {i toate acestea f`r` try...
class e {
public static void main(String[] args) {
int n=Integer.parseInt(cin.linie());
}
}

S` analiz`m antetul complet al metodei parseInt:


public static int parseInt(String s)
throws NumberFormatException

Observ`m faptul c`, \n cazul \n care apare o excep]ie, se apeleaz` la


clasa NumberFormatException. De aici, putem deduce o prim` observa]ie:
dac` dorim ca programul nostru s` furnizeze un mesaj \n caz de excep]ie,
putem proceda ca mai jos, adic` s` folosim construc]ia try, [i \n caz c`
se returneaz` un obiect al clasei NumberFormatException, s` afi[`m un
mesaj de eroare l`muritor.
class e {
public static void main(String[] args) {
System.out.print("n="); int n=1;
try
{ n=Integer.parseInt(cin.Token());}
catch (NumberFormatException e) {System.out.println ("Valoare
nenumerica");}
System.out.println(n);
}
}
Mai mult, citirea se poate efectua p@n` c@nd valoarea introdus` este
corect`, ca \n programul urm`tor:
class e {
public static void main(String[] args) {
int i=1, n=1;
while (i==1)
{ System.out.print("n=");
try
{ n=Integer.parseInt(cin.Token()); i=0;}
catch (NumberFormatException e)
{ System.out.println ("Valoare nenumerica");}
}
System.out.println(n);
}
}
Capitolul 8. Excepţii 175

 Dac` \n secven]a subordonat` lui try se depisteaz` o excep]ie, se


abandoneaz` executarea tuturor instruc]iunilor. |n exemplu, aceasta
implic` faptul c` i r`m@ne 1, deci se reia secven]a subordonat` lui
while. Dac` nu a ap`rut excep]ia, i devine 0 [i prin urmare,
executarea lui while este considerat` \ncheiat`.

 Dac` nu l-am fi declarat de la \nceput pe n cu valoare ini]ial`,


oricare ar fi ea, programul ar fi semnalat eroare la compilare, pentru
c` se ajunge la afi[area lui. Ori, \n Java, nu este permis` afi[area
con]inutului unei variabile neini]ializate.

Totu[i, nu se rezolv` problema pus`: cum este posibil ca parseInt


s` poat` fi folosit` f`r` construc]ia try?

Obiectele claselor care extind clasa RuntimeException sau Error


pot fi apelate f`r` ca antetul lor s` con]in` clauza throws, ca mai jos:

class Eroare extends RuntimeException


{ void afis()
{ System.out.println("1<=n<=5");}
}
class e {
public static int citesc() // fara throws
{ int n=Integer.parseInt(cin.Token());
if (n>=1 && n<=5) return n;
else throw new Eroare();
}
public static void main(String[] args) {
...
}
}

Pot exista urm`toarele cazuri:


a) Dac` \n main() avem secven]a de mai jos, atunci distingem dou`
cazuri:
int numar=citesc();
a1) Se introduce un num`r \ntre 1 [i 5 - programul nu genereaz`
excep]ie [i totul este OK!
a2) Se introduce un num`r \n afara intervalului. Va fi afi[at` o excep]ie
\ntr-un format implicit [i nu se va afi[a mesajul "1<=n<=5".
b) Dac` \n main() avem secven]a:
try
{ int numar=citesc();
System.out.println(numar);
}
catch (Eroare er) { er.afis();}
176 Bazele programării în Java

b1) Se introduce un num`r \ntre 1 [i 5 - programul nu genereaz`


excep]ie [i totul este OK!

b2) Se introduce un num`r \n afara intervalului. Va fi afi[at` excep]ia cu


mesajul "1<=n<=5".

8.3. Metodele care pot returna, în caz de excepţii,


obiecte ale unor alte clase
Privi]i antetul metodei parseInt a clasei Integer. Din considerente
didactice, p@n` acum antetul nu a fost prezentat integral. |n cazul \n care
se \nt@lne[te o excep]ie, se returneaz` un obiect al clasei
NumberFormatException:

public static int parseInt(String s)


throws NumberFormatException

Aceasta poate ajuta programatorul s` “gestioneze” situa]ia, ca \n


exemplul de mai jos, unde se cite[te o variabil` \ntreag` care este afi[at`.
|n cazul \n care valoarea introdus` nu este corect`, se reia citirea.

class e {
public static void main(String[] args) {
int i=0;
while (i==0)
try
{ int numar=Integer.parseInt(cin.Token());
System.out.println(numar);
i=1;
}
catch (NumberFormatException e)
{ System.out.println("Numar eronat");}
}
}

Iat` si antetul complet al metodelor parseFloat [i parseDouble:

1. public static double parseDouble(String s)


throws NumberFormatException

2. public static float parseFloat(String s)


throws NumberFormatException

 |n cazul \mp`r]irii la 0 pentru tipuri \ntregi, se returneaz` un obiect al


clasei ArithmeticException. Vede]i exemplul urm`tor:
Capitolul 8. Excepţii 177

class t {
public static void main(String[] args) {
System.out.print("n="); int n=Integer.parseInt(cin.Token());
System.out.print("m=");
int m=Integer.parseInt(cin.Token());
try { System.out.println(n/m);}
catch (ArithmeticException e)
{ System.out.println ("Impartire la 0 ");}
}
}

|n cazul \n care se \ncearc` s` se atribuie o valoare unei componente


inexistente a unui vector, se returneaz` pentru tipuri \ntregi un obiect al
clasei ArrayIndexOutOfBoundsException. Vede]i exemplul urm`tor:
class t {
public static void main(String[] args) {
int []v=new int[3];
System.out.print("indice=");
int indice=Integer.parseInt(cin.Token());
try { v[indice]=1;}
catch (ArrayIndexOutOfBoundsException e)
{ System.out.println ("Eroare indice");}
}
}

 Observa]ie foarte important`


Clasele ArrayIndexOutOfBoundsException, ArithmeticException ca
[i multe altele de acest tip, sunt rezultate \n urma unor deriv`ri ale clasei
Exception. Cum un parametru de tip referin]` c`tre un obiect al
superclasei poate re]ine referin]e c`tre obiectele subclaselor sale, atunci
putem scrie clauza catch de forma:

catch (Exception e) {...}

8.4. Exemple de tratare a excepţiilor


1. Validare pentru numere reale. S` se scrie un program care cite[te n,
num`r natural [i n numere reale. Se cere s` se calculeze suma numerelor
citite. Dac` un num`r real se introduce gre[it (nu respect` formatul de
num`r real) se reia citirea lui.
Rezolvare. Metoda parseDouble, a clasei Double, returneaz` fie un num`r
de format double, fie un obiect al clasei NumberFormatException.

class e {
public static void main(String[] args) {
double s=0;
System.out.print("n=");
int n=Integer.parseInt(cin.Token());
178 Bazele programării în Java

for (int i=0;i<n;i++)


try { double x=Double.parseDouble(cin.Token());s+=x;}
catch (NumberFormatException e)
{ System.out.println("Numar eronat");i--;}
System.out.println("S="+s);
}
}

2. Validare alfabetic`. Se cite[te un [ir de caractere alc`tuit din mai multe


cuvinte separate prin blank-uri. Dac` [irul citit con]ine numai literele
alfabetului (mici sau mari) sau blank-uri, acesta se va afi[a, altfel se va
tip`ri mesajul sir nealfabetic.

Rezolvare. Metoda citSir() cite[te [irul [i \l valideaz`. Dac` [irul este


valid, el este returnat, altfel se returneaz` un obiect al clasei Nealfabetic.
|n main() se testeaz` dac` a fost retrunat [irul (try), caz \n care acesta
este afi[at, sau a fost returnat un obiect al clasei Nealfabetic, caz \n
care se afi[eaz` mesajul de eroare sir nealfabetic prin utilizarea
metodei mesaj() a obiectului.
class Nealfabetic extends RuntimeException {
String mesaj()
{ return "sir nealfabetic"; }
}
class e {
static String citSir()
{ String sir=new String(cin.linie());
boolean gasit=false;
for (int i=0;i<sir.length();i++)
if ( (sir.charAt(i)<'A' || sir.charAt(i)>'Z') &&
(sir.charAt(i)<'a' || sir.charAt(i)>'z') &&
sir.charAt(i)!=' ') gasit=true;
if (gasit) throw new Nealfabetic();
else return sir;
}
public static void main(String[] args) {
boolean corect=false;
System.out.print("Tastati sirul ");
String s="";
try { s=citSir(); System.out.println(s);}
catch (Nealfabetic e) { System.out.println(e.mesaj());}
}
}

Probleme propuse
1. Se citesc n, num`r natural [i n numere reale. Se cere s` se afi[eze
suma numerelor citite. Pentru citirea numerelor, programul va utiliza
mecanismul excep]iilor (\n caz de introducere gre[it` a datelor - care nu
corespund formatului de num`r real, se va afi[a un mesaj corespunz`tor [i
se va relua citirea numerelor).
Capitolul 8. Excepţii 179

2. La fel ca mai sus numai c` cele n numere citite trebuie s` fie mai mici
dec@t 10. De asemenea, se va folosi mecanismul excep]iilor at@t pentru
formatul real, c@t [i pentru valorile admise.
3. Scrie]i un program care cite[te dou` numere reale a [i b [i afi[eaz`
rezultatul \mp`r]irii lui a la b. Dac` ambele numere sunt 0, se va afi[a un
mesaj l`muritor, dac` numai b este 0, se va tip`ri alt mesaj l`muritor, iar
dac` \mp`r]irea se poate face, se va afi[a rezultatul \mp`r]irii. Evident,
programul va utiliza mecanismul excep]iilor [i metode ale claselor
\nf`[ur`toare (de rev`zut).
4. La fel ca mai sus numai c` se vor utiliza excep]iile [i la citirea
numerelor a [i b, iar \n caz c` \mp`r]irea nu se poate efectua se va
repeta citirea numerelor a [i b.

Rezolvări:
1.
class test {
public static void main(String[] args) {
int n=1; double nr=0; int semnal=0;
// citesc pe n
while (semnal==0)
{ try
{ System.out.print("n=");
n=Integer.parseInt(cin.Token()); semnal=1;}
catch (Exception e) {System.out.println("Eroare la introducerea
lui n");}
}
// citesc cele n numere
double s=0;
for (int i=0;i<n;i++)
{ nr=0;
try
{ System.out.print("valoarea este=");
nr=Double.parseDouble(cin.Token());}
catch (Exception e) { System.out.println ("Valoare
nenumerica"); i--;}
s+=nr;}
System.out.println("Suma="+s);
}
}

2. class Er1 extends Exception {


void afis(){System.out.println ("valoarea trebuie sa fie mai
mica decat 10");}
}

class Er2 extends Exception {


void afis(){ System.out.println ("valoarea trebuie sa fie
numerica");}
}
180 Bazele programării în Java

class test {
public static void main(String[] args) {
int n=1; double nr=0; int semnal=0;
// citesc pe n
while (semnal==0)
{ try
{ System.out.print("n=");
n=Integer.parseInt(cin.Token()); semnal=1;}
catch (Exception e) {System.out.println("Eroare la introducerea
lui n");}
}
// citesc cele n numere
double s=0;
for (int i=0;i<n;i++)
{ nr=0;
try { nr=citesc();}
catch (Er1 e) { e.afis(); i--;}
catch (Er2 e) { e.afis(); i--;}
s+=nr;}
System.out.println("Suma="+s);
}
public static double citesc() throws Er1,Er2
{ double n=0;
try { n=Double.parseDouble(cin.Token());}
catch (Exception e) { throw new Er2();}
if (n>10) throw new Er1();
else return n;
}
}

3.
class Er1 extends Exception {
void afis() { System.out.println ("Impartire la 0");}
}
class Er2 extends Exception {
void afis() { System.out.println ("ambii operanzi sunt 0");}
}
class test {
public static void main(String[] args) {
double s=0;
System.out.print("a=");double a=Double.parseDouble(cin.Token());
System.out.print("b=");double b=Double.parseDouble(cin.Token());
try {double z=divide(a,b); System.out.println(z);}
catch (Er1 e) { e.afis();}
catch (Er2 e) { e.afis();}
}
static double divide (double a, double b) throws Er1,Er2
{ if (Double.isNaN(a/b)) throw new Er2();
else
if (Double.isInfinite (a/b)) throw new Er1();
else return a/b;
}
}
CAPITOLUL 9

Alte clase esenţiale în Java

Din cuprins:
Clasa Vector
Fişiere
Fire de execuţie
Probleme propuse
182 Bazele programării în Java

9.1. Clasa Vector


Clasa Vector ofer` posibilitatea lucrului cu o structur` asem`n`toare
vectorului, dar \n plus, ofer` posibilitatea ad`ug`rii sau [tergerii unor
elemente \n interiorul vectorului. Clasa Vector se g`se[te \n pachetul
java.util. Astfel, structura seam`n` mult cu o list` liniar` simplu
\nl`n]uit`. Idei de baz`:

 Elementele vectorului sunt referin]e c`tre obiecte, de orice tip dorim.


Aten]ie, am spus referin]e c`tre obiecte [i nu tipuri primitive. Pentru tipurile
primitive exist` acele clase \nf`[ur`toare, pe care v` sf`tuiesc s` le
revede]i.

 La baza ierarhiei arborescente a claselor din Java se g`se[te clasa


Object. Aceasta \nseamn` c` o variabil` de tip referin]` c`tre un obiect al
clasei Object poate re]ine orice referin]` c`tre un obiect al unei clase
descendente. Prin urmare, un element al “vectorului” poate re]ine o referin]`
c`tre orice alt tip de obiect. De aici rezult` faptul c` printr-un obiect al
clasei Vector se pot manipula obiecte de orice tip.

Principalele metode ale clasei Vector sunt:

 Vector() - constructor ce creeaz` un vector f`r` nici un element


(vector vid).

 void addElement (Object O); - adaug` la sf@r[itul vectorului un


element care re]ine o referin]` c`tre un anumit obiect.

 Object elementAt(i) - returnaz` referin]a c`tre obiectul re]inut de


componenta de indice i a vectorului.

 Object firstElement() - returneaz` referin]a c`tre primul element


al vectorului.

 Object lastElement() - returneaz` referin]a c`tre ultimul element al


vectorului.

 int size() - returneaz` num`rul de componente ale vectorului.

 void insertElementAt(Object O, int i) - insereaz` un obiect


\n vector pe pozi]ia i. Celelalte elemente ale vectorului sunt deplasate c`tre
dreapta cu o pozi]ie. Pozi]ia i trebuie s` fie cuprins` \ntre 0 [i size()-1.

 void removeElementAt(int i) - [terge un element al vectorului


aflat pe pozi]ia i. Celelalte elemente ale vectorului sunt deplasate c`tre
st@nga cu o pozi]ie. Pozi]ia i trebuie s` fie cuprins` \ntre 0 [i size()-1.
Capitolul 9. Alte clase esenţiale în Java 183

 setElementAt(Object O,int i) - seteaz` componenta de indice


i s` re]in` o referin]` c`tre un nou obiect. Vechiul obiect a c`rui pozi]ie
era re]inut` de componenta i se pierde. Pozi]ia i trebuie s` fie cuprins`
\ntre 0 [i size()-1.
 void removeAllElements() - [terge toate elementele vectorului.
 void removeElement(Object O) - [terge componenta care are
ca referin]` un obiect identic cu cel transmis prin parametru. Toate celelalte
componente ale vectorului sunt deplasate c`tre st@nga.
 int indexOf(Object O) – \ntoarce indicele primei apari]ii a
obiectului \n vector.
Exemplu: \n programul urm`tor se citesc [i se afi[eaz` n numere naturale.
Cele n numere naturale sunt re]inute de un obiect al clasei Vector.
import java.util.*;
class t {
public static void main(String[] args) {
Vector v=new Vector();
System.out.print("n="); int n=Integer.parseInt(cin.Token());
for (int i=0;i<n;i++)
{ System.out.print("V["+i+"]=");
int valoare=Integer.parseInt(cin.Token());
v.addElement(new Integer(valoare)); }
for (int i=0;i<n;i++)
{ Integer val=(Integer)v.elementAt(i);
System.out.println(val.intValue());}
}
}

 Observa]ii asupra programului:


a) Elementele vectorului sunt referin]e c`tre obiecte ale clasei Integer.
Fiecare obiect al clasei Integer re]ine un num`r citit.
int valoare=Integer.parseInt(cin.Token());
v.addElement(new Integer(valoare));

b) La citire se returneaz` referin]a c`tre obiectul de tip Integer.


Deoarece, de fapt, un element al vectorului re]ine o referin]` c`tre un obiect
de tip Object, referin]a este convertit` c`tre referin]` c`tre Integer.
Integer val=(Integer)v.elementAt(i);

 Pentru a afi[a num`rul citit, se utilizeaz` metoda intValue() a clasei


Integer, metod` care returneaz` valoarea re]inut` de obiect.
System.out.println(val.intValue());

 Liniile de la observa]iile 3 [i 4 pot fi \nlocuite cu linia de mai jos:


System.out.println(((Integer)v.elementAt(i)).intValue());
184 Bazele programării în Java

9.2. Fişiere

9.2.1. Noţiunea de flux


|n Java, fi[ierele sunt abordate pornind de la no]iunea de flux. Prin
flux vom \n]elege o cale pe care o urmeaz` datele pentru a ajunge de la
surs` la destina]ie. Putem imagina un flux ca o [osea pe care circul`
ma[ini. Astfel, \n Java, datele ar fi ma[inile care circul` pe [osea.
Exist` dou` tipuri de fluxuri:
A) Fluxuri de intrare - de la
surs` (un fi[ier), c`tre destina]ie fi[ier program
(programul), unde datele sunt Sursa Destinatie
prelucrate.

B) Fluxuri de ie[ire - de la
program fi[ier
surs`, (programul), c`tre destina]ie
(fi[ier), unde se re]in rezulatatele.. Sursa Destinatie

 Clasele pe care le studiem \n acest paragraf se g`sesc \n


pachetul java.IO.

9.2.2. Fluxuri de octeţi


|n acest caz, datele sunt date de octe]i.

A) Fluxurile de intrare sunt tratate de clasa FileInputStream. Sursa


este dat` de un fi[ier, iar destina]ia este memoria. Principalele metode ale
clasei FileInputStream sunt:

1. Constructorul - are rolul de a deschide fi[ierul al c`rui nume este dat de


parametrul de tip String. |n cazul \n care fi[ierul nu este g`sit (excep]ie),
se returneaz` un obiect al clasei FileNotFoundException.
public FileInputStream(String nume)
throws FileNotFoundException

2. Citirea unui octet se realizeaz` cu metoda read():


public int read()
throws IOException

3. |nchiderea fi[ierului se realizeaz` cu metoda close():


public void close()
throws IOException
Capitolul 9. Alte clase esenţiale în Java 185

 Observa]ii:

 Clasa IOException este o subclas` a clasei Exception. Prin


urmare, orice metod` care apeleaz` o alt` metod` care poate returna
un obiect al acestei clase trebuie s` aib` \n antet clauza throws sau
apelul s` fie f`cut sub try (vezi excep]ii).
 Numele fi[ierului poate con]ine [i calea c`tre el. Aceasta trebuie pus`
\n cazul \n care programul nu se g`se[te \n acela[i folder cu fi[ierul.

Exemple:

1. Crea]i \n Notepad un fi[ier text oarecare, s`-l numim in.txt. El va


con]ine un text oarecare, scris pe mai multe linii. Scrie]i un program care
afi[eaz` con]inutul fi[ierului.
import java.io.*;
public class f {
public static void main (String[ ] args) throws IOException {
FileInputStream f=new FileInputStream("in.txt");
int ch=0;
while ((ch=f.read())!=-1) System.out.print((char)ch);
}
}

 Sf@r[itul unui fi[ier se detecteaz` prin faptul c` ultimul octet


re]ine -1.
2. Programul urm`tor are acela[i efect ca [i cel precedent, dar fi[ierul de
intrare se g`se[te pe C:\, iar \n cazul \n care fi[ierul nu este g`sit, se
afi[eaz` un mesaj corespunz`tor:
import java.io.*;
public class f {
public static void main (String[ ] args)
{
try { FileInputStream f=new FileInputStream("C:\\in.txt");
int ch=0;
while ((ch=f.read())!=-1) System.out.print((char)ch); }
catch (IOException e) {System.out.println("Fisier negasit"); }
}
}

B) Fluxurile de ie[ire sunt tratate de clasa FileOutputStream. Sursa


este dat` de o variabil` de tip int a programului, iar destina]ia este un
fi[ier. Principalele metode ale clasei FileOutputStream sunt:

1. Constructorul - are rolul de a deschide fi[ierul al c`rui nume este dat de


parametrul de tip String [i de a-l preg`ti pentru scriere:
public FileOutputStream(String name)
throws FileNotFoundException
186 Bazele programării în Java

2. Scrierea unui octet se realizeaz` cu metoda write():

public void write(int b)


throws IOException

3. |nchiderea fi[ierului se realizeaz` cu metoda close():

public void close()


throws IOException

Exemplu: programul de mai jos copiaz` fi[ierul in.txt. Fi[ierul rezultat \n


urma copierii se nume[te out.txt [i se g`se[te \n acela[i folder cu sursa.
import java.io.*;
public class f {
public static void main (String[ ] args) throws IOException {
FileInputStream f=new FileInputStream("javac.exe");
FileOutputStream g=new FileOutputStream("javac1.exe");
int ch=0;
while ((ch=f.read())!=-1) g.write(ch);
f.close();
g.close();
}
}

 Observa]ii:

 Deschide]i fi[ierul astfel ob]inut cu Notepad. Ve]i observa c` nu


exist` nici o modificare fa]` de precedentul.
 Cu acest procedeu se pot copia [i executabilele. Testa]i. Copia]i un
executabil [i apoi, fi[ierul astfel ob]inut \l lansa]i \n executare. Evident,
noul fi[ier trebuie s` aib` extensia .exe.

9.2.3. Fluxuri de caractere


Vom utiliza fluxuri de caractere pentru a lucra cu fi[iere text. Acestea
pot con]ine una sau mai multe linii.

A) Fluxuri de intrare - se folosesc pentru citirea fi[ierelor text.

Pentru a transforma un flux de octe]i \ntr-un flux de caractere, vom utiliza


constructorul clasei InputStreamReader (care extinde clasa Reader):

 public InputStreamReader(InputStream in)

|ntruc@t clasa FileInputStream extinde clasa InputStream, parametrul


in (de tip InputSTream) poate fi o referin]` c`tre un obiect al clasei
FileInputStream.
Capitolul 9. Alte clase esenţiale în Java 187

Pentru a putea lucra cu u[urin]` cu caracterele, vom utiliza clasa


BufferedReader care permite ata[area fluxului de caractere a unei
memorii, numit` buffer. Practic, buffer-ul permite memorarea mai multor
caractere citite, care urmeaz` s` fie prelucrate. Constructorul clasei
BufferedReader este:

 public BufferedReader(Reader in1)

|ntruc@t clasa InputStreamReader extinde clasa Reader, parametrul in1


poate fi o referin]` c`tre un obiect al clasei InputStreamReader.

Clasa BufferedReader con]ine metoda readLIne() care cite[te din fi[ier


(flux) o \ntreag` linie de caractere:

 public String readLine()


throws IOException

Acestea fiind spuse, pute]i analiza programul de mai jos care afi[eaz`
toate liniile unui fi[ier text. De exemplu, dac` crea]i cu Notepad un fi[ier
cu mai multe linii, numit in.txt, programul \l afi[eaz`:

import java.io.*;
public class f {
public static void main (String[ ] args) throws IOException
{ FileInputStream f=new FileInputStream("in.txt");
InputStreamReader fchar=new InputStreamReader (f);
BufferedReader buf = new BufferedReader(fchar);
String linie;
while ((linie=buf.readLine() )!=null) System.out.println(linie);
fchar.close();
}
}

B) Fluxuri de ie[ire - se folosesc pentru scrierea fi[ierelor text.

Clasa FileOutputStream creeaz` un flux de ie[ire c`tre un fi[ier al c`rui


nume este transmis ca parametru. Ea extinde clasa OutputStream [i are
constructorul:

public FileOutputStream(String nume)


throws FileNotFoundException

Clasa PrintStream con]ine mai multe metode print [i println care


func]ioneaz` exact ca System.out.print() [i System.out.print().
Practic, valoarea care este scris` \n fi[ier este mai \nt@i convertit` c`tre
tipul String, a[a cum suntem deja obi[nui]i. Clasa este \nzestrat` cu
constructorul:

public PrintStream(OutputStream out)


188 Bazele programării în Java

Exemplu: programul de mai jos creeaz` un fi[ier text (numit out.txt) care
con]ine 3 linii, iar fiecare linie con]ine c@te un [ir de caractere:

import java.io.*;
public class f {
public static void main (String[ ] args) throws IOException
{ FileOutputStream f=new FileOutputStream("out.txt");
PrintStream fchar=new PrintStream (f);
fchar.println("O linie");
fchar.println("Alta linie");
fchar.print("A treia linie");
fchar.close();
}
}

9.2.4. Intrări de la tastatură


Pentru a gestiona intr`rile de la tastatur`, \n program se utilizeaz`
constanta de tip in a clasei System. Practic, ea re]ine referin]a c`tre fluxul
de intrare de la tastatur` (acesta din urm` este de tipul InputStream).

public static final InputStream in

Cel mai bun exemplu de utilizare a acestei clase este dat de metoda
linie() a clasei cin (cea pe care am folosit-o de at@tea ori p@n` acum).
import java.io.*;
import java.util.*;
class cin {
static InputStreamReader f = new InputStreamReader (System.in);
static BufferedReader tamp=new BufferedReader(f);
static String linie() {
try { return tamp.readLine();}
catch (IOException e) { return ("Eroare");}
}
static String Token(){
StringTokenizer v=new StringTokenizer(linie());
if (v.hasMoreTokens())return v.nextToken();
else return"";
}
}

9.3. Fire de execuţie


A]i observat, probabil, c` \n anumite programe apar mai multe cadre
\n care se afi[eaz` anumite anima]ii. V` da]i seama c` fiecare anima]ie
trebuie executat` separat. Imagina]i-v` c` un program con]ine, s` zicem, 6
astfel de anima]ii. Aparent, fiecare dintre ele se execut` independent. Cum
a fost scris acel program?
Capitolul 9. Alte clase esenţiale în Java 189

Dac` acel program a fost scris \n Java, atunci s-au utilizat firele de
execu]ie. Practic, un fir de execu]ie \nseamn` o secven]` de instruc]iuni.
Procesorul \[i \mparte timpul pentru a executa o parte dintr-un fir de
execu]ie, apoi o parte din alt fir de execu]ie, [.a.m.d. Mai mult, de c@te ori
el trebuie s` intre \n a[teptare pentru un fir de execu]ie (de exemplu, se
a[teapt` introducerea unei date), reia executarea altui fir de execu]ie,
[.a.m.d. V` da]i seama c` un astfel de mecanism este extrem de complex,
dar \n Java se poate folosi cu u[urin]` pentru c` acesta este foarte bine
pus la punct. Ce trebuie s` [tim pentru a crea fire de execu]ie?
1. Un fir de execu]ie este un obiect al unei clase care extinde
(mo[tene[te) clasa Thread.
2. Secven]a de instruc]iuni a acestui fir de execu]ie este con]inut` de
metoda run() a clasei.
3. Un fir de execu]ie se lanseaz` utiliz@nd metoda start() a clasei din
instan]ierea c`reia a rezultat firul de execu]ie respectiv. Evident, metoda
start() este mo[tenit` din clasa Thread.
4. Un fir de execu]ie poate fi pus \n a[teptare prin utilizarea metodei
sleep(long m), metod` mo[tenit` de la clasa Thread. Ea poate genera o
excep]ie, a[a c` trebuie pus` sub construc]ia try. Evident, \n acest timp,
procesorul poate relua executarea unui alt fir de execu]ie. Timpul este dat
\n milisecunde.
Exemple:
1. Programul urm`tor con]ine un fir de execu]ie, care incrementeaz`
valoarea unei variabile (date membru) apoi o afi[eaz`, dup` care st` \n
a[teptare o secund`, [.a.m.d., p@n` c@nd valoarea variabilei devine mai
mare dec@t 10:
class Fir extends Thread {
int i=0;
public void run()
{ while (i!=10)
{ i++;
System.out.println("i="+i);
try { sleep(1000);}
catch (Exception e) {}
}
}
}
public class pv {
public static void main(String args[]) {
Fir x=new Fir();
x.start();
}
}
190 Bazele programării în Java

2. Programul urm`tor con]ine dou` fire de execu]ie. Fiecare dintre ele


afi[eaz` valoarea unei variabile locale. Se va afi[a i=1, j=1, i=2, j=2,
[.a.m.d. Observa]i puterea firelor de execu]ie. Practic, c@nd un fir de
execu]ie este \ntrerupt, se salveaz` valoarea variabilelor locale [i se
memoreaz` punctul \n care firul a fost \ntrerupt.
class Fir extends Thread {
public void run()
{ int i=0;
while (i!=10)
{ i++;
System.out.println("i="+i);}
}
}
class AltFir extends Thread {
public void run()
{ int j=0;
while (j!=10)
{ j++;
System.out.println("j="+j);}
}
}
public class pv {
public static void main(String args[]) {
Fir x=new Fir();
AltFir y=new AltFir();
x.start();
y.start();
}
}

Probleme propuse
1. Implementa]i o stiv` prin utilizarea clasei Vector. Avantajul acestei
implement`ri este evident: se poate utiliza stiva pentru a re]ine orice tip de
obiect.

2. Memora]i \n stiva astfel ob]inut` 3 numere \ntregi [i afi[a]i-le \n ordinea


extragerii.

3. Memora]i \n stiva astfel ob]inut` n [iruri de caractere citite de la


tastatur` [i afi[a]i-le \n ordinea extragerii.

4. Crea]i o \nregistrare care re]ine pentru o persoan` numele [i vârsta.


Citi]i datele pentru n astfel de persoane, ad`uga]i-le \n stiv` [i afi[a]i-le \n
ordinea extragerii.
5. Implementa]i o coad` prin utilizarea clasei Vector.
Capitolul 9. Alte clase esenţiale în Java 191

6. Reface]i problemele de la 2 la 4 prin utilizarea structurii de tip coad`.


7. Fi[ierul text numere.in con]ine pe prima linie mai multe numere
naturale. Care este suma lor?
8. Fi[ierul text numere.in con]ine pe prima linie mai multe numere
naturale, dar [i alte [iruri de caractere. Numerele sunt separate prin spa]ii
de celelalte [iruri de caractere (vezi exemplul de mai jos). Care este suma
lor?
Exemplu: 1 asf 12 JKHS 17 aha 10 ngsvss 5 se afi[eaz` 45.
9. Reface]i programul de la problema 9, astfel \nc@t numele fi[ierului s` fie
preluat de linia de comand` din fereastra CMD.

Indicaţii / rezolvări:

1.
import java.util.*;
class Stiva {
Vector st=new Vector();
void push(Object x)
{ st.addElement (x);}
Object pop ()
{ if (st.size()>0)
{ Object retur=st.lastElement();
st.removeElementAt(st.size()-1);
return retur;
}
else return null;
}
}

2.
class test {
public static void main(String[] args) {
Stiva st=new Stiva();
st.push(new Integer (1));
st.push(new Integer (2));
st.push(new Integer (3));
Integer numar;
do
{ numar=(Integer)st.pop();
if (numar!=null)
System.out.println(numar.intValue());
} while (numar!=null);
}
}
192 Bazele programării în Java

7.
import java.io.*;
import java.util.*;
public class test {
public static void main (String[ ] args) throws IOException
{ FileInputStream f=new FileInputStream("numere.in");
InputStreamReader fchar=new InputStreamReader (f);
BufferedReader buf = new BufferedReader(fchar);
String linie=buf.readLine();
StringTokenizer t=new StringTokenizer(linie);
int s=0;
while (t.hasMoreTokens())
s+=Integer.parseInt(t.nextToken());
System.out.println(s);
fchar.close();
}
}

8.
import java.io.*;
import java.util.*;
public class test {
public static void main (String[ ] args) throws IOException
{ FileInputStream f=new FileInputStream("numere.in");
InputStreamReader fchar=new InputStreamReader (f);
BufferedReader buf = new BufferedReader(fchar);
String linie=buf.readLine();
StringTokenizer t=new StringTokenizer(linie);
int s=0;
int nr;
while (t.hasMoreTokens())
try { nr=Integer.parseInt(t.nextToken()); s+=nr;}
catch (Exception e) {}
System.out.println(s);
fchar.close();
}
}

9.
...
public static void main (String[ ] args) throws IOException
{ if (args.length==0)
System.out.println ("Fisierul?");
else
{ String nume_f=args[0];
FileInputStream f=new FileInputStream(nume_f);
...
CAPITOLUL 10

Iniţiere în programarea vizuală

Din cuprins:
Prima fereastră
Mecanismul prin care se ataşează componente
ferestrei. Clasa Container
Clasele JComponent şi ToolKit
Poziţionarea componentelor
Studiul principalelor componente
Mai mult despre clasa Container
Cutii de dialog
Clasele Graphics şi Graphics2D
Evenimente
Animarea imaginilor
Probleme propuse
194 Bazele programării în Java

10.1. Prima fereastră


O fereastr` este un obiect al clasei JFrame. Clasa JFrame este
re]inut` \n pachetul javax.swing. Mai jos pute]i observa un program care
afi[eaz` o fereastr`:
import javax.swing.*;
public class pv {
public static void main(String args[]) {
JFrame fer=new JFrame("Prima mea
fereastra");
fer.setSize(200,300);
fer.setLocation(300,400);
fer.setDefaultCloseOperation(
JFrame.EXIT_ON_CLOSE);
fer.setVisible(true);
}
}

 S` observ`m c` fereastra con]ine meniul implicit, poate fi maximizat`,


minimizat` (adus` pe bara de task-uri), dar poate fi [i \nchis`.

Din analiza programului deducem c@teva metode pe care le are clasa


JFrame:

 JFrame() - constructor. Dac` o fereastr` este creat` printr-un astfel


de constructor ea apare f`r` titlu.
 JFrame(String titlu) - constructor. Construie[te o fereastr` care
afi[eaz` un anumit titlu (\n exemplu, Prima mea fereastra).
 void setSize(int width, int height) - stabile[te l`]imea [i
\n`l]imea ferestrei.
 void setLocation (int x, int y) - stabile[te pozi]ia unde va fi
afi[at col]ul din st@nga sus al ferestrei ([i implicit pozi]ia ferestrei), \n
raport cu col]ul din st@nga sus al ecranului. Parametrul x precizeaz`
distan]a pe orizontal` a col]ului ferestrei, iar y distan]a pe vertical` a
acestuia (ambele sunt date \n pixeli).
 void setDefaultCloseOperation(int a) - stabile[te ce se
\nt@mpl` atunci c@nd se \nchide fereastra (s-a p`strat acel buton x).
Parametrii sunt constante de tip \ntreg ale clasei. Cea mai important`
constant` este EXIT_ON_CLOSE [i prin ea, se cere \nchiderea
ferestrei [i \ncheierea execu]iei programului.
 void setResizable(boolean ac) - dac` parametrul este false
nu se pot modifica dimensiunile ferestrei.
 setVisible(boolean x) - stabile[te dac` fereastra este vizibil`
(apare pe ecran) sau nu (de[i exist`, nu este afi[at`).
Capitolul 10. Iniţiere în programarea vizuală 195

Dac` dorim s` fim eficien]i, putem construi o clas`, de exemplu


numit` Fereastra, al c`rei constructor s` returneze obiectul cu toate
datele de mai sus (titlul, dimensiunile ferestrei, pozi]ia sa pe ecran).
Exemplu: programul de mai jos afi[eaz` o fereastr`:
import javax.swing.*;
class Fereastra extends JFrame
{ Fereastra(String Nume, int lat, int inalt, int dreapta, int
stanga)
{ super(Nume);
setSize(lat,inalt);
setLocation(dreapta, stanga);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
}

public class pv {
public static void main(String args[]) {
Fereastra f= new Fereastra ("Prima", 100,200, 25, 100);}
}

10.2. Mecanismul prin care se ataşează


componente ferestrei. Clasa Container

 Foarte important! Pentru ca unei ferestre (obiect de tip JFrame) s` i se


poat` ata[a alte componente (cum ar fi butoanele, liste, etc. – care sunt
obiecte de alte tipuri), este necesar ca aceasta s` con]in` o referin]` c`tre
o structur` special`, care la r@ndul ei va re]ine referin]e c`tre obiectele
(componentele) care sunt ata[ate ferestrei. Structura care re]ine referin]ele
c`tre obiectele care se afl` pe fereastr` este un obiect al clasei
Container.

Al`turat putem observa ierarhia


Object
claselor din care a rezultat Component
clasa JFrame. Prin urmare, un Container
obiect de tip JFrame sau Window
dintr-o subclas` a lui JFrame java.awt.Frame
javax.swing.JFrame
con]ine datele membru [i
metodele clasei Container.

Accesul la container-ul unei ferestre se face utiliz@nd o metod` a


clasei JFrame, numit` getContentPane().

 Container getContentPane() - returneaz` o referin]` c`tre


container-ul ferestrei. Pornind de la aceast` referin]`, putem realiza
dou` lucruri:
196 Bazele programării în Java

1. Putem ad`uga ferestrei componentele dorite. Pentru aceasta se folose[te


metoda add() a clasei Container:

 Component add(Component comp) - adaug` o component`


ferestrei. Important: toate componentele sunt derivate din clasa
Component. Prin urmare, parametrul comp poate re]ine referin]e c`tre
componente de orice tip.
2. Putem spune cum s` fie aranjate \n fereastr` componentele ad`ugate.
Important: Mecanismul din Java care rezolv` aceast` problem` presupune
existen]a unor a[a numi]i gestionari de pozi]ionare. Gestionarii de pozi]ionare
sunt obiecte ale unor clase specifice. Ei aranjeaz` automat componentele
unui container. Pentru a ata[a unui container un gestionar de pozi]ionare,
se utilizeaz` metoda clasei Container numit` setLayout():

 void setLayout(LayoutManager gest) - ata[eaz` unui container


un gestionar de pozi]ionare. LayoutManager - este o interfa]`. To]i
gestionarii de pozi]ionare pe care \i vom studia \ntr-un paragraf
separat au rezultat ca urmare a implement`rii acestei interfe]e.
Aceasta \nseamn` c` metoda poate fi utilizat` pentru ata[area oric`rui
gestionar de pozi]ionare.

Pentru \nceput, vom folosi gestionarul de pozi]ionare FlowLayout,

 care are un constructor f`r` parametri. Pe scurt, acesta a[eaz`


componentele \n fereastr`, pe linie, una dup` alta. |n cazul \n care o
linie s-a umplut, se trece la linia urm`toare.

! Clasa Container se g`se[te \n pachetul java.awt.

Exemplu: programul care urmeaz` afi[eaz` dou` butoane! Ap`sarea


butoanelor nu are nici un efect.

import java.awt.*;
import javax.swing.*;
class Fer extends JFrame
{ public Fer(String titlu) {
super(titlu);
setSize(200,100);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container x=getContentPane();
x.setLayout(new FlowLayout ());
JButton A=new JButton("Buton 1"); x.add(A);
JButton B=new JButton("Buton 2"); x.add(B);
setVisible(true);}
}

public class pv {
public static void main(String args[]) {
Fer fp=new Fer("Doua butoane");}
}
Capitolul 10. Iniţiere în programarea vizuală 197


Butoanele ata[ate sunt componente de tip JButton, care au un
constructor de tip JButton(String s). {irul s va ap`rea pe
suprafa]a butonului.

10.3. Un mecanism prin care butoanele răspund


evenimentului de “apăsare”
P@n` \n prezent [tim s` construim o fereastr`, [tim s`-i ata[`m unul
sau mai multe butoane, dar nu [tim s` facem de a[a manier` \nc@t la
“ap`sarea” butonului (click pe suprafa]a lui) s` aib` loc o anumit` ac]iune.
Este exact ce ne propunem s` prezent`m \n acest paragraf.

|n Java exist` o interfa]` numit` ActionListener, “ascult`torul” de


evenimente de tip ActionEvent. Un exemplu de eveniment de tip
ActionEvent este “ap`sarea” unui buton. Interfa]a con]ine antetul unei
singure metode: actionPerformed (ActionEvent e).

Pentru ca o component` s` poat` r`spunde la un eveniment de tipul


ActionEvent, trebuie s` implementeze clasa ActionListener. Aceasta
\nseamn` c`:

1. Clasa care include componenta (fereastra) s` con]in` clauza


implements ActionListener;
2. S` fie implementat` metoda actionPerformed(). Aceast` metod` se
va executa automat atunci c@nd este ap`sat butonul. Prin urmare,
implementarea ei va scrie codul necesar ac]iunii dorite.

ActionEvent este o clas` care con]ine metoda:

 String getActionCommand() - returneaz` [irul de caractere


asociat componentei care a transmis evenimentul. Metoda poate fi
utilizat` pentru a depista componenta care a transmis evenimentul.

Exemplu: extindem programul prezentat \n paragraful anterior. C@nd se


apas` un buton, \n fereastra CMD va ap`rea [irul re]inut de butonul ap`sat.

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
class Fer extends JFrame implements ActionListener
{ public Fer(String titlu) {
super(titlu);
setSize(200,100);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container x=getContentPane();
198 Bazele programării în Java

x.setLayout(new FlowLayout ());


JButton A=new JButton("Buton 1");
x.add(A);
JButton B=new JButton("Buton 2");
x.add(B);
A.addActionListener(this);
B.addActionListener(this);
setVisible(true);
}
public void actionPerformed (ActionEvent e)
{ if( e.getActionCommand().compareTo("Buton 1")==0)
System.out.println("Ai apasat Buton 1");
else
System.out.println("Ai apasat Buton 2");
}
}
public class pv {
public static void main(String args[]) {
Fer fp=new Fer("Doua butoane");}
}

10.4. Clasa JComponent


Prin component` vom \n]elege un obiect care are o reprezentare
grafic`. Exemple de componente: butoane, liste, edit-uri, etichete (am
preferat denumirea lor din cursul de Tehnologia Informa]iei. Dac` o
component` este obiect, \nseamn` c` o component` rezult` \n urma
instan]ierii unei clase. Fiecare tip de component` pe care o vom studia
rezult` \n urma instan]erii unei clase specifice ei. De exemplu, un
buton rezult` \n urma instan]ierii clasei JButton, o etichet` rezult` \n urma
instan]ierii clasei JLabel, un edit rezult` \n urma instan]ierii clasei
JtextField, [.a.m.d.

 Important: clasele tuturor componentelor enumerate mai sus sunt


subclase ale clasei JComponent. Aceasta \nseamn` c` putem folosi
metodele clasei JComponent pentru orice component`.

Clasa JComponent este descendent`, dar nu direct, a unei alte clase


numit` Component. Atunci c@nd prezent`m unele metode ale clasei
JComponent, care sunt mo[tenite de la clasa Component nu vom
mai face referire la acest lucru, ci le vom trata ca f`c@nd parte din
clasa JComponent.

|n continuare prezent`m c@teva metode ale clasei JComponent:

 void setBackground(Color c) - metoda stabile[te culoarea de


fond a componentei. S` observ`m c` parametrul ei este de tip
Color.
Capitolul 10. Iniţiere în programarea vizuală 199

 void setForeground(Color c) - seteaz` culoarea caracterelor (\n


cazul \n care componenta con]ine un text.

Clasa Color con]ine anumite constante care indic` culoarea [i mai


multe metode prin care se poate stabili o culoare. Exemple de
constante de culoare: black, red, white, yellow, etc. De
asemenea, clasa con]ine constructorul Color(float r, float g,
float b) prin care se poate forma o culoare \n sistemul RGB (Red,
Green, Blue), sistem studiat la tehnologia informa]iei.

 setFont(Font f) seteaz` font-ul cu care se scrie, stilul s`u [i


m`rimea. Parametrul este un obiect al clasei Font.
Clasa Font are, printre altele, constructorul:
Font(String nume, int stil, int marime).
unde:
nume - este numele font-ului;
stil - stilul. Valorile uzuale sunt: Font.ITALIC (italic), Font.BOLD
(bold), Font.PLAIN (clasic). Se pot folosi [i sume, cum ar fi pentru
italic [i bold: Font.ITALIC+Font.BOLD.
marime - m`rimea font-ului.

Exemplu: butonul cu fond ro[u, “Apasa” con]ine text scris cu verde, se


utilizeaz` font-ul Arial, m`rimea 20 [i este scris italic+bold. S` observ`m
faptul c` dimensiunea butonului este stabilit` automat, \n func]ie de m`rimea
textului pe care \l con]ine.

JButton A=new JButton("Apasa");


A.setBackground(Color.red);
A.setFont(new Font("Arial",Font.ITALIC+Font.BOLD, 20));
A.setForeground(Color.GREEN);

 void setToolTipText(String text); - metoda seteaz` un [ir de


caractere care va fi afi[at atunci c@nd cursorul mouse-ului sta]ioneaz`
asupra componentei. {irul are rolul unui mesaj l`muritor despre func]ia
respectivei componente.

Exemplu:
JButton B=new JButton("Buton 2");
B.setToolTipText("Eu sunt butonul 2");

 void setEnabled(boolean v) - Face ca o component` s` fie activat`


(v re]ine true) sau nu (v re]ine false). O component` dezactivat` nu
mai r`spunde comenzilor [i are un aspect specific prin care utilizatorul
este anun]at de faptul c` aceasta este dezactivat`.
200 Bazele programării în Java

Exemplu: \n imaginea al`turat` butonul 1 este


dezactivat [i butonul 2 este activat.

 void setVisible(boolean v) - dac` parametrul re]ine true,


componenta este vizibil`, altfel ea este invizibil`.

10.5. Clasa ToolKit


Se [tie faptul c` programele scrise \n Java trebuie s` ruleze
independent de rezolu]ia calculatorului. O clas` care face posibil acest lucru
este clasa ToolKit. |n acest sens, cele mai importante metode ale ei sunt:

 public static Toolkit getDefaultToolkit() - returneaz` un


obiect Toolkit (con]ine date despre set`rile curente);
 Dimension getScreenSize() - returneaz` o referin]` c`tre un
obiect de tip Dimension care con]ine lungimea (width) [i \n`l]imea
(height) \n pixeli a ecranului.

Exemplu: programul de mai jos creeaz` o fereastr` care, ini]ial, ocup`


\ntreg ecranul.
import java.awt.*;
import javax.swing.*;
class Fer extends JFrame
{ public Fer(String titlu) {
super(titlu);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Toolkit ec=Toolkit.getDefaultToolkit();
Dimension dim = ec.getScreenSize();
int i = dim.height; int l = dim.width;
setSize(dim.width, dim.height); setVisible(true);}
}
public class pv {
public static void main(String args[]) {
Fer fp=new Fer("Fereastra pe intreg ecranul");}
}

10.6. Poziţionarea componentelor


Pentru a a[eza componentele \n pozi]ia dorit`, putem s` utiliz`m
pozi]ionarea absolut` (dar este nerecomandat` pentru c` programul trebuie
s` ruleze corect pe o diversitate de platforme) sau unul dintre gestionarii de
pozi]ionare existen]i. Cum facem acest lucru? Ve]i vedea \n paragraful
acesta! Oricum, trebuie s` [ti]i c` mecanismul este pu]in mai complicat
decât cel cu care a]i fost obi[nui]i \n ipoteza c` a]i studiat programarea
vizual` (de exemplu \n Borland Delphi sau Borland Builder).
Nu uita]i, programele Java trebuie s` func]ioneze pe orice platform`!
Capitolul 10. Iniţiere în programarea vizuală 201

10.6.1. Poziţionarea absolută


Pentru a utiliza pozi]ionarea absolut` a componentelor trebuie s`
lucr`m \n absen]a unui gestionar de pozi]ionare, iar coordonatele sunt date
\n pixeli. Pentru aceasta trebuie s` cunoa[tem urm`toarele:

1. Secven]a de mai jos se utilizeaz` pentru a lucra \n absen]a unui


gestionar de pozi]ionare.
Container x=getContentPane();
x.setLayout(null);

2. |n pozi]ionarea absolut` componentele trebuie dimensionate [i


pozi]ionate, altfel nu sunt vizibile. Testa]i...

Pentru dimensionarea componentelor se utilizeaz` urm`toarele metode ale


clasei JComponent:

 setBounds(int x, int y, int lat, int inal); metoda


pozi]ioneaz` [i dimensioneaz` componenta. Parametrii x [i y dau
pozi]ia componentei \n raportat` la col]ul din st@nga sus al
componentei care o g`zduie[te, iar lat [i lung o dimensioneaz`.

Metoda de mai sus poate fi \nlocuit` cu urm`toarele dou` metode:

 setLocation(int x, int y) - metod` care are rolul de


pozi]ionare;

 setSize (int lat, int lung) - metod` care are rolul de


dimensionare.

Exemplu: utiliz`m pozi]ionarea absolut` [i a[ez`m un buton \n fereastr`:


Container x=getContentPane();
x.setLayout(null);
JButton A=new JButton ("Exemplu");
A.setBounds(10,10, 100, 40);

10.6.2. Gestionarul de poziţionare FlowLayout


.
Componentele sunt afi[ate pe linii,
\n ordinea \n care au fost declarate. Pe
fiecare linie ele sunt afi[ate de la
st@nga la dreapta (at@tea c@te \ncap).

|n continuare, pute]i observa cum


a fost creat` fereastra al`turat`:
202 Bazele programării în Java

class Fer extends JFrame


{
public Fer(String titlu) {
super(titlu);
setSize(300,150);
Container x=getContentPane();
x.setLayout(new FlowLayout ());
JButton A=new JButton("Buton 1"); x.add(A);
JButton B=new JButton("Buton 2"); x.add(B);
JButton C=new JButton("Buton 3"); x.add(C);
JButton D=new JButton("Buton 4"); x.add(D);
JButton E=new JButton("Buton 5"); x.add(E);
JButton F=new JButton("Buton 6"); x.add(F);
JButton G=new JButton("Buton 7"); x.add(G);
setVisible(true);
}
}

Clasa FlowLayout con]ine constante de aliniere pe linie, din care mai


importante sunt: CENTER, aliniere \n centru, op]iune implicit`, LEFT, la
st@nga [i RIGHT, la dreapta.

 Clasa FlowLayout este \nzestrat` cu 3 constructori:

a) FlowLayout() - distan]a \ntre r@nduri este de 5 unit`]i, distan]a pe


orizontal` \ntre componente este de 5 unit`]i [i componentele sunt aliniate
pe linie la centru (CENTER).
b) FlowLayout(int aliniere) - se cere explicit ca alinierea s` fie
\ntr-un anumit fel (CENTER, RIGHT, LEFT, acestea sunt constante ale clasei
FlowLayout).
c) FlowLayout(int aliniere, int dist_oriz, int dist_vert ) -
se specific` [i distan]a pe orizontal` \ntre componente [i distan]a pe
vertical` dintre ele.
Exemple de utilizare a constructorilor:

FlowLayout (FlowLayout.LEFT) FlowLayout (FlowLayout.RIGHT,15,8)


Capitolul 10. Iniţiere în programarea vizuală 203

 De re]inut:

1. Dimensionarea componentelor [i pozi]ionarea lor este f`cut` automat de


c`tre gestionar.
2. Metodele utilizate \n pozi]ionarea absolut` pentru pozi]ionarea [i
dimensionarea componentelor ( setBounds(), setLocation(), setSize())
de[i sunt acceptate la compilare, nu au nici un efect.
3. Exist`, totu[i, o metod` care dimensioneaz` componentele [i este
acceptat` de gestionarul FlowLayout. Ea apar]ine clasei JComponent:

 setPreferredSize(Dimension dim); Clasa Dimension are


constructorul Dimension(int lat, int inalt) prin care se
specific` l`]imea, respectiv \n`l]imea componentei.
Exemplu: prin utilizarea gestionarului FlowLayot se adaug` unei ferestre
dou` butoane, primul de dimensiune stabilit`, al doilea de dimensiune
implicit`:
Container x=getContentPane();
x.setLayout(new FlowLayout());
JButton A=new JButton ("Buton 1");
A.setPreferredSize(new Dimension(100, 100));
JButton B=new JButton ("Buton 2");
x.add(A);
x.add(B);

10.6.3. Gestionarul de poziţionare GridLayout


Clasa GridLayout - aranjeaz` componentele \ntr-o alt` logic`. Ideea de
baz` este aceea c` se \mparte suprafa]a ferestrei \n mai multe
dreptunghiuri de suprafa]` egal` [i \n fiecare dreptunghi astfel ob]inut se
a[eaz` o component` care este de cele mai multe ori extins` ca suprafa]`,
astfel \nc@t s` ocupe \ntreaga suprafa]` a dreptunghiului care \i revine.
Pentru a \n]elege modul de aranjare a componentelor vom prezenta pe
scurt cei trei constructori ai clasei:
a) GridLayout() - dac` avem n componente care trebuie a[ezate,
suprafa]a ferestrei este \mp`r]it` \ntr-o singur` linie [i n coloane. Fiecare
component` este a[eazat` \ntr-un dreptungi, iar componentele sunt f`r`
spa]iu \ntre ele.

b) GridLayout(int nr_linii, int


nr_coloane) - suprafa]a \mp`r]it` \n
nr_linii  nr_coloane dreptunghiuri.
Fiecare dreptunghi re]ine o component`.
Vede]i exemplul al`turat.
GridLayout (3,3)
204 Bazele programării în Java

c) GridLayout(int nr_linii,
int nr_col, int sp_o, int sp_v ) -
se procedeaz` ca anterior, numai c` se
trec [i spa]iile pe orizontal` [i pe vertical`
\ntre dreptunghiurile generate.

GridLayout (3,3,5,8)
! Pentru GridLayout nu are nici un efect metoda setPreferredSize().

10.6.4. Gestionarul de poziţionare BorderLayout

Clasa BorderLayout - \mparte suprafa]a ferestrei \n 5 p`r]i: nord (NORTH),


sud (SOUTH), est (EAST), vest (WEST) [i centru (CENTER). |n fiecare parte
se poate a[eza o component`. Mai jos pute]i observa cum am ob]inut
a[ezarea componentelor ca \n fereastra al`turat`.
x.setLayout(new BorderLayout ());
JButton A=new JButton("Buton 1");
x.add(A,BorderLayout.SOUTH);
JButton B=new JButton("Buton 2");
x.add(B,BorderLayout.NORTH);
JButton C=new JButton("Buton 3");
x.add(C,BorderLayout.WEST);
JButton D=new JButton("Buton 4");
x.add(D,BorderLayout.EAST);
JButton E=new JButton("Buton 5");
x.add(E,BorderLayout.CENTER);

 De re]inut:
1. Pentru ad`ugarea unei componente container-ului, se folose[te metoda
add cu 2 parametri, al doilea fiind cel care precizeaz` pozi]ia \n care este
ad`ugat` componenta. Vezi, mai sus!

2. Componentele sunt extinse pentru a ocupa \ntreaga suprafa]` alocat`.


Vede]i figura de mai sus.
3. Dac` lipse[te componenta din nord, sau cea din sud, spa]iul este
ocupat de linia din centru.
4. Dac` lipse[te componenta din centru, spa]iul este l`sat liber. Dac`
lipse[te componenta din est, sau cea din vest, spa]iul este ocupat de
componenta din centru.
5. Metoda setPreferredSize() are efect par]ial. Astfel avem: dac` este
aplicat` unei componente din nord sau din sud, se ia \n considerare numai
\n`l]imea transmis` de metod`. Dac` este aplicat` unei componente din est,
vest, sau centru se ia \n considerare numai l`]imea componentei.
Capitolul 10. Iniţiere în programarea vizuală 205

10.6.5. Gestionarul GridBagLayout

Gestionarul GridBagLayout() este o extindere a gestionarului


GridLayout(). {i el \mparte suprafa]a container-ului \n mai multe
dreptunghiuri, unde fiecare dreptunghi va fi ocupat de o component`.
Evident, dreptunghiurile sunt aranjate \n linii [i coloane. Dar, aici, propor]iile
\ntre linii [i coloane pot fi diferite, iar o component` poate ocupa unul sau
mai multe dreptunghiuri. De asemenea, o component` poate fi plasat` \n
cadrul dreptunghiului (dreptunghiurilor) \n mai multe feluri. S` vedem cum se
pot realiza toate acestea.

 Clasa GridBagLayout - un obiect al acestei clase este de fapt,


administratorul de pozi]ionare. Printre altele, clasa con]ine:

 GridBagLayout() - constructor;

 setConstraints(Component comp, GridBagConstraints cons)-


metod`. Pentru a [ti unde se pozi]ioneaz` fiecare component`, vom
utiliza un mecanism specific. El const` \n a scrie, pentru fiecare
component` \n parte, un set de restric]ii (cu ajutorul lor se determin`
pozi]ionarea acesteia). Restric]iile de pozi]ionare pentru fiecare compo-
nent` \n parte sunt memorate de c@te un obiect de tip
GridBagConstraints. Metoda pe care o trat`m \n acest moment
anun]` gestionarul de pozi]ionare, componenta [i restric]iile ei de
pozi]ionare.

Acum trebuie s` vedem cum stabilim restric]iile de pozi]ionare pentru o


component` oarecare. Pentru aceasta vom utiliza clasa
GridBagConstraints.
Ea are constructorul:

 GridBagConstraints(int gridx, int gridy,


int gridwidth, int gridheight,
double weightx, double weighty,
int anchor, int fill, Insets insets,
int ipadx, int ipady)

Semnifica]ia parametrilor este urm`toarea:

 gridx, gridy - specific` 0,0 1,0


dreptunghiul care con]ine
componenta. Pentru fiecare 0,1 1,1
dreptunghi din exemplul al`turat am
trecut, \n aceast` ordine: gridx,
gridy. 0,2 1,2
206 Bazele programării în Java

 gridwidth, gridheight - num`rul de dreptunghiuri pe linie,


respectiv pe coloan` care sunt ocupate de component`.
 weightx si weighty - l`]imea ocupat` de dreptunghi pe linie,
respectiv pe coloan`. Acestea nu sunt date \n pixeli. Pentru a u[ura
\n]elegerea vom lua ca exemplu linia. Presupunem c` avem c@te dou`
dreptunghiuri pe linie, ca \n exemplul de mai sus. Dac` pentru primul
dreptunghi weightx re]ine 1 [i pentru al doilea, weightx re]ine 2,
atunci l`]imea primului dreptunghi este 1/3 din l`]imea final`, iar a
celui de-al doilea dreptunghi este 2/3 din l`]imea final`.
 anchor - se refer` la pozi]ionarea componentei \n cadrul
dreptunghiului. Poate lua una din valorile: CENTER, NORTH,
NORTHEAST, EAST, SOUTHEAST, SOUTH, SOUTHWEST, WEST,
NORTHWEST.
 fill - se refer` la cazul \n care componenta ocup` mai mult sau
mai putin spa]iu dec@t dreptunghiul rezervat ei [i dorim s-o ajust`m
astfel \nc@t s` \ncap` exact. |n acest caz se pune problema mic[r`rii
sau m`ririi ei. Poate lua valorile: NONE (nu se ajusteaz`),
HORIZONTAL (se ajusteaz` pe l`]ime, dar \n`l]imea r`m@ne nemodi-
ficat`), VERTICAL (se ajusteaz` pe \n`l]ime, dar l`]imea r`m@ne
nemodificat`), BOTH (se ajusteaz` at@t l`]imea c@t [i \n`l]imea).
 insets - referin]` la un obiecte de tip Insets. Aceasta are rolul de
a ad`uga \n fiecare parte a componentei un spa]iu exterior (dat \n
pixeli). Constructorul clasei Insets are forma Insets(int sus,
int stanga, int jos, int dreapta). O component` care are
margini exterioare este separat` de alt` component` cel pu]in prin
acele margini.
 ipadx, ipady - adaug` spa]iu interior pe orizontal`, respectiv pe
vertical`. Dac`, de exemplu, ipadix re]ine 1, se adaug` de fapt un
pixel la st@nga [i un pixel la dreapta. Diferen]a \ntre spa]iul interior [i
cel exterior este dat` de faptul c` se presupune c` spa]iul interior
este al componentei, deci pe aceast` suprafa]` componenta r`spunde
la evenimente.

Exemplu: programul urm`tor afi[eaz`


o fereastr` care con]ine o etichet`,
un edit [i un buton. Cele trei
componente sunt afi[ate prin
utilizarea gestionarului de pozi]ionare
GridBagLayout. Butonul ocup` dou`
dreptunghiuri, iar raportul dintre spa]iul ocupat de etichet` [i cel ocupat de
edit este de 1/4. Nu trebuie s` v` \ngrijoreze faptul c` \n exemplu s-au
utilizat [i alte componente. Toate vor fi studiate \ncep@nd cu paragraful
urm`tor.
Capitolul 10. Iniţiere în programarea vizuală 207

import java.awt.*;
import javax.swing.*;
class Fer extends JFrame
{
public Fer(String titlu) {
super(titlu);
setSize(250,100);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
GridBagLayout pozitii=new GridBagLayout();
JLabel et=new JLabel ("Numele ");
JTextField txt=new JTextField(15);
JButton bt=new JButton("Ce-am citit?");
Container x=getContentPane();
// pozitionare eticheta
GridBagConstraints p_et=new
GridBagConstraints(0,0,1,1,1,2,GridBagConstraints.EAST,
GridBagConstraints.NONE,new Insets(0,0,0,0), 0,0);
pozitii.setConstraints(et,p_et);
// pozitionare edit
GridBagConstraints p_txt=new
GridBagConstraints(1,0,1,1,4,2,GridBagConstraints.EAST,
GridBagConstraints.NONE,new Insets(0,0,0,0), 0,0);
pozitii.setConstraints(txt,p_txt);
// pozitionare buton
GridBagConstraints p_bt=new
GridBagConstraints(0,1,2,1,1,1,GridBagConstraints.CENTER,
GridBagConstraints.NONE,new Insets(0,0,0,0), 0,0);
pozitii.setConstraints(bt,p_bt);
x.setLayout(pozitii);
x.add(et); x.add(txt); x.add(bt);
setVisible(true);
}
}

public class pv {
public static void main(String args[]) {
Fer fp=new Fer("Gestionar de pozitionare");
}
}

10.6.6. Gestionarul CardLayout


Gestionarul CardLayout este unul cu totul aparte. El se
caracterizeaz` prin faptul c`, la un moment dat, afi[eaz` o singur`
component`.

 CardLayout() - constructor;
 next(Container parinte) - afi[eaz` urm`toarea component`.
Dac` este afi[at` ultima component`, se afi[eaz` din nou prima
component`;
 last(Container parinte) - se afi[eaz` ultima component`;
208 Bazele programării în Java

 first(Container parinte) - se afi[eaz` prima component`;


 addLayout(String nume, Component c) - se adaug` o
component` c`reia i se [i atribuie un nume.

Exemplu: \n programul urm`tor se afi[eaz`


cu gestionarul CardLayout 3 butoane.
Aceasta \nseamn` c`, la un moment dat,
numai unul este vizibil. La ap`sarea butonului
vizibil se afi[eaz` urm`torul buton, [.a.m.d.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
class Fer extends JFrame implements ActionListener
{ CardLayout g=new CardLayout();
Container x=getContentPane();
public Fer(String titlu) {
super(titlu); setSize(200,100);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
x.setLayout(g);
JButton A=new JButton("Buton 1"); x.add("Buton 1",A);
A.addActionListener(this);
JButton B=new JButton("Buton 2"); x.add("Buton 2",B);
B.addActionListener(this);
JButton C=new JButton("Buton 3"); x.add("Buton 3",C);
C.addActionListener(this); setVisible(true);
}
public void actionPerformed (ActionEvent e)
{ g.next(x); }
}
public class pv {
public static void main(String args[]) {
Fer fp=new Fer("gestionarul CardLayout");
}
}

10.7. Studiul principalelor componente

10.7.1. Componente de tip JButton

Cu ajutorul componentelor de acest tip se creeaz` butoane. Vom


prezenta cele mai importante metode (constructori):

 JButton() - creeaz` un buton f`r` text, f`r` imagine asociat`.


 JButton(String text) - creeaz` un buton care afi[eaz` un text.
 JButton(Icon icon) - creeaz` un buton care re]ine o imagine de
mici dimensiuni.
Capitolul 10. Iniţiere în programarea vizuală 209

Exemplu:
Icon icon = new ImageIcon("om.gif");
JButton A=new JButton(icon);

 JButton(String text, Icon icon) - creeaz` un buton cu text [i


imagine.

Icon icon = new ImageIcon("om.gif");


JButton A=new JButton( "Java...",icon);

 metoda setVericalTextPosition(constanta) seteaz` pozi]ia pe


veritcal` a textului \n raport cu imaginea:
 deasupra (JButton.TOP),
 dedesubt (JButton.BOTTOM),
 \n centru (JButton.CENTER).

 metoda setHorizontalTextPosition(constanta) seteaz` pozi]ia


pe orizontal` a textului \n raport cu imaginea:
 st@nga (JButton.LEFT),
 dreapta (JButton.RIGHT),
 \n centru (JButton.CENTER).

Exemplu:
Icon icon = new ImageIcon("om.gif");
JButton A=new JButton( "Java...",icon);
A.setVerticalTextPosition(JButton.TOP);
A.setHorizontalTextPosition(JButton.CENTER);

 M`rimea imaginii determin` m`rimea butonului.

10.7.2. Componente de tip JLabel


Componentele de acest tip se utilizeaz` pentru a afi[a texte [i
imagini, cu rol l`muritor pentru alte componente. Clasa este \nzestrat` cu
urm`toarele metode mai importante:

 JLabel(string S) - se utilizeaz` pentru a afi[a un [ir de caractere.


210 Bazele programării în Java

Exemplu: dac` constructorul ferestrei con]ine secven]a de mai jos, atunci pe


fereastr` apare:
Container x=getContentPane();
x.setLayout(new BorderLayout ());
JLabel A=new JLabel ("Un text ");
x.add(A);

 JLabel(Icon image) - se utilizeaz` pentru a afi[a o imagine:

Exemplu: la fel ca mai sus, numai c` pe fereastr` se afi[eaz` o imagine:

Container x=getContentPane();
Container x=getContentPane();
x.setLayout(new BorderLayout ());
x.setLayout(new BorderLayout ());
Icon icon = new ImageIcon("idee.gif");
Icon icon = new ImageIcon("idee.gif");
JLabel A=new JLabel (icon);
JLabel A=new JLabel (icon);
x.add(A);
x.add(A);

 JLabel(String text, Icon icon, int horizontalAlignment)


afi[eaz` o imagine [i un text. Ansamblul (imagine + text) se aliniaz`
pe orizontal`, conform ultimului parametru (CENTER, LEFT, RIGHT).
 setVerticalTextPosition(c), setHorizontalTextPosition(c)
pot fi folosite [i la JLabel la fel ca la Jbutton:

Exemplu:
Container x=getContentPane();
x.setLayout(new GridLayout());
Icon icon = new ImageIcon("idee.gif");
JLabel A=new JLabel
("Asta era!!!",icon,JLabel.CENTER);
A.setHorizontalTextPosition(Jlabel.CENTER);
A.setVerticalTextPosition(JLabel.TOP);
x.add(A);

10.7.3. Componente de tip JPanel


Componentele JPanel (paneluri) sunt de tip container, adic` au rolul
de a con]ine pe suprafa]a lor alte componente. Clasa este \nzestrat` cu
urm`toarele metode:

 JPanel() - constructor, obiectul rezultat are gestionarul de pozi]ionare


FlowLayout().
 JPanel(LayoutManager layout) - constructor, obiectul rezultat are
gestionarul de pozi]ionare transmis ca parametru.
 setLayout(LayoutManager layout); - seteaz` gestionarul de
pozi]ionare.
 add(Compoment c) - adaug` o component` obiectului.
Capitolul 10. Iniţiere în programarea vizuală 211

Exemplu: fereastra programului urm`tor con]ine o component` de tip


JPanel. Pe ea sunt ata[ate 3 butoane. La ap`sarea unui buton,
componenta de tip JPanel va avea
culoarea afi[at` de buton.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
class Fer extends JFrame implements ActionListener
{ JPanel panel;
public Fer(String titlu) {
super(titlu);
setSize(300,300);
fer.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container x=getContentPane();
x.setLayout(new FlowLayout ());
panel=new JPanel();
JButton A=new JButton("Rosu");
panel.add(A); A.addActionListener(this);
JButton B=new J
Button("Galben");
panel.add(B); B.addActionListener(this);
JButton C=new JButton("Albastru");
panel.add(C);
C.addActionListener(this);
x.add(panel);
setVisible(true);}
public void actionPerformed (ActionEvent e)
{ String culoare=e.getActionCommand();
if (culoare.compareTo("Rosu")==0)
panel.setBackground(Color.red);
else
if (culoare.compareTo("Galben")==0)
panel.setBackground(Color.yellow);
else
panel.setBackground(Color.blue);
}
}
public class cv {
public static void main(String args[]) {
Fer fp=new Fer("Fereastra cu panel");
}
}

10.7.4. Componente de tip JTextField


Componentele de tip JTextField (edit-uri) sunt utilizate pentru ca
utilizatorul s` introduc` sau s` afi[eze [iruri de caractere de la tastatur`,
[iruri pe care programul urmeaz` s` le prelucreze. Cele mai importante
metode ale acestui obiect sunt:
212 Bazele programării în Java

 JTextField(int nr) - creeaz` un edit vid, dar


care are o l`]ime suficient` pentru a vizualiza
simultan nr caractere. {irul de caractere introdus
poate avea orice lungime.
 JTextField(String s) - creeaz` un edit care
ini]ial afi[eaz` un [ir de caractere.
 JTextField(String S, int nr) - creeaz` un edit care ini]ial
afi[eaz` un [ir de caractere [i care are o l`]ime suficient` pentru a
afi[a simultan un num`r de nr caractere.
 String getText() - returneaz` [irul de caractere re]inut de edit la
un moment dat.
 void setText(String s) - are rolul de a determina ca edit-ul s`
con]in` [irul de caractere specificat.

Exemplul . Programul urm`tor afi[eaz`


fereastra al`turat`. Utilizatorul introduce
un [ir de caractere [i, la ap`sarea
butonului se afi[eaz`, \n fereastra CMD,
textul introdus de acesta.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
class Fer extends JFrame implements ActionListener
{ JTextField txt;
public Fer(String titlu) {
super(titlu);
setSize(300,200);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container x=getContentPane();
x.setLayout(new FlowLayout ());
JLabel et=new JLabel ("Numele dv:");
x.add(et);
txt=new JTextField(15);
x.add(txt);
JButton but=new JButton("Ce-am introdus?");
x.add(but);
but.addActionListener(this);
setVisible(true);
}
public void actionPerformed (ActionEvent e)
{ System.out.println(txt.getText());}
}
public class pv {
public static void main(String args[]) {
Fer fp=new Fer("Exemplu de edit");
}
}
Capitolul 10. Iniţiere în programarea vizuală 213

Exemplul . Programul urm`tor rezolv`


ecua]ia de gradul 1 [i afi[eaz` o fereastr`
precum cea al`turat`.
Rezolvare:
a) Pentru a grupa elementele vom utiliza trei
componente de tip JPanel [i un obiect de tip
JButton. Fiecare component` de tip JPanel
va re]ine o component` de tip Jlabel (de ex
afi[eaz` “a=”) [i una de tip JTextField (de
exemplu, pentru introducerea lui a).
b) Datele citite sunt validate prin utilizarea mecanismelor de excep]ie.
c) La ap`sarea butonului se afi[eaz` rezultatul.

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
class Fer extends JFrame implements ActionListener
{ JTextField a,b,r; JButton but;
public Fer(String titlu) {
super(titlu); setSize(200,200);
fer.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container x=getContentPane();
x.setLayout(new FlowLayout ());
//primul panel
JPanel panel1 = new JPanel();
JLabel et=new JLabel ("a=");
panel1.add(et);
a=new JTextField(15);
panel1.add(a);
x.add(panel1);
//al doilea panel
JPanel panel2 = new JPanel();
JLabel et1=new JLabel ("b=");
panel2.add(et1);
b=new JTextField(15);
panel2.add(b);
x.add(panel2);
// al treilea panel
JPanel panel3 = new JPanel();
JLabel et2=new JLabel ("x=");
panel3.add(et2);
r=new JTextField(15);
panel3.add(r);
x.add(panel3);
// butonul Rezulta
but=new JButton("Rezultat");
x.add(but);
but.addActionListener(this);
setVisible(true);
}
214 Bazele programării în Java

public void actionPerformed (ActionEvent e)


{ double aR=0,bR=0,xR=0, er=0;
try // incerc sa-l citesc pe A
{ aR=Double.parseDouble(a.getText()); }
catch (NumberFormatException exc)
{ er=1;
System.out.println("a este introdus gresit");
r.setText("");}
try // incerc sa-l citesc pe B
{ bR=Double.parseDouble(b.getText()); }
catch (NumberFormatException exc)
{ er=1;
System.out.println("b este introdus gresit");
r.setText("");}
if (er==0)// daca aR si bR au fost citite
if (aR!=0)
r.setText(""+(double)-bR/aR);
else
if (bR==0) r.setText("Infinitate de solutii");
else
r.setText("Nu are solutie");
}
}

public class pv {
public static void main(String args[]) {
Fer fp=new Fer("Ecuatia de gradul 1");
}
}

10.7.5. Componente de tip JComboBox


Obiectele clasei JComboBox sunt a[a numitele liste, din care
utilizatorul poate selecta o anumit` op]iune (unic`). Principalele metode ale
clasei JComboBox sunt:

 JComboBox () – constructor.
 void addItem(Object s) - adaug` listei o op]iune. Cum clasa
Object este la baza ierarhiei de clase Java, parametrul efectiv poate
fi o referin]` c`tre orice obiect, inclusiv c`tre tipul des utilizat String.
 Object getSelectedItem() – returneaz` [irul de caractere
corespunz`tor op]iunii selectate.
 int getItemCount() - returneaz` num`rul de op]iuni.
 int getSelectedIndex() - returneaz` indexul op]iunii selectate.
 Object getItemAt(int ind) - returneaz` obiectul re]inut de
item-ul de indice ind (dac` trebuie s` ob]inem un obiect de tip
String, atunci converti]i c`tre String prin operatorul de conversie).
Capitolul 10. Iniţiere în programarea vizuală 215

Exemplu: Programul urm`tor afi[eaz`


o list`. Selecta]i din list` o op]iune [i
ap`sa]i butonul. |n fereastra CMD va fi
afi[at` op]iunea selectat`.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
class Fer extends JFrame implements ActionListener
{ JComboBox lista;
public Fer(String titlu) {
super(titlu); setSize(300,200);
fer.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container x=getContentPane();
x.setLayout(new FlowLayout ());
JLabel et=new JLabel ("Selectati materia preferata:");
x.add(et);
lista=new JComboBox ();
lista.addItem("Matematica");
lista.addItem("Informatica");
lista.addItem("Engleza");
lista.addItem("Alta materie");
x.add(lista);
JButton but=new JButton("Ce-am selectat?");
x.add(but);
but.addActionListener(this);
setVisible(true);
}
public void actionPerformed (ActionEvent e)
{ System.out.println(lista.getSelectedItem()); }
}
public class cp {
public static void main(String args[]) {
Fer fp=new Fer("Exemplu de lista");
}
}

10.7.6. Componente de tip JCheckBox şi JRadioButton


şi gruparea lor
Obectele clasei JCheckBox sunt a[a-numitele butoane de validare.
Fereastra poate con]ine unul sau mai multe astfel de butoane. Principalele
metode ale acestei clase sunt:
 JCheckBox(String s) - creeaz` un buton de validare care con]ine
[irul de caractere transmis ca parametru.
 JCheckBox(String s, boolean v) - creeaz` un buton de validare
care con]ine [irul de caractere transmis ca parametru [i care este
marcat sau nu \n func]ie de valoarea pe care o re]ine parametrul v,
respectiv true sau false.
216 Bazele programării în Java

 JCheckBox(String s, Icon f) - creeaz` un buton de validare


care con]ine [irul de caractere transmis ca parametru si o imagine.
 booolean isSelected() - returneaz` true dac` butonul a fost
selectat [i false \n caz contrar.
 String getText() - returneaz` [irul de caractere re]inut de buton.

Exemplu. Programul urm`tor afi[eaz` mai multe butoane


de validare, din care unul (cel care afi[eaz`
Informatica) este selectat de la \nceput! La ap`sarea
butonului Ce-am selectat? este afi[at` selec]ia
f`cut`.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
class Fer extends JFrame implements ActionListener
{ JCheckBox b1,b2,b3,b4;
public Fer(String titlu) {
super(titlu);
setSize(150,200);
Container x=getContentPane();
x.setLayout(new FlowLayout (FlowLayout.LEFT));
fer.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel et=new JLabel ("Selectati");
x.add(et);
b1=new JCheckBox("Matematica");x.add(b1);
b2=new JCheckBox("Informatica",true);x.add(b2);
b3=new JCheckBox("Engleza"); x.add(b3);
b4=new JCheckBox("Biologie");x.add(b4);
JButton but=new JButton("Ce-am selectat?");
x.add(but);
but.addActionListener(this);
setVisible(true);
}
public void actionPerformed (ActionEvent e)
{ if (b1.isSelected()) System.out.println(b1.getText());
if (b2.isSelected()) System.out.println(b2.getText());
if (b3.isSelected()) System.out.println(b3.getText());
if (b4.isSelected()) System.out.println(b4.getText());
}
}
public class pv {
public static void main(String args[]) {
Fer fp=new Fer("Validare");
}
}

 Obiectele de tip JRadioButton sunt asem`n`toare cu cele de tip


JCheckBox, negrupate au acela[i comportament, numai c` arat` ca
ni[te butoane radio.
Capitolul 10. Iniţiere în programarea vizuală 217

Butoanele pot fi grupate, adic` pot fi toate tratate ca un \ntreg. Un


exemplu conving`tor este dat de necesitatea grup`rii butoanelor radio (unde,
la un moment dat, numai un singur buton poate fi selectat). Pentru a grupa
butoanele se folose[te un obiect al clasei ButtonGroup. Cele mai
importante metode ale acestei clase sunt:

 ButtonGroup() - constructor;
 void add(AbstractButton b) – adaug` un buton grupului (clasa
AbstractButton este superclas` pentru JButton, JRadioButton,
JCheckBox).
 Enumeration getElements(); - returneaz` un pointer la grupul de
butoane.
 int getButtonCount() - returneaz` num`rul de butoane din grup.

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
class Fer extends JFrame implements ActionListener
{ ButtonGroup grup;
public Fer(String titlu) {
super(titlu); setSize(150,200);
fer.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container x=getContentPane();
x.setLayout(new FlowLayout (FlowLayout.LEFT));
JLabel et=new JLabel ("Selectati"); x.add(et);
JRadioButton b1=new JRadioButton("Matematica");x.add(b1);
JRadioButton b2=new JRadioButton("Informatica",true);x.add(b2);
JRadioButton b3=new JRadioButton("Engleza"); x.add(b3);
JRadioButton b4=new JRadioButton("Biologie");x.add(b4);
JButton but=new JButton("Ce-am selectat?"); x.add(but);
but.addActionListener(this);
grup = new ButtonGroup();
grup.add(b1);grup.add(b2);
grup.add(b3);grup.add(b4);
setVisible(true);
}
public void actionPerformed (ActionEvent e)
{
Enumeration enum=grup.getElements();
while (enum.hasMoreElements())
{ JRadioButton b=(JRadioButton)enum.nextElement();
if(b.isSelected()) System.out.println(b.getText());
}
}
}
public class pv {
public static void main(String args[]) {
Fer fp=new Fer("Validare");
}
}
218 Bazele programării în Java

10.7.7. Meniuri

|n Java, meniurile se construiesc prin utilizarea obiectelor mai multor


clase:

A) Clasa JMenuBar - obiectele acestei clase se utilizeaz` pentru a ob]ine


meniuri clasice, aflate \n partea de sus a ferestrei. Cele mai importante
metode ale acestei clase sunt:

 JMenuBar() - constructor;
 add(JMenu) - adaug` meniului componente de tip JMenu, vede]i \n
continuare.

B) Clasa JMenu - obiectele acestei clase au rolul de a \nscrie \n meniu


anumite op]iuni, care la r@ndul lor pot con]ine alte op]iuni. Cele mai
importante metode ale acestei clase sunt:

 JMenu(String s) - constructor. Obiectul va afi[a [irul s

 add(JMenuItem meniu) - adaug` o component` de tip JMenuItem.


Vede]i mai jos clasa JMenuItem;

 add (Comonent c) - adaug` o alt` component` (de un tip derivat


din tipul Component).

C) Clasa JMenuItem - o astfel de component` care apare \n meniu, arat`


ca o op]iune [i are rolul unui buton, adic` selectat`, conduce la o anumit`
ac]iune. Cele mai importante metode ale acestei clase sunt:

 JMenuItem(String s) - constructor, op]iunea afi[eaz` [irul s;

 JMenuItem(Icon ic) - constructor, op]iunea afi[eaz` o mic`


imagine;

 JMenuItem(String s, Icon ic) - constructor, op]iunea afi[eaz`


un [ir de caractere [i o mic` imagine.

Exemplu: programul urm`tor construie[te un


meniu clasic. Pentru fiecare op]iune selectat` se
afi[eaz` \n fereastra CMD [irul afi[at de op]iune.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
Capitolul 10. Iniţiere în programarea vizuală 219

class Fer extends JFrame implements ActionListener


{ TextArea t;
public Fer(String titlu) {
super(titlu);
setSize(400,400);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Bara meniu
JMenuBar bara = new JMenuBar();
// Creez meniul principal
JMenu meniu1 = new JMenu("Operatii 1");
bara.add(meniu1);
JMenu meniu2 = new JMenu("Operatii 2");
bara.add(meniu2);
// adaug itemi pentru fiecare optiune din meniul principal
JMenuItem item11 = new JMenuItem("OP 11");
item11.addActionListener(this);
meniu1.add(item11);
JMenuItem item12 = new JMenuItem("OP 12");
item12.addActionListener(this);
meniu1.add(item12);
JMenuItem item21 = new JMenuItem("OP 21");
item21.addActionListener(this);
meniu2.add(item21);
setJMenuBar(bara);
Container x=getContentPane();
x.setLayout(new GridLayout ());
setVisible(true);
}
public void actionPerformed (ActionEvent e)
{ System.out.println(e.getActionCommand());
}
}
public class pv {
public static void main(String args[]) {
Fer fp=new Fer("Fereastra cu meniu");
}
}

 Metoda clasei JFrame setJMenuBar(JMenuBar b) are rolul de a


ata[a bara de meniu ferestrei.

Meniurile pot con]ine [i submeniuri. Pentru aceasta, unei componente


de tip JMenu i se adaug`, pe lâng` alte
componente de tip JMenuItem, o alt` component`,
tot de tip JMenu. Acesteia din urm` i se adaug`
componente de tip JMenuItem.

Exemplu: pentru a ob]ine meniul al`turat, ad`uga]i


programului de mai sus secven]a urm`toare:
//submeniuri
JMenu altele = new JMenu("Altele");
meniu1.add(altele);
220 Bazele programării în Java

JMenuItem item131 = new JMenuItem("OP 131");


altele.add(item131);
item131.addActionListener(this);

JMenuItem item132 = new JMenuItem("OP 132");


altele.add(item132);
item132.addActionListener(this);

 Evident, procedeul se poate repeta pentru a


submeniuri dori]i.
ob]ine oric@te

Acceleratori. |n multe aplica]ii, anumite op]iuni din meniuri sunt \nzestrate cu


acceleratori (shortcut-uri de meniu) prin care o anumit` comand` se poate
ob]ine fie din meniu, fie dintr-o combina]ie de taste. {i \n Java se pot crea
acceleratori [i acest mecanism este prezentat \n continuare. Metoda:
void setAccelerator(KeyStroke keyStroke)
are rolul de a ata[a unui obiect de tip JMenuItem un accelerator, adic` de
a invoca ac]iunea specific` acestuia atunci c@nd utilizatorul a ap`sat fie o
tast`, fie o combina]ie de taste. |n primul caz (o tast`), se folose[te
metoda:
static KeyStroke getKeyStroke(char keyChar),
iar \n al doilea caz metoda:
static KeyStroke getKeyStroke(int keyCode, int modifiers)

Cum ob]inem parametrii pentru a doua metod` getKeyStrohe()?

 Primul parametru este o constant` a clasei KeyEvent. Iat` c@teva


astfel de constante: static int VK_1 (tasta 1), static int VK_2
(tasta 2), static int VK_F1 (tasta F1), static int VK_V (tasta
V) [.a.m.d.
 Al doilea parametru este o constant` a clasei ActionEvent:
SHIFT_MASK, (codul 1), CTRL_MASK (codul 2) , META_MASK ( codul 4),
ALT_MASK (codul 8).

Exemplu: \n primul program de la \nceputul


paragrafului, pentru item21 doresc s` am un
accelerator, adic` s` ob]in acela[i efect prin
ap`sarea combina]iei de taste ALT+2 ca [i \n
cazul \n care oper`m selec]ia din meniu:

JMenuItem item21 = new JMenuItem("OP 21");


item21.setAccelerator(KeyStroke.getKeyStroke
(KeyEvent.VK_2, ActionEvent.ALT_MASK));
item21.addActionListener(this);
Capitolul 10. Iniţiere în programarea vizuală 221

|n acest caz, dac` ap`s`m ALT+2, ob]inem acela[i efect ca atunci


c@nd oper`m selec]ia din meniu. Dac` dorim s` ob]inem o combina]ie din
trei taste, de exemplu CTRL+ALT+2, vom folosi (datorit` codific`rii din
ActionEvent):

getKeyStroke( KeyEvent.VK_2, ActionEvent.ALT_MASK


+ ActionEvent.CTRL_MASK));

Alte tipuri de componente. Unui meniu i se pot ad`uga


[i alte componente dintre cele prezentate. Iat` un
exemplu \n care se adaug` \n meniu mai multe
butoane:

JRadioButton b1=new JRadioButton("Text 1");


meniu1.add(b1);
JButton b2=new JButton("Text2");
meniu1.add(b2);
JCheckBox b3=new JCheckBox("Text 3");
meniu1.add(b3);

Grupuri de butoane. Meniurilor li se pot ad`uga grupuri


de butoane (revede]i Gruparea butoanelor). Mai mult,
pentru a identifica un grup \n meniu, se utilizeaz`
separatori (linii orizontale) care sunt obiecte ale clasei
JSeparator().

Exemplu:
meniu1.add(new JSeparator());
JRadioButton b1=new JRadioButton("Matematica");
meniu1.add(b1);
JRadioButton b2=new JRadioButton("Informatica");
meniu1.add(b2);
JRadioButton b3=new JRadioButton("Engleza");
meniu1.add(b3);
JRadioButton b4=new JRadioButton("Biologie");
meniu1.add(b4);
meniu1.add(new JSeparator());
ButtonGroup grup = new ButtonGroup();
grup.add(b1);
grup.add(b2);
grup.add(b3);
grup.add(b4);

10.7.8. Cutii (casete) de dialog predefinite


Cutiile de dialog predefinite sunt extrem de utile pentru introducerea
sau afi[area unor date. Pentru a putea folosi astfel de cutii, vom utiliza
clasa JOptionPane care con]ine mai multe metode statice care afi[eaz`
astfel de cutii. Cutiile sunt predefinite, con]inând automat anumite
componente (nu mai este necesar ca acestea s` fie create de programator).
222 Bazele programării în Java

10.7.8.1. Cutii de dialog de intrare

Iat` c@teva metode prin care putem apela astfel de cutii:


 public static String showInputDialog(Object mes) creeaz`
[i afi[eaz` \n centrul ecranului o cutie de dialog care afi[eaz`
mesajul transmis ca parametru. |n
cazul \n care utilizatorul apas`
Cancel, se returneaz` pointer-ul
null, motiv pentru care trebuie
tratat` aceast` excep]ie.
Exemplu:
try {
String intr = JOptionPane.showInputDialog("a=");
if (intr.length()==0)
System.out.println("Intr vida");
else System.out.println(intr);}
catch(NullPointerException exc) {
System.out.println("S-a apasat Cancel");}

 public static String showInputDialog(Object mes, Object


val) la fel ca mai sus, numai c` edit-ul memoreaz` de la \nceput
valoarea transmis` de al doilea parametru (valoare ini]ial`).
|n exemplul de mai jos, valoarea ini]ial afi[at` este “0”.
String intr = JOptionPane.showInputDialog("a=","0");

 public static String showInputDialog(Component par,


Object mes) - ca mai sus, numai c` se afi[eaz` o cutie de dialog
care are o component` p`rinte. |n exemplul urm`tor, afi[area se face
cu ajutorul clasei care descrie fereastra principal`, deci p`rintele este
this (acest obiect):
String intr = JOptionPane.showInputDialog(this,"a=");

 public static String showInputDialog(Component par,


Object mes, Object val) - ca mai sus, numai c` se afi[eaz` o
cutie de dialog \n care edit-ul re]ine [i o valoare ini]ial`.

10.7.8.2. Cutii de dialog pentru afişarea mesajelor

Astfel de cutii de dialog se utilizeaz` pentru a transmite utilizatorului


anumite mesaje de eroare, sau rezultate.
 public static void showMessageDialog(Component par,
Object mes) - afi[eaz` o cutie de dialog cu un mesaj dorit.
Exemplu: clasa asociat` ferestrei se g`se[te secven]a:
Capitolul 10. Iniţiere în programarea vizuală 223

int a=125;
JOptionPane.showMessageDialog(this
, "a="+a);

10.7.8.3. Cutii de dialog de confirmare


O astfel de cutie de dialog afi[eaz` trei butoane Yes, No [i Cancel.

 public static int showConfirmDialog(Component par,


Object mes);. Metoda returneaz` un \ntreg a c`rui valoare este
dat` de butonul pe care-l apas` utilizatorul: 0 pentru Yes, 1 pentru
No sau 2 pentru Cancel.

 Observa]ie: de fapt, se returneaz` indicele butonului ap`sat: Yes are 0


pentru c` este primul buton, No are 1 pentru c` este al doilea buton, iar
Cancel are 2 deoarece este al treilea buton.

Exemplu: secven]a urm`toare


testeaz`, prin afi[are, valorile returnate
de showConfirmDialog():

int a=125;
int rasp=
JOptionPane.showConfirmDialog(this,"a="+a+"?");
System.out.println(rasp);

10.7.8.4. Cutii de dialog cu opţiuni

Aceste cutii de dialog sunt mai complexe. Ele permit s` select`m un set de
butoane (vom vedea cum) [i s` le schimb`m numele conform propriilor
dorin]e!

 public static int showOptionDialog (Component f_par,


Object mesaj, String titlu, int tip_optiune,
int tip_mesaj, Icon icon, Object[] vect,
Object buton_selectat_initial)

Parametrii metodei sunt:

 Component f_par - fereastra p`rinte;


 Object mesaj - [irul de caractere care apare afi[at \n cutie;
 String titlu - titlul ferestrei;
224 Bazele programării în Java

 int tip_optiune - se alege una dintre op]iunile urm`toare pentru a


preciza tipul butoanelor (DEFAULT_OPTION, YES_NO_OPTION,
YES_NO_CANCEL_OPTION, OK_CANCEL_OPTION);
 int tip_mesaj - are ca efect selectarea unei mici imagini care este
afi[at` pe cutie. Astfel avem valorile:

ERROR_MESSAGE INFORMATON_MESSAGE WARNING_MESSAGE QUESTION_MESSAGE

 Icon icon - icon-ul ferestrei;


 Object[] vect - vector de obiecte cu numele butoanelor;
 Object buton_selectat_initial - butonul care este selectat
ini]ial.
Exemplu: \n programul urm`tor se afi[eaz`
o astfel de cutie \n care numele butoanelor
sunt buton 1, buton 2, buton 3. La
ap`sarea unui buton se afi[eaz` un mesaj
care precizeaz` numele butonului ap`sat.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
class Fer extends JFrame implements ActionListener
{ public Fer(String titlu) {
super(titlu); setSize(200,100);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container x=getContentPane(); x.setLayout(new FlowLayout ());
JButton A=new JButton("Apasa"); x.add(A);
A.addActionListener(this); setVisible(true);
}
public void actionPerformed (ActionEvent e)
{
Object[] butoane = {"Buton 1","Buton 2","Buton 3"};
int n = JOptionPane.showOptionDialog(this,
"Apasati un buton", "Test showOptionDialog",
JOptionPane.YES_NO_CANCEL_OPTION,
JOptionPane.QUESTION_MESSAGE, null, butoane, butoane[2]);
if (n==0) JOptionPane.showMessageDialog(this, " butonul 1");
else
if (n==1) JOptionPane.showMessageDialog(this, " butonul 2");
else JOptionPane.showMessageDialog(this, " butonul 3");
}
}
public class pv1 {
public static void main(String args[]) {
Fer fp=new Fer("Fereastra cu buton") }
}
Capitolul 10. Iniţiere în programarea vizuală 225

10.7.9. Componente de tip JTextArea


Componentele de acest tip permit utilizatorului s` introduc` text pe
mai multe linii. Se poate utiliza un singur font, de o singur` m`rime! Un
astfel de text, cu un singur font, care nu permite s` fie formatat se
nume[te text plan.

Cele mai importante metode ale clasei sunt:

 JTextArea() - constructor.
 void append(String S) - adaug` la sf@r[itul [irului re]inut de
component` un alt [ir.
 void insert(String s, int pozitie) - insereaz` \n text,
\ncep@nd de la pozitie un [ir de caractere. Dac` pozitie
dep`[e[te indicele ultimului caracter, atunci inserarea se face la
sf@r[itul [irului re]inut de component`.
 void replaceRange(String str, int start, int end) -
\nlocuie[te [irul dintre indicii start [i end cu [irul transmis ca
parametru. Evident, dac` acesta din urm` este vid, se [terge \ntreg
textul.
 setFont(Font f) - seteaz` fontul utilizat.
 String getText() - returneaz` [irul de caractere con]inut de
component` (inclusiv dac` el con]ine newline, altfel spus, mai multe
paragrafe).
 void setText(String S) - determin` ca obiectul de tip
JTextArea s` re]in` [irul S.
 void setBackground(Color c) - seteaz` culoarea de fond a
suprafe]ei care afi[eaz` literele.
 String getSelectedText() - returneaz` [irul de caractere
selectat.
 void selectAll() - selecteaz` \ntreg textul re]inut de component`.
 int getSelectionStart() - returneaz` indicele primului caracter
selectat.
 int getSelectionEnd() - returneaz` indicele ultimului caracter
selectat.
 void setLineWrap(boolean v) - dac` re]ine true, seteaz`
obiectul ca textul scris f`r` newline (adic` un singur paragraf) s` se
afi[eze pe mai multe r@nduri (\n cazul \n care nu \ncape pe l`]ime).
Dac` re]ine false, acesta este afi[at pe o singur` linie, chiar dac`,
la un moment dat, nu este toat` vizibil`.
226 Bazele programării în Java

Obiectele de tip JTextArea nu se afi[eaz` pe fereastr` \n mod


direct, ci prin intermediul altor obiecte de tip JScrollPane, asem`n`toare
obiectelor de tip JPanel, dar care permit ata[area unor bare de scroll, a[a
cum se vede mai jos:
JScrollPane panel = new JScrollPane(t);
panel.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWA
YS);
panel.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_
ALWAYS);

Exemplu: programul urm`tor afi[eaz` o


component` de tip JTextArea [i un
meniu. Utilizatorul introduce un text la
alegerea sa. Textul poate fi salvat cu
ajutorul meniului (File si Save) [i poate
fi recuperat tot cu ajutorul meniului (File
[i Open). Pentru simplificarea programului
fi[ierul \n care se salveaz` este
\ntotdeauna test.txt. |nainte de a studia
programul, recomand o scurt` recapitulare
a lucrului cu fi[iere.
import java.io.*;
import java.util.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
class Fer extends JFrame implements ActionListener
{ JTextArea t;
public Fer(String titlu) {
super(titlu); setSize(200,200);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container x=getContentPane();
x.setLayout(new GridLayout());
JMenuBar bara = new JMenuBar();
JMenu meniu1 = new JMenu("File");
bara.add(meniu1);
JMenuItem item11 = new JMenuItem("Open");
item11.addActionListener(this); meniu1.add(item11);
JMenuItem item12 = new JMenuItem("Save");
item12.addActionListener(this); meniu1.add(item12);
setJMenuBar(bara);
t=new JTextArea(); t.setLineWrap(true);
JScrollPane panel = new JScrollPane(t);
panel.setVerticalScrollBarPolicy
(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
panel.setHorizontalScrollBarPolicy
(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
x.add(panel);
setVisible(true);
}
Capitolul 10. Iniţiere în programarea vizuală 227

void scriuFisier() throws IOException


{ FileOutputStream f=new FileOutputStream("test.txt");
PrintStream fchar=new PrintStream (f);
StringTokenizer tok=new StringTokenizer(t.getText(),"\n");
while (tok.hasMoreTokens()) fchar.println(tok.nextToken());
fchar.close();
}
void citFisier() throws IOException
{ FileInputStream f=new FileInputStream("test.txt");
InputStreamReader fchar=new InputStreamReader (f);
BufferedReader buf = new BufferedReader(fchar);
t.setText(""); String linie;
while ((linie=buf.readLine() )!=null) t.append(linie+"\n");
}
public void actionPerformed (ActionEvent e)
{ if( e.getActionCommand().compareTo("Save")==0)
// Daca s-a selectat Save
{ try {scriuFisier(); }
catch (Exception excp) {} }
else
// Daca s-a selectat Open
{ try {citFisier(); }
catch (Exception excp) {} }
}
}
public class pv {
public static void main(String args[]) {
Fer fp=new Fer("Fereastra din care pot introduce textul");
}
}

10.7.10. Componente de tip JProgressBar


Astfel de componente, numite bare de progres, se utilizeaz` atunci
c@nd programul efectueaz` anumite opera]ii consumatoare de timp [i se
dore[te informarea utilizatorului asupra timpului r`mas pentru executarea
opera]iei respective. Clasa JProgressBar con]ine urm`toarele metode mai
importante:

 JProgressBar() - constructor;
 void setMinimum(int a) - memoreaz` valoarea la care
componenta indic` faptul c` nu s-a efectuat nimic;
 void setMaximum(int b) - memoreaz` valoarea la care
componenta indic` faptul c` opera]ia este terminat`;
 void setValue(int c) - seteaz` valoarea pe care o re]ine
componenta la un moment dat. Ea trebuie s` fie \ntre valorile a [i b,
setate cu setMinimum() [i setMaximum().
228 Bazele programării în Java

 void setStringPainted(boolean b) - dac` prime[te ca


parametru true, seteaz` bara ca s` afi[eze un [ir de caractere.
 void setString(String s) - seteaz` [irul de caractere care va fi
afi[at de bar`. Evident, trebuie ca s` fi fost executat` metoda
anterioar` cu parametrul true.

Exemplu: programul urm`tor, la ap`sarea


butonului Start, “pune \n mi[care” o bar`
de progres. |nainte de a-l studia, revede]i
fire de execu]ie. Bara “se mi[c`” \ntr-un
fir de execu]ie separat de program.
Lansarea firului de execu]ie se face la
ap`sarea butonului. Firul de execu]ie este
oprit, temporar, la fiecare actualizare a valorii re]inute de bar`.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
class AcBara extends Thread {
JProgressBar bara;
void ref(JProgressBar bara)
{ this.bara=bara; }
public void run()
{ for (int i=0;i<=1000;i++)
{ bara.setValue(i);
bara.setString(""+i/10+"%");
try {sleep(10);}
catch (Exception e) { }
}
}
}
class Fer extends JFrame implements ActionListener
{ JProgressBar bara; AcBara t;
public Fer(String titlu) {
super(titlu);
setSize(200,100);
Container x=getContentPane();
x.setLayout(new FlowLayout ());
JButton A=new JButton("Start"); x.add(A);
A.addActionListener(this);
bara = new JProgressBar();
bara.setMinimum(0); bara.setMaximum(1000);
bara.setStringPainted(true);
x.add(bara);
setVisible(true);
}
public void actionPerformed (ActionEvent e)
{ if (t==null)
{ t= new AcBara(); t.ref(bara); t.start();}
}
}
Capitolul 10. Iniţiere în programarea vizuală 229

public class pv {
public static void main(String args[]) {
Fer fp=new Fer("Bara de progres");
WindowListener t=new Evfer();
fp.addWindowListener(t);
}
}

|ntrebare: de ce a fost necesar ca “punerea \n mi[care” a barei


s` se fac` \ntr-un fir de execu]ie [i n-am descris secven]a de
instruc]iuni \n metoda care se ruleaz` la ap`sarea butonului
(actionPerformed()) ?
R`spuns: chiar merit` \ncercat! Exerci]iu! Dar, ve]i r`m@ne dezam`gi]i.
Practic, c@nd ap`sa]i butonul, acesta r`m@ne ap`sat p@n` se desf`[oar`
\ntreaga activitate consumatoare de timp. |n acest timp bara r`m@ne
nemodificat`. La sf@r[it, ea va indica brusc 100%. De ce?
Cum crede]i c` se actualizeaz` valoarea ar`tat` de bar` atunci c@nd se
utilizeaz` setValue()? Nu este o simpl` memorare, a[a cum pare la
prima vedere! Se memoreaz` valoarea [i se genereaz` un eveniment, \n
urma c`ruia se declan[eaz` o metod` a barei care actualizeaz` desenul
pentru a indica progresul. Atunci c@nd ap`s`m butonul se declan[eaz` un
eveniment. P@n` c@nd acesta nu este tratat, adic` p@n` c@nd nu se ruleaz`
metoda actionPerformed(), celelalte evenimente sunt \n a[teptare. Prin
urmare, la sf@r[it, sunt tratate rapid toate celelalte evenimente de
redesenare a barei, dar ac]iunea dureaz` at@t de pu]in, \nc@t noi vedem c`
bara arat` deodat` 100%.

10.7.11. Componente de tip JSpinner


Componentele de tip JSpinner sunt un tip special de liste, \n care o
valoare se poate selecta cu ajutorul unor s`ge]i. Principalele metode ale
acestei clase sunt:

 JSpinner(SpinnerModel model) - constructor, unde parametrul


SpinnerModel este o interfa]`.

 void setValue(Object value) - componenta va afi[a valoarea


setat`. Aten]ie la parametru, este de tip Object. Aceast` clas` st` la
baza ierarhiei de clase din Java. Prin urmare, parametrul poate primi
o referin]` c`tre orice obiect, \n particular pentru un \ntreg. Pentru a
folosi metoda vom crea un obiect de tip Integer pe care \l
transmitem ca parametru.
Exemplu:
s =new JSpinner (m);
s.setValue(new Integer (5));
230 Bazele programării în Java

 object getValue() - returneaz` valoarea selectat` de utilizator.


Valoarea selectat` este de tip Object. Pentru a o transforma \ntr-un
\ntreg, vom proceda ca mai jos:

Exemplu: pentru componenta JSpinner s;

int k =((Integer) s.getValue()).intValue();

unde =(Integer) s.getValue() este o referin]` c`tre un obiect


Integer, c`reia i se aplic` metoda intValue() care returneaz` valoarea
re]inut` de ea.
O implementare a interfe]ei SpinnerModel este dat` de clasa
SpinnerNumberModel, care are constructorul:
SpinnerNumberModel(int v_initiala, int v_min,
int v_max, int pas)

Constructorul seteaz` o plaj` de valori cuprins` \ntre v_min [i v_max,


o valoare care va fi afi[at` ini]ial de component` (v_initiala) [i pasul de
afi[are al valorilor (pas).

Exemplu: programul urm`tor afi[eaz` o component`


de tip JSpinner [i un buton. La ap`sarea
butonului se afi[eaz` valoarea selectat` \n
component`.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
class Fer extends JFrame implements ActionListener
{ JSpinner s;
public Fer(String titlu) {
super(titlu); setSize(200,100);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container x=getContentPane();
x.setLayout(new FlowLayout ());
SpinnerNumberModel m= new SpinnerNumberModel (0,-10, 10, 1);
s =new JSpinner (m); x.add(s);
JButton A=new JButton("Ce-am selectat?");
x.add(A);
A.addActionListener(this);
setVisible(true);
}
public void actionPerformed (ActionEvent e)
{ System.out.println(((Integer) s.getValue()).intValue());}
}
public class pv {
public static void main(String args[]) {
Fer fp=new Fer("JSpinner");
}
}
Capitolul 10. Iniţiere în programarea vizuală 231

10.7.12. Cutii de tip Open / Save

Astfel de cutii se utilizeaz` \n opera]iile de \nc`rcare [i salvare a


fi[ierelor. Cu ajutorul lor se selecteaz` fi[ierele [i folder-ele necesare acestor
opera]ii. Ele pot fi ob]inute cu metodele clasei JFileChooser(). Cele mai
importante metode ale acestei clase sunt:
 JFileChooser() - constructor;
 int showOpenDialog(Component fer_parinte) - afi[eaz` o cutie
de dialog de tip Open, a[a cum este cea de mai jos:

Valoarea returnat` este 0, dac` s-a ap`sat butonul Open sau este 1
dac` s-a ap`sat butonul Close. Rolul ei este ca, atunci c@nd a fost
selectat un anumit fi[ier [i s-a ap`sat Open, obiectul de tip
JFileChooser s` con]in` date despre fi[ierul selectat.
 int showSaveDialog(Component fer_parinte) - afi[eaz` o cutie
de dialog de tip Save, asem`n`toare cu cutia precedent`. Valoarea
returnat` este 0 dac` s-a ap`sat butonul Save [i 1 dac` s-a ap`sat
butonul Cancel. Ca [i cutia precedent` (de tip Open), rolul ei este
ca obiectul de tip JFileChooser s` con]in` date despre fi[ierul
salvat.


Aten]ie: cutia de tip Open nu deschide fi[ierul, iar cutia de tip Save
nu-l salveaz`. Rolul lor este de a ob]ine informa]iile necesare
deschiderii [i salv`rii fi[ierelor.
 File getSelectedFile() - metoda returneaz`, at@t \n cazul
salv`rii, c@t [i \n cazul deschiderii fi[ierelor, date despre fi[ierul
selectat (furnizate de showOpenDialog() [i showSaveDialog()).
Pentru a putea accesa aceste informa]ii, trebuie s` studiem c@teva
metode ale tipului File.
232 Bazele programării în Java

 void addChoosableFileFilter(Filter x); - metoda se


utilizeaz` pentru a ad`uga un filtru cutiilor de tip Open [i Save.
Despre filtre vom \nv`]a \n cadrul acestui paragraf.
 setCurrentDirectory(File f) - seteaz` cutia astfel \nc@t s` se
deschid` \ntr-un anumit folder.
Clasa File. Cele mai importante metode ale acestei clase sunt:
 File() - constructor;
 File(String nume) - construie[te un obiect care con]ine numele unui
fi[ier (folder).
 boolean isDirectory() - returneaz` true dac` fi[ierul re]inut de
obiect este folder (folder-ele sunt fi[iere speciale), sau false \n caz
contrar.
 String getName() - returneaz` numele fi[ierului.
 String getPath() - returneaz` numele \ntreg al fi[ierului, inclusiv
calea c`tre el.
Filtre. |n partea de jos a cutiilor de tip Open sau Save se g`se[te o list`
(File Name). Dac` programul nostru nu con]ine un filtru, implicit se
afi[eaz` doar op]iunea All Files, adic` cutiile vizualizeaz` toate folder-ele
[i toate fi[ierele, indiferent de tipul lor. |n cazul \n care dorim ca programul
s` con]in` filtre, adic` s` se vizualizeze doar fi[ierele de un anumit tip (sau
tipuri), vom utiliza clasa FileFilter.
Clasa FileFilter este abstract`. Pentru a crea un filtru este necesar s`
rescriem dou` metode ale sale:
 public String getDescription() - trebuie s` returneze un [ir de
caractere care va fi afi[at de lista File of Type, list` con]inut` de
cutiile Open [i Save.
 public boolean accept(File f) - metod` care returneaz` true
pentru un fi[ier care, fie are o extensie dorit`, fie este de tip folder,
altfel returneaz` false. Dac` metoda returneaz` true, fi[ierul este
aflat de cutiile Open/Save, altfel acesta nu este afi[at.
Exemple de utilizare a cutiilor Open [i Save:
1. Programul urm`tor afi[eaz` o fereastr` cu
dou` butoane: Open [i Save. La ap`sarea
unuia dintre ele se afi[eaz` cutia respectiv`.
Dup` ce utilizatorul selecteaz` fi[ierul (pentru
Open) sau selecteaz` folder-ul [i scrie \n edit-
ul corespunz`tor numele fi[ierului, \n fereastra
CMD se va afi[a numele fi[ierului selectat, inclusiv calea. Cutiile Open [i
Save vor afi[a doar folder-ele [i fi[ierele cu extensiile .java [i .txt.
Capitolul 10. Iniţiere în programarea vizuală 233

import java.io.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

class Filtre extends javax.swing.filechooser.FileFilter {


// redefinesc cele doua functii pentru filtru
public boolean accept(File f) {
if (f.isDirectory()) { return true;}
String nume_fis = f.getName();
return nume_fis.endsWith(".java") || nume_fis.endsWith(".txt") ;
}
public String getDescription() {
return "*.java" + " "+"*.txt" ;}
}
class Fer extends JFrame implements ActionListener
{ public Fer(String titlu) {
super(titlu); setSize(200,100);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container x=getContentPane();
x.setLayout(new FlowLayout ());
JButton A=new JButton("Open"); x.add(A);
JButton B=new JButton("Save"); x.add(B);
A.addActionListener(this);
B.addActionListener(this);
setVisible(true);
}
public void actionPerformed (ActionEvent e)
{ if (e.getActionCommand().compareTo("Open")==0)
// daca am apasat Open
{ JFileChooser c_op = new JFileChooser();
c_op.addChoosableFileFilter(new Filtre());
int valRet = c_op.showOpenDialog(this);
if (valRet==0)
{ File f=c_op.getSelectedFile();
System.out.println(f.getPath());}
}
else
// daca am apasat Save
{ JFileChooser c_save = new JFileChooser();
c_save.addChoosableFileFilter(new Filtre());
int valRet = c_save.showSaveDialog(this);
if (valRet==0)
{ File f=c_save.getSelectedFile();
System.out.println(f.getPath());}
}
}
}
public class pv {
public static void main(String args[]) {
Fer fp=new Fer("Open/Save");
}
}
234 Bazele programării în Java

2. Programul de mai jos este un editor primitiv de


fi[iere text. El nu con]ine \n meniu dec@t dou`
op]iuni: Open [i Save. Oricare dintre ele are ca
efect afi[area cutiilor respective [i salvarea sau
deschiderea cu afi[are a unui fi[ier cu una din
extensiile .java [i .txt. Afi[area fi[ierului se
face cu ajutorul unei componente de tip
JTextArea.
import java.io.*;
import java.util.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
class Filtre extends javax.swing.filechooser.FileFilter
public boolean accept(File f) {
if (f.isDirectory()) {return true;}
String nume_fis = f.getName();
return nume_fis.endsWith(".java") || nume_fis.endsWith(".txt");
}
public String getDescription() {
return "*.java" + " "+"*.txt" ;}
}
class Fer extends JFrame implements ActionListener
{ JTextArea t;
public Fer(String titlu) {
super(titlu); setSize(200,200);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container x=getContentPane();
x.setLayout(new GridLayout());
JMenuBar bara = new JMenuBar();
JMenu meniu1 = new JMenu("File"); bara.add(meniu1);
JMenuItem item11 = new JMenuItem("Open");
item11.addActionListener(this); meniu1.add(item11);
JMenuItem item12 = new JMenuItem("Save");
item12.addActionListener(this); meniu1.add(item12);
setJMenuBar(bara);
t=new JTextArea(); t.setLineWrap(true);
JScrollPane panel = new JScrollPane(t);
panel.setVerticalScrollBarPolicy
(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
panel.setHorizontalScrollBarPolicy
(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
x.add(panel); setVisible(true);
}
void scriuFisier(String nume) throws IOException
{ FileOutputStream f=new FileOutputStream(nume);
PrintStream fchar=new PrintStream (f);
StringTokenizer tok=new StringTokenizer(t.getText(),"\n");
while (tok.hasMoreTokens()) fchar.println(tok.nextToken());
fchar.close();
}
Capitolul 10. Iniţiere în programarea vizuală 235

void citFisier(String nume) throws IOException


{ FileInputStream f=new FileInputStream(nume);
InputStreamReader fchar=new InputStreamReader (f);
BufferedReader buf = new BufferedReader(fchar);
t.setText("");
String linie;
while ((linie=buf.readLine() )!=null) t.append(linie+"\n");
}
public void actionPerformed (ActionEvent e)
{ if( e.getActionCommand().compareTo("Open")==0)
{ JFileChooser c_op = new JFileChooser();
c_op.addChoosableFileFilter(new Filtre());
int valRet = c_op.showOpenDialog(this);
if (valRet==0)
{ File f=c_op.getSelectedFile();
{ try { citFisier(f.getPath()); }
catch (Exception excp) {}
}
}
}
else
{ JFileChooser c_save = new JFileChooser();
c_save.addChoosableFileFilter(new Filtre());
int valRet = c_save.showSaveDialog(this);
if (valRet==0)
{ File f=c_save.getSelectedFile();
{ try {scriuFisier(f.getPath()); }
catch (Exception excp) {} }
}
}
}
}
public class pv {
public static void main(String args[]) {
Fer fp=new Fer("Fereastra din care pot introduce textul");
}
}

10.7.13. Componente de tip JColorChooser


|n programarea vizual` culorile au un rol fundamental. Pentru a u[ura
selectarea culorilor, Java pune la dispozi]ia programatorilor clasa
JColorChooser. |n linii mari, aceast` clas` permite afi[area unui panou
prin care se selecteaz` u[or culorile (fie direct, fie folosind sistemul RGB, fie
folosind sistemul HSL). Iat` cele mai importante metode ale acestei clase:

 JColorChooser() - constructor. |n panoul culorilor este automat


selectat` culoarea alb`;
 JColorChooser(Color c) - constructor. |n panoul culorilor este
automat selectat` culoarea transmis` ca parametru;
236 Bazele programării în Java

 static Color showColorDialog (Component parinte, String mes,


Color c) - lanseaz`, modal, o cutie de dialog care con]ine panoul
culorilor. Dup` cum observa]i, metoda returneaz` culoarea selectat`
(dac` se apas` butonul OK, iar dac` se apas` Cancel se returneaz`
null). Parametrii sunt: parinte (fereastra p`rinte), mes (mesaj ce se
afi[eaz` pe bara de titlu a cutiei) [i c (culoarea ini]ial setat` \n cutie).
Utilizarea acestei metode este cel mai simplu mecanism prin care
utilizatorul poate selecta culoarea.

 Color getColor() - returneaz` culoarea selectat` \n cutie.

Exemplu. Din fereastra principal`,


la ap`sarea unui buton se afi[eaz`
o cutie de dialog specific` pentru
selectarea culorii. Culoarea
selectat` va fi culoarea de fond a
ferestrei principale.

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

class Fer extends JFrame


implements ActionListener
{
Container x;
public Fer(String titlu) {
super(titlu);
setSize(200,100);
x=getContentPane();
x.setLayout(new FlowLayout ());
JButton A=new JButton("Alta culoare");
x.add(A);
A.addActionListener(this);
setVisible(true);
}
public void actionPerformed (ActionEvent e)
{
Color c=JColorChooser.showDialog
(this, "Alege culoarea", Color.red);
if (c!=null) x.setBackground(c);
}
}

public class pv1 {


public static void main(String args[]) {
Fer fp=new Fer("Schimbarea culorii ferestrei");
}
}
Capitolul 10. Iniţiere în programarea vizuală 237

10.7.14. Componente de tip JToolBar

O astfel de component` creeaz` o “bar` cu unelte”. Pe ea se a[eaz`


numeroase alte componente, \ntocmai ca pe un panel. De regul` se
g`se[te \n partea de sus a ferestrei, dar \ntotdeauna sub meniu.
Clasa JToolBar con]ine urm`toarele metode mai importante:

 JToolBar() - constructor, creeaz` o bar` de unelte pozi]ionat`


orizontal;
 JToolBar(int orientare) - creeaz` o bar` de unelte orientat` fie
orizontal, orientare va avea valoarea JToolBar.HORIZONTAL, fie
vertical, orientare va avea valoarea JToolBar.VERTICAL. Diferen]a
de orientare afecteaz` modul \n care sunt a[ezate pe ea diferitele
componente (pe orizontal sau pe vertical).
 Component add(Component comp) - adaug` o component`;
 void addSeparator() - adaug` un separator (spa]iu liber) \ntre
componente.
Exemplu: mai jos pute]i observa
programul care afi[eaz` o
ferastr` cu o bar` de unelte [i
\n rest, un panel (component` de
tip JPanel):
import java.awt.*;
import javax.swing.*;

class Fer extends JFrame


{ public Fer(String titlu) {
super(titlu);
setSize(600,800);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container x=getContentPane();
JToolBar bara=new JToolBar();
bara.setBackground(Color.red);
bara.setLayout(new FlowLayout(FlowLayout.LEFT));
JPanel panel=new JPanel();
panel.setBackground(Color.yellow);
JComboBox lista=new JComboBox ();
x.setLayout(new BorderLayout());
x.add(bara,BorderLayout.NORTH);
x.add(panel,BorderLayout.CENTER);
JButton A=new JButton("buton 1");
bara.add(A);
A.setPreferredSize(new Dimension (70,30));
JButton B=new JButton("buton 2");
B.setPreferredSize(new Dimension (70,30));
bara.add(B);
238 Bazele programării în Java

bara.addSeparator();
lista.addItem("Optiunea 1");
lista.addItem("Optiunea 2");
bara.add(lista);
lista.setPreferredSize(new Dimension (100,30));
setVisible(true);
}
}
public class pv {
public static void main(String args[]) {
Fer fp=new Fer("Bara cu unelte");
}
}

 Observa]ii:
1. Pentru a pozi]iona bara orizontal se prefer` gestionarul GridLayout [i
bara se a[eaz` \n nord.
2 |n aceste condi]ii, panelul s-a aranjat \n centru. Cum celelalte trei
componente lipsesc, componenta din centru ocup` toat` linia din mijloc, iar
linia din mijloc ocup` [i partea de sud!
3. Pentru bar` se prefer` gestionarul FlowLayout (FlowLayout.LEFT)
care aranjeaz` componentele pe bar` de la dreapta la st@nga, dar aliniate
st@nga!
4. Pentru a ne asigura c` butoanele [i lista au aceea[i \n`l]ime, am
preferat dimensionarea lor prin setPreferredSize().
5. |ntre cele dou` butoane [i list` a fost introdus un separator. Observa]i-
l \n imaginea de pe pagina anterioar`!

10.7.15. Componente de tip JTable


Cu ajutorul componentelor de acest tip se creeaz` tabele. |n
continuare prezent`m cele mai importante metode ale acestui tip.
 JTable(Object[][] celule, object[] cap_t) - constructor.
Parametrul celule este o matrice de referin]e c`tre obiectele afi[ate
de celulele tabelului, iar cap_t este un vector de referin]e c`tre
obiectele afi[ate de capul de tabel. Num`rul coloanelor matricei de
referin]e celule trebuie s` coincid` cu num`rul elementelor vectorului
de referin]e cap_t [i reprezint` num`rul coloanelor din tabel.
|nainte de a da primul exemplu de tabel, trebuie precizat c` aceast`
component` se plaseaz`, de obicei, pe o component` de tip JScroolPane.
 public void setPreferredScrollableViewportSize(Dimension dim)
are rolul de preciza dimensiunea tabelului [i faptul c` acesta trebuie
s` con]in` o bara scroll vertical` (dac` tabelul are suficiente linii astfel
\nc@t s` nu \ncap` \n totalitate \n spa]iul generat de dim).
Capitolul 10. Iniţiere în programarea vizuală 239

Exemplu: tabelul al`turat a fost ob]inut


cu secven]a de mai jos:
class Fer extends JFrame
{ public Fer(String titlu) {
super(titlu);setSize(600,800);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Object[][] date = {
{"x(0,0)", "x(0,1)","x(0,2)"},
{"x(1,0)", "x(1,1)","x(1,2)"}
};
String[] cap_tabel = {"Coloana 1", "Coloana 2", "Coloana 3"};
Container x=getContentPane();
x.setLayout(new FlowLayout());
JTable table = new JTable(date, cap_tabel);
JScrollPane panel = new JScrollPane(table);
table.setPreferredScrollableViewportSize
(new Dimension(200, 30));
x.add(panel);setVisible(true);
}
}

 Dac` dorim, putem inversa ordinea coloanelor \n tabel prin drag


and drop. |ncerca]i!
Tabelul este, de fapt, format din dou` componente: tabelul propriu-zis
(de tip JTable) [i capul de tabel (de tip JTableHeader).

 JTableHeader getTableHeader()- metoda returneaz` o referin]`


c`tre capul de tabel.

Imediat ce cre`m un tabel ne punem problema culorilor de fond [i de


scriere, at@t pentru capul de tabel c@t [i pentru tabelul propriu-zis. Dac`
ambele sunt componente, atunci putem utiliza metodele clasei JComponent:
setBackground(), setForeground() [i setColor().

Exemplu: ad`uga]i exemplului anterior secven]a de mai jos [i ve]i ob]ine


efectul scontat!
// pentru tabel
table.setFont(new Font("Arial",Font.ITALIC, 10));
table.setBackground(Color.GREEN);
table.setForeground(Color.RED);
// pentru capul de tabel
JTableHeader cap= table.getTableHeader();
cap.setFont(new Font("Arial",Font.BOLD, 12));
cap.setBackground(Color.YELLOW);
cap.setForeground(Color.RED);

Observa]i faptul c` fiecare celul` a tabelului este editabil`. Aceasta

 \nseamn` c` dac` execut`m click pe celula respectiv`, aceasta se


comport` ca un edit oarecare. De aici, rezult` faptul c` un tabel poate
fi folosit [i pentru introducerea datelor, nu doar pentru afi[area lor!
240 Bazele programării în Java

 Object getValueAt(int linie, int coloana) \ntoarce o


referin]` c`tre obiectul memorat de celula respectiv`;
 void setValueAt(Object ref, int linie, int coloana) -
memoreaz` referin]a c`tre obiect \n linia [i coloana dat` de indicii
transmi[i.
 JTable(int n_linii, int n_coloane) - este un alt constructor
al tabelului, \n care se creeaz` un tabel n_linii [i n_coloane).
Liniile sunt numerotate \ncep@nd de la 0. De asemenea, coloanele
sunt numerotate \ncep@nd de la 0.

Exemplu: programul urm`tor creeaz`


un tabel f`r` date cu 2 linii [i 4
coloane. Utilizatorul introduce date \n
fiecare celul` a tabelului. La
ap`sarea butonului se afi[eaz`, \n fereastra CMD, valorile re]inute de fiecare
celul`. Observa]i faptul c` numele coloanelor a fost dat automat.
import java.awt.*;
import javax.swing.*;
import javax.swing.table.*;
import java.awt.event.*;
class Fer extends JFrame implements ActionListener
{ JTable table;
public Fer(String titlu) {
super(titlu);setSize(600,800);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container x=getContentPane();
x.setLayout(new FlowLayout());
table = new JTable(3, 4);
JScrollPane panel = new JScrollPane(table);
table.setPreferredScrollableViewportSize
(new Dimension(200, 30));
x.add(panel);
JButton A=new JButton("Afiseaza"); x.add(A);
A.addActionListener(this);
setVisible(true);
}
public void actionPerformed (ActionEvent e)
{ if (table.getCellEditor() != null)
table.getCellEditor().stopCellEditing();
for (int i=0;i<2;i++)
for (int j=0;j<4;j++)
System.out.println(i+" "+j+" "+table.getValueAt(i,j));
}
}
public class pv {
public static void main(String args[]) {
Fer fp=new Fer("Tabel");
}
}
Capitolul 10. Iniţiere în programarea vizuală 241

S` urm`rim metoda actionPerformed(). Ce rost are acel if?


Atunci c@nd se scriu datele \ntr-o celul`, p@n` nu s-a trecut la celula
urm`toare (click pe suprafa]a ei), data con]inut` de ea nu este memorat` [i
prin urmare, la afi[are va ap`rea null (obiectul null). Pentru a evita
aceasta, s-a utilizat metoda getCellEditor() a clasei JTable.

 TableCellEditor getCellEditor() - metoda returneaz` o


referin]` c`tre un obiect dac` o celul` a tabelului este sub editare [i
null \n caz contrar. TableCellEditor este o interfa]` care, evident,
este implementat`. F`r` a intra \n am`nunte, interfa]a con]ine antetul
metodei stopCellEditing(), metod` care are rolul de a stopa
editarea [i, prin urmare, de memorare a tuturor datelor introduse \n
tabel.

|n continuare, vedem cum putem proiecta capul de tabel! Clasa


JTable con]ine metodele:

 TableColumnModel getColumnModel(). TableColumnModel este


o interfa]`, implementat` de o anumit` clas`
(DefaultTableColumnModel). Prin urmare, putem utiliza metodele
clasei pornind de la referin]a \ntoars` de metod`. Cu ajutorul lor
proiect`m capul de tabel.

 TableColumn getColumn(int index) - returneaz` o referin]` c`tre


un obiect TableColumn. Un astfel de obiect con]ine toate atributele
unei coloane a tabelului. Iat` c@teva metode, mai importante ale
acestui obiect:

 void setHeaderValue(Object ob) - seteaz` obiectul afi[at de


coloana respectiv` (numele coloanei).
 setPreferredWidth(int lat) - seteaz` l`]imea coloanei.

 setResizable(boolean v); - \n mod normal, marginile unei


coloane se pot deplasa, astfel \nc@t l`]imea coloanei poate fi stabilit`
[i de utilizator. Dac` metoda prime[te ca parametru valoarea false,
marginile nu mai pot fi stabilite de utilizator.

Exemplu: secven]a de mai jos ne arat` cum


putem construi un tabel precum cel al`turat,
care con]ine numele coloanelor, dar \n care,
primei coloane nu i se poate modifica
l`]imea (implicit, [i celeilalte coloane).
table = new JTable(6, 2);
TableColumnModel mColoane=table.getColumnModel();
TableColumn coloana=mColoane.getColumn(0);
coloana.setHeaderValue("Coloana 1");
242 Bazele programării în Java

coloana.setPreferredWidth(150);
coloana.setResizable(false);
coloana=mColoane.getColumn(1);
coloana.setHeaderValue("Coloana 2");
JScrollPane panel = new JScrollPane(table);
table.setPreferredScrollableViewportSize
(new Dimension(200, 80));

Alte metode ale clasei JTable:


 void setGridColor(Color c) - seteaz` culoarea liniilor care separ`
celulele tabelului.
 void setRowHeight(int inalt) - seteaz` \n`l]imea liniilor
tabelului (\n pixeli).
 void setSelectionBackground(Color c) - seteaz` culoarea liniei
selectate (atunci c@nd se execut` click pe o celul`, se selecteaz`
\ntreaga linie).
 void setSelectionForeground(Color c) - seteaz` culoarea cu
care se scrie \n linia selectat` (mai pu]in celula \n care se editeaz`).
 setIntercellSpacing(Dimension dim) - seteaz` spa]iile \ntre linii
[i coloane. Aceasta nu afecteaz` liniile separatoare dintre celule
(vecine), ci numai spa]iul dintre p`rtile lor editabile. Primul parametru
pentru dim este pentru linii, al doilea parametru este pentru coloane.

 void setShowHorizontalLines(boolean v) - dac` parametrul


este false, atunci nu mai sunt trasate liniile orizontale ale tabelului.

 setShowGrid(boolean v) - dac` parametrul este false, atunci


nu mai sunt trasate liniile orizontale [i verticale ale tabelului.

10.8. Mai mult despre clasa Container

Este momentul s` analiz`m modul \n care fereastra aplica]iei re]ine


componentele grafice ata[ate. Logic vorbind, este nevoie de o variabil`,
asem`n`toare unui vector, \n care fiecare component` a sa va re]ine
referin]e c`tre componentele grafice. De asemenea, este necesar` [i o
variabil` care re]ine o referin]` c`tre gestionarul de pozi]ionare. Atunci c@nd
ata[`m ferestrei componente grafice, mai \nt@i declar`m o referin]` la un
obiect al clasei Container [i o ini]ializ`m cu adresa obiectului de tip
Container al ferestrei (returnat` de metoda clasei JFrame, numit`
getContentPane()):

Exemplu: Container x=getContentPane();.


Capitolul 10. Iniţiere în programarea vizuală 243

Clasa Container con]ine mai multe metode, dintre care le prezent`m


pe urm`toarele:

 Component add(Component c); - adaug` o component` container-


ului. Cum orice component` este un obiect al unei clase derivate din
clasa Component, parametrul metodei poate fi utilizat pentru a
transmite referin]e c`tre orice tip de component`. P@n` \n prezent am
folosit de multe ori aceast` metod`.

 int getComponentCount(); returneaz` num`rul componentelor


re]inute de container.


Spuneam c` un container este asem`n`tor unui vector. Astfel, prima
component` ad`ugat` cu metoda de mai sus are indicele 0, a doua
component` are indicele 1, [.a.m.d.

 Component getComponent(i); - returneaz` referin]a la componenta


de indice i.

Am precizat faptul c` tipurile tuturor componentelor grafice pe care


le-am studiat sunt derivate din clasa Component, dar nu direct. Aceasta din
urm` con]ine [i metodele:
 void setName(String name); - metoda prin care unei
componente, indiferent de tipul ei, i se poate ata[a un nume. Acesta
poate fi folosit atunci c@nd trebuie s` detect`m o anumit` component`
din container.

 String getName(); - metoda returneaz` numele componentei dat


prin setName().

Prin operatorul de conversie explicit`, o referin]` de tip Component


poate fi convertit` c`tre o referin]` la o component` de un anumit tip,


numai dac` componenta propriu-zis` are tipul respectiv. De exemplu,
dac` c este tip Component [i re]ine adresa unui obiect de tip
JButton, atunci conversia JButton buton (JButton)c; este
corect`. Dac` \ns` c re]ine adresa unei componente de tip JLabel,
atunci prin conversia de mai sus se ob]ine o excep]ie.

|n cazul componentelor de tip JPanel, lucrurile stau pu]in diferit, \n


sensul c` pentru a depista componentele pe care le con]ine, vom utiliza
metodele de mai jos (ale tipului JPanel):

 Ad`ugarea unei componente se face cu metoda add() a tipului


JPanel, a[a cum suntem deja obi[nui]i;

 Component[] getComponents() returneaz` un vector de referin]e


c`tre componente.
244 Bazele programării în Java

Exemplu: programul urm`tor creeaz` o fereastr` cu diverse componente: un


buton, o etichet` (obiect de tip JLabel) [i un panel (obiect de tip JPanel).
Acesta din urm` con]ine un buton [i o etichet`. Toate componentele au
primit un nume. La ap`sarea butonului
Componente, se afi[eaz` numele tuturor
componentelor din fereastr` [i panel.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
class Fer extends JFrame implements ActionListener
{ Container x; JPanel panel;
public Fer(String titlu) {
super(titlu);setSize(300,200);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
x=getContentPane();
x.setLayout(new FlowLayout ());
// Adaug elemente pe fereastra si panel
JButton A=new JButton("Componente");
A.setName("Buton A"); x.add(A);
JLabel et =new JLabel("O eticheta");
et.setName("Eticheta et");x.add(et);
JTextField txt=new JTextField(20);
txt.setName("edit-ul txt");x.add(txt);
panel=new JPanel(new FlowLayout());panel.setName("panelul");
JButton B=new JButton("Buton pe panel");
B.setName("Buton pe panel");panel.add(B);
JLabel et1 =new JLabel("Eticheta pe panel");
et1.setName("Eticheta pe panel"); panel.add(et1);
x.add(panel);
A.addActionListener(this);
setVisible(true);
}
public void actionPerformed (ActionEvent e)
{ int nr_comp=x.getComponentCount();
System.out.println
("Numar componente atasate ferestrei="+nr_comp);
// afisez numele componentelor de pe fereastra
for(int i=0;i<nr_comp;i++)
{ Component c=x.getComponent(i);
System.out.println(c.getName());}
Component[] vect=panel.getComponents();
System.out.println
("Numar componente atasate panelului="+vect.length);
// afisez numele componentelor de pe panel
for(int i=0;i<vect.length;i++)
{ Component c=vect[i];
System.out.println(c.getName());}
}
}
public class pv {
public static void main(String args[]) {
Fer fp=new Fer("Fereastra cu diverse componente");}
}
Capitolul 10. Iniţiere în programarea vizuală 245

10.9. Cutii de dialog


P@n` \n prezent am studiat numai cutiile de dialog predefinite. Desigur,
cutiile predefinite sunt u[or de folosit, dar nu r`spund tuturor necesit`]ilor.
Uneori, suntem obliga]i s` cre`m cutii de dialog care s` includ`
componentele pe care le dorim. |n acest paragraf vom prezenta modul \n
care putem construi cutiile de dialog dup` propria dorin]`.

Pentru \nceput trebuie spus c` putem afi[a o cutie de dialog \n dou`


feluri:
A) Modal - dup` afi[area cutiei nu mai putem ac]iona asupra ferestrei din
care aceasta a fost lansat`.
B) Nemodal - de[i cutia este afi[at`, putem ac]iona [i asupra
componentelor re]inute de cutie, dar [i asupra componentelor din fereastra
din care aceasta a fost lansat`.

Pentru a construi o cutie de dialog trebuie s` [tim c`:

1. Cutia de dialog propriu-zis` se ob]ine ca instan]iere a unei clase


derivat` din clasa JDialog. Clasa JDialog con]ine constructorul:

 JDialog (Dialog fer_parinte,String titlu,boolean modal)


prin care se specific` fereastra p`rinte (fereastra care con]ine
comanda care a lansat-o), titlul ferestrei [i un parametru de tip
boolean, care dac` re]ine true, afi[area va fi modal`, iar dac` re]ine
false, afi[area va fi nemodal`.

2. Clasa JDialog, ca [i clasa JWindow au o superclas` comun`


(Window). Aceasta are ca efect faptul c` putem construi cutia la fel cum
am construit fereastra principal`.

Exemplul  (afi[are modal`)


programul urm`tor afi[eaz`
fereastra al`turat`:

Dac` se apas` butonul “Afi[eaz` cutia” se


afi[eaz` cutia de dialog al`turat`. Introduce]i
\n edit un [ir oarecare de caractere [i ap`sa]i
butonul “Inchide cutia!”

Analiza]i modul \n care am detectat [irul de caractere introdus \n edit prin


ap`sarea butonului “Ce-am citit?”. Va ap`rea cutia de dialog standard
de mai jos:
246 Bazele programării în Java

Prezent`m programul:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
class Dial extends JDialog implements ActionListener
{
// Constructia cutiei de dialog
JButton buton=new JButton("Inchide cutia!");
JTextField txt=new JTextField(10);
Container y;
String sir=txt.getText();
Dial (JFrame parinte,String mesaj, boolean modal)
{ super(parinte,mesaj,modal);
y=getContentPane();
setSize(200,200);
y.setLayout(new FlowLayout());
y.add(buton);
y.add(txt);
buton.addActionListener(this);
setVisible(true);
}
public void actionPerformed (ActionEvent e)
// inchide cutia
{ setVisible(false);}
}
class Fer extends JFrame implements ActionListener
{
Dial cutie=null;
public Fer(String titlu) {
super(titlu);
setSize(400,400);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container x=getContentPane();
x.setLayout(new FlowLayout ());
JButton A=new JButton("Afiseaza cutia"); x.add(A);
A.addActionListener(this);
JButton B=new JButton("Ce-am citit?");
x.add(B);
B.addActionListener(this);
setVisible(true);
}
public void actionPerformed (ActionEvent e)
{
//Daca a fost apasat butonul “Afiseaza cutia”
if( e.getActionCommand().compareTo("Afiseaza cutia")==0)
//daca cutia nu a fost afisata
if (cutie==null) cutie=new Dial(this,"Cutie de dialog",
true);
// daca cutia a fost afisata
else cutie.setVisible(true);
Capitolul 10. Iniţiere în programarea vizuală 247

else
//daca a fost apasat butonul “Ce-am citit?”
if (cutie!=null)
{ // recuperez container-ul cutiei
Container t=cutie.y;
// recuperez referinta catre edit
JTextField com=(JTextField)t.getComponent(1);
// recuperez continutul edit-ului
JOptionPane.showMessageDialog(this,com.getText());
}
// daca vreau sa vad ce-am scris fara sa fi afisat cutia
else JOptionPane.showMessageDialog
(this,"Mai intai afiseaza cutia de dialog");
}
}
public class pv {
public static void main(String args[]) {
Fer fp=new Fer("Fereastra din care apelez cutia");
}
}

 Observa]ii:

 A \nchide o fereastr` (cutie de dialog) \nseamn` a o face invizibil`


(setVizible(false)). A deschide o fereastr`, deja creat`, care a
fost \nchis` \nseamn` a o face vizibil` (setVizible(true)). Prin
urmare, chiar dac` fereastra a fost \nchis`, pornind de la o referin]`
c`tre container-ul ei, putem accesa componentele pe care fereastra
(cutia de dialog) le con]ine, deoarece ea exist` \n memorie.

 Practic, datele din cutie se pot recupera pornind de la container-ul


cutiei, iar dac` se dore[te, din cutie se pot accesa datele ferestrei
pornind de la referin]a c`tre p`rintele cutiei, adic` fereastra.

Exemplul  (afi[are nemodal`). Programul de


mai jos creeaz` o fereastr` cu un buton. La
ap`sarea lui, se afi[eaz` o cutie de dialog cu
dou` butoane. Prin ap`sarea oric`rui buton al
cutiei, se schimb` culoarea de fond a ferestrei
principale.

Cutia de dialog este afi[at` nemodal! Practic, dac`


ap`s`m un buton al ei, culoarea ferestrei principale
se schimb` instantaneu, f`r` s` fim nevoi]i s`
\nchidem cutia.
248 Bazele programării în Java

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
class Dial extends JDialog implements ActionListener
{ Container y;
JFrame frs;
Dial (JFrame parinte,String mesaj, boolean modal)
{ super(parinte,mesaj,modal);
y=getContentPane();
frs=parinte;
setSize(100,100);
y.setLayout(new FlowLayout());
JButton b1=new JButton("Rosu"); y.add(b1);
b1.addActionListener(this);
JButton b2=new JButton("Galben"); y.add(b2);
b2.addActionListener(this);
setVisible(true);
}
public void actionPerformed (ActionEvent e)
{ Container z=frs.getContentPane();
if( e.getActionCommand().compareTo("Rosu")==0)
z.setBackground(Color.red);
else z.setBackground(Color.yellow);
}
}
class Fer extends JFrame implements ActionListener
{ Dial cutie=null;
public Fer(String titlu) {
super(titlu);
setSize(150,100);
Container x=getContentPane();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
x.setLayout(new FlowLayout ());
JButton A=new JButton("Seteaza culoarea"); x.add(A);
A.addActionListener(this);
setVisible(true);
}
public void actionPerformed (ActionEvent e)
{ if (cutie==null) cutie=new Dial(this,"Seteaza culoarea",
false);
else cutie.setVisible(true);
}
}
public class pv {
public static void main(String args[]) {
Fer fp=new Fer("Culori");
}
}

Exemplul  Din fereastra principal` se afi[eaz` nemodal o cutie de dialog


care con]ine un buton [i o component` de tip JColorChooser. Utilizatorul
selecteaz` culoarea [i apas` butonul. Automat (f`r` \nchiderea cutiei),
fereastra principal` va avea culoarea selectat`.
Capitolul 10. Iniţiere în programarea vizuală 249

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

class Dial extends JDialog implements ActionListener


{ Container y;
JColorChooser col;
JFrame frs;
Dial (JFrame parinte,String mesaj, boolean modal)
{ super(parinte,mesaj,modal);
y=getContentPane();
frs=parinte; setSize(500,500);
y.setLayout(new FlowLayout());
JButton b=new JButton("Gata!"); y.add(b);
b.addActionListener(this);
col = new JColorChooser(Color.yellow);
y.add(col);
setVisible(true);
}
public void actionPerformed (ActionEvent e)
{ Container z=frs.getContentPane();
z.setBackground(col.getColor());
}
}

class Fer extends JFrame implements ActionListener


{ Dial cutie=null;
public Fer(String titlu) {
super(titlu);
setSize(150,100);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container x=getContentPane();
x.setLayout(new FlowLayout ());
JButton A=new JButton("Seteaza culoarea"); x.add(A);
A.addActionListener(this);
setVisible(true);
}
public void actionPerformed (ActionEvent e)
{ if (cutie==null) cutie=new Dial
(this,"Seteaza culoarea",false);
else cutie.setVisible(true);
}
}

public class pv {
public static void main(String args[]) {
Fer fp=new Fer("Culori");
}
}
250 Bazele programării în Java

10.10. Clasa Graphics

10.10.1. Afişarea imaginilor


Pentru a afi[a o imagine aflat` \ntr-un fi[ier, vom scrie o clas` care
extinde clasa Canvas. Obiectele clasei Canvas con]in o metod` numit`
paint(Graphics ecr). Aceast` metod` este apelat` automat atunci c@nd
componenta respectiv` este afi[at` [i are rolul de a desena componenta.
Observa]i c` metoda paint() prime[te ca parametru o referin]` c`re un
obiect al clasei Graphics [i, pornind de la ea, putem apela toate metodele
acestei clase, metode cu ajutorul c`rora putem afi[a imaginea, scrie \n mod
grafic sau desena.

|n programul urm`tor, clasa care construie[te componenta ce afi[eaz`


imaginea se nume[te Imagine. Clasa Imagine con]ine:

1. O referin]` c`tre un obiect de tip Image. Un astfel de obiect poate


re]ine o imagine citit`. Referin]a este utilizat` \n metoda paint() pentru a
afi[a imaginea respectiv`.

2. Un constructor, care cite[te imaginea, stabile[te m`rimea componentei


(setSize()) [i culoarea de fundal (setBackground()). Pentru citirea
imaginii se utilizeaz` metoda clasei Toolkit numit` getImage():

 Image getImage(String fisier), unde parametrul reprezint` calea


c`tre fi[ierul respectiv.

3. Metoda paint() (redefinit`, pentru a avea acces). Metoda “deseneaz`”


imaginea [i folose[te metoda drawImage() a clasei Graphics):

 drawImage(image im, int a, int b, int latime, int inaltime,


this), unde:

 a,b - coordonatele relative (fa]` de col]ul din st@nga-sus al


componentei care afi[eaz` imaginea; \n exemplu Imagine) ale
col]ului din st@nga sus al dreptunghiului care con]ine imaginea.

 latime, inaltime - l`]imea [i \n`l]imea dreptunghiului care


con]ine imaginea.

 this - obiectul curent (cel al clasei Imagine). Nu trat`m


semnifica]ia general` a acestui parametru.

 Observa]ii:

 Metoda poate redimensiona imaginea citit` (o m`re[te sau o


mic[oreaz`) prin valorile transmise pentru latime [i inaltime.
Capitolul 10. Iniţiere în programarea vizuală 251

 Fi[ierul imagine se g`se[te \n Bin (folder-ul curent), dar \i putem


ata[a o cale.
 Exemplul urm`tor con]ine o component` care afi[eaz` desenul \n
centrul ei. Desigur, imaginea putea acoperi \ntreaga suprafa]` a
componentei Imagine, dar din considerente didactice, pentru a
distinge \ntreaga suprafa]` unde am fi putut desena, am preferat s`
folosim setBackground().

Programul de mai jos construie[te o fereastr`


care afi[eaz` o imagine:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
class Imagine extends Canvas
{ Image im;
Imagine()
{ Toolkit ec=Toolkit.getDefaultToolkit();
im=ec.getImage("calculator.jpg");
setSize(300,300);
setBackground(Color.YELLOW);
}
public void paint (Graphics ecr)
{ ecr.drawImage(im,50,50,200,200,this);}
}
class Fer extends JFrame
{ Imagine p=new Imagine();
public Fer(String titlu) {
super(titlu);setSize(150,200);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container x=getContentPane();
x.setLayout(new FlowLayout ());
x.add(p);
setVisible(true);
}
}
public class pv {
public static void main(String args[]) {
Fer fp=new Fer("Imagine");
}
}

10.10.2. Cum scriem ?


|nainte de parcurgerea acestui paragraf, revede]i 8.15. “Afi[area
imaginilor”. A]i putut observa acolo c` metoda Paint prime[te ca referin]`
un obiect al clasei Graphics. Putem utiliza metodele acestui obiect pentru
a desena ceva sau pentru a \nc`rca o imagine care se g`se[te \ntr-un
fi[ier. Cele mai importante metode ale acestei clase sunt:
252 Bazele programării în Java

 void setFont (Font f) - seteaz` obiectul pentru ca scrierea


grafic` s` se realizeze cu un anumit font;
 void setColor(Color c) - seteaz` culoarea de scriere (desenare);
 drawString(String str, int x, int y) - scrie pe ecran un [ir
de caractere. Şirul este scris cu font-ul [i culoarea setate la un
moment dat. Parametrii x [i y reprezint` coordonatele col]ului din
st@nga sus al [irului de caractere afi[at.

Exemplu: iat` cum arat` metoda


Paint() pentru a putea scrie dou`
[iruri de caractere cu font-uri [i culori
diferite:
public void paint (Graphics ecr)
{ Fontf=new Font("Arial",Font.ITALIC+Font.BOLD, 11);
ecr.setFont(f);
ecr.setColor(Color.red);
ecr.drawString("Un exemplu de scriere",20, 30);
ecr.setColor(Color.black);
Font f1=new Font("CourierNew",Font.BOLD, 14);
ecr.setFont(f1);
ecr.drawString("Scriu cu alta culoare si alt font",20, 50);
}

10.10.3. Cum desenăm ?


 drawLine(int x1, int y1, int x2, int y2) - deseneaz` o
linie (segment) \ntre punctele de coordonate (x1,y1) [i (x2,y2).

 drawRect(int x, int y, int latime, int inaltime) -


deseneaz` un dreptunghi pentru care col]ul din st@nga sus are
coordonatele (x,y) [i de l`]ime [i \n`l]ime date.

 drawRoundRect(int x, int y, int latime, int inaltime,


int lat, int inal) - deseneaz` un dreptunghi care are col]urile
rotunjite, (vede]i al`turat).
lat
 void fillRect(int x, int y, inal
int latime, int inaltime), la fel ca
drawRect(), numai c` dreptunghiul este
colorat \n interior.

 void fillRoundRect(int x, int y,


int latime, int inaltime, int lat,
int inal) - la fel ca drawRoundRect(),
numai c` dreptunghiul rotunjit este colorat \n
interior.
Capitolul 10. Iniţiere în programarea vizuală 253

 void drawPolygon(int[] X, int[] Y, int nr) - deseneaz` un


poligon care are nr vârfuri. Coordonatele x ale punctelor se g`sesc
\n vectorul X, iar coordonatele y ale punctelor se g`sesc \n vectorul
Y. Practic, primul punct are coordonatele (X[0],Y[0]), al doilea
punct are coordonatele (X[1],Y[1]), [.a.m.d. |n final, pentru a
ob]ine poligonul se unesc printr-un segment primul [i ultimul punct.
Poligonul este oarecare, deci poate fi [i neconvex.

Exemplu: ecr.setColor(Color.black);
int[] X= {10, 100,25, 80};
int[] Y= {10, 100,75, 30};
ecr.drawPolygon(X, Y, 4);

 void fillPolygon(int[] X, int[] Y, int nr) - la fel ca mai


sus, numai c` poligonul este colorat \n interior.

 void drawPolyline(int[] X, int[] Y, int nr) - la fel ca mai


sus, numai c` nu se mai une[te primul punct cu ultimul punct. Astfel
se ob]ine o succesiune de segmente.

 void drawOval(int x, int y, int latime, int inaltime) -


deseneaz` un oval. Coordonatele x [i y sunt ale col]ului din st@nga
sus al dreptunghiului circumscris ovalului, iar latime [i inaltime
sunt l`]imea [i \n`l]imea acelui
dreptunghi.
90
 fillOval(int x, int y, int
latime, int inaltime) - la fel ca
mai sus, numai c` ovalul este colorat
\n interior.
180 0
 drawArc(int x, int y, int
latime, int inaltime, int u1,
int u2) - traseaz` un arc. Arcul este
o por]iune dintr-un oval [i primii 4 270
parametri sunt ai ovalului c`ruia \i
apar]ine arcul. Ultimii doi parametri
sunt: unghiul de unde porne[te arcul [i num`rul de grade al arcului.
Unghiurile sunt date \n grade.

 fillArc(int x, int y, int latime, int inaltime, int u1,


int u2) - la fel ca drawArc, numai c` se consider` sectorul (nu
numai arcul) [i acesta este colorat. De exemplu, \n cazul \n care
latime [i inaltime re]in aceea[i valoare, ovalul este, de fapt, un
cerc. |n acest caz avem un sector de cerc.
254 Bazele programării în Java

 drawImage(image im, int a, int b, int latime, int inaltime,


this), unde:
 a,b sunt coordonatele relative (fa]` de componenta creat`, vezi
setSize()) ale col]ului din st@nga sus al dreptunghiului care
con]ine imaginea.
 latime, inaltime - l`]imea [i \n`l]imea dreptunghiului care
con]ine imaginea.
 this - obiectul curent (cel al clasei Imagine). Nu trat`m
semnifica]ia general` a acestui parametru.

 Observa]ie: Metoda a mai fost folosit` atunci c@nd am afi[at o imagine!

10.11. Clasa Graphics2D


Clasa Graphics2D mo[tene[te clasa Graphics [i prin urmare, ofer`
mai multe posibilit`]i de lucru, unele dintre ele cu adev`rat spectaculoase.
Pentru a o utiliza se procedeaz` ca mai jos, unde a fost rescris` metoda
paint() pentru o clas` care mo[tene[te clasa Canvas (la fel ca atunci
c@nd am creat imagini care se afi[eaz` pe fereastr`). Toate desenele [i
set`rile f`cute se utilizeaz` identic ca [i c@nd ar fi fost realizate \n
Graphics.

public void paint (Graphics ecr1)


{
Graphics2D ecr=(Graphics2D) ecr1;
ecr.setColor(Color.red);
...
}

10.11.1. Cum desenăm ?


Pentru desenare nu avem multe metode proprii (altele dec@t ale clasei
mo[tenite), dar se pot utiliza metode ale altor clase aflate \n pachetul geom
(ad`uga]i import java.awt.geom.*). Acestea construiesc obiectul \n
memorie, iar pentru afi[are vom utiliza metodele clasei Graphics2D
urm`toare:

 draw(Shape S) - deseneaz` obiectul f`r` a-l “umple” cu culoare sau


gradient, ori textur`. Toate aceste no]iuni sunt prezentate pe larg, \n
cadrul aceluia[i capitol.

 fill (Shape S) - deseneaz` obiectul „umplut‟ cu o culoare (gradient


sau textur`).
Capitolul 10. Iniţiere în programarea vizuală 255

Ambele metode au parametrii de tipul Shape, care este o interfa]`.


Clasele care construiesc figurile geometrice prezentate \n continuare, sunt
implement`ri ale tipului Shape:

Clasa Line2D.float - are constructorul:

 Line2D.Float(float x1, float y1, float x2, float y2);


construie[te o linie care une[te punctele de coordonate (x1,y1) [i
(x2,y2).
Exemplu: construiesc [i afi[ez o linie ro[ie (ecr este de tipul Graphics2D).
ecr.setColor(Color.red);
Line2D.Float linie = new Line2D.Float(10,10, 100,100);
ecr.draw(linie);

Clasa Rectangle2D.Float - are constructorul:

 Rectangle2D.Float(float x, float y, float latime,


float inaltime) - construie[te un dreptunghi. Col]ul din st@nga
sus are coordonatele (x,y), iar dreptunghiul are l`]imea [i \n`l]imea
specificate de parametri.
Exemplu: construiesc [i afi[ez un dreptunghi cu interiorul “umplut” cu ro[u:
ecr.setColor(Color.red);
Rectangle2D.Float drept = new Rectangle2D.Float(10,10, 50, 50);
ecr.fill(drept);

Clasa Ellipse2D.Float - are constructorul:

 Ellipse2D.Float(float x, float y, float latime,


float inaltime) - construie[te o elips`. Parametrii se refer` la
dreptunghiul circumscris elipsei.

Clasa Arc2D.Float - are constructorul:

 Arc2D.Float(float x, float y, float latime, float


inaltime, float start, float nr, int type) - construie[te
un arc. Primii 4 parametri se refer` la elipsa c`reia \i apar]ine arcul,
start este unghiul de pornire, nr este num`rul de grade al arcului,
iar type este o constant` care determin` modul \n care arat` arcul.
Valoarea constantei type rezult` din imaginile de mai jos:
Exemplu: construim un arc de 90 de grade al unui cerc. Punctul de start
al arcului este la 45 de grade:

Arc2D.CHORD Arc2D.OPEN Arc2D.PIE


256 Bazele programării în Java

Clasa GeneralPath se utilizeaz` pentru trasarea unei linii fr@nte sau,


\n particular, pentru trasarea unui poligon. Clasa con]ine:
 GeneralPath()- constructor;
 moveTo(float x, float y) - mut` un cursor imaginar \n punctul de
coordonate (x,y);
 lineTo(float x, float y) - traseaz` o dreapt` \ntre punctul \n
care se g`se[te cursorul imaginar [i cel de coordonate transmise ca
parametru;
 closePath() - traseaz` dreapta care \nchide linia fr@nt` (adic` se
creeaz` un poligon).

Exemplu: \n secven]a de mai jos se afi[eaz` un triunghi. V@rfurile sale sunt


(5.5). (100,100), (150,10):

GeneralPath path= new GeneralPath(0,0);


path.moveTo(5,5);
path.lineTo(100,100);
path.lineTo(150,10);
path.closePath();
ecr.draw(path);

10.11.2. Stabilirea modului de trasare a liniilor


|n clasa Graphics, toate liniile aveau o singur` grosime: 1 pixel. |n
Graphics2D, se poate stabili ca liniile s` aib` o anumit` grosime, mai
mare sau egal` cu 1. De asemenea, se pot face set`ri ale modului \n care
se termin` segmentele [i asupra modului \n care acestea se \mbin`. Pentru
a realiza aceste lucruri, se utilizeaz` o metod` a clasei Graphics2D,
numit` setStroke():

 void setStroke(Stroke s); Dup` cum vede]i, parametrul metodei


este de tip Stroke. Dar, Stroke este o interfa]`. Ea este
implementat` de clasa BasicStroke.

Clasa BasicStroke are mai mul]i constructori, din care, aici sunt
prezenta]i doar doi, mai importan]i:

 BasicStroke(float latime) - seteaz` l`]imea liniilor (\n pixeli);

 BasicStroke(float latime, int cap, int join) - seteaz`


l`]imea liniilor (latime), modul \n care arat` capetele segmentelor
(cap) [i modul \n care acestea sunt unite (join). Pentru ultimii doi
parametri, apelul metodei se realizeaz` utiliz@nd constantele clasei
BasicStroke.
Capitolul 10. Iniţiere în programarea vizuală 257

Exemplu: pentru a crea imaginea al`turat` am


utilizat clasa de mai jos:
class Imagine extends Canvas
{ Imagine()
{ setSize(300,300);}
public void paint (Graphics ecr1)
{ Graphics2D ecr=(Graphics2D) ecr1;
ecr.setColor(Color.red);
BasicStroke c =new BasicStroke(10, BasicStroke.CAP_ROUND,
BasicStroke.JOIN_BEVEL);
ecr.setStroke(c);
GeneralPath path= new GeneralPath(0,0);
path.moveTo(5,5);
path.lineTo(75,75);
path.lineTo(150,5);
ecr.draw(path);
}
}

|n continuare, ne propunem s` analiz`m valorile pe care le poate lua


parametrul cap, prezent@nd de fiecare dat`, c@te o dreapt` (segment).
Pentru ultimele dou` cazuri, segmentului i se adaug` un p`trat, respectiv un
semicerc:

CAP_BUTT CAP_SQUARE CAP_ROUND

Iat` care sunt valorile pe care le poate lua parametrul join (modul
de unire a segmentelor). Pentru fiecare din cazuri vom prezenta o linie
fr@nt` realizat` cu GeneralPath:

JOIN_MITER JOIN_BEVEL JOIN_ROUND

Parametrul join are efect doar \n cazul figurilor unitare (linie fr@nt`,

 dreptunghi, etc.). El nu va func]iona \n cazul \n care tras`m dou`


drepte (segmente) care se unesc \ntr-un punct, pentru c` nu exist`
informa]ii care s` determine acest efect.
258 Bazele programării în Java


Prin utilizarea parametrului join, nu mai sunt necesare metode de
tipul celor care creeaz` un dreptunghi cu col]urile rotunjite. Acestea
pot fi rotunjite prin valoarea pe care o transmitem pentru join.

10.11.3. Gradient

P@n` \n prezent, atunci c@nd am colorat o anumit` imagine, am


utilizat numai o singur` culoare. |n Graphics2D se poate utiliza un
gradient, adic` o trecere treptat` de la o culoare la alta, ob]in@ndu-se astfel
efecte deosebite. Pentru a realiza un gradient vom folosi metoda
setPaint() a clasei Graphics2D:

 setPaint(Paint p) - dup` cum observa]i, parametrul este de tip


Paint, care este o interfa]` implementat` de mai multe clase. Pentru
a stabili un gradient vom utiliza clasa GradientPaint.

Clasa GradientPaint are constructorul urm`tor:

 GradientPaint(float x1, float y1, Color c1, float x2,


float y2, Color c2, boolean cyclic);

Semnifica]ia parametrilor este urm`toarea: \n punctul de coordonate (x1,y1)


vom avea culoarea c1, \n punctul de coordonate (x2,y2) vom avea
culoarea c2. |ntre aceste puncte se va face o trecere treptat` de la
culoarea c1 la culoarea c2. Trecerea poate fi aciclic` (parametrul cyclic
re]ine false) sau ciclic` (parametrul cyclic re]ine true). Pentru cea
aciclic`, trecerea de la c1 la c2 se face treptat, iar pentru cea ciclic`, \ntre
cele dou` puncte se trece de mai multe ori de la c1 la c2 [i invers [i nu
exist` cerin]a ca \n punctele date s` fie exact culorile solicitate.

Exemplu: pentru a crea un dreptunghi cu gradient, prin trecerea de la


galben la negru, vom utiliza clasa de mai jos. |n exemplu, gradientul este
aciclic, dar figurile prezint` [i gradientul ciclic:

aciclic ciclic
Capitolul 10. Iniţiere în programarea vizuală 259

class Imagine extends Canvas


{ Imagine()
{ setSize(300,300);}
public void paint (Graphics ecr1)
{
Graphics2D ecr=(Graphics2D) ecr1;
GradientPaint g=new GradientPaint(50,50, Color.YELLOW,
100,100, Color.BLACK, false);
ecr.setPaint(g);
Rectangle2D.Float drept = new Rectangle2D.Float
(50,50, 100, 100);
ecr.fill(drept);
}
}

10.11.4. Clasa BufferedImage

Uneori, prefer`m s` cre`m un desen pe care s`-l p`str`m \n


memorie. Pentru aceasta utiliz`m clasa BufferedImage. Afi[area desenului
se face atunci c@nd dorim, \n paint(), cu drawImage() a[a cum suntem
obi[nui]i.

Clasa BufferedImage con]ine:

 BufferedImage(int latime, int inaltime, int imageType) -


constructor. Primii doi parametri specific` l`]imea [i \n`l]imea imaginii
memorate de obiect. Ultimul parametru prime[te o constant` a clasei
BufferedImage [i semnific` un anumit tip de imagine cu o anumit`
culoare de fond.

 Graphics2D createGraphics() - returneaz` o referin]` c`tre


obiect de tip Graphics2D cu ajutorul c`ruia putem desena o imagine
re]inut` de obiectul de tip BufferedImage.
 ImageProducer getSource() - returneaz` imaginea re]inut` de
obiect.
Pentru a realiza cele propuse mai avem nevoie s` utiliz`m o metod` a
clasei Toolkit (vezi 10.5):

 Image createImage(ImageProducer buf) - creeaz` un obiect de


tip Image pornind de la o implementare a interfe]ei ImageProducer.

class Imagine extends Canvas


{
Image im;
BufferedImage imag_a;
Graphics2D gr;
260 Bazele programării în Java

Imagine()
{ // creez un obiect BufferedImage
imag_a=new BufferedImage(200, 200, BufferedImage.TYPE_INT_RGB);
// pentru a desena ii asociez un un obiect Graphics2D
gr=imag_a.createGraphics();
// desenez
Line2D.Float linie = new Line2D.Float(10,10, 100,100);
gr.draw(linie);
// obtin un obiect de tip Image care contine desenul
im=Toolkit.getDefaultToolkit().createImage(imag_a.getSource());
setSize(300,300); setBackground(Color.WHITE);
}
public void paint (Graphics ecr)
{ // desenez imaginea p
ecr.drawImage(im,0,0,this);
}
}
class Fer extends JFrame
{ Imagine p=new Imagine();
public Fer(String titlu) {
super(titlu);setSize(400,400);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container x=getContentPane();
x.setLayout(new FlowLayout ());
x.add(p);
setVisible(true);
}
}
public class pv {
public static void main(String args[]) {
Fer fp=new Fer("Imagine ascunsa");
}
}

10.11.5. Texturi
Suprafe]ele pot fi acoperite de o aceea[i culoare, de un gradient sau
de o textur`. Pentru a acoperi o suprafa]` cu o textur`, vom utiliza aceea[i
metod` a clasei Graphics2D ca [i c@nd acoperim suprafa]a cu un gradient
[i anume setPaint(Paint p). Dup` cum am ar`tat, Paint este o
interfa]`. Ea este implementat` de clasa GradientPaint (cu ajutorul ei
cre`m un gradient), dar [i de clasa TexturePaint, clas` cu ajutorul c`reia
cre`m o textur`.

Clasa TexturePaint are constructorul:

 TexturePaint(BufferedImage buf, Rectangle drept). Dup`


cum observa]i, ambii parametri sunt de tip referin]` la obiect.
Obiectele apar]in de dou` clase distincte, BufferedImage [i
Rectangle.
Capitolul 10. Iniţiere în programarea vizuală 261

|nainte de a prezenta cei


doi parametri, s` vedem
principial, cum se realizeaz` o
textur` (textura al`turat` este
ob]inut` de programul din acest
paragraf). Atunci c@nd desen`m
o figur` geometric`, ea poate fi
acoperit` de o textur`. Textura
este alc`tuit` dintr-o imagine
desenat` care se repet` de c@te
ori \ncape \n cadrul figurii. Prin
urmare, pentru a defini textura,
trebuie s` cunoa[tem:

1. Care este imaginea care se


repet`?

2. Care este m`rimea afi[at` a imaginii care se repet`?

R`spunsul la prima \ntrebare este c`, pentru a specifica imaginea se


utilizeaz` un obiect al clasei BufferedImage. Pentru a preciza dimensiunea
imaginii care se repet`, se utilizeaz` un obiect al clasei Rectangle.

 Observa]ie. A nu se confunda dimensiunile imaginii re]inute de obiectul


de tip BufferedImage cu dimensiunile la care se va afi[a imaginea \n
textur`. Dac` imaginea re]inut` de obiectul de tip BufferedImage este mai
mic` dec@t cea la care se va afi[a imaginea, atunci imaginea este m`rit`
automat. Dac`, dimpotriv`, imaginea re]inut` de obiect are dimensiuni mai
mari dec@t cea afi[at`, se va afi[a ce se poate din ea (pornind de la col]ul
din st@nga sus).

Clasa Rectangle se utilizeaz`, a[a cum am precizat, pentru a specifica


m`rimea imaginii afi[ate. Unul din constructorii ei este:

 Rectangle (int latime, int inaltime). Prin utilizarea lui


preciz`m dimensiunile imaginii afi[ate.

Exemplu: programul de mai jos afi[eaz` textura dat`, de exemplu, \n acest


paragraf.

import java.awt.*;
import javax.swing.*;
import java.awt.geom.*;
import java.awt.image.BufferedImage;

class Imagine extends Canvas


{ Imagine()
{ setSize(300,300);}
262 Bazele programării în Java

public void paint (Graphics ecr1)


{ Graphics2D ecr=(Graphics2D) ecr1;
BufferedImage buf=new BufferedImage(50, 50,
BufferedImage.TYPE_INT_RGB);
Graphics2D model = buf.createGraphics();
model.setColor(Color.red);
Ellipse2D.Float el= new Ellipse2D.Float(0, 0, 50, 50);
model.fill(el);
Rectangle r = new Rectangle(50,50);
TexturePaint tp = new TexturePaint(buf, r);
ecr.setPaint(tp); ecr.fillRect(0,0,300,300);
}
}
class Fer extends JFrame
{ Imagine p=new Imagine();
public Fer(String titlu) {
super(titlu);
setSize(500,500);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container x=getContentPane();
x.setLayout(new FlowLayout ());
x.add(p);
setVisible(true);
}
}
public class pv {
public static void main(String args[]) {
Fer fp=new Fer("Imagine");
}
}

10.11.6. Dreptunghiuri 3D
Clasa Graphics2D ne ofer` posibilitatea s` desen`m dreptunghiuri \n
relief. |n acest scop, ea con]ine metodele draw3DRect() [i fill3DRect():

 draw3DRect(int x, int y, int latime, int inaltime,


boolean raised) - deseneaz` un deptunghi.

 fill3DRect(int x, int y, int latime, int inaltime,


boolean raised) - deseneaz` un deptunghi “umplut cu culoare”.

Primii parametrii parametri caracterizeaz` orice dreptunghi. Ultimul


parametru, de tip boolean, precizeaz` dac` dreptunghiul este ridicat (true)
sau cobor@t (false). Pentru a utiliza cu succes aceast` metod`, trebuie s`
[tim urm`toarele:

1. Metoda nu deseneaz` dec@t un dreptunghi cu linia de grosime 1 pixel.


Pentru a ob]ine efectul scontat, trebuie s-o utiliz`m de mai multe ori,
realiz@nd mai multe dreptunghiuri incluse unul \n altul, dar cu laturile lipite.
Capitolul 10. Iniţiere în programarea vizuală 263

2. Atunci c@nd parametrul raised re]ine true, laturile din st@nga [i sus
sunt desenate \ntr-o culoare deschis`, iar laturile din dreapta [i jos sunt
desenate \ntr-o culoare \nchis`. Dac` raised re]ine false, culorile laturilor
se inverseaz`. Exact aceste culori creeaz` impresia de ridicat sau cobor@t.
3. Practic, culoarea deschis` este cea setat` pentru desen, iar culoarea
\nchis` este aleas` automat de metod`. Din acest motiv, dac` avem setat`
culoarea negru, efectul este nul, iar dac` avem setat` culoarea alb efectul
este maxim.
Exemplu: butoanele al`turate au fost realizate \n clasa urm`toare:

class Imagine extends Canvas


{ Imagine() { setSize(300,300);}
public void paint (Graphics ecr1)
{ Graphics2D ecr=(Graphics2D) ecr1;
ecr.setColor(Color.red);
for (int i = 0; i <= 10; i++)
ecr.draw3DRect(50 - i, 20 - i, 80 + 2 * i, 30 + 2 * i, true);
for (int i = 0; i <= 10; i++)
ecr.draw3DRect(200 - i, 20 - i,80 + 2 * i, 30 + 2 * i,
false);
}
}

10.11.7. Spaţiul de coordonate al utilizatorului


P@n` \n prezent am lucrat folosind exclusiv spa]iul de coordonate al
dispozitivului. Tot ce am desenat a fost raportat la acest spa]iu. |n
Graphics2D se poate lucra \ntr-un alt spa]iu de coordonate, acela al
utilizatorului. Mecanismul este urm`torul:

1. Ini]ial, spa]iul de coordonate al dispozitivului coincide cu spa]iul de


coordonate al utilizatorului;

2. Spa]iul de coordonate al utilizatorului poate deveni altul fa]` de spa]iul


de coordonate al dispozitivului, \n urma unor opera]ii de transla]ie [i de
rota]ie. Pentru a realiza aceste opera]ii, se utilizeaz` urm`toarele metode ale
clasei Graphics2D:
 translate(int x1, int y1) - are rolul ca, dup` executarea ei,
originea spa]iului de coordonate al utilizatorului s` aib` originea \n
punctul de coordonate (x1, y1);
 rotate(double alfa) - rote[te spa]iul de coordonate \n sens invers
trigonometric (sensul acelor de ceasornic cu unghiul transmis ca
parametru). Unghiul alfa trebuie s` fie exprimat \n radiani. De acum,
spa]iul utilizatorului este cel ob]inut \n urma rota]iei.
264 Bazele programării în Java

3. |n urma opera]iilor de transla]ie [i rota]ie, ce era desenat anterior


r`m@ne nemodificat. |n noul spa]iu, se lucreaz` cu ceea ce se deseneaz`
de acum \ncolo.

Exemplu: Desenul de mai jos a fost ob]inut cu metoda urm`toare:

public void paint (Graphics ecr1)


{
Graphics2D ecr=(Graphics2D) ecr1;
ecr.setColor(Color.red);
ecr.setStroke(new BasicStroke(4));
Line2D.Float linie = new Line2D.Float(0,0,100,100);
ecr.draw(linie);
ecr.translate(0,25);
ecr.draw(linie);
ecr.rotate(Math.PI/4);
ecr.draw(linie);
Rectangle2D.Float drept = new Rectangle2D.Float(100,10, 50, 50);
ecr.fill(drept);
}

Aceea[i dreapt` (segment) a fost desenat` de 3 ori:


- o dat` clasic (prima din dreapta),

 -
-
apoi, \n urma unei transla]ii ( a doua din dreapta),
apoi, \n urma unei rota]ii (linia vertical`).
Se observ` [i faptul c` dup` aplicarea unei rota]ii, p`tratul se
afi[eaz` rotit.
Capitolul 10. Iniţiere în programarea vizuală 265

10.12. Evenimente
10.12.1. Generalităţi
|n exemplele date p@n` acum, majoritatea opera]iilor erau efectuate ca
urmare a ap`s`rii unui buton. |n realitate, mecanismul declan[`rii [i trat`rii
evenimentelor este cu mult mai complex. Exist` mai multe tipuri de
evenimente [i ele sunt tratate de “ascult`tori” diferi]i. |n continuare, le vom
prezenta pe cele mai des utilizate \n programarea vizual`.

10.12.2. Evenimente de tip Action

Aceste evenimente sunt produse de componente de tipurile:

 JButton - atunci c@nd se execut` click pe suprafa]a butonului;


 JComboBox - atunci c@nd se opereaz` o selec]ie \n list`;
 JTextField - atunci c@nd se scrie \n edit [i se tasteaz` Enter;
 JCheckBox, JRadioButton - atunci c@nd se bifeaz` sau se
debifeaz` butonul respectiv;
 JMenuItem - atunci c@nd se selecteaz` op]iunea respectiv`.

Pentru a le capta, trebuie ca:

1. Fereastra care include componentele s` implementeze interfa]a


ActionListener. Interfa]a con]ine antetul metodei care trebuie scris`:

 void actionPerformed(ActionEvent e) - metod` prin care se


programeaz` ac]iunea care trebuie \ntreprins`, dac` evenimentul s-a
produs.

Evenimentul produs are tipul ActionEvent. O metod` important` a acestei


clase este:
 String getActionCommand() - returneaz` un [ir de caractere
dup` care se poate identifica componenta care a transmis
evenimentul. Astfel, \n cazul butoanelor, se returneaz` [irul afi[at de
ele; \n cazul edit-ului, se returneaz` [irul de caractere introdus de
utilizator; \n cazul listelor, se returneaz` [irul ComboBoxChanged, iar
\n cazul componentelor de tip JMenuItem, se returneaz` [irul afi[at
de component`.

2. Fiecare component` care trebuie s` emit` un astfel de eveniment


trebuie s` fie ad`ugat` “ascult`torului” de evenimente de tip ActionEvent.
266 Bazele programării în Java

Astfel, fiecare component` care poate emite mesaje de acest tip con]ine
metoda:

 void addActionListener(ActionListener l) - prin care se


adaug` componenta gestionarului curent (al ferestrei).

 Testa]i programul urm`tor pentru a va convinge!

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
class Fer extends JFrame implements ActionListener
{
public Fer(String titlu) {
super(titlu);
setSize(200,100);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container x=getContentPane();
x.setLayout(new FlowLayout ());
//Butonul
JButton A=new JButton("Buton 1");
x.add(A);
A.addActionListener(this);
//Lista
JComboBox lista=new JComboBox ();
lista.addItem("Optiunea 1");
lista.addItem("Optiunea 2");
x.add(lista);
lista.addActionListener(this);
// Edit-ul
JTextField t=new JTextField(10);
x.add(t);
t.addActionListener(this);
// JCheckBox
JCheckBox b=new JCheckBox("Bifeaza");
x.add(b);
b.addActionListener(this);
// JCheckBox
JRadioButton c=new JRadioButton("Radio");
x.add(c);
c.addActionListener(this);
setVisible(true);
}
public void actionPerformed (ActionEvent e)
{ System.out.println(e.getActionCommand()); }
}

public class pv {
public static void main(String args[]) {
Fer fp=new Fer("Test ActionEvent");
}
}
Capitolul 10. Iniţiere în programarea vizuală 267

10.12.3. Evenimente de tip MouseEvent


Acestea sunt evenimente care se genereaz` \n urma ac]iunilor
executate cu mouse-ul. Componenta care recep]ioneaz` astfel de
evenimente trebuie s` implementeze una sau dou` dintre interfe]ele
prezentate mai jos:

Interfa]a MouseListener - con]ine antetele metodelor de mai jos, metode


care se ruleaz` atunci c@nd se \nt@lne[te un eveniment de mouse:

 mouseClicked(MouseEvent e) - se execut` atunci c@nd se


efectueaz` click pe suprafa]a componentei;
 mouseEnteed(MouseEvent e) - se execut` atunci c@nd cursorul
mouse-ului ajunge pe suprafa]a grafic` a componentei;
 mouseExited(MouseEvent e) - se execut` atunci c@nd cursorul
mouse-ului p`r`se[te suprafa]a grafic` a componentei;
 mousePressed(MouseEvent e) - se execut` aunci c@nd am ap`sat
butonul mouse-ului;
 mouseReleased (MouseEvent e) - se execut` aunci c@nd s-a
eliberat butonul mouse-ului.

Interfa]a MouseMotionListener - con]ine urm`toarele antete:

 MouseDragged() - metoda se execut` \n mod continuu, c@t timp


am ap`sat un buton al mouse-ului [i deplas`m cursorul (c` la
opera]ia Drag and Drop);
 MouseMoved(MouseEvent e) - se execut` \n mod continuu, c@t
timp cursorul mouse-ului se “plimb`” pe suprafa]a componentei.

Dup` cum observa]i, parametrul oric`rei metode care r`spunde unei


ac]iuni efectuate cu mouse-ul este de tip MouseEvent. Printre altele, clasa
MouseEvent con]ine urm`toarele dou` metode:

 getX() - returneaz` coordonata x a cursorului grafic;


 getY() - returneaz` coordonata y a cursorului grafic.

Ambele coordonate sunt relative la col]ul din st@nga-sus al componentei.

Evenimentele de mouse pot fi tratate de orice component` care are la


baz` clasa Component, deci sfera de ac]iune a sa este foarte larg`. Pentru
a implementa “ascult`torii” de evenimente de mouse, se utilizeaz` metodele
clasei Component:
268 Bazele programării în Java

 void addMouseListener(MouseListener l)
- pentru “ascult`torul” MouseListener;
 void addMouseMotionListener(MouseMotionListener l)
- pentru “ascult`torul” MouseMotionListener.

Exerci]iu: urm`ri]i modul \n care se genereaz` evenimentele de mouse,


rul@nd programul urm`tor. Pentru fiecare eveniment produs, \n fereastra CMD
se afi[eaz` numele evenimentului.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.image.*;
class Imagine extends Canvas implements MouseListener,
MouseMotionListener
{ Imagine()
{ setSize(200,200);
setBackground(Color.RED);
this.addMouseListener(this);
this.addMouseMotionListener(this);
}
public void mouseClicked(MouseEvent e)
{ System.out.println("MouseClicked"); }
public void mouseEntered(MouseEvent e)
{ System.out.println("MouseEntered");}
public void mouseExited(MouseEvent e)
{ System.out.println("MouseExiteted");}
public void mousePressed(MouseEvent e)
{ System.out.println("MousePressed");}
public void mouseReleased(MouseEvent e)
{ System.out.println("MouseReleased"); }
public void mouseDragged(MouseEvent e)
{ System.out.println("MouseDragged");}
public void mouseMoved(MouseEvent e)
{ System.out.println("MouseMoved");}
}
class Fer extends JFrame
{ Imagine p=new Imagine();
public Fer(String titlu) {
super(titlu); setSize(400,400);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container x=getContentPane();
x.setLayout(new FlowLayout ());
x.add(p); setVisible(true);
}
}
public class pv {
public static void main(String args[]) {
Fer fp=new Fer("MouseEvent");}
}
Capitolul 10. Iniţiere în programarea vizuală 269

Aplica]ie - program prin care se deseneaz` cu mouse-ul. Programul urm`tor


va exemplifica modul \n care se poate utiliza mouse-ul pentru a desena.

 Observa]i c`:

1. Desenul este re]inut de o component` dintr-o


clas` care mo[tene[te clasa Canvas. Clasa
componentei implementeaz` MouseListener [i
MouseMotionListener.
2. Desenul este practic realizat \n memorie, prin
utilizarea unui obiect de tip BufferedImage, iar
metoda Paint nu face altceva dec@t s`
deseneze pe ecran imaginea din memorie.
3. Evenimentele de mouse sunt generate astfel:
a) mousePressed() - memoreaz` \n pozvX [i pozvY coordonatele
cursorului grafic \n momentul \n care se apas` butonul mouse-ului.
b) void mouseDragged() - traseaz` un segment de dreapt` \ntre
coordonatele memorate \n pozvX [i pozvY [i cele actuale, memorate \n
poznX [i poznY. Apoi, coordonatele actuale sunt memorate \n pozvX [i
pozvY. Dup` aceasta, se redeseneaz` imaginea prin utilizarea metodei
repaint(). Cum evenimentul se genereaz` \n mod continuu, se ob]ine
efectul scontat.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.image.*;
class Imagine extends Canvas implements MouseListener,
MouseMotionListener
{ Image im;
BufferedImage desen;
Graphics gr;
int pozvX, pozvY, poznX, poznY;
Imagine()
{ desen = new BufferedImage
(200, 200, BufferedImage.TYPE_INT_RGB);
gr = desen.createGraphics();
im=Toolkit.getDefaultToolkit().createImage(desen.getSource());
setSize(200,200);
this.addMouseListener(this);
this.addMouseMotionListener(this);
}
public void paint (Graphics ecr)
{ ecr.drawImage(im,0,0,this); }
public void update(Graphics ecr) { paint(ecr);}
public void mouseClicked(MouseEvent e) { }
270 Bazele programării în Java

public void mouseEntered(MouseEvent e) {}


public void mouseExited(MouseEvent e) {}
public void mousePressed(MouseEvent e)
{ pozvX=e.getX();
pozvY=e.getY();
}
public void mouseReleased(MouseEvent e){ }
public void mouseDragged(MouseEvent e)
{ poznX=e.getX();
poznY=e.getY();
gr.drawLine(pozvX,pozvY,poznX,poznY);
pozvX=poznX;
pozvY=poznY;
im=Toolkit.getDefaultToolkit().createImage(desen.getSource());
repaint();
}
public void mouseMoved(MouseEvent e){}
}
class Fer extends JFrame
{ Imagine p=new Imagine();
public Fer(String titlu) {
super(titlu);
setSize(400,400);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container x=getContentPane();
x.setLayout(new FlowLayout ());
x.add(p);
setVisible(true);
}
}
public class pv {
public static void main(String args[]) {
Fer fp=new Fer("Imagine");
}
}


Observa]i faptul c` programul con]ine [i metoda update
(Graphics ecr). Ce este cu ea, de ce am pus-o?

Pentru a redesena, se apeleaz` repaint(). Practic, metoda apeleaz`


update() [i, aceasta din urm` apeleaz` paint(). Metoda update(),
apelat` implicit, are rolul de a [terge suprafa]a desenat` [i de a o afi[a,
dup` care se apeleaz` paint(). Apoi, metoda paint() realizeaz` noul
desen. Desigur, toate acestea se produc \ntr-un timp foarte scurt. Cu toate
acestea, apare o “p@lp@ire” a imaginii, care deranjeaz`. Solu]ia? Metoda
update() a fost rescris`. |n noua “versiune”, metoda nu mai cuprinde
[tergerea imaginii. Aceasta are un efect deosebit \n acest caz, deoarece
\ntotdeauna noua imagine se ob]ine din precedenta, la care se adaug` un
segment!
Capitolul 10. Iniţiere în programarea vizuală 271

10.12.4. Focus, evenimente de tip FocusEvent


Prin faptul c` o component` are focus-ul, \n]elegem c` respectiva
component` este preg`tit` s` primeasc` date sau comenzi de la tastatur`.
Putem distinge vizual componentele care au focus-ul. De exemplu, dac` un
buton are focus-ul, atunci el apare ca selectat (con]ine pe suprafa]a lui un
dreptunghi care marcheaz` acest fapt). Dac` este programat s` r`spund` la
evenimente de tip Action, simpla ap`sare a blank-ului ([i nu Enter) are
acela[i efect ca executarea unui click pe suprafa]a lui. Dac` un edit
(component` de tip JTextField) are focus-ul, atunci ce se tasteaz` apare
\n edit. De asemenea, \n interiorul lui, \n dreptul caracterului care urmeaz`
s` fie introdus, clipe[te cursorul de editare. Pentu a putea lucra cu focus-ul,
trebuie s` mai [tim urm`toarele:

1. O component` prime[te focus-ul dac` se execut` click pe suprafa]a ei.

2. Pentru ca focus-ul s` apar]in` componentei urm`toare, se apas` Tab.


Ordinea \n care se parcurg componentele, la ap`sarea tastei Tab, este de
la st@nga la dreapta, de sus \n jos. Astfel, teoretic, se poate lucra f`r`
mouse.
3. Se poate programa ca o anumit` component` s` primeasc` focus-ul. Se
va utilizeaza metoda:

 void requestFocus() – apar]ine de clasa Component.

4. Pentru a r`spunde la evenimente, se implementeaz` interfa]a


FocusListener cu cele dou` metode ale ei:

 void focusGained(FocusEvent e) - metoda se ruleaz` atunci


c@nd o component` prime[te focus-ul;

 void focusLost(FocusEvent e) - metoda se ruleaz` atunci c@nd o


component` pierde focus-ul.

Ambele metode con]in un parametru de tip FocusEvent. O metoda


important` a acestei clase este:

 Component getComponent() - metoda returneaz` o referin]` la


componenta care a recep]ionat evenimentul. Pornind de la aceast`
referin]`, se poate detecta componenta ca \n exemplul urm`tor:

Exemplul . Programul urm`tor probeaz` cele prezentate. Fereastra con]ine


dou` butoane [i un edit. Ini]ial, “Butonul 1” are implicit focus-ul. Dac`
ap`sa]i Blank ve]i ob]ine acela[i efect ca [i c@nd a]i executat click pe
suprafa]a butonului. Urm`ri]i atribuirea focus-ului prin ap`sarea tastei Tab.
Atunci c@nd o component` prime[te focus-ul, metoda focusGained()
afi[eaz` numele ei.
272 Bazele programării în Java

import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
class Fer extends JFrame implements FocusListener, ActionListener
{
JTextField txt;
public Fer(String titlu) {
super(titlu);
setSize(200,100);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container x=getContentPane();
x.setLayout(new FlowLayout ());
JButton A=new JButton("Buton 1"); x.add(A);
A.setName("Buton 1");
A.addFocusListener(this);
A.addActionListener(this);
JButton B=new JButton("Buton 2"); x.add(B);
B.addFocusListener(this);
B.setName("Buton 2");
txt =new JTextField(10);
txt.setName("Edit");
txt.addFocusListener(this);
x.add(txt);
setVisible(true);
}
public void focusGained(FocusEvent e)
{ System.out.println(e.getComponent().getName());}
public void focusLost(FocusEvent e) {}
public void actionPerformed (ActionEvent e)
{ System.out.println("blank sau click");}
}
public class pv {
public static void main(String args[]) {
Fer fp=new Fer("Focus");
}
}

Exemplul . Validare. Una dintre cele mai frecvente utiliz`ri a focus-ului


este dat` de opera]ia de validare. Concret:
c@nd un edit pierde focus-ul, \n metoda
focusLost() se scrie secven]a de validare.
Dac` data introdus` este incorect`, se
afi[eaz` mesajul corespunz`tor [i se
redirec]ioneaz` focus-ul c`tre edit. |n acest
fel, nu se poate p`r`si opera]ia de editare p@n` c@nd nu am introdus o
valoare corect`. |n exemplu, se cere ca valoarea introdus` s` fie de tip
double.
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
Capitolul 10. Iniţiere în programarea vizuală 273

class Fer extends JFrame implements FocusListener


{ JTextField txt;
public Fer(String titlu) {
super(titlu); setSize(200,100);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container x=getContentPane();
x.setLayout(new FlowLayout ());
JButton A= new JButton("Apasa"); x.add(A);
txt =new JTextField(10);
txt.addFocusListener(this);
x.add(txt); setVisible(true);
}
public void focusGained(FocusEvent e){}
public void focusLost(FocusEvent e)
{ String t=txt.getText();
try { double x=Double.parseDouble(txt.getText());
System.out.println(t);}
catch (Exception ex)
{ System.out.println("Numar eronat"); txt.requestFocus();}
}
}
public class pv {
public static void main(String args[]) {
Fer fp=new Fer("Focus");}
}

10.12.5. Evenimemente de selectare a item-ilor


Astfel de evenimente apar pentru componente precum JCheckBox sau
JComboBox. Ele se pot trata \n mod direct, imediat ce selectarea a fost
implementat`. Pentru aceasta, trebuie utilizat` interfa]a ItemListener care
con]ine o singur` metod`:

 void itemStateChanged(ItemEvent e) - metod` care se apeleaz`


de c@te ori se produce o deselectare sau o selectare. Aten]ie: dac`,
de exemplu, \ntr-o list` se selecteaz` o alt` op]iune, mai \nt@i
op]iunea curent` este deselectat`, dup` care este selectat` op]iunea
aleas` de utilizator. Aceasta \nseamn` c`, \n acest caz, metoda se
apeleaz` de dou` ori.

S` observ`m c` parametrul metodei de mai sus este de tipul


ItemEvent. O metod` important` a acestei clase este:

 int getStateChange() - returneaz` o valoare de tip int


corespunz`toare uneia din cele dou` posibilit`]i de generare a
evenimentului (deselectarea sau selectarea). Cele dou` valori sunt
SELECTED [i DESELECTED (constante ale clasei ItemEvent).

 Componentele care pot transmite astfel de evenimente con]in


metoda addItemListener(ItemLitener a).
274 Bazele programării în Java

Exemplu: programul urm`tor afi[eaz` o


fereastr` care con]ine o list`. La fiecare
selectare, se afi[eaz` \n fereastra CMD
numele op]iunii selectate. Observa]i faptul
c`, de aceast` dat`, ascult`torul de evenimente a fost implementat ca o
clas` aparte (AsLIsta).
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
class AsLista implements ItemListener
{ JComboBox lista;
AsLista(JComboBox lista)
{ this.lista=lista;}
public void itemStateChanged (ItemEvent e)
{ if (e.getStateChange()==ItemEvent.SELECTED)
System.out.println(lista.getSelectedItem());}
}
class Fer extends JFrame
{ JComboBox lista; JSpinner s;
public Fer(String titlu) {
super(titlu); setSize(200,200);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container x=getContentPane();
lista=new JComboBox ();
x.setLayout(new FlowLayout());
lista.addItem("Optiunea 1"); lista.addItem("Optiunea 2");
lista.addItem("Optiunea 3"); lista.addItem("Optiunea 4");
x.add(lista);
AsLista as=new AsLista(lista);
lista.addItemListener(as);
setVisible(true);
}
}
public class pv {
public static void main(String args[]) {
Fer fp=new Fer("ItemListener");}
}

10.12.6. Evenimemente pentru fereastră


Obiectele de tip JFrame pot transmite urm`toarele evenimente:

 WINDOW_ACTIVATED - se produce atunci c@nd fereastra devine


activ`. Acest eveniment se poate \nt@mpla atunci c@nd fereastra a fost
afi[at` pentru prima dat`, atunci c@nd dup` minimizarea ei se revine
la dimensiunea ini]ial` sau atunci c@nd a fost activat` o alt` fereastr`
(s-a executat click pe suprafa]a ei) dup` care este reactivat` fereastra
studiat`.
Capitolul 10. Iniţiere în programarea vizuală 275

 WINDOW_OPENED - se produce atunci c@nd este deschis` fereastra.


 WINDOW_DEACTIVATED - se produce c@nd fereastra devine inactiv`.
Evenimentul se poate \nt@mpla atunci c@nd am activat o alt` fereastr`
sau atunci c@nd am minimizat-o.
 WINDOW_CLOSING - se produce atunci c@nd se \nchide fereastra.
 WINDOW_ICONIFIED - se produce atunci c@nd am minimizat
fereastra.
 WINDOW_DEICONIFIED - se produce atunci c@nd se execut` click pe
fereastra minimizat`.
 WINDOW_CLOSED - se produce dup` ce fereastra a fost \nchis`.

Pentru fiecare eveniment, interfa]a WindowListener con]ine antetul


unei metode care trebuie apelat`. Leg`tura dintre numele evenimentelor [i
cel al metodelor este evident`.
Astfel, avem urmatoarele antete \n WindowListener:

public void windowOpened(WindowEvent e)


public void windowClosing(WindowEvent e)
public void windowClosed(WindowEvent e)
public void windowIconified(WindowEvent e)
public void windowDeiconified(WindowEvent e)
public void windowActivated(WindowEvent e)
public void windowDeactivated(WindowEvent e)

Metoda clasei JFrame,


void addWindowListener(WindowListener a)
are rolul de a asocia ferestrei ascult`torul de evenimente.

Exemplu: programul de mai jos v` permite s` studia]i “pe viu” evenimentele


declan[ate atunci c@nd se efectueaz` diverse opera]ii cu fereastra. Numele
evenimentelor este afi[at \n fereastra CMD:
import javax.swing.*;
import java.awt.event.*;

class InchidF extends Evfer


{ public void windowClosing(WindowEvent e)
{ System.out.println("WINDOW_CLOSING");
System.exit(0);
}
public void windowOpened(WindowEvent e)
{ System.out.println("WINDOW_OPENED");}
public void windowActivated(WindowEvent e)
{ System.out.println("WINDOW_ACTIVATED");}
276 Bazele programării în Java

public void windowDeactivated(WindowEvent e)


{ System.out.println("WINDOW_DEACTIVATED");}
public void windowIconified(WindowEvent e)
{ System.out.println("WINDOW_ICONIFIED"); }
public void windowDeiconified(WindowEvent e)
{ System.out.println("WINDOW_DEICONIFIED");}
}
public class td {
public static void main(String args[]) {
JFrame fp=new JFrame("Fereastra care se inchide");
WindowListener t=new InchidF();
fp.addWindowListener(t);
fp.setSize(200,300);
fp.setVisible(true);
}
}

10.13. Animarea imaginilor


Este momentul s` prezent`m modul \n care se realizeaz` \n Java
animarea imaginilor. În principal, dac` se dispune de o succesiune de
imagini, mecanismul este simplu:

1. Se \ncarc` imaginile \n memorie, \ntr-un vector de componente de tip


Image.
2. O imagine este afi[at` un inteval de timp, apoi se afi[eaz` urm`toarea
imagine un interval de timp, [.a.m.d.

Exemplu: avem mai multe imagini succesive \n fi[ierele Poza1.jpg,


Poza2.jpg,..., Poza12.jpg. O fereastr` afi[eaz` la nesf@r[it imaginile \n
ordinea 1, 2...12, apoi 12, 11, ...1, [i iar, 1, 2,...12, etc…

Poza1.jpg…………….Poza4.jpg…………....Poza8.jpg…………...Poza12.jpg

De fapt, efectul ob]inut este o iluzie optic`. Dac` anima]ia este realizat`
într-un mod coerent [i intuitiv, ea va fi perceput` foarte u[or de privitori.
Totul depinde de îndemânarea [i talentul programatorului la crearea unor
efecte vizuale cât mai realiste.
Capitolul 10. Iniţiere în programarea vizuală 277

Programul este urm`torul:


import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
class Fir extends Thread {
// fir de executie pentru afisarea imaginilor la nesfarsit
// constructorul primeste ca parametru referinta catre imagine
Imagine imag ;
int i;
Fir (Imagine imag) { this.imag=imag;}
public void run()
{ while (true)
{ while (i!=11)
{ i++; imag.afis(i);
try { sleep(300); }
catch (Exception e) {} }
while (i!=0)
{ i--; imag.afis(i);
try { sleep(300); }
catch (Exception e) {} }
}
}
}
class Imagine extends Canvas
{ Image[] im= new Image[12];
int i=0;
Imagine()
{ Toolkit ec=Toolkit.getDefaultToolkit();
for (int i=0;i<=11;i++)
im[i]=ec.getImage("C:\\Foto\\Poza"+(i+1)+".jpg");
setSize(300,300);
setBackground(Color.YELLOW);
}
public void paint (Graphics ecr)
{ ecr.drawImage(im[i],0,0,300,300,this);}
public void update(Graphics ecr)
{ paint(ecr);}
void afis(int i)
{ this.i=i;
repaint();}
}
class Fer extends JFrame
{ Imagine p=new Imagine();
public Fer(String titlu) {
super(titlu); setSize(400,400);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container x=getContentPane();
x.setLayout(new FlowLayout ()); x.add(p);
Fir f=new Fir(p); f.start();
setVisible(true);
}
}
278 Bazele programării în Java

public class pv {
public static void main(String args[]) {
Fer fp=new Fer("Imagine");}
}

 Observa]ii asupra programului:


1. Clasa imagine este asem`n`toare cu clasa care afi[eaz` o imagine [i
este dat` ca exemplu \n acesat` carte (vezi 10.10.1). Deosebirile sunt
date de urm`toarele:
a) Nu se re]ine o imagine, ci 12. Ele sunt \nc`rcate de constructorul
clasei.
b) Clasa are data membru i. Metoda paint() deseneaz` imaginea cu
indicele i.
c) Metoda afis() are rolul de a transmite valoarea care este memorat`
de i [i de a comanda redesenarea imaginii.
d) Metoda update() este redefinit`, pentru c` dac` n-ar fi fost redefinit`,
\nainte de a fi desenat` noua imagine de paint(), vechea imagine ar fi
fost [tears`. Aceasta ar crea efectul de “p@lp@ire”.
2. Practic, clasa Fir este un fir de executare care asigur` animarea
imaginilor. S-a procedat \n felul urm`tor:
a) Constructorul ei prime[te ca parametru referin]a c`tre obiectul de tip
Imagine [i o memoreaz`;
b) Pornind de la aceast` referin]`, se apeleaz` continuu metoda afis() a
clasei Imagine, metod` care redeseneaz` imaginea de indice dat.

Probleme propuse
1. Scrie]i un program \n care o fereastr` afi[eaz` un buton. La ap`sarea
butonului, programul va afi[a \n fereastra CMD rezolu]ia ecranului.
2. Scrie]i un program \n care o fereastr`
afi[eaz` dou` butoane: Buton 1 [i Buton 2.
{tiind c` metoda boolean isEnabled() a clasei
JComponent returneaz` true dac` butonul este activ [i false \n caz
contrar, face]i \n a[a fel \nc@t, la ap`sarea primului buton, daca al doilea
buton este activ s` devin` inactiv [i invers, dac` este inactiv s` devin`
activ.
3. Cum se pot a[eza dou` butoane \n fereastr`
ca \n exemplul al`turat? Observa]i faptul c` primul
buton ocup` toat` partea de sus, iar al doilea
este a[ezat centrat pe orizontal`, \n partea de jos.
Capitolul 10. Iniţiere în programarea vizuală 279

4. Cum se poate ca o fereastr` s` afi[eze cinci butoane, precum cea de


mai jos:

5. Prin utilizarea gestionarului de pozi]ionare GridBagLayout, crea]i


fereastra de mai jos:

6. Se [tie c` pentru a citi o parol`


se utilizeaz` o component` de tip
JPasswordField (clas` care are ca
superclas` pe JTextField). Se [tie de asemenea, c` pentru o
component` de tip JPasswordField, metoda getText() este depreciat`
[i \n locul ei se utilizeaz` metoda: char[] getPassword(). Se cere ca
programul dvs. s` citeasc` o parol` [i s` afi[eze OK dac` parola introdus`
este [irul “Mama” [i NO \n caz contrar.

7. Realiza]i un program \n care \ntr-un edit s` se


poat` introduce numere prin ap`sarea unor butoane,
ca al`turat. Extinde]i apoi programul pentru
simularea unui calculator de buzunar.

8. S` se scrie un program care con]ine trei


metode prin care se determin` dac` un num`r
natural n citit este prim sau nu. Prima dintre ele
testeaz` to]i divizorii num`rului de 2 la n-1, a
n
doua divizorii de la 2 la , a treia de 2 la n.
2
Pentru citerea num`rului, fereastra va con]ine o etichet` [i un edit, pentru
selectarea algoritmului se va utiliza o list`, iar dup` introducerea num`rului
[i selectarea algoritmului, un buton va declan[a prelucrarea corespunz`toare.
280 Bazele programării în Java

9. Programul dvs. va efectua o copie a un fi[ier text. Numele fi[ierului


care se copiaz` va fi introdus \ntr-un edit, iar numele fi[ierului destina]ie \n
alt edit.
10. Scrie]i un program care genereaz` un fi[ier text cu n numere naturale.
Valoarea lui n va fi introdus` cu ajutorul unui edit!
11. Scrie]i un program care creeaz`, pornind de la fi[ierul anterior, un altul
care con]ine acelea[i numere, dar sortate cresc`tor. Se vor implementa mai
mul]i algoritmi de sortare, iar selec]ia celui care va sorta fi[ierul se va face
cu ajutorul unei liste aflat` pe fereastra principal`.
12. Scrie]i un program care cite[te dou` numere reale. Programul va putea
afi[a suma, diferen]a, produsul [i c@tul lor. Opera]ia care se efectueaz` se
va selecta dintr-un meniu. Rezultatul va fi afi[at cu ajutorul unor cutii de
dialog predefinite.
13. Crea]i un fi[ier text \n care fiecare linie con]ine numele unei persoane
[i v@rsta ei. Datele se introduc secven]ial. Pentru a le introduce, o fereastr`
va avea ata[ate dou` edit-uri (unul pentru nume [i altul pentru v@rst`) [i
un buton. La ap`sarea butonului se va efectua validarea datelor (alfabetic
pentru nume [i numar natural \ntre 1 [i 99 pentru v@rst`). Dac` datele
introduse nu corespund, se va afi[a un mesaj de avertizare [i utilizatorul va
fi invitat s` introduc` corect datele. Dac` datele sunt introduse corect, se
va scrie linia corespunz`toare \n fi[ierul text.
14. Ad`uga]i o list` ferestrei de la problema precedent` din care se pot
selecta mai multe op]iuni, \n urma c`rora programul va putea afi[a:
a) Media v@rstelor persoanelor a c`ror date au fost trecute \n fi[ier;
b) Num`rul de persoane care au datele trecute \n fi[ier.
15. Scrie]i un program care afi[eaz` [i actualizeaz` fi[ierul creat la
problema 13. Pentru a realiza opera]iile propuse se va utiliza o component`
de tip JTextArea, iar opera]iile Open, Save [i Save As se vor selecta
dintr-un meniu.
16. Scrie]i un program care genereaz` un fi[ier text care con]ine cel pu]in
10.000 numere naturale aleatoare. Apoi, scrie]i un alt program care
sorteaz` fi[ierul prin utilizarea mai multor metode de sortare. Metoda de
sortare se va selecta dintr-o list`. La fiecare sortare, se va estima timpul
r`mas prin utilizarea unei componente de tip JProgressBar.
17. Scrie]i un program \n care o component` de tip JTextArea afi[eaz`
un text preluat dintr-un fi[ier text dat. Se cere s` se seteze font-ul prin
selectarea sa dintr-o list` [i m`rimea lui prin utilizarea unei componente de
tip JSpinner.
18. Scrie]i un program \n care se creeaz` [i se actualizeaz` un fi[ier text.
Textul se introduce cu ajutorul unei componente de tip JTextArea. Pentru
Capitolul 10. Iniţiere în programarea vizuală 281

deschiderea fi[ierului [i salvarea lui, se utilizeaz` cutii de dialog de tip


Open / Save apelabile dintr-un meniu.
19. Completa]i programul anterior astfel \nc@t culoarea suprafe]ei
componentei de tip JTextArea s` poat` fi selectat` cu ajutorul unei
componente de tip JColorChooser, apelabil` cu ajutorul unui buton aflat
pe bara de unelte. De asemenea, fontul va fi selectat dintr-o list`, iar
m`rimea lui cu ajutorul unei componente de tip JSpinner, ambele aflate pe
bara cu unelte (component` de tip JToolBar).
20. Citi]i dou` matrice 44. Afi[a]i produsul lor. Pentru citire [i afi[are se
vor utiliza componente de tip JTable.
21. Scrie]i un program care creeaz` [i actualizeaz` fi[ierul text
persoane.txt. Fi[ierul con]ine, pe fiecare linie, numele [i v@rsta unei
persoane. Pentru introducerea datelor [i actualizarea lor se va utiliza o
component` de tip JTable.
22. La fel ca la problema 21, numai c` pentru introducerea datelor sau
actualizarea lor se se utilizeaz` mai multe cutii de dialog create de dvs.
23. Scrie]i un program \n care fereastra va afi[a, la alegere, mai multe
imagini. Imaginea afi[at` va fi selectat` dintr-o list`.
24. Scrie]i un program care afi[eaz` toate solu]iile pentru problema celor
n dame. |n exemplu, se consider` n=8. Dup` afi[area unei solu]ii, pentru a
fi afi[at` urm`toarea solu]ie, se va ap`sa un buton. Pentru afi[are, ve]i
utiliza o component` de tip JTable.
25. Scrie]i un program \n care fereastra afi[eaz` \n permanen]` un
segment care se rote[te \n jurul unei extremit`]i.
26. Programul va afi[a un p`trat care se rote[te \n jurul unui col] al s`u.
27. Scrie]i un program care v` permite s` realiza]i desene. Cerin]e: se pot
utiliza mai multe culori, selectabile cu ajutorul unei componente de tip
JColorChooser. De asemenea, programul v` va permite s` [terge]i
por]iuni din desen.

Indicaţii:

1. La ap`sarea butonului, r`spunde metoda:

public void actionPerformed (ActionEvent e)


{ Toolkit ec=Toolkit.getDefaultToolkit();
Dimension dim = ec.getScreenSize();
System.out.println(dim.width);
System.out.println(dim.height);
}
282 Bazele programării în Java

2. JButton B trebuie declarat ca dat` membru a clasei pentru a avea


acces la el din metoda urm`toare, care r`spunde la ap`sarea primului
buton:
public void actionPerformed (ActionEvent e)
{ if (B.isEnabled()) B.setEnabled(false);
else B.setEnabled(true);
}

3. Fereastra are gestionarul de pozi]ionare BorderLayout. |n nord, avem


primul buton. |n centru avem un panel. Acesta se extinde pe \ntreaga
suprafa]` r`mas`. La r@ndul lui, panelul este gestinat de FlowLayout. Lui
\i ad`ug`m al doilea buton.
...
Container x=getContentPane();
x.setLayout(new BorderLayout ());
JButton A=new JButton("Buton 1");
x.add(A,BorderLayout.NORTH);
JPanel panel=new JPanel();
x.add(panel,BorderLayout.CENTER);
panel.setLayout(new FlowLayout());
B=new JButton("Buton 2");
panel.add(B);
...

4.
...
Container x=getContentPane();
x.setLayout(new BorderLayout ());
JButton A=new JButton("Buton 1");
x.add(A,BorderLayout.SOUTH);
JPanel panel=new JPanel();
x.add(panel,BorderLayout.CENTER);
panel.setLayout(new GridLayout(2,2));
JButton B=new JButton("Buton 2"); panel.add(B);
JButton C=new JButton("Buton 3"); panel.add(C);
JButton D=new JButton("Buton 4"); panel.add(D);
JButton E=new JButton("Buton 5"); panel.add(E);
...

5.
class Fer extends JFrame
{
public Fer(String titlu) {
super(titlu); setSize(250,200);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
GridBagLayout pozitii=new GridBagLayout();
JLabel et=new JLabel ("Numele ");
JTextField txt=new JTextField(15);
JLabel et1=new JLabel("Varsta");
JTextField txt1=new JTextField(2);
JButton bt=new JButton("Apasa");
Container x=getContentPane();
Capitolul 10. Iniţiere în programarea vizuală 283

// pozitionare et
GridBagConstraints p_et=new
GridBagConstraints(0,0,1,1,1,2,GridBagConstraints.WEST,
GridBagConstraints.NONE,new Insets(0,0,0,0), 0,0);
pozitii.setConstraints(et,p_et);
// pozitionare txt
GridBagConstraints p_txt=new
GridBagConstraints(1,0,1,1,4,2,GridBagConstraints.WEST,
GridBagConstraints.NONE,new Insets(0,0,0,0), 0,0);
pozitii.setConstraints(txt,p_txt);
// pozitionare et1
GridBagConstraints p_et1=new
GridBagConstraints(0,1,1,1,1,2,GridBagConstraints.WEST,
GridBagConstraints.NONE,new Insets(0,0,0,0), 0,0);
pozitii.setConstraints(et1,p_et1);
// pozitionare txt1
GridBagConstraints p_txt1=new
GridBagConstraints(1,1,1,1,4,2,GridBagConstraints.WEST,
GridBagConstraints.NONE,new Insets(0,0,0,0), 0,0);
pozitii.setConstraints(txt1,p_txt1);
// pozitiona buton
GridBagConstraints p_bt=new
GridBagConstraints(0,2,2,1,1,1,GridBagConstraints.CENTER,
GridBagConstraints.NONE,new Insets(0,0,0,0), 0,0);
pozitii.setConstraints(bt,p_bt);
x.setLayout(pozitii);
x.add(et);
x.add(txt);
x.add(bt);
x.add(et1);
x.add(txt1);
setVisible(true);
}
}

6. Utiliza]i metoda:

public void actionPerformed (ActionEvent e)


{
String parola=new String(txt.getPassword());
if (parola.compareTo("Mama")==0)
System.out.println("OK");
else System.out.println("KO");
}

7. Proceda]i ca mai jos:

class Fer extends JFrame implements ActionListener


{
JButton zero=new JButton("0");
JButton unu=new JButton("1");
JButton doi=new JButton("2");
JButton trei=new JButton("3");
JButton patru=new JButton("4");
284 Bazele programării în Java

JButton cinci=new JButton("5");


JButton sase=new JButton("6");
JButton sapte=new JButton("7");
JButton opt=new JButton("8");
JButton noua=new JButton("9");
JTextField txt=new JTextField("");
JPanel panel=new JPanel();

public Fer(String titlu) {


super(titlu);
setSize(200,200);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container x=getContentPane();
x.setLayout(new BorderLayout ());
panel.setLayout(new GridLayout(4,3));
x.add(txt,BorderLayout.NORTH);
x.add(panel,BorderLayout.CENTER);
panel.add(unu);
panel.add(doi);
panel.add(trei);
panel.add(patru);
panel.add(cinci);
panel.add(sase);
panel.add(sapte);
panel.add(opt);
panel.add(noua);
panel.add(zero);
unu.addActionListener(this);
doi.addActionListener(this);
trei.addActionListener(this);
patru.addActionListener(this);
cinci.addActionListener(this);
sase.addActionListener(this);
sapte.addActionListener(this);
opt.addActionListener(this);
noua.addActionListener(this);
zero.addActionListener(this);
setVisible(true);
txt.setHorizontalAlignment(JTextField.RIGHT);
}
public void actionPerformed (ActionEvent e)
{ txt.setText(txt.getText()+e.getActionCommand());
}
}
CAPITOLUL 11

Applet-uri

Din cuprins:
Crearea şi executarea applet-urilor
Arhive Java şi atributele elementului APPLET
Redefinirea unor metode ale applet-ului
Afişarea imaginilor. Clasa URL
Redarea sunetelor
Exemple de applet-uri
Capitolul 11. Applet-uri 286

11.1. Generalităţi
Pentru a \n]elege acest capitol, trebuie s` ave]i no]iuni despre HTML
[i modul \n care se “posteaz`” pe Internet o pagin` WEB. Aceste no]iuni pot
fi g`site, fie \n “Crearea [i programarea paginilor WEB”, fie \n “Tehnologia
Informa]iei [i a Comunica]iilor”, manual pentru clasa a IX-a, ambele scrise
de autorii acestei c`r]i.

 Important:
1. Un applet este asem`n`tor unei ferestre. El poate con]ine una sau mai
multe componente pe suprafa]a sa.
2. Pentru crearea unui applet vom utiliza o component` de tip JApplet.
3. Applet-ul este ata[at unui fi[ier HTML, la fel ca o imagine.
4. Applet-ul este afi[at de c`tre browser-ul calculatorului de pe care se
vizualizeaz` pagina WEB [i este rulat tot de acesta.
5. Pentru ca browser-ul s` poat` rula applet-ul este necesar ca pe acel
calculator s` se g`seasc` implementat` (instalat`) o ma[in` virtual` Java
(Java Virtual Machine, JVM). Cum noi avem deja implementat soft-ul de
dezvoltare Java, nu mai avem nici o problem`, deoarece JVM este inclus \n
acesta. Dar, un utilizator oarecare poate desc`rca [i instala JVM de pe
site-ul firmei Sun.
6. M`surile de securitate impun anumite restric]ii. V` da]i seama ce ar fi
dac` nu s-ar lua m`surile de securitate de mai jos:
 Applet-urile nu pot scrie sau citi fi[iere;
 Nu pot apela programe aflate pe sistemul utilizatorului.

11.2. Crearea şi executarea applet-urilor


Mai jos ave]i un exemplu de applet. Pe suprafa]a sa se g`se[te un
buton, la ap`sarea c`ruia se afi[eaz` o cutie de dialog cu un mesaj
oarecare. Observa]i c@t de asem`n`tor este acest program cu un altul care
afi[eaz` o fereastr` cu un buton. {i aici avem un container c`ruia i s-a
ad`ugat un buton, am implementat ActionListener pentru ca butonul s`
r`spund` la ap`sare. Pentru crearea [i afi[area unui applet, trebuie s`
respecta]i urm`torii pa[i:

 Textul applet-ului se va g`si \ntr-un fi[ier text. Pentru a-l scrie [i


corecta, putem folosi Notepad-ul. Fi[ierul text care-l con]ine, va avea
extensia .java. Numele fi[ierului trebuie s` coincid` cu numele clasei care
con]ine applet-ul, \n exemplu Ap.java.
287 Bazele programării în Java

import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class Ap extends JApplet implements ActionListener
{ public void init () {
Container x = getContentPane();
x.setLayout(new FlowLayout ());
JButton A=new JButton("merge");
A.addActionListener(this);
x.add(A);
}

public void actionPerformed (ActionEvent e)


{ JOptionPane.showMessageDialog
(this, "La fel ca la fereastra clasica");
}
}

 Compil`m programul a[a cum suntem deja obi[nui]i: pentru exemplul


dat, vom scrie comanda javac Ap.java.

 Scriem un text HTML (tot cu Notepad) care include applet-ul scris, ca


mai jos. Observa]i faptul c` prin WIDTH [i HEIGHT am precizat (\n pixeli)
l`]imea, respectiv \n`l]imea dreptunghiului \n care se \ncadreaz` applet-ul.
Fi[ierul are \n mod obligatoriu extensia .html, dar numele lui poate fi
oarecare (nu este obligatoriu s` coincid` cu cel al applet-ului):

<HTML>
<BODY>
<APPLET CODE="Ap.class" WIDTH=300 HEIGHT=300>
</BODY>
</HTML>

 Test`m rezultatul, execut@nd dublu


click pe fi[ierul cu extensia .html.
Automat, va fi apelat browser-ul care va
afi[a applet-ul.

 Dup` ce fi[ierul HTML este gata


(putem ad`uga orice altceva \n el, a[a
cum suntem obi[nui]i), \l transfer`m pe
site cu ajutorul unui program FTP
(eventual cu programul WS_FTP). De
asemenea, transfer`m pe site [i applet-ul
compilat (cu extensia class). De acum,
\l putem apela de pe orice calculator cu
acces la Internet [i care are
implementat` JVM.
Capitolul 11. Applet-uri 288

11.3. Arhive Java şi atributele elementului APPLET


Ce se \nt@mpl` \n situa]ia \n care applet-ul utilizeaz` mai multe
clase? Dar dac`, \n plus, sunt necesare [i fi[iere imagine? Dup` cum
vedem, \n fi[ierul HTML se declar` un singur fi[ier de tip class, dar la
compilare, pentru fiecare clas` rezult` c@te un fi[ier de acest tip...

Mediul de dezvoltare Java con]ine [i un program care poate crea


arhive. O arhiv` este un fi[ier alc`tuit din mai multe fi[iere. Prin arhivare
\n]elegem opera]ia prin care, pornind de la mai multe fi[iere, se creeaz` o
arhiv` \n care datele sunt compresate, iar prin dezarhivare se \n]elege
opera]ia prin care, pornind de la o arhiv`, se refac toate fi[ierele care o
alc`tuiesc.

|n Java, arhivele se creeaz` cu programul jar, furnizat de mediul de


dezvoltare (ca [i javac, de exemplu). Arhivele pot fi recunoscute dup`
extensia lor: .jar. Forma simplificat` a apelului programului jar pentru
crearea unei arhive alc`tuit` din fi[ierele: f1, f2,... fn este:

jar cf nume_arhiva f1 f2... fn

 Pute]i vedea to]i parametrii programului jar, dac`-l apela]i f`r`


nici un parametru !

Exemplu: \n mod for]at, applet-ul dat ca exemplu \n paragraful anterior a


fost creat prin utilizarea a dou` clase:
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;

class Buton extends JButton


{ }

public class Ap extends JApplet implements ActionListener


{ public void init () {
Container x = getContentPane();
x.setLayout(new FlowLayout ());
Buton A=new Buton();
A.addActionListener(this);
x.add(A);
}

public void actionPerformed (ActionEvent e)


{ JOptionPane.showMessageDialog(this, "La fel ca la fereastra
clasica");
}
}
289 Bazele programării în Java

La compilare, rezult` dou` fi[iere cu extensia .class: Ap.class [i


Buton.class. Form`m arhiva arh.jar prin comanda:
jar cf arh.jar Ap.class Buton.class

Mai jos, se poate observa cum arat` de aceast` dat` fi[ierul HTML:

<HTML>
<BODY>
<APPLET CODE="Ap.class" ARCHIVE="arh.jar" WIDTH=300 HEIGHT=300>
</BODY>
</HTML>

Dup` testare, vom transfera pe site fi[ierul HTML [i arhiva.

P@n` acum, am prezentat pe scurt modul \n care se ata[eaz` un


applet \n fi[ierul HTML. Am v`zut faptul c` pentru a realiza acest lucru, se
folose[te elementul APPLET. Atributele acestuia sunt:

 CODE - numele fi[ierului care con]ine clasa ce extinde JApplet;


 HEIGHT, WIDTH - \n`l]imea [i l`]imea dreptunghiului care afi[eaz`
applet-ul;
 ARCHIVE - numele fi[ierului care con]ine resursele utilizate de applet
(clase [i fi[iere imagine);
 ALLIGN - alinierea applet-ului \n pagin`. Mai importante sunt valorile:
- LEFT - aliniere st@nga;
- RIGHT - aliniere dreapta;
- TOP - \n partea de sus;
 HSPACE, VSPACE - spa]iul, \n pixeli, care trebuie p`strat \ntre
dreptunghiul care \ncadreaz` applet-ul [i text sau alte componente ale
aflate pe pagina WEB. (HSPACE, spa]iul l`sat pe orizontal`) [i VSPACE
(spa]iul l`sat pe vertical`).

11.4. Redefinirea unor metode ale applet-ului


Componentele de tip JApplet con]in [i metodele de mai jos, care
pot fi redefinite:

 void init() - este prima care se apeleaz` atunci c@nd am definit


un applet. Redefinit`, ea poate con]ine cod pentru anumite opera]ii
care dorim s` fie efectuate la \nceput. Aceast` metod` se execut` o
singur` dat`.
Capitolul 11. Applet-uri 290

 void start() - se apeleaz` atunci c@nd applet-ul devine activ, dar


[i \n alte situa]ii, de exemplu, atunci c@nd a fost p`r`sit` pagina web
[i se revine asupra ei.

 void stop() - se apeleaz` atunci c@nd se opre[te applet-ul sau


c@nd a fost p`r`sit` pagina web care-l con]ine.

 void paint(Graphics ecr) - se apeleaz` de c@te ori este cazul.


Prin intermediul ei se deseneaz` componenta. Ea este apelat` dup`
metodele init() [i start().

 void update(Graphics ecr) - spre deosebire de clasa Canvas,


unde metoda mai \nt@i [tergea desenul, dup` care apela paint(), de
aceast` dat`, metoda are corpul vid. Din acest motiv, nu mai este
necesar` rescrierea ei pentru a elimina fenomenul de “p@lp@ire” a
imaginii, dar dac` dorim ca ea s` [tearg` imaginea, atunci va trebui
redefinit`, iar opera]ia de [tergere trebuie scris` de dezvoltatorul
applet-ului.

Exemplu: pentru a vedea cum func]ioneaz` metodele de mai sus, rula]i


applet-ul urm`tor. Ini]ial, o cutie de dialog afi[eaz` „Init‟, apoi o alta
afi[eaz` “Start” [i, dreptunghiul care reprezint` applet-ul devine ro[u:

import java.awt.*;
import javax.swing.*;
public class Ap extends JApplet{
public void init()
{ JOptionPane.showMessageDialog (this, "Init");}
public void start()
{ JOptionPane.showMessageDialog (this, "Start");}
public void paint(Graphics g)
{ setBackground(Color.RED);}
}

11.5. Afişarea imaginilor. Clasa URL


Pentru a afi[a o imagine, mai \nt@i ea trebuie transferat` pe site
(eventual cu WS_FTP).

Pentru ca applet-ul s` aib` acces la ea, el va con]ine un obiect URL


(Uniform Resource Locator). Aceast` clas` se g`se[te \n pachetul
java.net. Clasa are constructorul:

 URL(String s) - unde s reprezint` adresa url a imaginii. |ntruc@t


la acea adresa s-ar putea s` nu se g`seasc` resursa respectiv`,
crearea unui obiect URL trebuie s` se fac` sub construc]ia try.

Pentru a citi imaginea, se utilizeaz` metoda de mai jos a clasei JApplet:


291 Bazele programării în Java

 Image getImage(URL adr) - metoda returneaz` imaginea.

|n rest, pentru a afi[a imaginea, vom utiliza metoda drawImage() a


clasei Graphics, metod` pe care o cunoa[tem deja. De asemenea, pentru
a putea folosi applet-ul cu dimensiuni diferite (scrise \n HTML, APPLET), se
utilizeaz` dou` metode ale clasei JApplet:

 int getWidth() - returneaz` l`]imea dreptunghiului care con]ine


applet-ul.
 int getHeight() - returneaz` \n`l]imea dreptunghiului care con]ine
applet-ul.
Exemplu: applet-ul urm`tor afi[eaz` o imagine
pe \ntreaga sa suprafa]`:
import java.awt.*;
import javax.swing.*;
import java.net.*;
public class Ap extends JApplet{
Image im;
int w,h;
URL x;
public void init()
{ try { x=new URL("http://www.xxxx.ro/imagine1.jpg");}
catch (Exception e)
{ JOptionPane.showMessageDialog (this, "Imaginea?");}
im=getImage(x);
w=getWidth();
h=getHeight();
}
public void paint (Graphics ecr)
{ ecr.drawImage(im,0,0,w,h,this);}
}

11.6. Redarea sunetelor


O component` de tip JApplet poate reda sunete. Fi[ierele pot fi de
mai multe tipuri: .au, .aiff, .wav. Ini]ial, fi[ierul audio este transferat pe
site.
Pentru a lucra cu sunete se utilizeaz` interfa]a AudioClip (se
g`se[te \n java.applet). Ea con]ine antetul a trei metode:

 void play() - red` sunetele din fi[ier o singur` dat`;


 void loop() - red` sunetele din fi[ier \n mod continuu;
 void stop() - opre[te redarea sunetelor din fi[ier. |n cazul \n care
nu se utilizeaz` aceast` metod`, sunetele se redau [i dup` ce
vizitatorul p`r`se[te pagina care con]ine applet-ul.
Capitolul 11. Applet-uri 292

De asemenea, pentru a putea lucra cu fi[iere audio, vom utiliza [i


metoda:

 AudioClip getAudioClip(URL url) - returneaz` un obiect


AudioClip (o implementare a interfe]ei).

Exemplu: applet-ul urm`tor afi[eaz` un dreptunghi ro[u, dar red` \n mod


continuu un fi[ier audio:
import java.awt.*;
import javax.swing.*;
import java.net.*;
import java.applet.*;
public class Ap extends JApplet{
URL adr;
AudioClip muzica;
public void init()
{ try {adr=new URL("http://www.ls-infomat.ro/spacemusic.au");}
catch (Exception ex) { }
muzica=getAudioClip(adr);
}
public void paint(Graphics ecr)
{ setBackground(Color.RED);}
public void start()
{ muzica.loop();}
public void stop()
{ muzica.stop();}
}

11.7. Exemple de applet-uri


1. Applet-ul urm`tor afi[eaz` un text
oarecare (vezi 8.10.2):
import java.awt.*;
import javax.swing.*;
public class Ap extends JApplet{
Font f;
public void init()
{ f=new Font("Arial",Font.BOLD, 20);
setBackground(Color.YELLOW);
}
public void paint (Graphics ecr)
{ ecr.setFont(f);
ecr.setColor(Color.BLACK);
ecr.drawString("Un exemplu de applet",50, 150);
}
}
293 Bazele programării în Java

2. Applet-ul urm`tor afi[eaz` o imagine pe care


am scris un mesaj !
import java.awt.*;
import javax.swing.*;
import java.net.*;
public class Ap extends JApplet{
Image im; int w,h; URL x;
Font f;
public void init()
{ try
{ x=new URL("http://www.xxxxxx.ro/
fericire.jpg");}
catch (Exception e) {}
im=getImage(x);
w=getWidth(); h=getHeight();
f=new Font("Arial",Font.BOLD, 30);
}
public void paint (Graphics ecr)
{ ecr.drawImage(im,0,0,w,h,this);
ecr.setFont(f);
ecr.drawString("Fericire generala!!!",50,270);
}
}

3. Pute]i realiza un applet


care rote[te (cicleaz`) la
nesf@r[it un [ir de caractere.
Este o form` la care se apeleaz` de multe ori atunci c@nd se dore[te ca o
anumit` pagin` s` aib` un con]inut informativ! Pentru a ob]ine acest efect
am utilizat un fir de execu]ie. Practic, primul caracter al [irului afi[at se
a[eaz` pe ultima pozi]ie, se a[teapt` un interval de timp, apoi primul
caracter al [irului astfel ob]inut se a[eaz` pe ultima pozi]ie, se a[teapt`,
etc. De vreme ce avem un fir de execu]ie, trebuie creat` o arhiv` care va
fi pus` pe site. Arhiva va con]ine fi[ierele Ap.class [i Fir.class.
import java.awt.*;
import javax.swing.*;
class Fir extends Thread {
JTextField txt;
Fir (JTextField txt)
{ this.txt=txt;}
public void run()
{ while (true)
{ String s=txt.getText();
try { sleep(300); }
catch (Exception e) {}
s= s.substring(1)+s.substring (0,1);
txt.setText(s);
}
}
}
Capitolul 11. Applet-uri 294

public class Ap extends JApplet{


JTextField txt;
public void init()
{ Container x = getContentPane();
x.setLayout(new BorderLayout());
txt=new JTextField ("Acesta este un sir de caractere care se
roteste pe durata de viata a applet-ului.
Pentru a-l implementa avem nevoie de doua
clase ");
txt.setBackground(Color.YELLOW);
Font f=new Font("Arial",Font.BOLD, 20);
txt.setFont(f);
x.add(txt,BorderLayout.NORTH);
Fir fir=new Fir(txt);
fir.start();
}
}

4. Applet-ul urm`tor prezint` modul \n care se pot realiza anima]ii pe


Internet. Mai \nt@i, au fost trecute pe site mai multe imagini (12). Apoi,
printr-un mecanism asem`n`tor celui de la 10.14. (revede]i), s-a realizat
anima]ia:
import java.awt.*;
import javax.swing.*;
import java.net.*;
class Fir extends Thread {
Ap acesta;
int i;
Fir (Ap acesta)
{ this.acesta=acesta;}
public void run()
{ while (true)
{ while (i!=11)
{ i++;
acesta.afis(i);
try { sleep(300); }
catch (Exception e) {}
}
while (i!=0)
{ i--;
acesta.afis(i);
try { sleep(300); }
catch (Exception e) {}
}
}
}
}
public class Ap extends JApplet{
Image[] im =new Image[12];
URL[] url;
int w,h,indice=0;
String s=new String("http://www.xxxx.ro/Poza");
URL t=null;
295 Bazele programării în Java

public void init()


{ for (int i=0;i<12;i++)
{ try {
t=new URL(s+(i+1)+".jpg");
im[i]=getImage(t);}
catch (Exception e) { }
}
w=getWidth(); h=getHeight();
Fir fir=new Fir(this);
fir.start();
}
public void paint (Graphics ecr)
{ ecr.drawImage(im[indice],0,0,200,200,this);}
void afis(int i)
{ indice=i; repaint();}
}

5. Efecte. Applet-ul urm`tor afi[eaz` un


gradient ciclic dinamic (vezi 10.11.3). Efectul
este deosebit. Analiza]i-l!
import java.awt.*;
import javax.swing.*;
import java.awt.geom.*;
class Fir extends Thread {
Ap acesta;
Fir (Ap acesta) {this.acesta=acesta; }
public void run()
{ try { sleep(50); }
catch (Exception e) { }
acesta.afis();}
}
public class Ap extends JApplet{
int x1,y1,x2,y2;
public void init()
{ Fir x=new Fir(this); x.start();}
public void paint (Graphics ecr1)
{ Graphics2D ecr=(Graphics2D) ecr1;
GradientPaint g=new GradientPaint(x1,y1, Color.YELLOW,
x2,y2, Color.BLACK, true);
ecr.setPaint(g);
Rectangle2D.Float drept = new Rectangle2D.Float
(0,0, getWidth(),getHeight());
ecr.fill(drept);
}
void afis()
{ x1=(int)Math.round(1+Math.ceil(Math.random()*50));
y1=(int)Math.round(1+Math.ceil(Math.random()*50));
x2=(int)Math.round(1+Math.ceil(Math.random()*50));
y2=(int)Math.round(1+Math.ceil(Math.random()*50)); repaint();
}
}
Capitolul 11. Applet-uri 296

6. Applet-ul urm`tor este un exemplu simplu de anima]ie. Practic, un cerc


se “plimb`” la st@nga [i la dreapta. Observa]i faptul c`, de aceast` dat`, a
fost necesar s` rescriem metoda update(), care va [terge cercul \nainte
ca metoda paint() s`-l redeseneze:
import java.awt.*;
import javax.swing.*;
import java.awt.geom.*;
class Fir extends Thread {
Ap acesta;
Fir (Ap acesta)
{ this.acesta=acesta; }
public void run()
{ int i;
while (true)
{ for (i=0;i<100;i++)
{ try { sleep(200); }
catch (Exception e) { }
acesta.afis(i);}
for (;i>0;i--)
{ try { sleep(200); }
catch (Exception e) { }
acesta.afis(i);}
}
}
}
public class Ap extends JApplet{
int x=100,y=100,r=100;
public void init()
{ Fir f=new Fir(this);
f.start();
}
public void paint (Graphics ecr)
{ ecr.fillOval(x, y, 50, 50);}
public void update(Graphics ecr)
{ ecr.setColor(getBackground());
ecr.fillRect(0,0,getWidth(),getHeight());
ecr.setColor(Color.BLACK);
paint(ecr);
}
void afis(int i)
{ x=100+i;
repaint();
}
}

7. Applet-ul care “plimb`” acela[i cerc ca [i cel


anterior, dar care nu [terge desenul (efectul se vede \n
figura al`turat`). Sursa s-a ob]inut din cea anterioar` la
care s-a [ters metoda update().