Sunteți pe pagina 1din 110

Universitatea Transilvania din Braov s Facultatea de Stiinte Catedra de Informatic a ERNEST SCHEIBER

Programare Java n

Braov s 2001

Cuprins
1 HelloWorld 2 Java Elementele de baz a 2.1 Uniti lexicale . . . . . . . . . . . . . . . at 2.1.1 Identicatori . . . . . . . . . . . . 2.1.2 Literali . . . . . . . . . . . . . . . 2.1.3 Separatori . . . . . . . . . . . . . . 2.1.4 Operatori . . . . . . . . . . . . . . 2.1.5 Comentarii . . . . . . . . . . . . . 2.2 Tipuri primitive . . . . . . . . . . . . . . . 2.3 Instructiuni Java . . . . . . . . . . . . . . 2.3.1 Instructiunea de atribuire . . . . . 2.3.2 Instructiunea if-else . . . . . . . . 2.3.3 Instructiunea switch-case . . . . . 2.3.4 Instructiunea de ciclare while . . . 2.3.5 Instructiunea de ciclare do-while 2.3.6 Instructiunea de ciclare for . . . . 2.3.7 Instructiunea vid . . . . . . . . . a 2.4 Aplicatii . . . . . . . . . . . . . . . . . . . 5 7 7 7 8 8 8 10 11 11 11 11 11 11 12 12 12 12 14 14 16 17 17 17 19 27 27

. . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . .

3 Referinte 3.1 Tablouri . . . . . . . . . . . . . . . . . . . . . . . . . 3.2 Elemente de programare orientat obiect . . . . . . . a 3.3 Clase i obiecte Java . . . . . . . . . . . . . . . . . s n 3.3.1 Denirea unei clase . . . . . . . . . . . . . . . 3.3.2 Denirea/declararea cmpurilor i metodelor a s 3.3.3 Utilizarea obiectelor . . . . . . . . . . . . . . 3.3.4 Clasa Object . . . . . . . . . . . . . . . . . . 3.4 Interfete . . . . . . . . . . . . . . . . . . . . . . . . . 2

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

CUPRINS

4 Tratarea exceptiilor 30 4.1 Instructiunea try . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 4.2 Denirea unei exceptii proprii . . . . . . . . . . . . . . . . . . . . . 31 5 Clase Java predenite I 34 5.1 Clasa String . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34 5.2 Clasa StringBuffer . . . . . . . . . . . . . . . . . . . . . . . . . . 38 5.3 Clase acoperitoare tipurilor predenite . . . . . . . . . . . . . . . . 40 6 Pachete : biblioteci de programe 42

7 Miniaplicatii Java 45 7.1 HTML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45 7.2 Applet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47 8 Operatii de Intrare Ieire s 8.1 Accesul la sistemul de iere . . . . . . . . . . . . . . . . s 8.2 Operatii de Intrare Ieire la nivel de octeti . . . . . . . s 8.2.1 FileInputStream,FileOutputStream . . . . . . . . 8.2.2 ByteArrayInputStream, ByteArrayOutputStream 8.2.3 PipedInputStream, PipedOutputStream . . . . . 8.2.4 SequenceInputStream . . . . . . . . . . . . . . . 8.2.5 DataInputStream, DataOutputStream . . . . . . 8.3 Operatii de Intrare Ieire la nivel de caracter . . . . . s 8.3.1 FileReader, FileWriter . . . . . . . . . . . . . . . 8.3.2 CharArrayReader, CharArrayWriter . . . . . . . 8.3.3 PipedReader, PipedWriter . . . . . . . . . . . . . 8.3.4 BueredReader, BueredWriter . . . . . . . . . . 8.4 Introducerea datelor de la tastatur . . . . . . . . . . . a 9 Aspecte concurentiale Java n 9.1 Fire de executie Java . . . . . . . . . . . n 9.2 Extinderea clasei java.lang.Thread . . . . . 9.3 Implementarea interfetei java.lang.Runnable 9.4 Activiti de control a relor de executie . . at 9.5 Rezolvarea problemelor de sincronizare . . . 9.6 Fire de executie ntr-un applet . . . . . . . 51 51 53 54 55 56 59 60 62 62 64 65 67 68 71 71 72 73 74 79 89

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

10 Interfete fundamentale 93 10.1 Interfata Clonable . . . . . . . . . . . . . . . . . . . . . . . . . . . 93 10.2 Interfata Enumeration . . . . . . . . . . . . . . . . . . . . . . . . . 97

4 11 Interfata grac Swing a 11.1 Realizarea unei interfete grace Swing 11.2 Componente grace Swing . . . . . . . 11.2.1 Gestionari de pozitionare . . . 11.2.2 Consumatoare de evenimente . 11.3 Aplicatii . . . . . . . . . . . . . . . . .

CUPRINS

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

98 98 101 104 104 104

Capitolul 1

HelloWorld
acest curs se utilizeaz distributia JDK 1.3 (Java Development Kit), proIn a dus se rma sun. a Realizarea unui program Java const din: a 1. Editarea programului ntr-un editor de texte; 2. Compilarea programului. Intr-o fereastr DOS se comand comanda a a javac NumeProgram.java 3. Executarea programului. Tot fereastra DOS se lanseaz n a java NumeClas a NumeClas este numele clasei care contine metoda main. a Intr-un program Java trebuie s existe o singur clas care posed o metod main. a a a a a Structura unui program simplu Java este class NumeClas { a public static void main(String args[ ]){ . . . codul programului . . . } } linia de comand, la lansarea compilatorului javac i a interpretorului In a s java, scrierea parametrilor NumeProgram i respectiv NumeClas este cases a sensitive. Produsul JCreator integraz a ntr-o interfat unic editarea, compilarea i a a s executia programului. Drept prim exemplu, e programul

CAPITOLUL 1. HELLOWORLD

class HelloWorld{ public static void main(String args[]){ System.out.println("Hello World"); } } salvat ca inceput.java Compilarea i executarea se obtine prin s javac inceput.java java HelloWorld Pentru nceput, s retinem modul de aare pe ecranul monitorului al unui a s ir de caractere (string) cu ajutorul metodei s

String.out.println("irul de caractere"); s Utilitarul jar realizeaz comprimarea / decomprimarea unui program Java. a Programul inceput.java se comprim prin a jar cvf inc.jar inceput.java iar decomprimarea se obtine prin jar xvf inc.jar Utilitarul javadoc produce o documentatie a unui program Java. javadoc inceput.java

Capitolul 2

Elementele de baz ale a limbajului de programare Java


2.1 Uniti lexicale at

Unitile lexicale ale limbajului Java sunt: at cuvinte cheie; identicatori; literali (constante); separatori; operatori; comentarii.

2.1.1

Identicatori

Un identicator este o secvent de lungime oarecare alctuit din litere, cifre a a a i caracterul de subliniere, primul caracter ind liter sau caracterul de subliniere. s a Conventii de scriere 1. Identicatorii variabilelor se scriu cu litere mici; 2. Prima litera a identicatorului unei clase se scrie cu majuscul; a 3. cuvintele compuse, In ncepnd cu al doilea, prima liter a cuvntului se a a a scrie cu majuscul; a Exemplu. unIdentificatorLung 7

CAPITOLUL 2. JAVA ELEMENTELE DE BAZA

4. Identicatorii constantelor (variabile cu modicatorul final) se scriu cu majuscule. Exemplu. Math.PI

2.1.2

Literali

Scrierea unui caracter: a Scrierea unui ir de caractere: Exemplu de ir de caractere s s Scrierea valorilor logice: true, false Scrierea numerelor: Numrul a ntreg 101=6516 = 1458 se scrie : 101 baza 10; n 0x65 baza 16; n 0145 baza 8; n 101l sau 101L baza 10, format lung; n 0x65l sau 0x65L baza 16, format lung; n 0145l sau 0145L baza 8, format lung. n Numrul real 10,52 se scrie: a 10.52 sau 10.52f sau 10.52F sau 0.1052e+2=1052e-2 cu reprezentare pe 4 octeti ; 10.52d sau 10.52D cu reprezentare pe 8 octeti ;

2.1.3

Separatori

Separatorii sunt {} () [] ; , .

2.1.4

Operatori

Operatori algebrici

2.1. UNITATI LEXICALE

Operator + * / % ++

--

Semnicatie adunare x+=y x x + y scdere a x-=y x x y nmultire x*=y x x y artire mp x/=y x x/y restul artiri mp ntregi incrementare x++ evaluarea valorii naintea incrementrii a ++x evaluarea valorii dup incrementre a a decrementare x- - evaluarea valorii naintea decrementrii a - -x evaluarea valorii dup decrementre a a

Exemplu. Dac a = 2, b = a + +, c = + + a atunci vom avea b = 2 i c = 4. a s Operatori relationali Operator < <= > >= == != Semnicatie < > = =

Operatori logici Operator && || ! Semnicatie conjunctie disjunctie negatie

Exemplu. Operatorul sau exclusiv a dou variabile a, b se programeaz prin a a (a && !b) || (!a && b). Operatorul conditional conditie ? expresia1 : expresia2 Operatori la nivel de biti

10

CAPITOLUL 2. JAVA ELEMENTELE DE BAZA

Operator >>

<<

& |

Semnicatie shift la dreapta x >> y : bitii lui x se deplaseaz a de la stga la dreapta cu y pozitii a shift la stnga a x << y : bitii lui x se deplaseaz a de la dreapta la stnga cu y pozitii a conjunctie disjunctie sau exclusiv complement

Exemplu. Dac a = 000010002 = 8, atunci a << 2 = 001000002 = 32 i a s a >> 2 = 000000102 = 2.

2.1.5

Comentarii

Exist trei moduri de a introduce comentarii a ntr-un program Java

/* text - comentariu care se poate intinde pe mai multe randuri */

//

text - comentariu pe aceasta linie

/** text - comentariu care se introduce si in documentatia generata de javadoc */

2.2. TIPURI PRIMITIVE

11

2.2
Tipul byte short int long

Tipuri primitive
Valoare Numr a ntreg [128..127] Numr a ntreg [32768..32767] Numr a ntreg [2.147.483.648..2.147.483.647] Numr a ntreg [9.223.372.036.854.775.808..9.223.372.036.854.775.807] Numr virgul mobil a n a a Numr virgul mobil a n a a Caracter (UNICODE) Valoare logic a Nr. octeti 1 2 4 8 4 8 2

float double char boolean

2.3
2.3.1

Instructiuni Java
Instructiunea de atribuire

variabila = expresie;

2.3.2
if [else

Instructiunea if-else

(conditie) instructiune; instructiune]1 ;

2.3.3

Instructiunea switch-case

switch ( selector) { [case valoare: instructiuni; break;] [default : instructiune;] }

2.3.4

Instructiunea de ciclare while

while (conditie) instructiune;


1 [. . .] nu face parte din sintax, notatia [. . .] indic faptul c elementele cuprinse a a a ntre parantezele ptrate pot lipsi iar notatia [. . .] arat c elementele cuprinse se pot repeta de un a a a numr de ori. a

12

CAPITOLUL 2. JAVA ELEMENTELE DE BAZA

2.3.5
do {

Instructiunea de ciclare do-while

instructiuni; } while (conditie);

2.3.6

Instructiunea de ciclare for

for (initializare ; test-sfrit ; reluare) a s instructiune; Instructiunea break are ca efect saltul la instructiunea urmtoare a progra a mului. Instructiunea continue are ca efect scurtcircuitarea ciclului.

2.3.7

Instructiunea vid a

2.4

Aplicatii

Partea de cod al unui program Java este alctuit din declaratii / denitii de a variabile i actiuni traduse instructiunile limbajului. s n O variabil se declar prin a a tip numeVariabil [=valoare]; a Odat declarat o variabil de tip predenit este initializat implicit. Astfel, a a a a o variabil de tip numeric primete valoarea 0, o variabil de tip char primete a s a s valoarea null=\0000 iar o variabil de tip boolean primete valoarea false. a s Declaratiile de variabile i instructiunile pot amestecate, dar orice entitate s utilizat trebuie declarat sau denit prealabil. a a a n 1. Calculul celui mai mare divizor comun a dou numere, utiliznd algoritmul a a lui Euclid programul este class Cmmdc{ public static void main(String args[]){ int m=56,n=96,r,d; do{ d=n; r=m % n; m=n; n=r;

2.4. APLICATII

13

} while (r!=0); System.out.println("cmmdc="+d); } } 2. S se calculeze suma a


n 1 k=1 n2 .

class Suma{ public static void main(String args[]){ int n=500; double suma=0; for(int k=1;k<=n;k++) suma+=1/((double)k*k); System.out.println("Suma primilor "+n+ " termeni este "+suma); System.out.println("Suma seriei este "+ Math.PI*Math.PI/6); } }

Capitolul 3

Referinte
O referint se folosete pentru a accesa (referi) un tablou, un obiect sau o a s interfat cadrul unui program Java. a n Declararea unei referinte nu duce automat la rezervarea spatiului de memorie pentru entitatea referit. a Pentru o referint, rezervarea spatiului de memorie necesar se face cu new. a Doar declarat, o variabil referint are valoarea null. a a a

3.1

Tablouri

cele ce urmeaz ne ocupm de denirea irurilor tablouri unidimensionale In a a s i a matricelor tablouri bidimensionale. s Declararea i/sau denirea unui ir. s s Se pot utiliza urmtoarele variante a 1. tip numeSir [ ];

2. tip [ ]numeSir; 3. tip numeSir[ 4. tip numeSir[ ]= new tip[dimensiune]; ]= {irulElementelor}; s

Declararea i/sau denirea unei matrice. s 1. tip numeMatrice [ 2. tip [ ][ ][ ];

]numeMatrice; ]; ]= new tip[numrLinii][numrColoane]; a a 14

3. tip [ ]numeMatrice[ 4. tip numeMatrice[ ][

3.1. TABLOURI

15

5. tip numeMatrice[ ]= { {elementelePrimeiLinii},. . . . . . ,{elementeleUltimeiLinii} }; Intr-un ir de elemente acestea se separ prin virgul. s a a orice tablou primul element are indicele 0. In tip se refer la tipul elementelor tabloului. Elementele unui tablou sunt omoa gene din punctul de vedere al tipului elementelor componente. Un tablou denit prin new are toate elementele initializate. Dimensiunile unui tablou pot att constante ct i expresii. a a s Accesul la elementele unui tablou. Accesul la elementele unui ir se obtine prin s numeSir[indice] Accesul la elementele unei matrice se obtine prin numeMatrice[numrLinie][numrColoan] a a a Determinarea dimensiunilor unui tablou. Dimensiunea unui ir este dat de s numeSir.length Dimensiunile unei matrice se obtin prin numrulLiniilor=numeMatrice.length a numrulColoanelor=numeMatrice[0].length a

Aplicatie. S se ordoneze cresctor un ir numeric. a a s class Sort{ public static void main(String args[]){ int s[]={4,2,3,1,5}; int n=s.length,x; boolean ord; do{ ord=true; for(int i=0;i<n-1;i++){ if(s[i]>s[i+1]){ ord=false; x=s[i]; s[i]=s[i+1]; s[i+1]=x;

16

CAPITOLUL 3. REFERINTE

} } } while(!ord); for(int i=0;i<n;i++) System.out.println(s[i]); } }

3.2

Elemente de programare orientat obiect a

Clasele reprezint elementele de baz ale unei aplicatii Java. O clas este a a a un model de obiect. Ea contine cmpuri interne i metode prin care se poate a s interactiona cu obiectul. Declararea unei clase este similar cu declararea unui nou tip de date, adic a a se descrie numai cum arat i ce tie s fac un obiect de tipul respectiv (de clasa as s a a respectiv), fr s se creeze un astfel de obiect. a aa a Java regsim notiunile: In a ncapsulare; supra arcarea (overloading) metodelor; nc motenire; s legarea dinamic. a Supra arcarea metodelor nc nseamn c se pot deni mai multe metode cu a a acelai nume, cu acelai tip de rezultat, dar care difer prin signatur, adic s s a a a numrul i tipul parametrilor. a s Motenirea. O clas poate extins prin redenirea unor metode i/sau s a a s adgarea unor metode sau cmpuri noi. O metod care a a a nlocuiete o metod a s a supraclasei (clasa printe) are acela nume, tip rezultat i aceeai signatur. O a s s s a clas care se extinde se numete supraclas, sau clasa printe. O clas obtinut a s a a a a prin extindere se numete subclas sau clas descendent. Limbajul Java permite s a a doar motenirea simpl: orice clas are o singur supraclas. Toate clasele Java s a a a a au un strmo comun clasa Object. a s Legarea dinamic. Asocierea apelului unei metode cu metoda se face faza a n de executie cu alte cuvinte codul generat de compilator este continut numele n metodei i momentul executiei se caut metoda care se potrivete. s n a s Obiectul se creaz prin instantierea unei clase. La creare (cu new) se face a alocarea de memorie pentru cmpuri i se execut prelucrrile indicate de cona s a a structorul clasei invocat.

3.3. CLASE SI OBIECTE JAVA IN

17

Un constructor este o metod care are acelai nume cu clasa respectiv i este a s as apelat implicit la crearea obiectului. Singurul context care un constructor a n poate apelat ca metod este din alt constructor. Fiecare clas are cel putin un a a constructor, cel al supraclasei. Java, constructorii nu au rezultat i ca urmare In s nu se specic tipul rezultatului denitia lor. a n

3.3
3.3.1

Clase i obiecte Java s n


Denirea unei clase

[modicator ] class NumeClas a [extends NumeSupraclas ] a [implements NumeInterfat ] { a . . . cmpuri, metode a . . . } Modicatorii pot : public O clas public este accesibil de oriunde. Spatiul de cutare este denit a a a a de variabila sistem classpath. O clas cu modicatorul public trebuie s a a e salvat ierul NumeClas.java n s a final O clas nal nu mai poate extins. a a abstract O clas cu modicatorul abstract nu poate instantiat. Subclasele ei a a trebuie s implementeze metodele abstracte pe care le contine. O clas cu a a acest modicator reprezint un model ce trebuie realizat. a *** lipsa unui modicator o clas este vizibil catalogul curent. In a a n

3.3.2

Denirea/declararea cmpurilor i metodelor a s

Denirea/declararea unui cmp: a [modicator ] [protectie] tip numeCmp [ = valoare]; a Modicatorii i protectia unui cmp pot : s a

18

CAPITOLUL 3. REFERINTE

modicator static final

protectie private protected public

Denirea/declararea unei metode: [modicator ] [protectie] tipRezultat numeMetod ( [listaVariabilelorFormale]) a [throws NumeExceptie]{ . . . corpul (codul) metodei . . . } Modicatorii i protectia unei metode pot : s modicator protectie static private final protected abstract public native synchronized Fiecare component a listeiVariabilelorFormale este de forma tip numeVaria abil. a Cmpurile / metodele statice se asociaz claselor i nu unei instante a clasei. a a s Astfel ele pot accesate fr s existe o instant a clasei respective. O metod aa a a a static nu poate redenit nici o subclas. a a n a Un cmp nal nu se poate modica, deci functioneaz ca o constant. De a a a asemenea cmpurile / metodele cu modicatorul nal nu pot redenite nici a n o subclas. a O metod abstract nu are corp. Metoda trebuie imlementat de o subclas. a a a a O metod nativ este implementat alt limbaj de programare dect Java. a a a n a Modicatorul synchronized este legat de programarea concurent. a Protectia se refer la drepturile de acces la resursele (cmpuri, metode) unei a a clase. Tabelul urmtor arat drepturile de acces functie de protectia folosit: a a n a protectie private protected public clas a subclas a 1 pachet 1 peste tot

3.3. CLASE SI OBIECTE JAVA IN

19

1 se refer doar la subclasele aate acela pachet cu clasa care s-a fcut a n s n a declaratia. La apelarea unei metode, transmisia datelor de la programul apelant la metod a se face prin valoare. Rezultatul este ntors de metod prin instructiunea a return expresie;

3.3.3

Utilizarea obiectelor

1. Declararea unui obiect (variabil obiect, referint a unei clase): a a NumeClas numeObiect; a 2. Instantierea obiectului: numeObiect= new NumeClas ([variabile actuale]); a Aceti doi pai pot legati: s s NumeClas numeObiect=new NumeClas ([listaVariabileActuale]); a a Constructia NumeClas ([listaVariabilelorActuale]) reprezint apelarea con a a structorului clasei. 3. Resursele unui obiect se folosesc cu sintaxa numeObiect.numeCmp a numeObiect.numeMetod ([listaVariabilelorActuale]) a 4. Distrugerea obiectelor pentru care nu mai exist referinte se realizeaz aua a tomat de Colectorul de gunoaie (Garbagge Collector). Un program Java va alctuit din una sau mai multe clase, iar una din ele va a contine mod obligator metoda static public void main(String args[]). n Aplicatii. 1. Calculul celui mai mare divizor comun a dou numere. a class Date{ long m=56,n=42; } class Cmmdc{

20

CAPITOLUL 3. REFERINTE

long euclid(long m, long n){ long c,r; do{ c=n; r=m % n; m=n; n=r;} while (r!=0); return c; } long recCmmdc(long m, long n){ if (m==n) return m; else if (m<n) return recCmmdc(m,n-m); else return recCmmdc(m-n,n); } } class CalculCmmdc{ public static void main(String args[]){ Date d=new Date(); Cmmdc app=new Cmmdc(); System.out.println("Calcul cmmdc"); System.out.println("Algorimul lui Euclid :"+ app.euclid(d.m,d.n)); System.out.println("Algoritm recursiv :"+ app.recCmmdc(d.m,d.n)); System.out.println("Press any key to exit"); } } 2. Rezolvarea unei ecuatii algebrice f (x) = 0 cu ajutorul metodei tangentei f (xk ) xk+1 = xk f (xk ) . class Data{ int maxIter=100,ind; double eps=1.0e-3,x=1.0;

3.3. CLASE SI OBIECTE JAVA IN

21

double fct(double x){ return x*x*x-8; } double dfct(double x){ return 3*x*x; } } class EqAlg{ Data d; EqAlg(Data d){ this.d=d; } void tangenta(){ int ni=0; double xv=d.x; double xn,err; do{ ni++; xn=xv-d.fct(xv)/d.dfct(xv); err=Math.abs(xn-xv); if (err<d.eps) d.ind=0; else d.ind=1; xv=xn; d.x=xn; } while ((err >= d.eps)&&(ni<d.maxIter)); } } class RezEq{ public static void main(String args[]){ Data d=new Data(); EqAlg eqAlg=new EqAlg(d); eqAlg.tangenta(); System.out.println("Indicatorul de raspuns : "+d.ind); System.out.println("Solutia : "+d.x); } }

22

CAPITOLUL 3. REFERINTE

constructorul clasei EqAlg apare variabila predenit this. Ea desemIn a neaz clasa / obiectul cauz. a n a O alt variabil predenit este super, care se refer la clasa / obiectul a a a a printe. a 3. Calculul unei integrale cu ajutorul metodei trapezelor
b a n1 ba ba f (x)dx [f (a) + 2 f (a + k ) + f (b)] 2n n k=1

class Data{ double margStanga=0,margDreapta=1; int n=500; double f(double x){ double p=1; for(int i=0;i<15;i++) p*=x; return 16*p; } } class Integrare{ Data d; Integrare(Data d){ this.d=d; } double trapeze(){ double h=(d.margDreapta-d.margStanga)/d.n; double s=d.f(d.margStanga)+d.f(d.margDreapta); for(int k=1;k<d.n;k++) s+=2*d.f(d.margStanga+k*h); return 0.5*h*s; } } class CalcInteg{ public static void main(String args[]){ Data d=new Data(); Integrare app=new Integrare(d); System.out.println("Integrala = "+ app.trapeze());

3.3. CLASE SI OBIECTE JAVA IN

23

} } 4. S se determine multimea aranjamentelor de n luate cte m, utiliznd ala a a goritmul backtracking.

public class Backtracking{ int x[]; int v,n,m; Backtracking(int n,int m){ this.m=m; this.n=n; x=new int[m+1]; v=0; x[v]=0; } boolean cont(){ boolean cnt=true; if (v>0) for(int i=0;i<v;i++) if(x[i]==x[v]) cnt=false; return cnt; } void back(){ while(v>-1){ if (v==m){ for(int i=0;i<m;i++) System.out.print(x[i]+" "); System.out.println(); v+=-1; } else if(x[v]<n){ x[v]+=1; if(cont()){ v+=1; x[v]=0; }

24

CAPITOLUL 3. REFERINTE

} else v+=-1; } } } class Back{ public static void main(String args[]){ int m=3,n=3; Backtracking bt=new Backtracking(n,m); bt.back(); } } 5. S se creeze o list antuit cu elementele multimii { a , e , i , o , u } i a a nl a s s se realizeze parcurgerea ei. a

class Element{ char c; Element leg; Element(char ch){ c=ch; leg=null; } } class SimpleLink{ Element p; // primul element al listei inlantuite SimpleLink(Element p){ this.p=p; } // adaugarea unui element Element adaug(Element u, char ch){ Element x=new Element(ch); u.leg=x; return x; }

3.3. CLASE SI OBIECTE JAVA IN

25

// parcurgere recursiva directa String recParcDir(Element x){ if (x==null) return ""; else return x.c+recParcDir(x.leg); } // parcurgere recursiva inversa String recParcInv(Element x){ if (x==null) return ""; else return recParcInv(x.leg)+x.c; } // parcurgere directa String parcDir(Element inc){ Element x=inc; String s=""; while(x!=null){ s=s+x.c; x=x.leg; } return s; } } class Link{ public static void main(String arg[]){ Element p,u; char ch[]={a,e,i,o,u}; p=new Element(ch[0]); u=p; SimpleLink sl=new SimpleLink(p); for (int i=1;i<ch.length;i++) u=sl.adaug(u,ch[i]); System.out.println("**********************"); System.out.println(sl.parcDir(p)); System.out.println(sl.recParcDir(p));

26

CAPITOLUL 3. REFERINTE

System.out.println(sl.recParcInv(p)); } } Problem. S se modice programul anterior astfel at lista s e dublu a a nc a antuit, utiliznd denitiile: nl a a

class Element{ char c; Element urm,pre; //urmatorul, precedentul ...... } class DoubleLink{ Element p,u; // primul, ultimul ...... // adaugarea unui element Element append(Element u, char ch){ ...... // parcurgerea directa a listei dublu inlantuite String parcDir(Element x){ ...... // parcurgerea inversa a listei dublu inlantuite String parcInv(Element x){ ...... 6. Constructor cu protectia private. Fie programul class PrivateConstructorClass{ private PrivateConstructorClass(){} static PrivateConstructorClass creare(){ return new PrivateConstructorClass(); } void prel(){ System.out.println("Prelucrare"); } }

3.4. INTERFETE

27

class Folosire{ public static void main(String args[]){ PrivateConstructorClass pcc=PrivateConstructorClass.creare(); pcc.prel(); } } Clasa PrivateConstructorClass nu poate instantiat deoarece construc a torul clasei a fost declarat cu protectia private. Pentru crearea unui asemenea obiect s-a introdus metoda static creare(), care instantiaz a a i returneaz un obiect de clas PrivateConstructorClass. Utilizarea este s a a exemplicat de clasa Folosire. a

3.3.4

Clasa Object

Orice clas este descendent al clasei Object. Componentele acestei clase sunt: a Constructori: Object() Metode: protected protected public public public nal public nal public nal public nal public nal public Object void boolean String int Class void void void void clone() nalize() equals(Object obj) toString() hashCode() getClass() notify() notifyAll() wait() wait(long timeout)

Actiunile efectuate de aceste metode sunt descrise documentatia ce ete n nsot s distributia JDK, dezarhivat catalogul docs. a n

3.4

Interfete

O interfat Java este o clas abstract format din constante i declaratii a a a a s de metode (adic far denirea corpului). Interfetele Java servesc la evitarea a a motenirii multiple. Se pot crea ierarhii de interfete similar ierarhiilor de clase. s O interfat Java este o promisiune pe care orice clas care o implementeaz a a a trebuie s o respecte. a

28

CAPITOLUL 3. REFERINTE

O clas care implementeaz interfata trebuie s specice codul metodelor a a a interfetei, dar poate s contin cmpuri i metode proprii, care nu apar interfat. a a a s n a O clas poate implementa mai multe interfete. a Totodat o interfat Java este un tip. O variabil de tip interfat este o a a a a referint ctre o clas care implementeaz interfata respectiv sau care extinde o a a a a a astfel de clas. De aici decurge modul de utilizare al variabilelor de tip interfat. a a Astfel, utilizarea interfetelor presupune 1. Denirea interfetei: [public] interface NumeInterfat [extends [NumeInterfat ] ]{ a a [public] tip numeCmp=valoare; a . . . [public] tip numeMetoda([listaVariabilelorFormale)]; . . . } 2. Implementarea interfetei: clauza implements [NumeInterfat ] din denitia a unei clase precizeaz interfetele care sunt implementate clasa respectiv. a n a Fiecare metod a interfetei apare denit codul clasei. a a n 3. Utilizarea interfetei se face prin (a) Declararea unei variabile de tip interfat: a NumeInterfat numeVariabil; a a (b) Instantierea variabilei folosind constructorul unei clase ce implementeaz a interfata: numeVariabil =new NumeClasa([listaVariabilelorActuale]); a (c) Variabila de tip interfat se folosete ca orice variabil referint a unei a s a a clase. Aplicatie. Relum problema calculului celui mai mare divizor comun a dou a a numere. Pentru aceasta denim interfata public interface ICmmdc{ public long recCmmdc(long m,long n); public long euclid(long m,long n); } Acest text surs se salveaz sub numele ICmmdc.java. a a Clasa Cmmdc implementeaz interfata ICmmdc.java. a

3.4. INTERFETE

29

public class Cmmdc implements ICmmdc{ public long euclid(long m, long n){ long c,r; do{ c=n; r=m % n; m=n; n=r;} while (r!=0); return c; } public long recCmmdc(long m, long n){ if (m==n) return m; else if (m<n) return recCmmdc(m,n-m); else return recCmmdc(m-n,n); } } Textul surs al clasei se salveaz cu numele Cmmdc.java. La compilarea clasei a a Cmmdc are loc i compilarea interfetei ICmmdc. Operatiile au loc s ntr-un catalog (director, folder) ce contine toate ierele implicate. s nal, programul App apelm resursele unei instante a clasei Cmmdc. In n a class App{ public static void main(String args[]){ int m=56,n=42; ICmmdc app=new Cmmdc(); System.out.println("Calculul cmmdc"); System.out.println("Metoda recursiva : "+ app.recCmmdc(m,n)); System.out.println("Algoritmul lui Euclid : "+ app.euclid(m,n)); } }

Capitolul 4

Tratarea exceptiilor
O artire la 0 sau utilizarea unui indice ce depete o dimensiunea declarat mp as s a a unui tablou reprezint un eveniment care perturb executia normal a prograa a a mului. Aceste evenimente se numesc exceptii. Java dispune de un mecanism care permite programatorului s ia controlul programului care apare o atare a n exceptie i s o trateze. s a Toate exceptiile Java sunt subclase ale clasei Exception. De cele mai multe ori suntem interesati s cunoatem cauza exceptiei. Metoda a s getMessage() a clasei Exception aeaz o informatie util acest caz. s a a n

4.1
try{

Instructiunea try

Sir de instructiuni ce pot genera exceptii } [catch(ClasaExceptie variabilExceptie){ a Sir de instructiuni de tratare a exceptiei de clas ClasaExceptie a }] [finally{ Sir de instructiuni care se execut neconditionat nal a n }] Exemplu. Avem de rezolvat un numr de ecuatii de gradul ai ai x = a nt bi , i {1, . . . , n}. Unele ecuatii pot conduce la artire la 0, ceea ce produce mp exceptia ArithmethicException.

30

4.2. DEFINIREA UNEI EXCEPTII PROPRII

31

class EcGrad1{ public static void main(String args[]){ int a[]={1,1,0,0},b[]={2,0,0,1},x; for(int i=0;i<a.length;i++) try{ x=b[i] / a[i]; System.out.println("Solutia ecuatiei "+a[i]+"x="+b[i]+ " este : "+x); } catch(ArithmeticException e){ System.out.println("Ecuatia "+a[i]+"x="+b[i]+ " produce "+e.getMessage()); } } } Rezultatele sunt: Solutia Solutia Ecuatia Ecuatia ecuatiei 1x=2 este : 2 ecuatiei 1x=0 este : 0 0x=0 produce / by zero 0x=1 produce / by zero

4.2

Denirea unei exceptii proprii

Denirea unei exceptii se obtine prin crearea unei subclase clasei Exception. Intr-un program depistarea cazului de exceptie revine programatorului: la aparitia conditiei care trebuie s genereze exceptia se apeleaz instructiunea a a throw ctre o instant a subclasei create. O secvent catch realizeaz prinderea a a a a exceptiei. Exemplu. Java radical dintr-un numr negativ nu genereaz o exceptie, In a a rezultatul ind NaN -- Not a Number. Denim exceptia NegativeSquareException care s permit tratarea separat a a a a radicalului dintr-un numr negativ. a class NegativeSquareException extends Exception{ public NegativeSquareException(){ super(); } public String getMessage(){ return "NegativeSquareException"; }

32

CAPITOLUL 4. TRATAREA EXCEPTIILOR

} Avem de rezolvat un numr de ecuatii de gradul al doilea x2 +ai x+bi = 0, i a {1, . . . , n}. Unele ecuatii pot conduce la un radical dintr-un numr negativ. a In acest caz vom cere programului s fac un salt la exceptia NegativeSquareExcepa a tion, care prins, se prelucreaz dup voie. a a a class EcGrad2{ public static void main(String args[]) { double a[]={-3,1,-2},b[]={2,1,1},x,y,delta=0; for(int i=0;i<a.length;i++) try{ delta=a[i]*a[i]-4*b[i]; if (delta<0) throw new NegativeSquareException(); x= (-a[i]+Math.sqrt(delta))/2; y= (-a[i]-Math.sqrt(delta))/2; System.out.println("Radacinile ecuatiei "+ "x^2+("+a[i]+")x+("+b[i]+")=0 sunt"); System.out.println("x1="+x+" x2="+y); } catch(NegativeSquareException e){ System.out.println("Delta negativ : "+e.getMessage()); System.out.println("Radacinile ecuatiei "+ "x^2+("+a[i]+")x+("+b[i]+")=0 au"); System.out.println("Partea reala = "+a[i]/2+ " Partea imaginara = "+Math.sqrt(-delta)/2); } } } Rezultatele sunt: Radacinile ecuatiei x^2+(-3.0)x+(2.0)=0 sunt x1=2.0 x2=1.0 Delta negativ : NegativeSquareException Radacinile ecuatiei x^2+(1.0)x+(1.0)=0 au Partea reala = 0.5 Partea imaginara = 0.8660254037844386 Radacinile ecuatiei x^2+(-2.0)x+(1.0)=0 sunt x1=1.0 x2=1.0 Dac a ntr-o metod se genereaz o exceptie (de exemplu, prin apelarea unei a a instructiuni throw sau ca urmare a apelrii unei metode care arunc o exceptie) a a

4.2. DEFINIREA UNEI EXCEPTII PROPRII

33

i care nu este prins de un catch, atunci exceptia trebuie aruncat mai departe s a a prin clauza throws ClasaExceptie plasat denitia metodei. a n

Capitolul 5

Clase Java predenite I


Distributia JDK contine o serie de clase. Documentatia itoare prezint nsot a detaliu cmpurile, constructorii i celelalte metode ale lor. cele ce urmeaz, n a s In a pentru unele clase se prezint doar informatii utilizate aplicatiile prezentului a n curs.

5.1

Clasa String

Un obiect de tip String contine un ir de caractere ce nu pot modicate. Un s obiect de tip String pe scurt string este echivalent cu un tablou unidimensional de caractere. Astfel String s="abc"; este acelai lucru cu s char data[]={a,b,c}; String s=new String(data); Constructori: public String() public String(String val ) public String(char [ ] val ) String-ul desemneaz un string vid. Oeratorul binar + realizeaz cona a catenarea (juxtapunerea) a dou string-uri sau a unui string cu un caracter.. a cazul programului: In

34

5.1. CLASA STRING

35

class Str1{ public static void main(String args[]){ String s="aaa"; s=s+"bbb"; System.out.println(s); s="xxx"; System.out.println(s); s=s+a; System.out.println(s); s=a+s; System.out.println(s); } } se obtin rezultatele: aaabbb xxx xxxa axxxa S-ar prea c string-ul s si schimb valoarea. realitate instructiunea a a a In n s=s+aaa referintele lui s din membrul stng i din membrul drept sunt diferite. a s Cu valoarea referintei din membrul drept se construiete un nou string, cel vechi s ind distrus. Acest lucru se poate demonstra cu programul class Str2{ public static void main(String args[]){ String s="aaa",t; t=s; s=s+"bbb"; if(s==t) System.out.println("Referintele s si t coincid"); else System.out.println("Referintele s si t NU mai coincid"); } } Metode ale clasei String public int length() Are ca valoare lungimea irului de caractere. s

36

CAPITOLUL 5. CLASE JAVA PREDEFINITE I

public char charAt(int i ) Rentoarce caracterul de pe pozitia i. Primul caracter este pe pozitia 0. a Dac lui i nu-i corespunde nici un caracter atunci se genereaz exceptia a a IndexOutOfBoundsException. public String substring(int inc) Rentoarce string-ul care a ncepe cu pozitia inc public String substring(int inc, int sf ) Rentoarce string-ul cuprins a ntre pozitiile inc i sf. s Metodele urmtoare realizeaz conversia string-ului de referint a a a public char[] toCharArray() Are ca valoare irul de caractere al string-ului de referint. s a public String toUpperCase() Are ca valoare string obtinut prin conversia tuturor caracterelor majus n cule. public String toLowerCase() Are ca valoare string obtinut prin conversia tuturor caracterelor litere n mici. Urmtoarele metode permit identicarea unui element. a public int indexOf(char car ) Are ca valoare indicele primei aparitii a caracterului car string. n public int indexOf(char car, int inc) Are ca valoare indicele primei aparitii a caracterului car string, cutarea n a ncepnd de la pozitia inc. a public int indexOf(String substring) Are ca valoare indicele primei aparitii a string-ului substring obiectul de n referint. a public int indexOf(String substring, int inc) Are ca valoare indicele primei aparitii a string-ului substring obiectul de n referint, cutarea a a ncepnd de la pozitia inc. a public int lastIndexOf(char car ) Are ca valoare indicele ultimei aparitii a caracterului car string. n public int lastIndexOf(char car, int sf ) Are ca valoare indicele ultimei aparitii a caracterului car string, cutarea n a fcndu-se pn la pozitia sf. a a a a

5.1. CLASA STRING

37

public int lastIndexOf(String substring) Are ca valoare indicele ultimei aparitii a string-ului substring obiectul de n referint. a public int lastIndexOf(String substring, int sf ) Are ca valoare indicele ultimei aparitii a string-ului substring obiectul de n referint, cutarea fcndu-se pn la pozitia sf. a a a a a a Metodele urmtoare realizeaz comparatii a a ntre iruri de caractere. s boolean equals(String st) Valoarea true se obtine dac stringul st coincide cu string-ul de referint. a a boolean startsWith(String prex ) Valoarea true se obtine dac a nceputul string-ului de referint coincide cu a irul de caractere prex. s boolean endsWith(String sux ) Valoarea true se obtine dac sfritul string-ului de referint coincide cu a as a irul de caractere sux. s Conversia unei variabile de tip predenit ntr-un string se realizeaz cu metoda a static String valueOf(tip val ) unde val este un literal de un tip predenit oarecare. Aplicatie. S se converteasc un numr natural cuprins a a a ntre 1 i 3999 s n cifre romane. class Conv{ static String conversie(int n){ String c="",s="DLVMCXI"; int v[]=new int[4]; int i=0; do{ v[i]=n % 10; n=n/10; i++; } while (n!=0); if (v[3]!=0) for(i=0;i<v[3];i++) c=c+M;

38

CAPITOLUL 5. CLASE JAVA PREDEFINITE I

for(i=0;i<=2;i++) switch (v[2-i]){ case 0:;break; case 1: c=c+s.charAt(4+i); break; case 2: c=c+s.charAt(4+i)+s.charAt(4+i); break; case 3: c=c+s.charAt(4+i)+s.charAt(4+i)+s.charAt(4+i); break; case 4:c=c+s.charAt(4+i)+s.charAt(i); break; case 5:c=c+s.charAt(i); break; case 6:c=c+s.charAt(i)+s.charAt(4+i); break; case 7:c=c+s.charAt(i)+s.charAt(4+i)+s.charAt(4+i); break; case 8:c=c+s.charAt(i)+s.charAt(4+i)+s.charAt(4+i)+s.charAt(4+i); break; case 9:c=c+s.charAt(4+i)+s.charAt(3+i); break; } return c; } public static void main(String arg[]){ int n=3999; System.out.println(conversie(n)); } }

5.2

Clasa StringBuffer

Un obiect de tip StringBuffer contine un ir de caractere care se poate s modica cursul programului. Orice obiect StringBuffer are o capacitate, n exprimat printr-un numr a ntreg, ce reprezint numrul caracterelor care pot a a cuprinse obiect. Dac modicarea irului de carectere duce la depirea n a s as capacitii, acesta se mrete automat. at a s Constructori. public StringBuffer()

5.2. CLASA STRINGBUFFER

39

Creaz un obiect vid cu capacitatea 16. a public StringBuffer(int capacitate) Creaz un obiect vid cu capacitatea specicat. a a public StringBuffer(String s) Creaz un obiect ce contine string-ul s. a Metode. public int length() Rentoarce numrul caracterelor din irul de caractere. a a s public int capacity() Rentoarce capacitatea obiectului. a public synchronized StringBuffer append(tip var ) Concateneaz obiectul de referint cu irul de caractere denit de variabila a a s var. Tipul acestei variabile, tip poate : boolean, int, long, float, double, char, char[], String, Object. public synchronized StringBuffer insert(int adresaRel, tip var ) Insereaz obiectul de referint, de la adresa relativ adresaRel, cu irul a n a a s de caractere denit de variabila var. Tipul acestei variabile, tip poate : boolean, int, long, float, double, char, char[], String, Object. public StringBuffer replace(int inc, int sf, String s) Inlocuiete subirul de caractere cuprinse s s ntre pozitiile inc i sf cu string-ul s s. public String toString( ) Convertete obiectul string. s n Aplicatie. S se realizeze inversarea unui ir de caractere (primul caracter a s devine ultimul, al doilea caracter devine penultimul, etc.). Sirul de caractere se transmite ca argument al programului. class ReverseString{ String reverseIt(String sursa){ int i,lung=sursa.length(); StringBuffer dest=new StringBuffer(lung); for (i=lung-1;i>=0;i--)

40

CAPITOLUL 5. CLASE JAVA PREDEFINITE I

dest.append(sursa.charAt(i)); return dest.toString(); } public static void main(String args[]){ ReverseString rs=new ReverseString(); if (args.length==0) System.out.println("N-am argument !?!"); else System.out.println(rs.reverseIt(args[0])); } } Clasa StringBuer contine metoda public StringBuffer reverse() care realizeaz transformarea de mai sus. Utiliznd aceast metod programul este a a a a

public class RevString{ public static void main(String args[]){ if (args.length==0) System.out.println("N-am argument !?!"); else{ StringBuffer sb=new StringBuffer(args[0]); System.out.println(sb.reverse()); } } }

5.3

Clase acoperitoare tipurilor predenite

Fiecrui tip predenit corespunde o clas acoperitoare potrivit tabelului a i a Tipul predenit int byte short long oat double boolean char Clasa acoperitoare Integer Byte Short Long Float Double Boolean Character

5.3. CLASE ACOPERITOARE TIPURILOR PREDEFINITE

41

Notm prin ClasaAcop oricare din clasele acoperitoare ale tabelului de mai sus a i prin val un literal de tip predenit corespunztor clasei acoritoare ClasaAcop. s a Fiecare clas are constructorii a public ClasaAcop(val ) public ClasaAcop(String s) Exemple. Integer vi=new Integer(123); Character vc= new Character(a); Double vd= new Double("3.1415"); Boolean vb= new Boulean(true); Conversia unui obiect de tip clas acoperitoare variabil de tip a n a predenit se obtine cu ajutorul metodelor public tip tipValue( ) unde tip este unul din tipurile predenite din Java. Exemple. Utiliznd variabilele exemplului anterior a int ei= vi.intValue(); char ec= vc.charValue(); double ed= vd.doubleValue(); boolean eb= vb.bouleanValue(); Conversia unui obiect de tip clas acoperitoare obiect de tip a n String i invers se realizeaz cu metodele s a public String toString( ) public static ClasaAcop valueOf(String s) Exemple. String si=vi.toString(); Integer i; i=Integer.valueOf(si); String sd=vd.toString(); Double d; d=Double.valueOf(sd); Conversia unui obiect de tip String ntr-o variabil de tip predenit a numeric (short, byte, int, long, oat, double) se obtine cu metodele public static tip parseTip(String s) cazul care stringul nu se poate converti In n ntr-un numr, deoarece contine a caractere nenumerice se genereaz o exceptie NumberFormatException. a

Capitolul 6

Pachete : biblioteci de programe


Un pachet este o colectie de clase i interfete care asigur o modalitate de s a gestionare a numelor de clas. a Fiierele .class rezultate urma compilrii claselor i a interfetelor care s n a s determin un pachet se retin a ntr-un catalog (director, folder) cu acelai nume cu s cea a pachetului. Construirea unui pachet. Apartenenta unei clase la un pachet se indic a prin package numePachet; plasat prima linie a codului. catalogul numePachet ecare clas are codul n In a package numePachet; public class NumeClas { a . . . } i este salvat sub numele de ier NumeClas.java. s s a Utilizarea unui pachet. Dup compilare, resursele unui pachet pot utia lizare la elaborarea altor clase. acest sens, utilizarea clasei NumeClas a In a pachetului numePachet se indic prin a import numePachet.numeClas ; a sau import numePachet.* ; 42

43 ultimul caz, toate resursele pachetului sunt utilizabile. In Dac catalogul numePachet nu este un subcatalog al catalogului de lucru a atunci calea pn la printele catalogului numePachet trebuie inclus variabila a a a a n de mediu classpath. linia de comand a unei ferestre DOS executm In a a set classpath=%classpath%;cale la printele catalogului numePachet a Pachetele, asemeni cataloagelor, pot forma o structur arborescent. a a Distributia JDK contine o serie de pachete: java.lang, java.util, java.io, java.awt, java.applet, etc. Pachetul java.lang se ncarc implicit de ctre compilatorul JDK. Resursele a a celorlalte pachete trebuie importate. Exemplu. Relum programul dezvoltat Cap. 3, la implementarea interfetelor a n privind calculul celui mai mare divizor comun a dou numere. a S presupunem c ne situm catalogul \lucru\java unde se creaz un a a a n a subcatalog cmmdc care se introduc ierele ICmmdc.java i Cmmdc.java. n s s package cmmdc; public interface ICmmdc{ public long recCmmdc(long m,long n); public long euclid(long m,long n); } package cmmdc; public class Cmmdc implements ICmmdc{ public long euclid(long m, long n){ long c,r; do{ c=n; r=m % n; m=n; n=r;} while (r!=0); return c; } public long recCmmdc(long m, long n){ if (m==n) return m; else

44

CAPITOLUL 6. PACHETE : BIBLIOTECI DE PROGRAME

if (m<n) return recCmmdc(m,n-m); else return recCmmdc(m-n,n); } } Dac ne plasm catalogul printe catalogului cmmdc atunci compilarea a a n a celor dou uniti poate a at javac cmmdc\*.java Presupunem acum c ne situm alt catalog (de exemplu: \lucru\aplicatii a a n unde este programul import cmmdc.*; class App{ public static void main(String args[]){ long m=56,n=42; ICmmdc app=new Cmmdc(); System.out.println("Calculul cmmdc"); System.out.println("Metoda recursiva : "+ app.recCmmdc(m,n)); System.out.println("Algoritmul lui Euclid : "+ app.euclid(m,n)); } } Fixarea variabilei de mediu classpath, comanda compilrii i executiei sunt a s set classpath=c:\lucru\java javac App.java java App

Capitolul 7

Miniaplicatii Java
Programele Java realizate pn acum ruleaz a a a ntr-o fereastr DOS. O catea gorie deosebit de programe Java reprezint miniaplicatiile sau applet-uri, care a l a se execut prin intermediul unui program de navigare WWW (World Wide a n Web) browser. Navigatoarele uzuale de WWW (Microsoft Internet Explorer, Netscape Navigator, Opera) tiu Java, sensul c pot excuta codul compilat al s n a unei miniaplicatii. Astfel, miniaplicatia este o resurs depus a a ntr-o zona public, accesibil a a prin Internet. Un program de navigare preia codul miniaplicatiei i execut. s l a Apelarea unei miniaplicatii se face dintr-un ier .html. s Datorit acestui mod de folosire, miniaplicatiile au o structur special i sunt a a as supuse la reguli stricte de securitate : nu pot scrie informatii pe calculatorul pe care se execut. a Distributia JDK contine un program appletviewer cu ajutorul cruia se pot a executa pe calculatorul propriu miniaplicatiile. Utilizarea acestui program este appletviewer numeFiier.html s unde numeFiier este ierul .html care apeleaz miniaplicatia. s s a

7.1

HTML

Un program de navigare WWW interpreteaz continutul (textul) unui ier n a s .html (Hyper Text Markup Language). Limbajul HTML const dintr-o colectie de marcaje (ancore, tag-uri) insera ate ntr-un text ASCII (American Standard Codes for Information Interchange). Marcajele au rolul de a descrie modul care va aprea aat textul, de asemenea n a s marcajele pot comanda programul de navigare s utilizeze i alte resurse Internet, a s aate iere diferite, particular codul compilat al unei miniaplicatii. n s n Sintaxa unui marcaj este 45

46

CAPITOLUL 7. MINIAPLICATII JAVA

<NumeTag [atribut]> text </NumeTag> Un atribut se scrie sub forma: NumeAtribut = valoare Structura unui document .html este <html> <head > <title > titlul documentului </title > </head > <body > text corpul documentului </body > </html> Marcajul <applet>. Parametri obligatorii ai unui marcaj applet sunt code Valoarea parametrului este numele ierului cu clasa miniaplicatiei. s width Valoarea parametrului este limea ferestrei atribuit de navigator miniaplicatiai at a la aarea documentului .html. s height Valoarea parametrului este altimea ferestrei atribuit de navigator miniaplicatiai n a la aarea documentului .html. s Parametri optionali sunt codebase Valoarea parametrului este adresa URL ( Universal Resource Locator) sau calea la ierul cu clasa miniaplicatiei. lipsa acestui parametru, cutarea s In a clasei are loc catalogul din care a fost arcat sursa .html. n nc a vspace Valoarea parametrului este lungimea, exprimat pixeli, care se las liber a n a a deasupra i dedesuptul ferestrei miniaplicatiei. s hspace Valoarea parametrului este lungimea, exprimat pixeli, care se las liber a n a a la stnga i la dreapta ferestrei miniaplicatiei. a s

7.2. APPLET

47

marcajul <applet> prin intermediul marcajului <param> pot inclui In s parametri ce pot preluati de miniaplicatie. Un parametru se denete prin s atributele: name Valoarea parametrului este numele variabilei recunoscut miniaplicatie. n value Valoarea parametrului este valoarea receptionat de miniaplicatie i este de s tip String. Preluarea se realizeaz cu metoda a public String getParameter(String name)

7.2

Applet

Structura unei miniaplicatii. import java.applet.*; import java.awt.*; public classNumeClas extends Applet{ a public void init(){ Actiuni efectuate la instantierea clasei miniaplicatiei. } public void start(){ Actiuni efectuate la lansarea applet-ului executie sau la n rentoarcerea pagina applet-ului. a n } public void paint(Graphics g){ Actiuni efectuate ori de cte ori este necesar redesenarea a a ferestrei miniaplicatiei. } public void stop(){ Actiuni efectuate la oprirea miniaplicatiei, ca urmare a nchiderii ferestrei corespunztoare applet-ului. a } public void destroy(){ Actiuni efectuate la distrugerea applet-ului, ce au loc cnd a navigatorul prsete documentul .html din care s-a apelat a a s miniaplicatia. } }

48

CAPITOLUL 7. MINIAPLICATII JAVA

Executarea miniaplicatiei de ctre programul navigator revine la apelarea a metodelor 1. init 2. start 3. paint Aplicatii. Relum unele din programele realizate pn acum, transformndu a a a a le miniaplicatii. n 1. HelloWorld. Codul miniaplicatiei este: import java.awt.*; import java.applet.*; public class Inceput extends Applet { public void init(){ } public void paint(Graphics g){ g.drawString("Hello World !!", 50, 60 ); } } Documentul .html corespunztor este: a <HTML> <HEAD> <TITLE> Un Inceput </TITLE> </HEAD> <CENTER> <APPLET code = "Inceput.class" width = "500" height = "300" > </APPLET> </CENTER>

7.2. APPLET

49

</BODY> </HTML> 2. Calculul celui mai mare divizor comun a dou numere transmise a prin intermediul documentului .html. Codul surs este: a import java.awt.*; import java.applet.*; public class Cmmdc extends Applet { long m,n; String s; public void init(){ String sm=getParameter("m"),sn=getParameter("n"); m=(new Long(sm)).longValue(); n=(new Long(sn)).longValue(); /* sau m=Long.parseLong(sm); n=Long.parseLong(sn); */ s=(new Long(euclid(m,n))).toString(); } public void paint(Graphics g){ g.drawString("Cmmdc = "+s, 50, 60 ); } long euclid(long m, long n){ long c,r; do{ c=n; r=m % n; m=n; n=r; } while (r!=0); return c; } }

50 Documentul .html corespunztor este: a <HTML> <HEAD> </HEAD> <CENTER> <APPLET code = "Cmmdc.class" width = "500" height = "300" > <PARAM name="m" value="56" > <PARAM name="n" value="42" > </APPLET> </CENTER> </BODY> </HTML>

CAPITOLUL 7. MINIAPLICATII JAVA

S se ruleze miniaplicatia mediu distribuit, adica apelarea prin intera n mediul navigatorului, ierul .html i ierul Cmmdc.class sunt pe trei cals s s culatoare diferite. Indicatie Pentru completarea corect a atributului codebase a marcajului a applet se poate utiliza gestionarul de iere WindowsCommander, care s aeaz calea ctre un ier selectat. s a a s

Capitolul 8

Operatii de Intrare Ieire s


Operatiile de intrare ieire utilizeaz uxuri (stream). Un ux este un obiect s a care poate s produc sau s consume date. a a a Clasele prin care un programator lucreaz cu uxuri i cu ierele sistemului a s s gazd se gsesc pachetul java.io. a a n Fluxurile trateaz ierele la nivel de octeti sau la nivel de caracter. general a s In exist o simetrie a ntre operatiile de intrare (consum de date) i operatiile de ieire s s (producere de date).

8.1

Accesul la sistemul de iere i s s cataloage ale sistemului de operare

Clasa File permite executarea unor operatii cu ierele i cataloagele sis s s temului de operare al sistemului gazd. a Cmpuri a public static final String separator caracter folosit pentru desprtirea componentelor unei ci; a a public static final char separatorChar caracter folosit pentru desprtirea componentelor unei ci; a a public static final String pathSeparator caracter folosit pentru desprtirea cilor a a ntr-o siruire de ci; n a public static final char pathSeparatorChar caracter folosit pentru desprtirea cilor a a ntr-o siruire de ci; n a Constructori 51

52

CAPITOLUL 8. OPERATII DE INTRARE IESIRE

public File(String cale) creaz o referint (variabil ier) pentru ierul sau catalogul specicat a a a s s prin cale. Dac ierul nu exist atunci se genereaz o exceptie NullPointerException a s a a (descendent din IOException) . public File(String printe, String descendent) a printe, descendent sunt ci pn ierul sau catalogul pentru care se reala a a a s izeaz referinta. a public File(File printe, String descendent) a Metode public String[ ] list( ) returneaz toate ierele din catalogul de referint; a s a long length( ) returneaz numrul de octeti al ierului de referint; a a s a boolean isDirectory( ) ia valoarea true daca obiectul de referint este un catalog. a Aplicatie. S se scrie un program care aeaz continutul unui catalog a s a transmis ca argument. import java.io.*; class Dir{ public static void main(String args[]){ String tab[]=new String[100]; String numeDir=""; if (args.length>0) numeDir=args[0]; else{ System.out.println("Numele catalogului lipseste!"); System.exit(0); } File f=new File(numeDir); tab=f.list(); long size; char ch; for(int i=0;i<tab.length;i++){ File ff=new File(f,tab[i]); size=ff.length();

8.2. OPERATII DE INTRARE IESIRE LA NIVEL DE OCTETI

53

if (ff.isDirectory()) ch=d; else ch= ; System.out.println(ch+" "+tab[i]+" "+size); } } }

8.2

Operatii de Intrare Ieire la nivel de octeti s

O selectie a claselor care reprezint uxuri la nivel de octeti este a


Object InputStream FileInputStream ByteArrayInputStream PipedInputStream SequenceInputStream FilterInputStream FileOutputStream ByteArrayOutputStream PipedOutputStream FilterOutputStream

DataInputStream

OutputStream

DataOutputStream

File

Clasele InputStream i OutputStream sunt clase abstracte, prevzute cu un s a constructor fr argumente i cteva metode. aa s a Metode ale clasei InputStream. public abstract int read( ) throws IOException citete urmtorul octet din uxul de intrare. Valoarea returnat este de s a a tip predenit int din intervalul 0..255. Dac nu mai sunt date ux se a n returneaz -1. a public int read(byte[ ] b, int index, int lung) throws IOException citete cel mult lung octeti care sunt depui tabloul b cu deplasamentul s s n index. Metoda returneaz numrul de octeti cititi sau -1 dac nu mai sunt a a a date ux. n public int read(byte[ ] b, ) throws IOException echivalent cu read(b, 0, b.length) Metode ale clasei OutputStream. public abstract void write(byte b) throws IOException scrie octetul b uxul de ieire. n s

54

CAPITOLUL 8. OPERATII DE INTRARE IESIRE

public void write(byte[ ] b, int index,int lung ) throws IOException scrie uxul de ieire lung octeti din tabelul b n s ncepnd cu indicele index. a

8.2.1

Clasele FileInputStream i FileOutputStream s

Clasele FileInputStream i FileOutputStream leag uxurile de intrare/ieire s a s de ierele sistemului gazd s a Constructori public FileInputStream(String nume) creaz un ux care citete octeti din ierul nume. a s s public FileInputStream(File varFi ) s creaz un ux care citete octeti din ierul varFi. a s s s public FileOutputStream(String nume) creaz un ux care va scrie octeti din ierul nume. a s public FileOutputStream(File varFi ) s creaz un ux care va scrie octeti din ierul varFi. a s s public FileOutputStream(String nume, boolean append) Dac parametrul append are valoarea true atunci creaz un ux care va a a scrie octeti la sfritul ierului nume. as s Dac ierul din care se citete nu exist sau dac ierul care se scrie nu a s s a a s n se poate crea sau deschide atunci se genereaz o exceptie FileNotFoundExcepa tion. Un conict cu drepturile de acces la ier genereaz o exceptie SecurityException. s a Aplicatie. S se realizeze un program care copiaz, octet cu octet, un ier a a s alt ier. n s import java.io.*; public class Copy { public static void main(String[] args){ String numeFisSursa="",numeFisDestinatie=""; if (args.length>1){ numeFisSursa=args[0]; numeFisDestinatie=args[1]; } else{ System.out.println("Lipsesc numele fisierului"+ " sursa si/sau destinatie");

8.2. OPERATII DE INTRARE IESIRE LA NIVEL DE OCTETI

55

System.exit(0); } try{ File inputFile = new File(numeFisSursa); File outputFile = new File(numeFisDestinatie); FileInputStream in = new FileInputStream(inputFile); FileOutputStream out = new FileOutputStream(outputFile); int c; while ((c = in.read()) != -1) out.write(c); in.close(); out.close(); } catch(IOException e){ System.out.println(e.getMessage()); } } }

8.2.2

Clasele ByteArrayInputStream i s ByteArrayOutputStream

Un obiect ByteArrayInputStream preia octetii unui tablou (ByteArray) i le s transfer ux, iar un obiect ByteArrayOutputStream depoziteaz datele din a n a ux ntr-un tampon. Constructori public ByteArrayInputStream(byte tab[ ]) creaz un ux de intrare care preia octetii tabloului tab. a public ByteArrayInputStream(byte tab[ ], int index, int lung) creaz un ux de intrare care preia din tabloul tab un numr de lung octeti a a ncepnd cu pozitia index. a public ByteArrayOutputStream( ) creaz un ux de ieire, care scrie datele a s ntr-un tampon a crei capacitate a initial este 32, dar care poate crete. a s public ByteArrayOutputStream(int dim) creaz un ux de ieire, care scrie datele a s ntr-un tampon a crei capacitate a initial este dim. a Metode ale clasei ByteArrayOutputStream.

56

CAPITOLUL 8. OPERATII DE INTRARE IESIRE

public synchronized void writeTo(OutputStream out) throws IOException scrie continutul uxului uxul out. n public synchronized byte [ ] toByteArray( ) copiaz continutul uxului a ntr-un tabou. Aplicatie. S se realizeze un program care efectueaz succesiv operatiile: a a 1. Transfer un ir de numere a s ntregi ntr-un ux ByteArrayInputStream; 2. Selecteaz numerele pare care se scriu a ntr-un ux ByteArrayOutputStream; 3. Se copiaz continutul ultimului ux a ntr-un tablou, care se aeaz. s a

import java.io.*; class ByteArray{ public static void main(String args[]){ byte v[]={1,2,3,4,5,6}; int n=v.length,c; byte w[]=new byte[0]; ByteArrayInputStream in=new ByteArrayInputStream(v); ByteArrayOutputStream out=new ByteArrayOutputStream(); while ((c = in.read()) != -1) if (c % 2 == 0) out.write(c); w=out.toByteArray(); n=w.length; for(int i=0;i<w.length;i++) System.out.println(w[i]); } }

8.2.3

Clasele PipedInputStream, PipedOutputStream

elegerea subsectiunii necesit cunoaterea aspectelor legate de programarea Int a s concurential paralel Java. a a n Fluxurile PipedInputStream, PipedOutputStream sunt folosite pentru dirijarea datelor dintr-un r de executie ctre alt r de executie. a Fluxurile Piped folosesc tampoane de capacitate limitat pentru depozitarea a octetilor. Dac tamponul este plin atunci rul de executie care scrie uxul a n PipedOutputStream este blocat. Dac tamponul este gol atunci rul de executie a

8.2. OPERATII DE INTRARE IESIRE LA NIVEL DE OCTETI

57

care citete din uxul PipedInputStream este blocat. felul acesta problemele s In de sincronizare pe conditie sunt rezolvate de limbajul de programare. Constructori public PipedInputStream( ) throws IOException creaz un ux de intrare neconectat la nici un ux de ieire. a s public PipedInputStream(PipedOutputStream out) throws IOException creaz un ux de intrare conectat la uxul de ieire specicat. a s public PipedOutputStream( ) throws IOException creaz un ux de ieire neconectat la nici un ux de intrare. a s public PipedOutputStream(PipedInputStream in) throws IOException creaz un ux de ieire conectat la uxul de intrare specicat. a s Metode public void connect(PipedOutputStream out)throws IOException leag uxul de intrare de referint de uxul de ieire specicat. a a s public void connect(PipedInputStream in)throws IOException leag uxul de ieire de referint de uxul de intrare specicat. a s a Aplicatie. S se rezolve problema Productorului i Consumatorului cazul a a s n care productorul genereaz octeti ce sunt transmii consumatorului prin intern a a s mediul unui ux PipedOutputStream, consumatorul receptionnd datele printr a un ux PipedInputStream.

import java.io.*; class Consumator extends Thread{ PipedInputStream in; public Consumator(PipedInputStream in){ this.in=in; } public void run(){ int inreg; try{ while((inreg=in.read())!=-1) System.out.println(" inreg "+inreg); }

58

CAPITOLUL 8. OPERATII DE INTRARE IESIRE

catch(IOException e){ System.out.println("Consumator "+e.getMessage()); } } } class Producator extends Thread{ int noInreg=7; PipedOutputStream out; public Producator(PipedOutputStream out){ this.out=out; } public void run(){ try{ for(int i=0;i<noInreg;i++) out.write(i*10); } catch(IOException e){ System.out.println("Producator "+e.getMessage()); } } } class ProdCons{ public static void main(String args[]){ try{ PipedOutputStream outProd=new PipedOutputStream(); PipedInputStream inCons=new PipedInputStream(outProd); Producator p=new Producator(outProd); Consumator c=new Consumator(inCons); p.start(); c.start(); } catch(IOException e){ System.out.println("Main "+e.getMessage()); } } }

8.2. OPERATII DE INTRARE IESIRE LA NIVEL DE OCTETI

59

8.2.4

Clasa SequenceInputStream

Clasa SequenceInputStream permite concatenarea mai multor uxuri de tip InputStream.. Constructori SequenceInputStream(Enumeration e) Creaz un ux prin parcurgerea unei multimi ale crei elemente sunt de tip a a InputStream. SequenceInputStream(InputStream s1,InputStream s2) Creaz un ux prin concatenarea uxurilor s1 i s2. a s Aplicatie. S se realizeze un program de concatenare a mai multor iere a s ale cror nume se transmit programului ca argumente. Se va crea o clas care a a implementeaz interfata Enumeration, constructorul clasei primind ca argument a lista numelor ierelor. s import java.util.*; import java.io.*; class Concatenate { public static void main(String[] args)throws IOException{ ListOfFiles mylist = new ListOfFiles(args); SequenceInputStream s = new SequenceInputStream(mylist); int c; while ((c = s.read()) != -1) System.out.write(c); s.close(); } } class ListOfFiles implements Enumeration{ private String[] listOfFiles; private int index=0; public ListOfFiles(String listOfFiles[]){ this.listOfFiles=listOfFiles; }

60

CAPITOLUL 8. OPERATII DE INTRARE IESIRE

public boolean hasMoreElements(){ if (index<listOfFiles.length) return true; else return false; } public Object nextElement(){ InputStream in=null; if (!hasMoreElements()) throw new NoSuchElementException("No more files"); else{ String nextElement=listOfFiles[index]; index++; try{ in=new FileInputStream(nextElement); } catch(FileNotFoundException e) { System.out.println("ListOfFiles : Cant open " + nextElement); } return in; } } }

8.2.5

Fluxuri de tip ltru, Clasele DataInputStream i DataOutputStream s

Clasele abstacte FilterInputStream, FilterOutputStream sunt supraclasele tuturor claselor care ltreaz uxuri la nivel de octeti. Clasele descendente preiau a informatii provenite de la un alt ux (nu sunt surse primare de date), le prelu creaz iar datele ce rezult pot rndul lor prelucrate de alte uxuri de tip a a a ltru. Clasa DataOutputStream, scrie ux date de tip predenit (int, long, oat, n double, boolean, char), ux care este transformat intr-un ux de tip OutputStream. Clasa DataInputStream, citete dintr-un ux de tip InputStream date de s tip predenit (int, long, oat, double, boolean, char). Fluxul de intrare de tip InputStream trebuie s fost obtinut ca ieirea unui ux DataOutputStream a s Intre scrierea datelor ntr-un ux DataOutputStream i citirea lor din uxul s

8.2. OPERATII DE INTRARE IESIRE LA NIVEL DE OCTETI

61

DataInputStream, conectat la primul ux, trebuie s existe o corelatie din punca cazul unei necorelatii se genereaz tul de vedere al ordinii i al tipului datelor. In s a o exceptie IOException. Constructori DataInputStream(InputStream in) DataOutputStream(OutputStream out) Metode boolean readBoolean( ) byte readByte( ) char readChar( ) double readDouble( ) float readFloat( ) int readInt( ) long readLong( ) short readShort( ) int readUnsignByte( ) int readUnsignShort( ) void void void void void void void void writeBoolean(boolean x) writeByte(byte x) writeChar(char x) writeDouble(double x) writeFloat(Float x) writeInt(int x) writeLong(long x) writeShort(short x)

Aplicatie. S se realizeze un program care execut urmtoarele operatii: a a a 1. O matrice se scrie ntr-un ux DataOutputStream, numrul liniilor i al a s coloanelor ind scrise la nceput. Datele se retin ntr-un ier. s 2. Fiierul se conecteaz la un ux DatainputStream, cu ajutorul creia se s a a reface matricea initial. a

import java.io.*; public class DataIO{ public static void main(String[] args) throws IOException { // Scrie matricea in fluxul de iesire out DataOutputStream out = new DataOutputStream(new FileOutputStream("matrix.txt")); double mat[][]={{1,2,3},{4,5,6},{7,8,9},{10,11,12}}; out.writeInt(mat.length); out.writeInt(mat[0].length); for(int i=0;i<mat.length;i++) for(int j=0;j<mat[0].length;j++) out.writeDouble(mat[i][j]);

62

CAPITOLUL 8. OPERATII DE INTRARE IESIRE

out.close(); // Refacerea matricei prin citirea fluxului in DataInputStream in = new DataInputStream(new FileInputStream("matrix.txt")); int m,n; m=in.readInt(); n=in.readInt(); double a[][]=new double[m][n]; for(int i=0;i<m;i++) for(int j=0;j<n;j++) a[i][j]=in.readDouble(); for(int i=0;i<m;i++){ for(int j=0;j<n;j++) System.out.print(a[i][j]+" "); System.out.println(); } in.close(); } }

8.3

Operatii de Intrare Ieire la nivel de caracter s

O selectie a claselor care reprezint uxuri la nivel de caracter este a


Object Reader InputStreamReader CharArrayReader PipedReader BufferedReader OutputStreamWriter CharArrayWriter PipedWriter BufferedWriter FileReader

Writer

FileWriter

8.3.1

Clasele FileReader i FileWriter s

Clasele FileReader i FileWriter corespund claselor FileInputStream i s s respectiv FileOutputStream Constructori public FileReader(String nume) creaz un ux care citete caractere din ierul nume. a s s

8.3. OPERATII DE INTRARE IESIRE LA NIVEL DE CARACTER

63

public FileReader(File varFi ) s creaz un ux care citete caractere din ierul varFi. a s s s public FileWriter(String nume) creaz un ux care va scrie caractere din ierul nume. a s public FileWriter(File varFi ) s creaz un ux care va scrie caractere din ierul varFi. a s s public FileWriter(String nume, boolean append) Dac parametrul append are valoarea true atunci creaz un ux care va a a scrie caractere la sfritul ierului nume. as s Aplicatie. S se realizeze un program care copiaz, caracter cu caracter, un a a ier alt ier. s n s import java.io.*; public class Copy { public static void main(String[] args){ String numeFisVechi="",numeFisNou=""; if (args.length>1){ numeFisVechi=args[0]; numeFisNou=args[1]; } else{ System.out.println("Lipsesc numele fisierului"+ " sursa si/sau destinatie"); System.exit(0); } try{ File inputFile = new File(numeFisVechi); File outputFile = new File(numeFisNou); FileReader in = new FileReader(inputFile); FileWriter out = new FileWriter(outputFile); int c; while ((c = in.read()) != -1) out.write(c); in.close(); out.close(); } catch(IOException e){

64

CAPITOLUL 8. OPERATII DE INTRARE IESIRE

System.out.println(e.getMessage()); } } }

8.3.2

Clasele CharArrayReader i s CharArrayWriter

Clasele CharArrayReader i CharArrayWriter corespund respectiv claselor s ByteArrayInputStream i ByteArrayOutputStream. s Constructori public CharArrayReader(char tab[ ]) creaz un ux de intrare care preia caracterele tabloului tab. a public CharArrayReader(char tab[ ], int index, int lung) creaz un ux de intrare care preia din tabloul tab un numr de lung cara a actere ncepnd cu pozitia index. a public CharArrayWriter( ) creaz un ux de ieire, care scrie datele a s ntr-un tampon a crei capacitate a initial este 32, dar care poate crete. a s public CharArrayWriter(int dim) creaz un ux de ieire, care scrie datele a s ntr-un tampon a crei capacitate a initial este dim. a Metode ale clasei CharArrayWriter. public synchronized void writeTo(Writer out) throws IOException scrie continutul uxului uxul out. n public synchronized char [ ] toCharArray( ) copiaz continutul uxului a ntr-un tabou. Aplicatie. S se realizeze un program care efectueaz succesiv operatiile: a a 1. Transfer un ir de caractere a s ntr-un ux CharArrayReader; 2. Selecteaz literele mici care se scriu a ntr-un ux CharArrayWriter; 3. Se copiaz continutul ultimului ux a ntr-un tablou, care se aeaz. s a

8.3. OPERATII DE INTRARE IESIRE LA NIVEL DE CARACTER

65

import java.io.*; class CharArray{ public static void main(String args[]){ char v[]={a,2,&,e,z,o,u}; int n=v.length,c; char w[]=new char[0]; CharArrayReader in=new CharArrayReader(v); CharArrayWriter out=new CharArrayWriter(); try{ while ((c = in.read()) != -1) if ((c>=a)&&(c<=z)){ System.out.println(c); out.write(c); } } catch(IOException e){ System.out.println(e.getMessage()); } w=out.toCharArray(); n=w.length; for(int i=0;i<w.length;i++) System.out.println(w[i]); } }

8.3.3

Clasele PipedReader i PipedWriter s

Fluxurile PipedReader i PipedWriter sunt similare respectiv, uxurilor s PipedInputStream, PipedOutputStream. Constructori public PipedReader( ) throws IOException creaz un ux de intrare neconectat la nici un ux de ieire. a s public PipedReader(PipedWriter out) throws IOException creaz un ux de intrare conectat la uxul de ieire specicat. a s public PipedWriter( ) throws IOException creaz un ux de ieire neconectat la nici un ux de intrare. a s public PipedWriter(PipedReader in) throws IOException creaz un ux de ieire conectat la uxul de intrare specicat. a s

66 Metode

CAPITOLUL 8. OPERATII DE INTRARE IESIRE

public void connect(PipedWriter out)throws IOException leag uxul de intrare de referint de uxul de ieire specicat. a a s public void connect(Pipedreader in)throws IOException leag uxul de ieire de referint de uxul de intrare specicat. a s a Aplicatie. S se rezolve problema Productorului i Consumatorului cazul a a s n care productorul genereaz caractere ce sunt transmii consumatorului prin n a a s intermediul unui ux PipedWriter, consumatorul receptionnd datele printr-un a ux PipedReader.

import java.io.*; class Consumator extends Thread{ PipedReader in; public Consumator(PipedReader in){ this.in=in; } public void run(){ int inreg; try{ while((inreg=in.read())!=-1) System.out.println(" inreg "+(char)inreg); } catch(IOException e){ System.out.println("Consumator "+e.getMessage()); } } } class Producator extends Thread{ char ch[]={a,e,i,o,u}; PipedWriter out; public Producator(PipedWriter out){ this.out=out; } public void run(){ try{ for(int i=0;i<ch.length;i++) out.write(ch[i]);

8.3. OPERATII DE INTRARE IESIRE LA NIVEL DE CARACTER

67

} catch(IOException e){ System.out.println("Producator "+e.getMessage()); } } } class ProdCons{ public static void main(String args[]){ try{ PipedWriter outProd=new PipedWriter(); PipedReader inCons=new PipedReader(outProd); Producator p=new Producator(outProd); Consumator c=new Consumator(inCons); p.start(); c.start(); } catch(IOException e){ System.out.println("Main "+e.getMessage()); } } }

8.3.4

Clasele BufferedReader i BufferedWriter s

Clasele BufferedReader i BufferedWriter ofer o modalitate ecient de s a a citire / scriere a caracterelor, tablourilor i liniilor de text prin utilizarea unui s tampon, de dimensiune sucient de mare pentru retinerea datelor. Preluarea (transmiterea) octetilor, convertirea lor caractere (sau invers) i prelucrarea n s rezultatelor se face pentru toate datele din tampon. Constructori BufferedReader(Reader in) creaz un ux care preia datele din uxul in. a BufferedReader(Reader in, int size) creaz un ux care preia datele din uxul in cu dimensiunea tamponului a xat prin al doilea parametru. a BufferedWriter(Writer out) creaz un ux care transmite datele uxul out. a n BufferedWriter(Writer out, int size)

68

CAPITOLUL 8. OPERATII DE INTRARE IESIRE

creaz un ux care transmite datele uxul out cu dimensiunea tamponua n lui xat prin al doilea parametru. a Metode String readLine( ) citete o linie de text. O linie de text se termin cu separatorul \n. s a void newLine( ) scrie separatorul de linie \n.

8.4

Introducerea datelor de la tastatur a

Scopul acestei sectiuni este prezentarea unui program cu ajutorul caruia se pot prelua date introduse la tastatura unui sistem de calcul.

import java.io.*; public class MyRead{ public String getString(){ String s=""; try{ InputStreamReader isr=new InputStreamReader(System.in); BufferedReader br=new BufferedReader(isr); s=br.readLine(); } catch(IOException e){ System.out.println(e.getMessage()); } return s; } public char getChar(){ boolean ok; String s; char c= ; do{ try{ ok=true; s=getString(); c=s.charAt(0); }

8.4. INTRODUCEREA DATELOR DE LA TASTATURA

69

catch(StringIndexOutOfBoundsException e){ ok=false; } } while(!ok); return c; } public int getInt(){ boolean ok; String s; int i=0; do{ try{ ok=true; s=getString(); i=Integer.parseInt(s); } catch(NumberFormatException e){ ok=false; } } while(!ok); return i; } public double getDouble(){ boolean ok; String s; double d=0; do{ try{ ok=true; s=getString(); d=(Double.valueOf(s)).doubleValue(); } catch(NumberFormatException e){ ok=false; } } while(!ok); return d;

70

CAPITOLUL 8. OPERATII DE INTRARE IESIRE

} } Observatie. Clasa java.lang.System contine variabilele static PrintStream err static PrintStream out static InputStream in utilizate pentru perifericele standard de intrare ieire ale sistemului de calcul. s

Capitolul 9

Aspecte concurentiale Java n


Limbajul de programare Java permite executia simultan a mai multor a activiti prin intermediul relor de executie (thread). at Spre deosebire de un proces, un r de executie nu presupune executia sa ctre a un procesor dedicat i toate rele de executie s mpart acelai spatiu de adrese. s Fiecare r de executie are o stiv proprie pentru gestionarea metodelor apelate a i a variabilelor locale. s Avnd acelai spatiu de adrese, rele de executie comunic prin variabile a s a comune. Utilizarea relor de executie nu conduce la reducerea timpului de executie - mai ales dac exist o singur unitate central. a a a a Intr-un program Java, rolul utilizrii relor de executie este simplicarea programrii. Este mai uor de scris a a s o secvent de cod pentru ecare activitate a algoritmului, executarea lor trecnd a a sarcina Mainii Virtuale Java i a sistemului de operare care simuleaz executia n s s a simultan. a Singura problem care rmne sarcina programatorului este rezolvarea a a a n problemelor de sincronizare dintre diferitele re de executie. acest scop limba In jul posed mecanisme pentru rezolvarea problemelor de sincronizare. a

9.1

Fire de executie Java n

Java permite generarea relor de executie dou moduri: n a Declararea unei clase care extinde clasa java.lang.Thread; Declararea unei clase care implementeaz interfata java.lang.Runnable. a ecare mod de utilizare este nevoie de denirea metodei In public void run(){. . .} ce contine codul ce va executat de rul de executie. 71

72

CAPITOLUL 9. ASPECTE CONCURENTIALE JAVA IN

9.2

Fire de executie create prin extinderea clasei java.lang.Thread

Crearea unui r de executie. acest mod, schema cadru pentru crearea In unui r de executie este [public] class NumeFir extends Thread{ [public] NumeFir(){ // Constructorul clasei } void public run(){ // Codul executat de firul de executie } } Utilizarea relor de executie const din a 1. Declararea rului de executie: NumeFir varFir; 2. Crearea unei instante a clasei NumeFir (de fapt a rului de executie): varFir=new NumeFir(); 3. Lansarea rului in executie: varFir.start(); Exemplu. Constructorul clasei Fir primete o variabil de tip String, pe s a care metoda run o aeaz pe ecranul monitorului. s a programul principal (main), se denesc trei re de executie instante ale In clasei Fir, care sunt lansate executie. n class Fir extends Thread{ private String text; Fir(String text){ super(); this.text=text; } public void run(){

9.3. IMPLEMENTAREA INTERFETEI JAVA.LANG.RUNNABLE

73

System.out.println(text); } } class AplicF{ public static void main(String args[]){ Fir a,b,c; a=new Fir("Primul fir de executie"); b=new Fir("Al doilea fir de executie"); c=new Fir("Al treilea fir de executie"); c.start(); a.start(); b.start(); } }

9.3

Fire de executie create prin implementarea interfetei java.lang.Runnable

Java o clas poate extinde doar o singur clas (nu exist posibilitatea In a a a a motenirii multiple). Dac o clasa trebuie s deneasc un r de executie i s a a a s extinde o alt clas atunci modul de creare i utilizare a relor de executie prin a a s implementarea interfetei Runnable este singura solutie. Interfata Runnable face parte din pachetul java.lang i contine o singur s a metod public void run(). a Crearea unui r de executie. class NumeClasa implements Runnable{ . . . public void run(){ // Codul executat de firul de executie } . . . } Utilizarea relor de executie const din a 1. Crearea unei instante a clasei NumeClas: a NumeClasa v=new NumeClasa();

74

CAPITOLUL 9. ASPECTE CONCURENTIALE JAVA IN

2. Crearea unui r de executie ataat variabilei v: s Thread varFir=new Thread(v); 3. Lansarea rului in executie: varFir.start(); Exemplul anterior programat cu aceast tehnic este a a

class AplicR implements Runnable{ private String text; AplicR(String text){ this.text=text; } public void run(){ System.out.println(text); } public static void main(String args[]){ AplicR a=new AplicR b=new AplicR c=new Thread p=new Thread q=new Thread r=new p.start(); q.start(); r.start(); } } AplicR("Primul fir de executie"); AplicR("Al doilea fir de executie"); AplicR("Al treilea fir de executie"); Thread(a); Thread(b); Thread(c);

9.4

Activiti de control a relor de executie at

Programatorul are posibilitatea de a interveni asupra unui r de executie cu ajutorul metodelor clasei Thread: public static void join() throws InterruptedException

9.4. ACTIVITATI DE CONTROL A FIRELOR DE EXECUTIE

75

Firul de executie (metoda) care este apelat metoda join() ateapt ca n a s a rul de executie asupra creia actioneaz s se termine. a a a Schema de utilizare a acestei metode este . . . NumeClasa c= new NumeClasa(...); Thread t=new Thread(c); t.start(); try{ t.join(); } catch(InterruptedException e){} . . . Exemplicm utilizarea metodei join programul a n class Join extends Thread{ private String text; Join(String text){ super(); this.text=text; } public void run(){ for(int i=0;i<3;i++){ System.out.println(text); } } } class TestJoin{ public static void main(String args[]){ Join f=new Join("join"); f.start(); try{ f.join(); } catch(InterruptedException e){ System.out.println(e.getMessage()); } for(int i=0;i<5;i++) System.out.println("main");

76

CAPITOLUL 9. ASPECTE CONCURENTIALE JAVA IN

} } Metoda main cedeaz prioritatea arii mesajului main favoarea exea sa n cutrii rului de executie Join f. Programul aeaz a s a join join join main main main Renuntnd la apelarea f.join() rezultatele sunt a main main main join join join public static void yield() Permite unui r de executie de aceai prioritate s e executat. s a programul In class Yield extends Thread{ private String text; Yield(String text){ super(); this.text=text; } public void run(){ for(int i=0;i<5;i++){ System.out.println(text); this.yield(); } } }

9.4. ACTIVITATI DE CONTROL A FIRELOR DE EXECUTIE

77

class TestYield{ public static void main(String args[]){ Yield f1,f2; f1=new Yield("1"); f2=new Yield("2"); f1.start(); f2.start(); } } ecare din rele de executie f1, f2 cedeaz succesiv prioritatea executiei a celuilalt r de executie, rezultatul ind 2 1 2 1 2 1 2 1 2 1 Renuntnd la apelul this.yield rezultatul este a 1 1 1 1 1 2 2 2 2 2 public static void sleep(int n) throws InterruptedException Se suspend executia rului de executie pentru n milisecunde, fr prsirea a aa aa acestuia.

78

CAPITOLUL 9. ASPECTE CONCURENTIALE JAVA IN

Java rele de executie au prioriti ce determin ordinea lor de lansare In at a n executie. Prioritatea se exprim printr-un numr natural cuprins a a ntre Thread. MIN PRIORITY (=1) i Thread.MAX PRIORITY (=10). parantez sunt trecute s In a valorile implicite ale constantelor. Prioritatea unui r este egal cu cea a rului a de executie care l-a pornit. Potrivit teoriei, rele de executie sunt lansate executie ordinea des n n cresctoare a prioritilor ataate. Dac un r de executie are o prioritate mai a at s a mare dect cel care se execut, atunci el trece starea gata de executie. a a n Programatorul poate xa prioritatea unui r de executie cu ajutorul metodei setPriority(int p) i deduce prioritatea unui r cu metoda getPriority(). s Exemplicm utilizarea prioritilor cu programul a at class Scrie extends Thread{ private int index; Scrie(int index){ super(); this.index=index; } public void run(){ System.out.println("indice="+index+"prioritate="+getPriority()); } } class Prior{ public static void main(String args[]){ Scrie s; for (int i=0;i<5;i++) { s=new Scrie(i); s.setPriority(2*i+2); s.start(); } } } Programul lanseaz 5 re de executie, atribuindu-le prioritile 2i + 2, i = a at 0, . . . , 4. Un r de executie aeaz indicele i i prioritatea atribuit. Rezultatul s a s a

9.5. REZOLVAREA PROBLEMELOR DE SINCRONIZARE

79

este invariabil1 indice=2 indice=3 indice=4 indice=1 indice=0 prioritate prioritate prioritate prioritate prioritate =6 =8 =10 =4 =2

Dac se scoate linia de cod care xeaz prioritatea rului de executie, atunci a a toate rele aeaz prioritatea 5 (=Thread.NORM PRIORITY) iar ordinea indicilor s a devine aleatoare.

9.5

Rezolvarea problemelor de sincronizare

Testul pentru sfritul unui r de executie se obtine cu metoda a s isAlive (), rezultatul ind o valoare logic: adevrat, dac rul de executie nu a a a s-a terminat. Testul este important cazul care continuarea unui program depinde de n n sfritul executiei unor procese lansate. as Un exemplu elocvent este rezolvarea unui sistem algebric de ecuatii liniare prin metoda lui Jacobi. Regula de oprire se poate efectua dupa ce toate componentele noii aproximatii au fost calculate. class Date { public double a[][]={{4,1,1},{1,4,1},{1,1,4}}; // matricea sistemului public double b[]={9,12,15}; // termenii liberi public int n=a.length; // dimensiunea sistemului public double x[]={0,0,0}; // aproximatia initiala public double eps=1.0e-5; // toleranta (test de precizie) public int nmi=50; // numarul maxim admis de iteratii public int error; // indicatorul de raspuns al metodei public double y[]=new double[n]; // solutia obtinuta } class Termen extends Thread { Date d; int myindex;
1

In functie de platforma de calcul, rezultatul poate diferit.

80

CAPITOLUL 9. ASPECTE CONCURENTIALE JAVA IN

public Termen(int myindex,Date d) { super(); this.myindex=myindex; this.d=d; } public void run() // Calculeaza componenta myindex a aproximatiei urmatoare { double suma=0; for(int i=0;i<d.n;i++) if (i!=myindex) suma+=d.a[myindex][i]*d.x[i]; d.y[myindex]=(d.b[myindex]-suma)/d.a[myindex][myindex]; } } class Jacobi{ static void jacobi(Date d){ int ni=0; boolean guard; double nrm; Termen t[]=new Termen[d.n]; do{ ni++; // o iteratie for(int i=0;i<d.n;i++) { // Pentru fiecare ecuatie t[i]=new Termen(i,d); // se creaza un fir de executie t[i].start(); // care se lanseaza in executie } do { guard=true; // Sincronizarea pe for(int i=0;i<d.n;i++) // conditia de terminare guard=guard && !t[i].isAlive(); // a tuturor firelor } // de executie while (!guard); nrm=0; for(int i=0;i<d.n;i++) // Regula de oprire {

9.5. REZOLVAREA PROBLEMELOR DE SINCRONIZARE

81

if(nrm<Math.abs(d.x[i]-d.y[i])) nrm=Math.abs(d.x[i]-d.y[i]); d.x[i]=d.y[i]; } } while ((nrm>=d.eps)&&(ni<d.nmi)); if (nrm<d.eps) d.error=0; else d.error=1; } public static void main(String arg[]){ Date d=new Date(); jacobi(d); System.out.println("Indicatorul de raspuns = "+d.error); System.out.println("Solutia sistemului "); for(int i=0;i<d.n;i++) System.out.println("x["+i+"]="+d.y[i]); } } Programarea sincronizrii pe conditia de terminare a tuturor relor de executie a lansate se poate face i utiliznd metoda join(). Pentru programul de mai sus s a secventa de cod este try{ for(int i=0;i<d.n;i++) t[i].join(); } catch(InterruptedException e){} Regula de oprire a programelor de calcul numeric utilizeaz parametrul Numa a rul Maxim Admis de Iteratii. cele ce urmeaz In a nlocuim acest parametru cu Durata Maxim Admis de Timp (dmt) exprimat milisecunde (ms). a a n O clas WatchDog lanseaz, a a ntr-un r de executie t, aplicatia util, dup a a care se pune ateptare pentru dmt ms. n s class WatchDog{ public WatchDog(Runnable r,int dmt){

82

CAPITOLUL 9. ASPECTE CONCURENTIALE JAVA IN

Thread t= new Thread(r); t.start(); try{ Thread.sleep(dmt); } catch(InterruptedException e){} } } Aplicatia util este inclus a a n class Aplicatie implements Runnable{ public void run(){ // codul aplicatiei } } Asamblarea celor dou componente se obtine prin a class Ansamblu{ public static void main(String args[]){ Aplicatie a=new Aplicatie(); WatchDog w=new WatchDog(a,1000); } } Rezolvarea sistemului algebric de ecuatii liniare utiliznd metoda lui Jacobi a cu aceast regul de oprire este: a a class Date { public double a[][]={{4,1,1},{1,4,1},{1,1,4}}; //matricea sistemului public double b[]={9,12,15}; //termenii liberi public int n=a.length; // dimensiunea sistemului public double x[]={0,0,0}; // aproximatia initiala public double eps=1.0e-5; // toleranta (test de precizie) public int error; // indicatorul de raspuns al metodei public double y[]=new double[n]; // solutia obtinuta } class Termen extends Thread {

9.5. REZOLVAREA PROBLEMELOR DE SINCRONIZARE

83

Date d; int myindex; public Termen(int myindex,Date d) { super(); this.myindex=myindex; this.d=d; } public void run() // Calculeaza componenta myindex a aproximatiei urmatoare { double suma=0; for(int i=0;i<d.n;i++) if (i!=myindex) suma+=d.a[myindex][i]*d.x[i]; d.y[myindex]=(d.b[myindex]-suma)/d.a[myindex][myindex]; } } class WatchDog{ public WatchDog(Runnable r,int ms){ Thread t= new Thread(r); t.start(); try{ Thread.sleep(ms); } catch(InterruptedException e){} } } class Jacobi implements Runnable{ Date d; Jacobi(Date d){ this.d=d; } public void run(){ boolean guard; double nrm;

84

CAPITOLUL 9. ASPECTE CONCURENTIALE JAVA IN

Termen t[]=new Termen[d.n]; do{ // o iteratie for(int i=0;i<d.n;i++) { // Pentru fiecare ecuatie t[i]=new Termen(i,d); // se creaza un fir de executie t[i].start(); // care se lanseaza in executie } do { guard=true; // Sincronizarea pe for(int i=0;i<d.n;i++) // conditia de terminare guard=guard && !t[i].isAlive(); // a tuturor firelor } // de executie while (!guard); nrm=0; for(int i=0;i<d.n;i++) // Regula de oprire { if(nrm<Math.abs(d.x[i]-d.y[i])) nrm=Math.abs(d.x[i]-d.y[i]); d.x[i]=d.y[i]; } if (nrm<d.eps) d.error=0; else d.error=1; } while (nrm>=d.eps); } } class Rezolvare{ public static void main(String arg[]){ Date d=new Date(); int dmt=1000; Jacobi a= new Jacobi(d); WatchDog w=new WatchDog(a,dmt); System.out.println("Indicatorul de raspuns = "+d.error); System.out.println("Solutia sistemului "); for(int i=0;i<d.n;i++) System.out.println("x["+i+"]="+d.y[i]);

9.5. REZOLVAREA PROBLEMELOR DE SINCRONIZARE

85

} } Programarea excluderii reciproce. Modicatorul synchronized ataat s unei metode permite doar unui r de executie s execute, la un moment dat, a metoda unui obiect cu acest modicator. Fiecrui obiect i se asociaz un mecana a ism de zvor. Dac un r de executie apeleaz o metod cu modicatorul a a a a synchronized al unui obiect, atunci zvorul asociat obiectului se a nchide. Spunem c acest r de executie detine controlul asupra obiectului. consecint, orice a In a alt r de executie care apeleaz o metod a obiectului, avnd modicatorul a a a synchronized, este blocat pn la deschiderea zvorului. Cnd rul de executie a a a a care detine controlul asupra obiectului termin metoda apelat, atunci unul din a a rele de executie blocate de zvor va deblocat i acesta va deveni rul care a s detine controlul asupra obiectului. felul acesta se asigur excluderea reciproc la metodele (i deci la resursele) In a a s obiectului implicat. Astfel o instant a unei clase ce contine cel putin o metod cu modicatorul a a synchronized se comport asemenea unui monitor. a Considerm exemplul: a class NumeClasa{... synchronized metodaA... synchronized metodaB... metodaC... ... care s-au declarat dou metode cu modicatorul synchronized i unul fr. n a s aa Dac un r de executie apeleaz metodaA() sau metodaB() atunci nici un alt r a a de executie nu poate executa nici una din aceste dou metode, schimb orice r a n de executie poate apela metodaC(). Acest mecanism functioneaz i cazul care nu se opereaz asupra unui a s n n a obiect, ci asupra clasei. Asfel, pentru exemplul de mai sus, dac un r de executie a execut a NumeClasa.metodaA() atunci nici un alt r de executie nu poate executa NumeClasa.metodaA() i s NumeClasa.metodaB(). Exemplicm cu rezolvarea Problemei Adunrii Concurente a a ntr-o versiune putin modicat. a La apelarea metodei add, la variabila n se adun de 5000000 de ori cte 1. a a

86

CAPITOLUL 9. ASPECTE CONCURENTIALE JAVA IN

Un r de executie apeleaz aceast metod. a a a programul principal se lanseaz lucru 5 re de executie, la sfritul crora In a n as a se aeaz valoarea lui n. s a class Actiune{ int n; synchronized void add(){ for(int i=0;i<5000000;i++) n+=1; } } class Fd extends Thread{ Actiune c; int myindex; Fd(Actiune c,int myindex){ this.myindex=myindex; this.c=c; } public void run(){ c.add(); } } class Pac{ public static void main(String arg[]){ boolean guard; Actiune c=new Actiune(); Fd f[]=new Fd[5]; c.n=0; for (int i=0;i<5;i++) { f[i]=new Fd(c,i); f[i].start(); } do{

9.5. REZOLVAREA PROBLEMELOR DE SINCRONIZARE

87

guard=true; for(int i=0;i<5;i++) guard=guard && !f[i].isAlive(); } while (!guard); System.out.println("N="+c.n); } } Renuntnd la modicatorul synchronized ataat metodei add se poate obtine a s un rezultat incorect. Java exist posibilitatea executrii prin excludere reciproc a unei secvente In a a a de cod, folosind sintaxa: sir de instructiuni executate concurent synchronized(Obiect){ sir de instructiuni executate in acces exclusiv } sir de instructiuni executate concurent Secventa de cod cuprins ntre acolade se execut cu a nchiderea zvorului asociat a obiectului. Acest obiect poate chiar obiectul cruia apartine metoda, fapt a i indicat prin this. Problema sincronizrii pe conditie. Executia unui r de executie se poate a bloca prin metoda public wait() care genereaz o intrerupere InterruptedExa a ception. Firul de executie se deblocheaz prin metoda notify() sau notifyAll() a Pentru problema Productorului i Consumatorului se denesc dou clase ce a s a extind clasa Thread. Programul principal creaz, prin instantiere cte un r de a a executie pentru ecare din cele dou clase. a Productorul preia de la tastatur un numr intreg pe care a a a ncearc sa-l a introduc a ntr-un tampon. Consumatorul preia date din tampon si le aeaz pe ecranul monitorului. s a Tamponului corespunde o clas Buffer cu dou metode get i put, avnd i a a s a ecare modicatorul synchronized. Dac tamponul este gol, rul de executie a corespunztor Consumatorului este blocat (prin wait()). La fel, dac tamponul a a este plin, rul de executie al Productorului este blocat. Dup o introducere a a sau o extragere din tampon, eventualele procese blocate sunt deblocate (prin notify()) pentru a-i s ndeplini sarcinile.

88

CAPITOLUL 9. ASPECTE CONCURENTIALE JAVA IN

class Buffer{ int DIM=4,r=0,w=0; int t[]=new int[DIM]; public synchronized void put(int inreg){ while ((w+1) % DIM == r) try{ wait(); } catch(InterruptedException e){}; w=(w+1) % DIM ; t[w]=inreg; notify(); } public synchronized int get(){ while (r==w) try{ wait(); } catch(InterruptedException e){}; r=(r+1) % DIM; notify(); return t[r]; } } class Producator extends Thread{ Buffer tampon; MyRead k=new MyRead(); public Producator(Buffer tampon){ this.tampon=tampon; } public void run(){ int x=0; while (x>=0){ System.out.print("Introduceti un numar : "); x=k.intRead(); tampon.put(x);

9.6. FIRE DE EXECUTIE INTR-UN APPLET

89

} } } class Consumator extends Thread{ Buffer tampon; public Consumator(Buffer tampon){ this.tampon=tampon; } public void run(){ int x=0; while (x>=0){ x=tampon.get(); System.out.println(\n+"S-a consumat : "+x); } } } class PC{ public static void main(String args[]){ Buffer tampon=new Buffer(); Consumator c=new Consumator(tampon); Producator p=new Producator(tampon); c.start(); p.start(); } }

9.6

Fire de executie ntr-un applet

Un applet este o colectie de clase Java care se execut prin interpretarea a codului obiect ntr-un program de navigare (ex. Internet Explorer, Netscape Navigator, etc.) care tie Java. Crearea unui applet necesit extinderea clasei s a java.applet.Applet. Programul de navigare, la arcarea unui applet execut automat urmtoarele nc a a metode:

90 public void init()

CAPITOLUL 9. ASPECTE CONCURENTIALE JAVA IN

Metoda este apelat o singur dat i se poate xa parametrii applet-ului. a a as Deorece executia applet-ului nu a nceput a pe ecranul monitorului nu nc se vede nimic se recomand ca prelucrrile acestei metode s e ct mai a a a a simple. public void start() Metoda este execitat ori de cte ori pagina care contine applet-ul este a a vizitat. a public void stop() Metoda este apelat la prsirea paginii care contine applet-ul. a aa public void paint(Graphics g) Metoda este apelat de programul navigator pentru a face applet-ul viza ibil prima dat sau atunci cnd zona ecran care contine applet-ul trebuie a a reaat, deoarece a fost temporar acoperit de o alta fereastr. Ori de s a a a cte ori dorim s schimbm continutul zonei aat de applet apelm, prin a a a s a repaint(), aceast metod. a a Exemplul urmtor aeaz ora i data curent. Firul de executie, creat prin a s a s a implementarea interfetei Runnable, comand reaarea timpului din secund a s a n secund. Preluarea i prelucrarea datelor referitoare la timp este fcut de metada a s a a paint. import import import import java.applet.Applet; java.util.*; java.text.DateFormat; java.awt.*;

public class Ceas extends Applet implements Runnable{ private Thread firCeas; public void init(){ if (firCeas==null) firCeas=new Thread(this); firCeas.start(); } public void start(){ }

9.6. FIRE DE EXECUTIE INTR-UN APPLET

91

public void paint(Graphics g){ Calendar cal=Calendar.getInstance(); Date data=cal.getTime(); String df=DateFormat.getTimeInstance().format(data); g.drawString(df,5,20); g.drawString(data.toString(),5,50); } public void stop(){ firCeas=null; } public void run(){ while (Thread.currentThread()==firCeas){ repaint(); try{ Thread.sleep(1000); } catch(InterruptedException e){} } } } Metoda currentThread() returneaz referinta la rul curent. a Pentru executia este nevoie de un document .html, care marcajul (tag-ul) n applet, face referint la codul obiect rezultat urma compilrii. a n a Pentru exemplul anterior acest document .html este <html> <head> <title> Fire de executie intr-un Applet </title> </head> <body> <applet align=center code="Ceas.class" width=300 height=200> </applet> </body>

92

CAPITOLUL 9. ASPECTE CONCURENTIALE JAVA IN

</html> Appletul se execut e prin deschiderea documentului .html programul de a n navigare, e prin intermediul programului appletviewer din distributia JDK.

Capitolul 10

Interfete fundamentale
10.1 Interfata Clonable

Considernd secventa de cod a Clasa x,y; x=new Clasa(); y=x; y este o referint ctre acela obiect ca i x. Crearea unui obiect nou, idena a s s tic cu unul existent, care din momentul creerii s aib o evoluie / comportare a a t independent de obiectul initial se obtine prin intermediul clasei Clonable. a O clas care implementeaz interfata Clonable permite utilizarea metodei a a Object.clone( ), pentru copierea cmp cu cmp a instantelor unei clase. a a Aplicatie. S se realizeze o versiune concurent a metodei backtracking. a a Ideea algoritmului const parcurgerea arborelui ataat spatiului solutiilor. a n s Frunzele arborelui reprezint solutiile problemei. Vizitarea unui nod presupune a stabilirea naturii nodului frunz, adic solutie, sau nod intern, care caz a a n pentru toate extensiile posibile ce veric conditiile de continuare se continu a a parcurgerea. Algoritmul backtracking se utilizeaz pentru determinarea multimii a S = {(x1 , x2 , . . . , xn ) A1 A2 . . . An |n (x1 , x2 , . . . , xn ) = 0}, cazul care multimile Ak , k {1, 2, . . . , n} i functia n n s n : A1 A2 . . . An {0, 1} sunt date. Cardinalul multimii Ak este nk , k {1, 2, . . . , n}. Presupunem c relatiile de continuare sunt de forma a k (x1 , x2 , . . . , xk ) = 0, 93 k = 2, 3, . . . , n.

94

CAPITOLUL 10. INTERFETE FUNDAMENTALE

Algoritmul prezentat se bazeaz pe utilizarea relor de executie i pe mecaa s nismul de clonare a obiectelor. Trebuie subliniat rolul colectorului de gunoaie ce elibereaz automat memoria de rele de executie care i-au terminat activitatea. a s Initial, pentru ecare element al multimii A1 se lanseaz n1 re de executie a avnd elementul respectiv vrful unei stive. a n a Iterativ, presupunem c a ntr-un r de executie, stiv sunt elementele n a (x1 , x2 , . . . , xi ) A1 A2 . . . Ai i2

care satisfac relatiile de continuare k (x1 , x2 , . . . , xk ) = 0, k = 2, 3, . . . , i. Pentru ecare element xi+1 Ai+1 se creaz o clon a stivei, vrful creia se a a n a a introduce xi+1 . Pentru ecare clon, dac este satisfcut conditia de continuare a a a a i+1 (x1 , x2 , . . . , xi+1 ) = 0, atunci se lanseaz un nou r de executie cu aceast stiv. a a a Firele de executie pentru care stiva are n elemente contine cte o solutie a a problemei. Textul surs programului Java, cazul problemei generrii aranjamentelor a n a de n luate cte m este: a class Date{ // Generarea Aranjamentelor de n luate cate m int n,m; // n reprezinta dimensiunea stivei void param(){ MyRead k=new MyRead(); System.out.println("Aranjamente de "); n=k.intRead(); System.out.println("...luate cate "); m=k.intRead(); } } class Stiva implements Cloneable{ int x[]; int varf,m; Stiva myClone(){

10.1. INTERFATA CLONABLE

95

try { Stiva ObiectNou=(Stiva) super.clone(); ObiectNou.x=(int[])x.clone(); return ObiectNou; } catch (CloneNotSupportedException e){ return null; } } Stiva(int m){ this.m=m; x=new int[m]; varf=0; } synchronized void write(){ StringBuffer s=new StringBuffer(); for(int i=0;i<m;i++) s.append(x[i]); System.out.println(s); } void push(int val){ varf++; x[varf]=val; } } class T extends Thread{ Stiva s; Date d; ThreadGroup tg; T(Stiva s,Date d,ThreadGroup tg){ super(tg,"fir"); this.tg=tg; this.s=s; this.d=d;

96

CAPITOLUL 10. INTERFETE FUNDAMENTALE

} boolean sfarsit(Stiva s){ if (s.m-1==s.varf) return true; else return false; } boolean valid(Stiva s){ boolean vd=true; for(int i=0;i<s.varf;i++) if (s.x[i]==s.x[s.varf]) { vd=false; break; } return vd; } public void run(){ T nT; // verificarea terminarii if (!sfarsit(s)) // Generarea elementelor multimii A_{s.varf+1} for(int i=0;i<d.n;i++) { Stiva ns=s.myClone(); ns.push(i+1); // verificarea conditiei de continuare if (valid(ns)) { nT=new T(ns,d,tg); nT.start(); } } else s.write(); }

10.2. INTERFATA ENUMERATION

97

} class Bk{ public static void main(String args[]){ ThreadGroup tg=new ThreadGroup("MyTG"); Date d=new Date(); d.param(); Stiva s=new Stiva(d.m),ns; T nT; for(int i=0;i<d.n;i++) { ns=s.myClone(); ns.x[s.varf]=i+1; nT=new T(ns,d,tg); nT.start(); } while (tg.activeCount()>0); tg.destroy(); System.out.println("Sfarsit"); } }

10.2

Interfata Enumeration

Interfata Enumeration ofer un mecanism de parcurgere a elementelor unei a multimi de obiecte. Interfata contine dou metode a boolean hasMoreElements( ) returneaz true cazul care multimea are elemente netratate procesul a n n n de enumerare. Object nextElement( ) returneaz urmtorul element cadrul parcurgerii multimii. a a n

Capitolul 11

Interfata grac Swing a


Incepnd cu distributia JDK 1.2, prin a mbuntirea portabilitii programelor a at at Java ntre diverse platforme, s-a impus utilizarea interfetei grace Swing. Interfetele Swing prelungesc faculitile puse la dispozitie de resursele pachetului java.awt at Realizarea unei interfete grace Swing const parcurgerea mai multor a n etape: 1. Importul pachetelor Swing; 2. Alegerea naturii interfetei (Look and Feel); 3. Fixarea containerului rdcin; a a a 4. Contruirea containerului cu componente; 5. Adugarea evenimentelor legate de componentele de comand. a a

11.1

Realizarea unei interfete grace Swing

Importul pachetelor necesare este import javax.swing.*; import java.awt.*; import java.awt.event.*; Alegerea naturii interfetei (Look and Feel). metoda main introducem In public static void main(String args[]){ try{UIManager.setLookAndFeel( UIManager.getSystemLookAndFeelClassName()); } 98

11.1. REALIZAREA UNEI INTERFETE GRAFICE SWING

99

catch(Exception e){} ............................................................. } functie de platforma de calcul (Windows, Linux, Solaris, etc) interfata In grac va specic acesteia. a a Fixarea containerului rdcin. Componentelor grace care vor alctui a a a a interfata grac a unui program se leaga de un container de folosint general a a a sau de un container de folosint special. Acest container trebuie legat de aa a a s numitul container rdcin care poate a a a JFrame JApplet JDialog JWindows cele ce urmeaz tratm containerul rdcin JFrame. In a a a a a Constructori. JFrame( ) creaz un cadru fr titlu. a aa JFrame(String titlu) creaz un cadru cu titlul specicat. a Metode. Container getContentPane( ) adaug la containerul rdcin JFrame containerul cu componentele grace a a a a ale interfetei. public void setTitle(String titlu) xeaz titlul cadrului. a Metod motenit de la clasa java.awt.Frame. a s a public void setSize(int lime, int altime) at n xeaz dimensiunea cadrului (exprimat pixeli). a a in Metod motenit de la clasa java.awt.Component. a s a public void setVisible(boolean b) Dac b are valoarea true atunci componenta este vizibil pe ecran. a a Metod motenit de la clasa java.awt.Component. a s a

100

CAPITOLUL 11. INTERFATA GRAFICA SWING

public void pack( ) dimensiunile componentelor grace se calculeaz de ctre sistemul de calcul a a pentru a obtine un aspect grac plcut. a Metod motenit de la clasa java.awt.Windows. a s a addWindowListener(WindowListener l ) se xeaz un obiect care rspunde de tratarea evenimentelor Windows. a a Metod motenit de la clasa java.awt.Windows. a s a Structura programului devine: import javax.swing.*; import java.awt.*; import java.awt.event.*; public class NumeClasa{ ............................................................. public static void main(String args[]){ try{UIManager.setLookAndFeel( UIManager.getSystemLookAndFeelClassName()); } catch(Exception e){} ............................................................. JFrame frame=new JFrame("Titlul ecranului principal"); ............................................................. frame.getContentPane()........ frame.addWindowListener(........); frame.pack(); frame.setVisible(true); frame.setSize(400,300); } } Contruirea containerului cu componente. Componentele grace se construiesc ntr-o metod a public Component containerCuComponenteGrace( ) Inglobarea containerului se realizeaz prin a 1. crearea unei instante a clasei NumeClas ; a

11.2. COMPONENTE GRAFICE SWING

101

2. apelarea metodei containerCuComponenteGrace; 3. includerea containerului cu componentele grace containerul rdcin n a a a prin apelarea metodei Component.add(. . . ); Schema cadru devine: import javax.swing.*; import java.awt.*; import java.awt.event.*; public class NumeClasa{ ............................................................. public Component containerCuComponenteGrafice(){ ............................................................. } ............................................................. public static void main(String args[]){ try{UIManager.setLookAndFeel( UIManager.getSystemLookAndFeelClassName()); } catch(Exception e){} NumeClasa aplicatie=new NumeClasa(); Component panouComponente=aplicatie.containerCuComponenteGrafice(); JFrame cadru=new JFrame("Titlul ecranului principal"); ............................................................. cadru.getContentPane().add(panouComponente,........); cadru.addWindowListener(........); cadru.pack(); cadru.setVisible(true); cadru.setSize(400,300); } }

11.2

Componente grace Swing

Rolul unei componente grace este de a permite utilizatorului s interactioneze a cu un program. Actiunile utilizatorului constau n introducere date;

102

CAPITOLUL 11. INTERFATA GRAFICA SWING

comanda sau selectarea unei comenzi care are ca efect executia unei ac tiviti specice a programului. at Componentele grace se retin ntr-un container. Acest container poate de folosint general (JPanel, JScrollPane, JSplitPane, JTabbedPane sau de a a folosint special JInternalFrame, JLayeredPane, JRootPane, JToolBar. a a Containerul JPanel Contructori JPanel() creaz un container JPanel. a Metode add(Component comp) adaug container componenta specicat. a n a Aarea componentelor pe ecran se xeaz cu un gestionar de pozitionare. s a Legtura a ntre o component grac i actiunea / actiunile legate de acea a a s component se denesc prin intermediul unui consumator de evenimente. Printra un eveniment se elege o actiune a mouse-ului sau apsarea unei taste. nt a Semnalm urmtoarele componente grace a a JButton. Buton: un clic al mouse-ului pe buton permite lansarea unei actiuni a programului. Constructori JButton( ) creaz o component JButton fr nume. a a aa JButton(String text) creaz o component JButton cu numele specicat de text. a a Metode JLabel. Etichet: Aeaz pe ecran un text scurt, informativ. O etichet a s a a nu rspunde nici unui eveniment. a Constructori JLabel( ) creaz o component JLabel fr text. a a aa

11.2. COMPONENTE GRAFICE SWING

103

JLabel(String text) creaz o component JLabel ce aeaz textul specicat. a a s a Metode JTextField. Linie text: care utilizatorul poate introduce un text i n s n care programul poate aa un rezultat. s Constructori JTextField( ) creaz o component JTextField vid. a a a JTextField(String text) creaz o component JTextField ce aeaz textul specicat. a a s a Metode public String getText( ) rentoarce textul aat componenta JTextField. a n public void setText(String text) xeaz textul ce se aeaz componenta JTextField. a s a n JTextArea. Zon text: care utilizatorul poate introduce un text i a n s n care programul poate aa un rezultat. s Constructori JTextArea( ) creaz o component JTextArea vid. a a a JTextArea(String text) creaz o component JTextArea ce aeaz textul specicat. a a s a JTextArea(String text,int linii,int coloane)

Metode public String getText( ) rentoarce textul aat componenta JTextArea. a n public void setText(String text) xeaz textul ce se aeaz componenta JTextArea. a s a n

104

CAPITOLUL 11. INTERFATA GRAFICA SWING

11.2.1

Gestionari de pozitionare

La crearea unui container de componente grace se xeaz gestionarul de a pozitionare, printr-un obiect care implementeaz interfata LayoutManager. JDK a dispune de multi gestionari de pozitionare: FlowLayout. Potrivit acestui gestionar de pozitionare, aarea are loc de la s stnga la dreapta, de sus jos, ordinea adugrii componentelor grace a n n a a la container. Acest gestionar de pozitionare este utilizat implicit. BorderLayout. Gestionarul de pozitionare BorderLayout cunoate 5 pozitii s "North", "South", "West", "East", "Center". momentul adugrii In a a unei componente cu metoda add(String pozitie,Component component ) a se xeaz i pozitia de aare. as s GridLayout. Gestionarul de pozitionare GridLayout(m, n) dispune com ponentele grace pe m linii i n coloane. s Fixarea gestionarului de pozitionare a componentelor grace ale unui con tainer se face apelnd metoda a public void setLayout(LayoutManager gestionarDePozitionare)

11.2.2

Consumatoare de evenimente

Consumatoarele de evenimente se denesc prin implementarea unor interfete ale pachetului java.awt. O lista a acestor interfetele este dat Tabelul 1. a n Un eveniment aprut este distribuit tuturor consumatorilor de evenimente a nregistrati. Legarea consumatorului de evenimente de componenta grac pe care o dea servete se realizeaz cu metoda componentei s a public void addNumeInterfat (Object obj ) a unde obj este un obiect care implementeaz interfata indicat. a a Dac interfata corespunztoare consumatorului de evenimente este implemena a tat chiar de clasa curent atunci legarea se realizeaz prin a a a componentaGrac.addNumeInterfat (this) a a

11.3

Aplicatii

1. Pentru calculul celui mai mare divizor comun a dou numere naturale s se a a realizeze un program cu o interfat grac. a a

11.3. APLICATII

105

Nume interfat (metode) a

Evenimente pentru receptionarea crora trebuie implementat interfata a a ActionListener actiuni asupra unui control public void actionPerformed(ActionEvent e) ComponentListener redimensionri, deplasri, ascunderi ale unei a a componente public void componentResized(ComponentEvent e) public void componentRemoved(ComponentEvent e) public void componentShown(ComponentEvent e) public void componentHidden(ComponentEvent e) FocusListener preluare / pierdere focus (componenta este inta intrrii de la tastatur sau nu t a a public void focusGained(FocusEvent e) public void focusLost(FocusEvent e) ItemListener selectie / desectie list, meniu, n a cutie de optiune public void itemStateChanged(ItemEvent e) TextListener modicarea textului unui control public void textValueChanged(TextEvent e) AdjustmentListener modicarea unei valori variind ntre dou limite a public void adjustmentValueChanged(AdjustmentEvent e) KeyListener apsare, eliberare, tastare a public void keyTyped(KeyEvent e) public void keyPressed(KeyEvent e) public void keyReleased(KeyEvent e) MouseListener ieire / intrare mouse, clic, apsare, eliberare s a public void mouseClicked(MouseEvent e) public void mousePressed(MouseEvent e) public void mouseReleased(MouseEvent e) public void mouseEntered(MouseEvent e) public void mouseExited(MouseEvent e) MouseMotionListener micare, tragere (drag) s public void mouseDragged(MouseEvent e) public void mouseMoved(MouseEvent e) WindowListener nchidere, minimizare, maximizare, etc. 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) ContainerListener adugare, tergere component a s a public void componentAdded(ContainerEvent e) public void componentRemoved(ContainerEvent e) Tabelul 1.

106

CAPITOLUL 11. INTERFATA GRAFICA SWING

import javax.swing.*; import java.awt.*; import java.awt.event.*; public class TSwing{ long m=0,n=0; public long euclid(long m, long n){ long c,r; do{ c=n; r=m % n; m=n; n=r;} while (r!=0); return c; } public Component createComponent(){ JButton rezButton; JLabel mLabel,nLabel; final JTextField mTextField,nTextField,rezTextField; JPanel pane=new JPanel(); mLabel=new JLabel("m="); mTextField=new JTextField(); nLabel=new JLabel("n="); nTextField=new JTextField(); rezButton=new JButton("Rezult"); rezTextField= new JTextField(); pane.setLayout(new GridLayout(3,2)); pane.add(mLabel); pane.add(mTextField); pane.add(nLabel); pane.add(nTextField); pane.add(rezButton); rezButton.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e){ m=(new Long(mTextField.getText())).longValue(); n=(new Long(nTextField.getText())).longValue();

11.3. APLICATII

107

rezTextField.setText((new Long(euclid(m,n))).toString()); } }); pane.add(rezTextField); return pane; } public static void main(String args[]){ try{UIManager.setLookAndFeel( UIManager.getSystemLookAndFeelClassName()); } catch(Exception e){} TSwing app=new TSwing(); Component pane=app.createComponent(); JFrame frame=new JFrame("Cel mai mare divizor comun"); frame.getContentPane().add(pane,BorderLayout.CENTER); frame.addWindowListener(new WindowAdapter(){ public void windowClosing(WindowEvent e){ System.exit(0); } }); frame.pack(); frame.setVisible(true); frame.setSize(400,300); } } 2. Exemplu de utilizare a unei liste de selectii.

import javax.swing.*; import java.awt.*; import java.awt.event.*; public class SChoice{ public Component createComponent(){ JLabel tLabel=new JLabel("Alegeti"); final Choice l=new Choice(); l.addItem("A");

108

CAPITOLUL 11. INTERFATA GRAFICA SWING

l.addItem("B"); l.addItem("C"); l.addItem("D"); l.select("D"); final JTextField rezTextField=new JTextField("S-a ales: D"); l.addItemListener(new ItemListener(){ // metodele interfetei ItemListener public void itemStateChanged(ItemEvent e){ String s=l.getSelectedItem(); rezTextField.setText("S-a ales: "+s); } }); JPanel pane=new JPanel(); pane.setLayout(new BorderLayout()); pane.add("West",l); pane.add("North",tLabel); pane.add("East",rezTextField); return pane; } public static void main(String args[]){ try{UIManager.setLookAndFeel( UIManager.getSystemLookAndFeelClassName()); } catch(Exception e){} SChoice app=new SChoice(); Component pane=app.createComponent(); JFrame frame=new JFrame("Lista de selectare"); frame.getContentPane().add(pane,BorderLayout.CENTER); frame.addWindowListener(new WindowAdapter(){ public void windowClosing(WindowEvent e){ System.exit(0); } }); frame.pack(); frame.setVisible(true); frame.setSize(400,300); } } O alternativ la scrierea consumatorului de evenimente legat de lista de a

11.3. APLICATII

109

optiuni ItemListener const denirea unei clase a n class MyItemListener implements ItemListener{ Choice l; JTextField tf; MyItemListener(Choice l,JTextField tf){ this.l=l; this.tf=tf; } // metodele interfetei ItemListener public void itemStateChanged(ItemEvent e){ String s=l.getSelectedItem(); tf.setText("S-a ales: "+s); }

} Legarea controlului de consumatorul de evenimente este acest caz n MyItemListener mil=new MyItemListener(l,rezTextField); l.addItemListener(mil); 3. Exemplu de creare a unei pnze cu un desen. a import javax.swing.*; import java.awt.*; import java.awt.event.*; class Scriere extends Canvas{ Scriere(){ this.setForeground(Color.red); this.setBackground(Color.blue); this.setFont(new Font("Serif",Font.BOLD,20)); } public void paint(Graphics g){ g.drawString("Text afisat",30,150); }

110

CAPITOLUL 11. INTERFATA GRAFICA SWING

} public class Desen{ public Component createComponent(){ Scriere myCanvas=new Scriere(); return myCanvas; } public static void main(String args[]){ try{UIManager.setLookAndFeel( UIManager.getSystemLookAndFeelClassName()); } catch(Exception e){} Desen app=new Desen(); Component pane=app.createComponent(); JFrame frame=new JFrame("Un desen"); frame.getContentPane().add(pane,BorderLayout.CENTER); frame.addWindowListener(new WindowAdapter(){ public void windowClosing(WindowEvent e){ System.exit(0); } }); frame.pack(); frame.setVisible(true); frame.setSize(400,300); frame.show(); } } Observatii. Metoda public void show() aeaz componenta grac de tip Canvas. s a a Metoda public void drawString(String s,int x,int y) aeaz texs a tul s pozitia denit de coordonatele (x, y). Pe pnza de desen axale n a a de coordonate au originea coltul nord-vest. n Facilitile curente de desen 2D sunt cuprinse pachetul Graphics2D. at n

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