Severin BUMBARU

PROGRAMAREA ORIENTATĂ PE OBIECTE ÎN LIMBAJUL JAVA

Editura Fundaţiei Universitare "Dunărea de Jos" - Galaţi, 2002

1

Severin Bumbaru Severin Bumbaru Programarea orientată pe obiecte în limbajul Java Editura Fundaţiei Universitare "Dunărea de Jos" din Galaţi - 2002 ISBN 973-8352-53-3 Referent ştiinţific: prof.dr.ing. Cornelia NOVAC

2

Programarea orientata pe obiecte în limbajul Java

CUPRINSUL
0. Introducere 1. Scurtă prezentare a platformei Java şi a programării orientate pe obiecte 2. Şiruri. Elemente lexicale ale limbajului Java. Variabile şi tipuri de date primitive 3. Expresii. Instrucţiuni simple şi instrucţiuni structurate. Tratarea excepţiilor în limbajul Java 4. Tipul referinţă. Utilizarea claselor din pachetul java.lang. Tablouri. Utilizarea parametrilor din linia de comnadă 5. Declararea claselor 6. Caracteristicile obiectelor şi claselor şi reflectarea lor în declararea claselor. Interfete. Clase imbricate 7. Interfeţe utilizator grafice şi programarea orientată pe evenimente 8. Componentele grafice din JFC/Swing 9. Utilizarea ferestrelor de dialog. Desenarea 10. Introducere în HTML. Crearea şi utilizarea de appleturi 11. Fluxuri de intrare/ieşire şi fişiere 12. Fire de execuţie Index de clase şi interfeţe Bibliografie Anexă : Fişierele sursă ale claselor date ca exemple
4 7 27 66 99 137 163 198 240 267 291 306 333 363 458 460

3

Severin Bumbaru

Introducere
Obiectivele cursului Cum este structurat acest curs Recomandări privind modul de lucru 4 5 5

Obiectivele cursului
Cursul "Programare orientată pe obiecte în limbajul Java" se adresează studenţilor profilelor "Ingineria sistemelor şi calculatoarelor" şi "Electronic" de la Universitatea "Dunărea de Jos" din Galaţi şi îşi propune următoarele obiective:
      

însuşirea conceptelor de bază ale programării orientate pe obiecte; însuşirea limbajului de programare Java; formarea deprinderilor privind realizarea de aplicaţii şi miniaplicaţii în limbajul Java; iniţiere în utilizarea bibliotecilor de clase Java; însuşirea proiectării interfeţei grafice utilizator şi a programării orientate pe evenimente; iniţiere în utilizarea fluxurilor de date şi fişierelor în limbajul Java; iniţiere în programarea concurentă (realizarea de programe cu mai multe fire de execuţie).

Cursul poate fi folosit şi de toţi cei care doresc să se iniţieze în utilizarea limbajului Java şi în programarea orientată pe obiecte.

4

Programarea orientata pe obiecte în limbajul Java

Cum este structurat cursul
Cursul este structurat ca un ciclu de 12 lecţii, care cuprind atât prezentarea conceptelor care trebuie însuşite de studenţi, cât şi indicaţii asupra lucrărilor practice şi exemple de întrebări pentru verificarea cunoştinţelor. Cursul se prezintă în format electronic (hipertext), fiind alcătuit dintr-un ansamblu de pagini legate între ele. Din punct de vedere al obligativităţii citirii şi însuşirii cunoştinţelor conţinute, aceste pagini sunt situate pe patru niveluri, care difera între ele prin culoarea fundalului (background):

Nivelul 0: Informaţii cu caracter organizatoric. Trebuie citite şi respectate, dar nu constituie subiect de examinare. Nivelul 1: Concepte de bază cu caracter obligatoriu. Fără cunoaşterea lor nu poaste fi promovată această disciplină. Nivelul 2: Concepte necesare pentru o bună cunoaştere a programării orientate pe obiecte şi a limbajului Java. Constituie subiecte de verificare şi sunt luate în consideraţie la stabilirea notei. Nivelul 3: Documentaţie necesară pentru elaborarea aplicaţiilor şi miniaplicaţiilor în limbajul Java: descrierea unor clase si interfete, prezentarea pachetelor s.a. Nu se cere memorarea acestei documentaţii, dar la sustinerea programelor elaborate trebuie sa cunoaşteti semnificaţia tuturor componentelor utilizate. Nivelul 4: Informaţii suplimetare, utile pentru o bună întelegere şi însuşire a disciplinei, dar care nu constituie subiecte de examinare. Cursul conţine, de asemenea, un index de clase si interfeţe, în care se dau legături către pagini care prezintă unele clase şi interfeţe din bibliotecile platformei Java (Java API) utile în realizarea aplicaţiilor.

Recomandări privind modul de lucru
Cercetările în domeniul psihologiei educaţionale au dus la concluzia că învăţarea este eficientă atunci când studentul contribuie activ, analizând critic materialele studiate, experimentând şi susţinându-şi opiniile în faţa altora. În consecinţă, pentru o bună însuşire a acestei discipline, vă recomandăm:
 

să lucraţi în echipă; fiecare membru al echipei, după ce şi-a însuşit conceptele de bază ale unei lecţii: o propune şi realizează experimente pentru clarificarea acestor concepte; o discută cu colegii cele constatate în urma experimentelor efectuate;

5

Severin Bumbaru
  

 

membrii echipei îşi împart între ei temele de aplicaţii şi miniaplicaţii primite la laborator, concep şi realizează aceste aplicaţii (miniaplicaţii); la elaborarea aplicaţiilor şi miniaplicaţiilor, folosiţi atât acest curs, cât şi alte surse de documentare, în special documentaţia originală; dacă, în timpul realizarii aplicaţiei, întâmpinaţi dificultăţi, consultati-vă cu colegii sau cu cadrul didactic îndrumător. Faceţi aceasta numai dacă sunteţi convins că nu puteţi rezolva singur; după realizarea aplicaţiei, explicaţi colegilor de echipă cum aţi realizat-o şi ce dificultăţi aţi avut; deşi accentul se pune pe experimentare, atragem atenţia că obiectivul principal al cursului este însuşirea conceptelor care sunt puse în evidenţă în fiecare lecţie. Numai că această însuşire de concepte se realizează nu doar prim simpla citire a materialului documentar, ci prin experimentare, dezvoltare de aplicaţii şi schimb de opinii.

6

Programarea orientata pe obiecte în limbajul Java

Scurtă prezentare a platformei Java şi a programării orientate pe obiecte
O prima cunoştinţă cu limbajul şi platforma Java Scurt istoric al limbajului şi platformei Java Introducere în programarea orientată pe obiecte Prezentarea principalelor tipuri de produse software care se pot scrie în limbajul Java Şablonul unei aplicaţii simple în limbajul Java Aplicarea acestui şablon la realizarea unei aplicaţii simple, în care se afişează un text pe ecran; Editarea, compilarea şi execuţia aplicaţiilor Java Întrebări 7 17 18 19 20 21 21 26

O primă cunoştinţă cu limbajul şi platforma Java
În informatică, Java este

un limbaj de programare, ale cărui calităţi i-au permis răspândirea rapidă, fiind în prezent unul din limbajele cele mai larg folosite. Limbajul este simplu, orientat pe obiecte, robust, sigur, portabil, interpretat, neutru faţă de arhitectură, concurent, dinamic si distribuit; un mediu de execuţie pentru aplicaţiile Java, numit în prezent în engleză "Java 2 Runtime Environment", care conţine maşina virtuală Java şi un nucleu al bibliotecilor de clase Java; o platformă pentru dezvoltarea de aplicaţii în care se foloseşte limbajul Java, care se numeşte în prezent în engleză "Java 2 Platform" şi conţine: o compilatorul Java (Java Compiler); o maşina virtuală Java (Java Virtual Machine); o bibliotecile de clase Java (Java Class Libraries); o vizualizatorul de appleturi Java (Java AppletViewer); o depanatorul Java (Java Debbuger) şi alte instrumente de dezvoltare; o documentaţia; o tehnologie software puternică şi modernă, care corespunde cerinţelor lucrului în reţele de calculatoare.

Există, desigur, şi alte semnificaţii ale cuvântului Java, care însă nu au legatură directă cu informatica.

Limbajul Java
Java este un limbaj de programare de utilizare largă, care are următoarele proprietăţi:

7

Severin Bumbaru
   

 

 

este simplu: deşi sintaxa se aseamănă cu cea a limbajelor C/C++, au fost eliminate acele aspecte care constituiau surse de erori sau produceau confuzii; este orientat pe obiecte: în limbajul Java nu este posibil să se scrie aplicaţii care nu respectă normele programării orientate pe obiecte; este robust: programele scrise în Java sunt foarte fiabile, deoarece sunt prevăzute numeroase verificări atât la compilare, cât şi în timpul executării; este sigur: fiind destinat lucrului în reţele de calculatoare, la realizarea sistemului Java s-a avut în vedere necesitatea ca programele să nu poată aduce daune calculatoarelor pe care rulează, cum ar fi accesul neautorizat la informaţie sau chiar distrugerea acesteia; este portabil, adică programul poate fi mutat de pe un calculator pe altul, de alt tip hardware şi/sau cu alt sistem de operare; este compilat şi interpretat: programul sursă, scris în limbajul Java, este translatat de către compilatorul Java într-un program intermediar sub formă de cod de octeţi (engleza: bytecode). În timpul execuţiei, acest cod de octeţi este interpretat de către maşina virtuală Java, care conţine un interpretor; este neutru faţă de arhitectură: codul de octeţi generat de compilatorul Java nu depinde de arhitectura echipamentului pe care acesta va fi executat, deoarece el nu este executat direct de către procesorul hardware al acestui echipament, ci este interpretat de către maşina virtuală Java; permite programarea concurentă: în limbajul Java se pot scrie programe cu mai multe fire de execuţie (engleza: multithreading), care pot fi executate simultan şi sincronizate; este dinamic, deoarece legarea între ele a claselor şi obiectelor nu se face static (la compilare), ci dinamic (în momentul execuţiei); este distribuit, adică permite realizarea de programe utilizabile în reţele heterogene (care conţin calculatoare de tipuri diferite);

În enumerarea de mai sus, care nu este nicidecum completă apar, probabil, şi unii termeni care vă sunt, deocamdata, neclari sau necunoscuţi. Unii din aceşti termeni vor fi clarificaţi chiar în acest capitol, alţii - în capitolele următoare. Atenţie! Deşi sintaxa limbajului Java se aseamănă cu cea a limbajelor C sau C++, Java nu este C. Pe parcursul lecţiilor următoare vom atrage atenţia programatorilor de C/C++ asupra principalelor deosebiri dintre Java şi aceste limbaje.

Simplificări făcute în Java faţă de C/C++
Deşi sintaxa limbajului Java a fost inspirată de cea a limbajelor C şi C++, autorii limbajului Java au eliminat acele aspecte care produceau dificultăţi programatorilor, constituind surse de erori şi confuzii. Dintre acestea menţionăm:
    

reducerea numărului de tipuri de date primitive prin eliminarea tipurilor fără semn (unsigned); introducerea tipului de date boolean, astfel încât datele logice să nu se mai confunde cu cele întregi; şirurile de caractere nu mai sunt tablouri, ci obiecte ale clasei String; tablourile sunt ele însele obiecte; în timpul execuţiei se verifică dacă indicele se încadrează în dimensiunea tabloului şi se generează o excepţie în caz contrar; 8

Programarea orientata pe obiecte în limbajul Java
  

s-au eliminat pointerii şi operaţiile cu pointeri, menţinându-se numai tipul referinţă din C++; s-a renunţat la supraîncărcarea operatorilor; limbajul este strict tipizat, adică se verifică atât la compilare, cât şi în timpul execuţiei (în operaţiile de atribuire şi de calcul şi la transferul de parametri către subprograme), corectitudinea tipurilor de date utilizate şi se semnalează excepţiile; s-a renunţat la moştenirea multiplă (care există în C++), menţinându-se numai moştenirea simplă. Ca urmare, toate clasele formează o ierarhie unică, avand ca radacină clasa Object; distrugerea obiectelor care nu mai sunt necesare se face automat, de către un "colector de reziduuri" (în engleză: garbage collector), deci nu mai trebuie făcută prin program.

Neutralitatea arhitecturală
În mod ideal, un program sub forma de cod de octeţi (bytecode) ar trebui să poată fi executat pe orice tip de calculator, indiferent de arhitectura acestuia, tipul procesorului, capacitatea de memorie etc, deci să fie independent de platformă. În realitate, calculatorul trebuie să aibă o memorie disponibilă suficient de mare pentru a conţine cel puţin maşina virtuală Java (JVM). Apare deci o contradicţie: pentru a executa programe mari, JVM trebuie să aiba o memorie mare, deci şi calculatorul gazdă trebuie să aibă o memorie mare. Pe de altă parte, pentru a putea executa programe Java pe calculatoare de capacitate foarte mică (cum sunt cele încorporate în diverse aparate electrocasnice, aparate de automatizare etc) este necesară o JVM cu memorie mică. Un program destinat unui calculator mic poate fi executat şi pe unul cu memorie mare, dar nu şi invers. Aceasta a condus la necesitatea de a avea mai multe "medii de execuţie Java", în funcţie de dimensiunile şi destinaţia calculatorului pe care se instalează, iar între caracteristicile programelor Java nu se mai mentioneaza "independenţa de platformă" ci "neutralitatea faţă de arhitectură". Neutralitatea faţă de arhitectură înseamnă, de fapt, că arhitectura maşinii virtuale Java, care este ea însăşi un calculator abstract (organizarea memoriei, convenţiile de reprezentare a datelor în memorie, setul de instrucţiuni al procesorului etc) nu depinde de arhitectura calculatorului pe care aceasta se instaleaza. Întrucat codul de octeţi obţinut din compilarea programului Java nu se execută nemijlocit pe calculatorul gazdă, ci pe maşina virtuală Java, el poate fi acelaşi pe orice calculator pe care este instalata o astfel de maşină, deci este neutru faţă de arhitectura calculatorului gazda. Este însa necesar să precizăm că maşina virtuală Java însăşi este un produs software, care este instalat şi funcţionează direct pe calculatorul gazdă, deci respectă convenţiile arhitecturale ale acestuia. În consecinţă, pe fiecare tip de calculator trebuie instalată o maşină virtuală Java corespunzătoare. Se poate, deci, vorbi de neutralitatea faţă de arhitectura a programelor Java, dar nu şi a maşinii virtuale Java.

9

Severin Bumbaru

Calculatoare abstracte. Modelul von Neuman
Conceptul de calculator abstract
Sistemele de calcul reale sunt extrem de complicate, astfel că cel care doreşte să le cunoască în detaliu are nevoie de cunoştinţe aprofundate în domenile tehnice cărora le aparţin echipamentele care le compun (electronica, electrotehnica, mecanica etc.). Din fericire, asemenea cunostinţe nu sunt absolut necesare pentru a programa un calculator, deşi uneori pot fi utile. În realitate, programatorul nu scrie programul pentru calculatorul real, ci pentru un calculator abstract, dat sub forma unui model care elimina detaliile, păstrând numai acele elemente care sunt necesare pentru limbajul de programare folosit. Asa dar, la stabilirea schemei calculatorului abstract, trebuie să se ţină seama atât de calculatorul real pe care îl modelează, cât şi de limbajul de programare folosit. Este deci posibil ca, pentru acelaşi calculator concret, să existe mai multe modele abstracte, folosite pentru diferite limbaje. Este însă, de asemenea, posibil ca pentru mai multe calculatoare concrete să se folosească acelaşi calculator abstract, diferenţa între ele manifestandu-se prin acele detalii, care se pierd la abstractizare. În general, un calculator abstract are un set de instrucţiuni, un set de regiştri şi un model de memorie.

Modelul de memorie
Memoria calculatorului abstract este o succesiune de locaţii de memorie. Fiecare locaţie de memorie este privită ca o "casetă" care conţine un numar fix de cifre binare (biţi). Numărul de ordine al locaţiei (care arată poziţia acesteia în cadrul memoriei) se numeste adresă. În consecinţă, memoria calculatorului este adresabilă. Locaţia este cea mai mică zonă de memorie care poate fi citită sau înregistrată. La orice operaţie de citire/scriere se transferă un numar întreg de locaţii. În principiu, modelele de memorie pot să difere între ele prin numărul de biţi conţinut în locaţia de memorie (prin "lungimea" locaţiei). Totuşi, la majoritatea calculatoarelor actuale, locaţia de memorie conţine opt biţi şi se numeşte octet (engl.: byte). Iată un exemplu de model de memorie organizată pe octeţi:

10

se obisnuieşte să se folosească drept unitate de masură octetul sau multiplii acestuia. Le-am scris în sistemul de numeratie zecimal.: byte). mult mai mare. de la care s-au luat începutul şi sfârşitul. Aceasta este. prescurtat M sau Mo sau MB . megabyte) = 1024 kiloocteţi = 1'048'576 octeţi. Un octet (byte) este însă un număr format din 8 cifre binare. Numele este o prescurtare de la denumirea din engleză a unităţii binare: binary unit. deci din 8 biţi.: gigabyte) = 1024 megaocteţi = 1'073'741'824 octeţi. pentru multipli nu s-au folosit puterile lui 10. Având în vedere că sistemul de numeraţie folosit în memoria internă a calculatorului este cel binar. deci într-un registru pot fi "încărcaţi" un număr întreg de octeţi. arbitrar. dispozitive în care se memorează numere binare de lungime fixă. desigur. Regiştrii procesorului sunt. Multiplii octetului sunt kilooctetul. În coloana din dreapta au fost reprezentate locaţiile de memorie. la fel ca locaţiile de memorie. exprimându-se prin cifrele binare 0 si 1. gigaoctetul si teraoctetul. sau în cel hexazecimal. De obicei însă. pentru a fi mai uşor de urmărit. Primul este unitatea binara. ci puterile lui 2 cele mai apropiate de acestea: 1 kilooctet (engl. prescurtat K sau Ko sau KB . 11 . prescurtat G sau Go sau GB .Programarea orientata pe obiecte în limbajul Java În acest model. 1 teraoctet (engl: terabyte) = 1024 gigaocteţi =1'099'511'627'776 octeţi. 1 gigaoctet (engl. Procesorul abstract Procesorul abstract este caracterizat printr-un set de regiştri şi un set de instrucţiuni. kilobyte) = 1024 octeţi = 210 octeţi. 1 megaoctet (engl. Numărul de locaţii este însă în realitate. Conţinutul a fost aici ales. Totuşi. ca în sistemul zecimal. conţinând fiecare exact opt cifre binare. exprimandu-se de regulă în megaocteţi. specifică procesorului respectiv. în coloana din stânga apar adresele locaţiilor. desigur. prescurtat T sau To sau TB . Capacitatea de memorie Capacitatea memoriei calculatorului se poate exprima în biţi. ele se exprimă în sistemul binar. megaoctetul. întrucât majoritatea calculatoarelor moderne au memoria organizată pe octeţi. în general un multiplu de 8. Reamintim că nu trebuie sa confundam un bit cu un octet (engl.

memorarea. . 12 . .o unitate aritmetică şi logică. adresa din memorie a operandului şi numărul registrului în care se încarcă. Maşina von Neumann Matematicianul american de origine maghiară John von Neumann a publicat în anul 1945 prima descriere a unui calculator cu program memorat.operaţii de calcul (aritmetice sau logice). .Severin Bumbaru Instrucţiunile sunt codificate intern tot prin numere binare.o unitate de control.o unitate de memorie. .o unitate de intrare/ieşire. numărul registrului de origine şi adresa din memorie a destinaţiei. instrucţiunea conţine codul operaţiei de încarcare. de regulă. Această descriere a avut o influenţă foarte mare asupra evoluţiei ulterioare a calculatoarelor şi este cunoscută sub numele "maşina von Neumann". fie între un operand dintr-un registru şi unul din memorie. într-un registru. formate din cel puţin două părţi: un cod al operaţiei şi adresa operandului (uneori adresele operanzilor). sau numărul unui registru şi o adresă din memorie. Unitatea aritmetică şi logică şi unitatea de control formează împreună procesorul (unitatea centrală) de la calculatoarele actuale. . adică transferul unui operand din memorie într-un registru. Instrucţiunea de salt indică trecerea la executarea unei instrucţiuni situată la o altă adresă din memorie. . care ar fi putut fi construit. prin care se modifică fluxul normal (secvenţial) al executării instrucţiunilor. Maşina von Neumann este formată din: . în ordinea în care acestea sunt situate în memorie. În mod normal. se trece la cea imediat următoare. adică inregistrarea la o anumită adresă din memorie a conţinutului unui registru. Exemple de operaţii: . Rezultatul operaţiei rămane. după ce s-a executat o instrucţiune din program. se dau: codul operaţiei.încărcarea. Fiecare instrucţiune este înregistrată în memorie pe o lungime unul sau mai multi octeţi. care se efectueaza fie între operanzii din registre. În instrucţiune se dau codul operaţiei şi numerele registrelor între care se face aceasta.instrucţiuni de salt.

adună operanzii din cei doi regiştri (rezultatul rămâne în registrul acumulator A). de exemplu. ci pentru el a fost conceput un alt calculator abstract. aceste instrucţiuni vor fi reprezentate în cod binar. ale căror operaţii pot. Este unul din motivele pentru care acest limbaj nu mai are la bază maşina von Neumann. dorim să se efectueze calculul c=a+b. înmulţire. numit în engleză Java Runtime Environment. Chiar dacă. Ea conţine doi regiştri. în sensul că el permite să existe în paralel mai multe fire de executie. iar rezultatul rămâne în registrul acumulator. Pascal. împărţire) se fac între numerele din cei doi regiştri. cât şi adresele din memorie vor fi exprimate prin numere în sistemul de numeraţie cu baza 2. 13 . Caracteristica principală a maşinii von Neuman este ca funcţionarea ei este un proces secvenţial: la un moment dat se execută o singură instrucţiune. în general. În toate operaţiile participă unitatea centrală şi regiştrii acesteia. Primele generaţii de calculatoare construite au respectat destul de fidel modelul maşinii von Neuman. iar executarea unei instrucţiuni poate să înceapă numai după ce s-a încheiat executarea celei precedente. memorează conţinutul registrului A la adresa c din memorie. C++ ş.Java Virtual Machine) este. au aparut calculatoare cu mai multe procesoare.operaţiile de calcul (adunare. valoare absoluta). în principiu. Cobol. limbajele de programare au continuat.operaţiile de intrare/ieşire se fac între registrul acumulator şi unitatea de intrare/ieşire.). Acest mediu trebuie instalat pe orice calculator. adica atât operaţiile. Maşina virtuală Java (engleză: JVM . Basic. . încarcă în registrul R operandul situat în memorie la adresa b. împărţire întreagă. Exemple bine cunoscute de astfel de limbaje sunt Fortran. Orice operaţie se face folosind regiştrii unităţii centrale: . să se realizeze pe procesoare diferite. implementată software sub forma unui produs program adecvat calculatorului pe care acesta se instalează. Limbajul Java face parte din categoria limbajelor pentru procese concurente.încărcarea este transferul unui operand din memorie în unul din registri. să fie făcute pentru calculatoare abstracte de tip von Neumann. care funcţionează în paralel. scădere.a. etc. în majoritatea lor. pe care se doreşte să se execute programe Java. Unitatea aritmetică şi logică efectuează operaţiile de calcul (adunare. înmulţire. numit maşina virtuală Java. evoluţia calculatoarelor şi a sistemelor de operare a suferit abateri de la acest model (s-a introdus accesul direct la memorie al unităţilor de intrare/ieşire.Programarea orientata pe obiecte în limbajul Java Maşina von Neuman lucrează numai cu numere întregi. C. ulterior. Bineînţeles. scădere. aceasta înseamnă că se vor executa următoarele instructiuni: încarcă în registrul A operandul situat în memorie la adresa a. Mediul de execuţie Java Mediul de execuţie Java. . . dintre care unul se numeste registru acumulator. Dacă.memorarea este transferul continutului registrului acumulator la o anumită adresă din memorie. conţine maşina virtuală Java şi un nucleu de clase Java.

Fortran etc. Pascal. frigidere. componenta principală a maşinii virtuale Java este un interpretor. Orice program este un ansamblu de clase şi de obiecte. este ca . Este vorba. Din această cauză. care sunt instanţieri ale claselor. care pot fi executate de procesorul calculatorului gazdă. pe care se execută programe Java. În consecinţă. Mai mult. de acele clase care asigură comunicarea dintre programul Java şi sistemul de operare al calculatorului gazdă. În mediul de execuţie Java este inclusă şi o bibliotecă de clase predefinite. telefoane. pe fiecare calculator. poate fi executat (rulat) pe orice calculator. deci care să poată fi executate pe orice echipament. 14 . arhitectura şi setul de instrucţiuni al calculatorului. s-a decis ca în tehnologia Java portabilitatea programelor sa se realizeze la nivel de cod de octeţi (bytecode). în special. Run Anywhere" (scrie o singură dată şi rulează oriunde). care arată că un program. adică sub forma de cod binar destinat unui calculator abstract. Ea se exprimă prin sloganul "Write Once. Această conversie necesită un anumit timp. (The Java Virtual Machine Specification). numit maşina virtuală Java. implementarea lor este dependenta de platformă. de la produse de uz casnic comandate numeric (televizoare. codul de octeţi generat de compilatorul Java nu poate fi executat nemijlocit de procesorul (procesoarele) calculatorului pe care acesta se execută. Pentru realizarea acestui obiectiv. Deşi interfaţa acestor clase cu programul Java nu depinde de tipul calculatorului gazdă.să se poată creea produse software neutre faţă de arhitectura sistemului de calcul. Nucleul de clase: Limbajul Java este orientat pe obiecte. principala deficienţă care se semnala la primele implementări ale maşinii virtuale Java era că durata de execuţie a programelor era sensibil mai mare decât a celor scrise in limbaje "tradiţionale" compilate. în care se prezintă în detaliu arhitectura şi funcţionarea acestei maşini. Dacă este realizată software (aşa cum se întamplă în majoritatea cazurilor).pe baza acestora . pe care se execută un program Java. pentru acelaşi calculator pot fi realizate mai multe maşini virtuale Java. Acest produs program trebuie să respecte specificaţia maşinii virtuale Java. În principiu.Severin Bumbaru Ideea de bază a limbajului şi tehnologiei Java. maşina virtuală Java este ea însăşi un produs program. adică un program care parcurge instrucţiunile conţinute în codul de octeţi Java din memoria maşinii virtuale Java şi le converteşte în instrucţiuni native. maşini de spălat. Implementarea maşinii virtuale Java De regulă. trebuie sa existe o implementare (o realizare concretă sub forma de produs software sau hardware) a maşinii virtuale Java. din care cauză durata de execuţie a unui program interpretat este intotdeauna mai mare decât a unuia compilat direct în codul nativ. după ce a fost scris şi compilat. care execută efectiv programul dat sub forma de cod de octeţi. dar diferă între ele prin modul de realizare. la fel ca şi cea a maşinii virtuale Java. cum ar fi C. etc) pană la supercalculatoare. C++. care este scris şi compilat special pentru tipul de calculator pe care se instalează. În acest scop:   s-a întocmit o descriere riguroasă numită specificaţia maşinii virtuale Java. care toate respecta specificaţia. diferă de cele ale maşinii virtuale Java. dar realizarea concretă depinde de tipul de calculator pe care se instalează. deci foloseşte setul de instrucţiuni nativ al acestuia.

Standard Edition. în momentul execuţiei.0 au devenit depreciate în JDK 1. JDK 1. JDK 1. în special. 15 . Java 2 Platform. bibliotecă de clase.1 a reprezentat o revizuire de concepţie.1 la JDK 1.pentru utilizarea pe calculatoare de capacitate foarte mică. Enterprise Edition (J2EE) . acesta s-a numit "setul de dezvoltare Java" (în engleza: JDK Java Development Kit). O componentă importantă pentru programatori a setului de dezvoltare Java este "Interfaţa pentru programarea de aplicaţii" (API . Trecerea de la JDK 1. în special în ce priveşte API. MicroEdition (J2ME) . documentaţie etc. SE . Aceasta se realizează.2" (SDK .4". Desigur că cea mai eficientă reducere a duratei de execuţie se produce atunci când maşina virtuală Java este implementata hardware. încorporate în echipamente electrice sau electronice. care se apropie deja de cea a programelor compilate. depanator. În consecinţă. în care se dă specificaţia claselor. in anii 1996.0 la JDK 1.1. La trecerea de la JDK 1. Au existat mai multe versiuni succesive: JDK 1. Java 2 Platform. nu se mai recomanda folosirea în programele Java a JDK 1. Ca urmare.2 nu a mai apărut o astfel de situaţie. JDK 1.Programarea orientata pe obiecte în limbajul Java Implementările moderne ale maşinii virtuale Java se caracterizează prin mărirea sensibilă a vitezei de executie. În anul 1998 s-a introdus denumirea de "Platforma Java 2". SE v1. La început.0. In prezent. iar din documentaţia oferită de firma Sun vom folosi în special documentaţia API pentru această platformă. v . dar numărul de clase a fost sensibil mărit.0. SE v1.Application Programming Interface). in cod nativ pentru calculatorul gazdă şi abia apoi este executat. În cursul nostru vom folosi J2SE.pentru dezvoltarea de aplicaţii pentru serverele de întreprindere. resurse software şi documentaţie puse la dispoziţie programatorilor şi utilizatorilor de Java. Standard Edition (J2SE) . care se referă la întregul complex de specificaţii. 1997 si 1998.Software Development Kit. adică descrierea riguroasă a modului în care clasă respectivă este vazută de către programul de aplicaţie. Aceasta este acea parte din documentaţie. respetiv. În acest caz. Platforma Java 2 se oferă în prezent de firma Sun Microsystems în trei variante:    Java 2 Platform.2 a fost redenumit "Java 2 Platform SDK. Platforma Java 2 Un mare avantaj al programatorilor in limbajul Java este că au la dispoziţie un set puternic de instrumente de dezvoltare a programelor: compilator. durata de execuţie a programului este aceeaşi cu cea a unui program compilat tradiţional.pentru dezvoltarea aplicaţiilor şi miniaplicaţiilor obişnuite (de pe staţiile de lucru). astfel că numeroase clase existente în JDK 1. prin introducerea unei compilări "just in time": codul de octeţi este compilat. astfel încât codul de octeti Java (bztecode) este cod nativ al acestei maşini.version). se utilizează deja "Java 2 Platform SDK.2 aparute.1. fiind înlocuite cu clase noi.

Un număr foarte mare de firme producătoare de software şi numeroşi programatori individuali din intreaga lume s-au angajat în dezvoltarea de clase.specificaţia claselor interfeţei de programare de aplicaţii Java şi bibliotecile care implementează aceste clase. a introducerii unor norme pe care să le respecte întreaga comunitate a programatorilor. Limbajele orientate pe obiecte existente anterior (C++. în special a Internet-ului. interfaţa grafică cu utilizatorul. legătura cu baze de date. pe care programatorii le au la dispoziţie. prelucrări de texte. nu puteau sta la baza producerii unor componente utilizabile pe orice platformă hardware şi sub orice sistem de operare şi . Întreţinerea şi dezvoltarea acestor specificaţii este facută. În afară de clasele din SDK (puse la dispoziţie de firma Sun Microsystems). Deşi a apărut recent. componente şi aplicaţii programate în Java. deocamdată.Severin Bumbaru Tehnologia Java Datorită caracteristicilor sale. Acest rol il îndeplinesc acum specificatiile: specificatia limbajului Java. calcul distribuit. acest rol sa fie conferit unui organism de standardizare internaţional. Când s-a trecut de la programarea procedurală la programarea orientată pe obiecte. lucrul cu fişiere. etc) nu au reuşit. fiind utilizabile în domenii din ce în ce mai variate: prelucrări de date numerice. s-a arătat că aceasta poate fi comparată cu trecerea de la fabricaţia artizanală la cea industrială: programul nu mai trebuie creat "de la zero". Nu este exclus ca. Dintre resursele cele mai importante puse la dispoziţia programatorilor de tehnologia Java.deci . răspândirea foarte rapidă a platformei Java se datoreşte tocmai faptului că apariţia ei a corespuns cu dezvoltarea amplă a reţelelor de calculatoare. multe din ele disponibile liber pe Internet. Aceasta presupune însă.nu puteau fi folosite fara dificultăţi într-o reţea de calculatoare eterogenă. ci poate fi conceput ca un ansamblu de componente (obiecte) "prefabricate". şi necesitatea unei standardizări. să stea la baza unei astfel de "industrializări". de firma Sun Microsystems. Java API. securitatea datelor. ca în orice alta tehnologie. pentru a nu se creea avantaje unui anumit producător de software. etc. Object Pascal. fiind limbaje compilate. cu timpul. menţionăm:  Java API . Forţa tehnologiei Java constă nu în limbajul folosit. specificatia maşinii virtuale Java. Ca urmare. din aceste componente. etc. Java nu mai poate fi considerat doar un limbaj de programare asociat cu o platformă de dezvoltare de aplicaţii. fără a fi necesar sa fie refăcute când se trece de la un tip de calculator la altul. Cauza principală este că. se poate spune că baza tehnologică a programării în Java creşte exponenţial. comunicatii în reţele. ci în numărul din ce în ce mai mare de clase reutilizabile. ci a devenit o veritabilă tehnologie software. Programatorii se pot împărţi în două categorii: cei care creeaza clasele de obiecte şi le oferă "pe piaţa" şi cei care. Numărul de clase din Java SDK creşte continuu. crează aplicaţii (produse software finite) oferite utilizatorilor. Limbajul Java în sine este simplu şi uşor de învăţat. totuşi. şi în faptul că programele realizate pot fi utilizabile practic oriunde. programatorii pot folosi un numar mare de clase şi componente Java ("Java beans") oferite de alte firme. 16 .

Scurt istoric al platformei Java În anul 1990. Se ofera şi instrumente de dezvoltare pentru astfel de componente: BDK (Beans Development Kit) pentru dezvoltarea de componente. frigidere.NET . Platforma Java este foarte convenabilă pentru crearea şi utilizarea agenţilor în reţele eterogene. Borland JBuilder . realizat si oferit gratuit pentru utilizări necomerciale de firma Sun MicroSystems.un mediu de programare vizual. care să fie simplu. şi multe altele. neutre faţă de tipul calculatorului şi sistemul de operare. televizoare etc. realizat de firma Borland.produse software care se pot deplasa de la un calculator la altul într-o reţea şi pot îndeplini în mod autonom pe calculatorul de destinaţie sarcinile pentru care au fost trimise. Există. oferite de diverse firme. Java Plug-in (pentru legătura cu Active-X de la Microsoft). Acest nou limbaj a fost numit Oak (în romaneste "nuc".un mediu de dezvoltare vizual al firmei Microsoft şi altele.un mediu de programare vizual realizat de firma IBM. iar programul binar obţinut prin compilare să poată fi rulat pe calculatoare de capacitate mică şi cu arhitecturi diferite. JINI . localizarea componentelor şi altele. între care şi James Gosling. Începând cu Platforma Java 2 este inclusă în Java API.biblioteca de clase pentru realizarea unor interfeţe grafice cu utilizatorul independente de sistemul de operare utilizat. numeroase medii de programare pentru Java.un mediu de programare vizual. etc. VisualAge for Java .tehnologie bazată pe Java. realizat de firma WebGain. cum sunt:       Forte for Java . JAF (JavaBeans Activation Framework) pentru identificarea. prima lui variantă fiind gata la mijlocul lui 1991.o arhitectură de componente reutilizabile. S-a ajuns astfel la concluzia că este necesar un nou limbaj de programare. Visual J# .Programarea orientata pe obiecte în limbajul Java       JFC (Java Foundation Classes) . tehnologia agenţilor software . În acest curs. al cărui obiectiv era realizarea de software pentru aparate electrocasnice cu comanda numerică (maşini de spălat. de asemenea. cadrul de dezvoltare a agentilor Java Java Agents Framework (JAF) de la Universitatea din Massachutess. pentru asigurarea conectivităţii echipamentelor în reţele de calculatoare. care pot fi utilizate în medii de programare vizuale. uşor de învăţat şi de utilizat. Exemple sunt tehnologia agleţilor oferita de firma IBM. WebGain VisualCafe . se spune că atunci când a trebuit sa-i dea un nume. Java Beans . să se folosească pentru programare limbajul C++. Standard Edition. deoarece programele obţinute erau prea mari şi nu erau portabile la nivel de cod binar. lucrau la proiectul "Green". 17 . un grup de programatori de la firma Sun Microsystems. cuptoare cu microunde. folosind numai Java 2 SDK. pentru început.un mediu de programare vizual.). telefoane. S-a încercat. Gosling s-a uitat pe fereastră şi a văzut un nuc în faţa ei). JDBC (Java Data Base Connectivity) .componente pentru legătura cu baze de date. ne vom rezuma la însuşirea limbajului Java şi a unor componente din Java API. dar s-a constatat rapid că acesta nu corespundea scopului urmărit.

decembrie 1996 .decembrie 1998 . .4 Introducere în programarea orientată pe obiecte Programarea orientată pe obiecte (POO) este o formă de programare. Iată dece acest nume apare frecvent scris sub forma JavaTM. nu corespundea încă cerinţelor pieţei. Se considera ca.februarie 1997 . care a fost şi înregistrat ca marcă comerciala (TM .0. ceeace a provocat din partea acestuia un anumit raspuns (deci b a manifestat o anumita comportare). folosirea limbajului şi apoi a tehnologiei Java a căpătat o dezvoltare exponenţială. J2EE si J2ME. Obiectul este o instantiere (o instanta) a clasei. iar programul conţine un ansamblu de clase şi obiecte.iunie 1999 . orientarea către aparatura electrocasnică ("de consum"). . Iată câteva date: . Starea obiectului depinde de datele pe care acesta le contine. comunicarea prin mesaje consta in invocarea de metode. . . Fiecare obiect se caracterizeaza prin stare si comportament.lansarea JDK 1. în timpul unei discuţii "la o ceaşcă de cafea". deci să capete o componentă dinamică. aceasta poate avea ca efect modificarea starii obiectului b (adica modificarea unor date continute in structura de date a lui b) si/sau poate primi o valoare intoarsa de metoda respectiva. . Introducerea de appleturi (miniaplicaţii) Java în paginile de Web a permis ca acestea sa devina interactive. care comunică între ele prin mesaje.1.este lansată platforma J2SE v 1. s-a ajuns la concluzia că cea mai buna utilizare a noului limbaj este realizarea de software pentru reţelele de calculatoare.se lansează JFC (Java Foundation Classes). in timp ce comportamentul este dat de metodele clasei respective. Daca obiectul a invoca o metoda a obiectului b. După o serie de alte încercări.Severin Bumbaru Desi s-a realizat o cantitate mare de software.lansarea versiunii finale a JDK 1. Prima utilizare comercială a acestui limbaj a fost includerea unui interpretor Java în navigatorul (browserul) de Web al firmei Netscape. autorii au decis sa-i dea limbajului numele Java. în vremea respectivă. In acelasi program se pot folosi mai multe obiecte apartinand aceleeasi clase.1. In general.Trade Mark). 18 . Clasa este o extensie a conceptului de tip de date şi conţine o structură de date. Întrucat denumirea "Oak" nu a putut fi înregistrată oficial. sau unor clase diferite.se anunta trei ediţii ale platformei Java 2: J2SE. .se lansează platforma J2SE v 1. obiectul a a transmis un mesaj obiectului b.3. în care programatorii definesc clase de obiecte. versiunea beta. prin invocarea metodei. In continuare.martie 1998 .mai 2000 .ianuarie 1996 .lansarea JDK 1.februarie 2002 . s-a constatat că. . împreună cu metodele (functiile) care se aplica acestor date.se lansează "Java 2 Platform".

variabila varsta va avea valori diferite pentru fiecare pasare. PoligonRegulat).este un produs software care se instalează pe un anumit calculator şi funcţionează direct sub controlul sistemului de operare.25. evident. care toate sunt poligoane regulate. apotema. deci este o variabila a instantei (nestatica). deci au valori diferite de la un obiect la altul. perimetrul. Cele publice sunt accesibile din orice alta clasa. Metodele statice (ale clasei) pot folosi numai variabilele statice ale clasei respective. deci se modifica starea poligonului. datele si metodele unei clase pot fi publice sau private. fiind o variabila statica sau a clasei. in timp ce metodele nestatice pot folosi atat variabilele statice. iar comportamentul acestui obiect a constat in punerea in executie a metodei invocate si intoarcerea valorii calculate a ariei. Tipuri de produse software scrise în Java Limbajul Java este folosit cel mai frecvent pentru a scrie urmatoarele trei tipuri de programe: aplicaţie . Prin invocarea acestei metode. Una din clasele aplicaţiei trebuie sa conţină metoda principală. dar difera intre ele prin numarul de laturi si/sau prin lungimea laturii. Variabilele de instanta (nestatice) apartin obiectului (instantei). având acces la toate resursele calculatorului respectiv. cat si metodele pot fi statice sau nestatice.arie() are ca efect calcularea functiei arie()pentru obiectul p. In schimb. in timp ce cele private sunt accesibile numai din clasa careia ii apartin. adica de numarul de laturi si de lungimea laturii. de starea in care se gaseste p in momentul invocarii metodei. cat si pe cele ale instantei. Fie p un PoligonRegulat cu 4 laturi de lungime 3. Valoarea intoarsa depinde. Atat variabilele. cu care începe execuţia aplicatiei. Metodele pot fi. evident. mici programe (functii) prin care se calculeaza aria. s-a transmis obiectului p mesajul ca se cere calcularea ariei. deci se va obtine ca raspuns valoarea 12. Variabilele statice (ale clasei) apartin clasei. Pot exista. Clasa are un nume (de ex. mai multe instante (obiecte) ale acestei clase. Invocarea metodei p. aceasta variabila va avea valoarea 2 pentru toate pasarile.Programarea orientata pe obiecte în limbajul Java Exemplu Sa consideram clasa poligoanelor regulate. De exemplu. daca clasa Pasare contine variabila numarAripi. adica au aceeasi valoare pentru toate obiectele clasei respective. Această metodă se numeşte main şi are forma: 19 . de exemplu. Pot exista si metode prin care se modifica numarul de laturi sau lungimea laturii. Din punct de vedere al modului de acces. raza cercului circumscris etc. Structura de date contine doua variabile: numarul de laturi (care este o variabila de tip intreg) si lungimea unei laturi (care este o variabila de tip real). deci pentru toate instantele clasei respective.5.

// corpul metodei main - este o succesiune de instrucţiuni şi comentarii care respectă sintaxa limbajului Java. Părţile componente ale acestui şablon pot fi explicate pe baza cunoştintelor pe care le avem deja despre programarea orientată pe obiecte şi despre limbajele de programare.este un program care se transmite sub formă de cod de octeţi (bytecode) prin reţeaua de calculatoare şi este executat în cadrul unui navigator (browser) de Web. fiecare cuvânt începe cu majusculă. . corpul clasei conţine o singura metodă. <nume_clasa> .numele clasei trebuie să înceapă cu o literă şi este format numai din litere.descrierea (definirea) unei clase începe prin cuvantul class. . dar nu este recomandabil sa fie prea mare.în cazul nostru.metoda are forma unei funcţii. 20 . care se numeşte main şi are un singur argument numit args. .în cazul numelor compuse din mai multe cuvinte.lungimea numelui nu este limitată. în aplicaţiile făcute la curs şi la laborator vom utiliza următorul şablon: class <nume_clasa> { public static void main(String args[]) { // corpul metodei main } } Părţile scrise cu negru (inclusiv parantezele şi acoladele) le vom considera obligatorii. adică un tablou de şiruri de caractere. . } . . Un şablon de aplicaţie simplă în limbajul Java În prima parte a acestui curs. servlet .liniuţa de subliniere.este numele clasei. numele de clasă începe întotdeauna cu o majusculă. fără a avea acces la fişierele sau sistemul de intrare/ieşire al calculatorului pe care se execută. urmat de numele clasei.. . cifre şi eventual .Severin Bumbaru public static void main(String args[]) { // corpul metodei } applet (miniaplicaţie) .corpul clasei este cuprins între acolade { . Vom vedea ulterior că acesta este un tablou de obiecte din clasa String.un program care se execută pe un server dein reţea. iar cele scrise cursiv cu roşu sunt la latitudinea programatorului.prin convenţie (deşi aceasta nu este o regulă de sintaxă).. fiind ales de către programator cu respectarea următoarelor condiţii: . Tot atunci vom vedea că acest argument serveşte pentru preluarea parametrilor din linia de comandă.

println("Prima noastra aplicatie a reusit!"). . În acest scop. prin care este invocată metoda println a obiectului out din clasa System. testarea şi eliminarea erorilor de concepţie. Pentru a dezvolta aplicaţii Java: 21 . -metoda main este statică. Deşi nu cunoaştem încă modul în care se definesc şi se utilizează clasele şi obiectele în limbajul Java. care conţine metoda main. Efectul executării acestei aplicaţii este că se afişează pe ecran textul Prima noastra aplicatie a reusit! Editarea. Exemplu de aplicaţie simplă Dăm aici un exemplu de aplicaţie simplă scrisă în limbajul Java. Standard Edition.privită ca o funcţie.out. corpul clasei este constituit dintr-o singură instrucţiune. metoda nu întoarce o valoare. metoda main trebuie.out. deci apartine clasei şi nu instanţelor acestei clase. În acest caz. compilarea şi eliminarea erorilor sintactice. pe calculatorul pe care lucraţi trebuie sa existe un set de dezvoltare Java. } } Remarcăm urmatoarele:    programul respectă şablonul de aplicaţie simplă adoptat de noi. are ca efect afişarea pe ecran a şirului primit ca argument. (punct şi virgulă). instrucţiunile simple se termină cu caracterul . numele clasei este PrimaAplicatie. executarea. în principiu. Exemplul 1 Considerăm următorul program: class PrimaAplicatie { public static void main(String args[]) { System.println(<sir_de_caractere>).Programarea orientata pe obiecte în limbajul Java . preferabil Java 2 Platform SDK. să întoarcă o valoare. lipsă). Aplicaţia este o clasă Java. ea este apelată de maşina virtuală Java la punerea în execuţie a aplicaţiei). adică poate fi utilizată de obiecte din alta clasă (în cazul nostru. În limbajul Java.metoda main (metoda principală) este publică. compilarea şi executarea aplicaţiilor Java Fiecare aplicaţie Java parcurge următoarele etape: editarea programului sursă. menţionam aici că instrucţiunea de forma System. deci tipul valorii întoarse este void (loc gol.

respectiv "Text Editor" sau "Advanced Editor". dacă lucraţi sub Linux sau Unix. veţi folosi o fereastră de X-Terminal. de exemplu "Notepad" daca lucraţi sub Windows sau sub Linux cu WinLinux99.java este fişierul sursă editat de noi. sub care să selectaţi din bara de scule pictograma "Terminal Emulation".java. Acesta este fişierul care conţine bytecode-ul clasei compilate. care respectă şablonul indicat anterior. Obţineţi un mesaj de eroare. după care dăm comanda javac PrimaAplicatie. Editarea fisierului sursă Pentru început. Exemplu de utilizare corectă Sa considerăm ca am creat corect fişierul sursă PrimaAplicatie. de asemenea. care au fost sesizate de compilator. compilarea a decurs normal. Programul sursă pentru această clasă va fi editat sub forma unui fişier separat. vom considera că aplicaţia este constituită dintr-o singură clasă.java. Sub Linux vă recomandăm sa folosiţi KDE. va deplasaţi în subdirectorul în care se găseşte programul sursă pe care doriţi să-l compilaţi şi daţi comanda javac <fisier_sursa> De exemplu. ci apare din nou promptul sistemului de operare.java. fără a se afişa un mesaj de eroare. De exemplu.java Constatăm că pe ecran nu apare nici un mesaj de eroare. fie că există erori în linia de comandă prin care aţi cerut compilarea. Este preferabil să puneţi acest fişier într-un subdirector separat. este necesar să eliminaţi erorile şi să reluaţi compilarea. în timp ce 22 . care poartă numele clasei şi extensia class. care are acelaşi nume cu clasa şi are extensia . De exemplu puteti crea un subdirector numit javaLab. În acest scop. 2. în care să creaţi un alt subdirector numit sapt1.Severin Bumbaru   dacă lucrati sub Windows. numit javac. Dacă dăm acum comanda dir Constatăm.class PrimaAplicatie. care indică fie că există erori în program. iar dacă daţi comanda dir veţi constata ca în subdirectorul curent a apărut un nou fişier. sau din meniul Applications sa alegeti optiunea "X Terminal". În acest caz.java Dintre acestea.java. veţi folosi o fereastră MS-DOS (Command Prompt). Pentru crearea fişierului se va folosi un editor de text simplu. Pe ecran apare din nou promptul sistemului de operare. pentru a compila fişierul care conţine clasa PrimaAplicatie mergeti în subdirectorul în care se găseste fişierul respectiv şi daţi comanda javac PrimaAplicatie.java După ce aţi dat această comandă. clasa PrimaAplicatie va fi editată sub forma unui fişier de text cu numele PrimaAplicatie. daca lucraţi sub Linux cu KDE. care generează numai text neformatat. că în lista de fişiere care se afişează apar: PrimaAplicatie. veţi obţine unul din următoarele rezultate: 1. Compilarea şi eliminarea erorilor semnalate de compilator Translatarea programului sursă în program sub forma de cod de octeţi (bytecode) se face cu ajutorul compilatorului Java. PrimaAplicatie. În ambele cazuri. în care sa puneţi fişierul PrimaAplicatie.

daţi comanda jamac PrimaAplicatie. Exemplul 4 de eroare Să considerăm acum că fişierul sursă editat de noi conţine erori. Într-adevar.java. veţi obtine un mesaj prin care se arată că cuvantul jamac nu este o comandă corectă (nu este numele unei comenzi interne a sistemului de operare sau numele unui program executabil).java:3: No variable ont defined in class Java. obtineţi următorul mesaj: PrimaAplicatie is an invalid option or argument. Făcând corecţia în fişier şi compilând din nou. linia 3. usage: javac <options> <source files> urmat de o lista de opţiuni. 23 . Aceste nume de fişiere trebuie sa conţină obligatoriu extensia java. Remarcăm că. Un exemplu este fişierul PrimaAplicatie1.java". dar lipşeste extensia.lang. programul nu este corect. Observăm că a fost reprodusa linia din program în care apare eroarea şi s-a marcat prin ^ locul apariţiei erorii.pintln("Prima noastra aplicatie a reusit!").System System. totuşi. care nu există în clasa System din pachetul (biblioteca) java. În acest caz. Exemplul 1 de eroare Considerăm că.Programarea orientata pe obiecte în limbajul Java PrimaAplicatie. după ce aţi creat fişierul sursă PrimaAplicatie.conform şablonului dat anterior. eroarea constă în faptul că apare ont în loc de out.java În acest caz.lang.ont. care cere ca comanda javac să fie urmată (eventual) de una sau mai multe opţiuni din lista dată.java în care numele compilatorului este introdus greşit (jamac în loc de javac). deoarece .class este fişierul de cod de octeti rezultat în urma compilării. care are următorul conţinut: class PrimaAplicatie1 { void main(String args[]) { System. de exemplu: javac PimaAplicatie. constatăm că nu mai apare nici un mesaj de eroare. mesajul de eroare este can't read: PimaAplicatie. Ca efect. deci compilatorul nu a mai sesizat nici o eroare şi a creat fişierul care conţine codul de octeţi corespunzător.java.class. Dacă dăm comanda dir. apare variabila ont. de exemplu: jamac: command not found Exemplul 2 de eroare Să considerăm acum că numele fişierului sursă este introdus greşit. ^ Acest mesaj se interpretează astfel: în fişierul PrimaAplicatie1. Aceasta înseamnă că nu s-a respectat sintaxa comenzii.java adică "nu pot citi: PimaAplicatie.println("Prima noastra aplicatie a reusit!").ont. constatam că în directorul curent nu a apărut clasa PrimaAplicatie1. după care trebuie să apară numele fişierului (fişierelor) sursă care trebuie compilate. ceeace înseamnă că un astfel de fişier nu există în directorul curent. în locul marcat mai jos prin ^. Exemplul 3 de eroare Să urmărim ce se întâmplă dacă introducem comanda javac PrimaAplicatie în care numele fişierului este corect. } } Compilând acest fişier obţinem următorul mesaj de eroare: PrimaAplicatie1.java.

Exerciţiu Încercaţi să faceţi şi alte modificări în programul sursă şi să constataţi ce erori apar la compilare. main. static. fără extensia class. string. adica nu a fost găsită definiţia clasei PimaApicatie. Exemplul 1 Considerăm că a reuşit compilarea fişierului corect PrimaAplicatie. Dând acum comanda java PrimaAplicatie1 se obţine mesajul de eroare 24 . pe ecran apare textul Prima noastra aplicatie a reusit! Exemplul 2 Să dăm acum comanda java PimaApicatie în care numele clasei este dat greşit. Efectul acestei comenzi este. Exemplul 3 Să considerăm acum că am eliminat erorile de compilare din fişierul PrimaAplicatie1.class. clasa poate sa conţina şi o metoda main de forma celei date în acest fisier.NoClassDefFoundError: PimaApicatie Acest mesaj arată că nu s-a găsit definiţia clasei PimaAplicatie (Eroarea constatată se deduce din numele acesteia: NoClassDefFoundError provine de la "no class definition found error". însă.lang. Compilaţi fişierul astfel modificat şi interpretati mesajele de eroare obţinute.class.java şi am obţinut fişierul PrimaAplicatie1. Executarea aplicaţiei Dacă în directorul curent există fişierul <nume_aplicaţie>. Puteţi introduce intenţionat şi mai multe din erorile de mai sus simultan. executarea acestei aplicaţii se solicită prin comanda java <nume_aplicaţie> Remarcăm că se dă ca parametru numai numele clasei.class. obţinem mesajul de eroare Exception in thread "main" java. Prin comanda java se pune în execuţie interpretorul maşinii virtuale Java. puneţi acolade sau paranteze în plus. fie aparitia unui mesaj de eroare de execuţie. se semnalează printr-un mesaj de eroare.java şi s-a obţinut astfel fişierul PrimaAplicatie. sau dacă el nu conţine o astfel de metodă. Am arătat că lipsa acestor modificatori nu dă eroare de compilare. în principiu. fie executarea aplicatiei. după care se dă comanda java PrimaAplicatie Ca rezultat.Severin Bumbaru prima linie din metoda main trebuia să aibă forma public static void main(String args[]){ Compilatorul nu a sesizat această eroare deoarece. Ca rezultat. încarcă în memorie codul de octeţi pe care îl conţine şi pune în execuţie metoda public static void main(). dar că metoda main a rămas fără modificatorii public static.class. System. println. omiteţi unele dintre acolade sau paranteze. Acest interpretor verifică dacă în directorul curent există fişierul <nume_aplicaţie>. Dacă fişierul nu există. că eroarea apare la executarea programului. Daca acesta există. De exemplu:    scrieti incorect cuvintele public. Vom vedea.

4. Care este metoda care trebuie să existe în mod obligatoriu în orice aplicaţie? 17. 3. Ce conţine platforma Java? 5. Ce deosebire există între metodele statice şi cele nestatice? 12. în realitate. în această clasă.NoSuchMethodError: main "No such method" se traduce prin "nu exista o astfel de metoda". Prin ce comandă se cere executarea unei aplicaţii? Nivel 2 1. 7. 8. Care sunt principalele tipuri de produse software care pot fi scrise în limbajul Java? 14.Programarea orientata pe obiecte în limbajul Java Exception in thread "main" java. Ce calităţi are limbajul de programare Java? 3. Ce deosebire există între variabilele statice şi cele nestatice? 11. Ce este obiectul şi ce legatură există între clasă şi obiect? 8. Ce deosebire există între applet şi aplicatie? 15. Prin ce se defineşte comportamentul obiectului? 10. 2. Prin ce se determină starea obiectului? 9. Ce se obţine dacă compilarea nu a reuşit? 22. Ce deosebire există între datele sau metodele publice şi cele private? 13. Ce este clasa? 7. nu există. Ce conţine mediul de execuţie Java? 4. Ce se obţine în cazul în care compilarea a decurs corect? 21. Ce este programarea orientată pe obiecte? 6. Noi ştim că. Ce deosebire exista între applet şi servlet? 16. numai că nu este cea pe care o caută interpretorul java pentru a pune aplicaţia in execuţie: acesta caută metoda public static void main(String args[]) care. Ce fel de editor se foloseşte pentru crearea fişierului sursă? 19. 5. Urmeaza două puncte şi numele metodei care nu există: main.lang. Prin ce comandă se cere compilarea unui fişier sursă Java? 20. Întrebări Nivel 1 1. Ce este Java? 2. Ce este un fişier sursă Java şi cum se stabileşte numele lui? 18. în clasa PrimaAplicatie1 exista o metodă numita main. Dece limbajul Java este mai simplu decât C/C++? Limbajul Java este compilat sau interpretat? Ce fel de cod generează compilatorul Java? Ce se înţelege prin portabilitatea programelor? Dece limbajul Java este neutru faţă de arhitectură? Dece limbajul Java permite programarea concurentă? Ce este maşina virtuală Java? Ce deosebire este între specificaţia maşinii virtuale Java şi implementarea acesteia? 25 . 6.

Ce este un navigator de Web? 14.Severin Bumbaru 9. Ce se întâmplă dacă în comanda javac numele fişierului sursă este introdus fără extensia java? 20. 18. Ce este SDK si ce legatura există între JDK şi SDK? 11. Ce este un browser? 15. Ce este API? 12. JDK 1. Ce se întâmplă dacă în faţa metodei main se omit modificatorii public static? 26 . Cum sunt semnalate de compilator erorile care apar în program? 21. Ce sunt JDK 1. Ce se întâmplă dacă în comanda javac numele fişierului sursă este introdus greşit? 19.2? 10. Ce navigatoare de Web cunoaşteti? 17. Ce platforme de dezvoltare pentru Java se folosesc în prezent? 13.0.1 şi JDK 1. Ce este WWW? 16. Daţi şablonul unei aplicaţii simple şi explicati părţile componente.

deci au forma // <comentariu> c/ comentarii care sunt destinate reproducerii în documentaţia clasei şi au forma /** <comentariu>*/ deci se deosebesc formal de cele de la punctul a numai prin faptul ca incep cu simbolul /**. Metode pentru afişarea pe ecran a şirurilor. Comentariile sunt utile pentru o mai buna înţelegere a programului de către om. care incep cu simbolul // si continua pana la sfarsitul liniei respective. Declararea şi iniţializarea variabilelor. Variabile şi tipuri de date primitive Comentarii în fişierul sursă Şiruri. Elementele lexicale ale limbajului Java. se pot folosi trei feluri de comentarii: a/ comentarii care se pot extinde pe una sau mai multe linii şi au forma /* <comentariu> */ b/ comentarii de sfarsit de linie. Tipuri de date primitive şi declaraţii de tip tipul boolean tipuri numerice tipuri de date întregi tipuri de date în virgulă mobilă tipul char Întrebări 27 28 29 30 30 31 32 32 34 34 35 36 39 41 45 57 61 63 Comentarii în fişierul sursă Comentariile sunt texte care pot fi introduse în programul sursă. în timp ce ultima este specifică numai limbajului Java. Primele două forme de comentariu există şi în limbajul C++. dar nu sunt luate în consideraţie de compilator şi deci nu au efect în timpul executării programului.Programarea orientata pe obiecte în limbajul Java Şiruri. 27 . Unităţi lexicale ale limbajului Java identificatori cuvinte cheie şi cuvinte rezervate literali separatori şi operatori spaţii şi comentarii Variabile. variabile finale. concatenarea şirurilor. În programele Java.

println("Prima noastra aplicatie a reusit!"). vom constata că efectul este acelaşi ca în cazul clasei PrimaAplicaţie.java. deci. care conţine cele două şiruri-operanzi puse unul după altul. De exemplu. } } // sfarsitul metodei main // sfarsitul clasei Comentarii Dacă vom compila şi pune în executie această aplicaţie. cu care incepe executarea programului */ public static void main(String args[]) { /* Urmeaza instructiunea prin care se invoca metoda println pentru afisarea unui text */ System. Este. dar acesta fost completat cu comentarii. abuzul de comentarii poate să facă urmarirea acestuia dificilă.Severin Bumbaru Exemplu Dăm aici ca exemplu fişierul Comentarii. recomandabil să se introducă în program toate comentariile necesare pentru o bună înţelegere a acestuia. La aprecierea programelor scrise de Dvs. dar nu mai mult. deoarece comentariile introduse în fişierul sursă nu au efect în timpul execuţiei programului. În acelaşi timp.java. expresia "abcde"+"fgh" dă ca rezultat şirul "abcdefgh".out. care are la bază fişierul PrimaAplicatie. Iată câteva exemple de şiruri: "sir de caractere" "ABCDefgh" "1A23bc7" "*+_/?" "" Ultimul exemplu este un şir vid (care nu conţine nici un caracter). OBSERVAŢIE: Comentariile sunt absolut necesare pentru înţelegerea programului. Concatenarea şirurilor Asupra şirurilor se poate aplica operaţia de concatenare. are ca rezultat un nou şir. se va lua întotdeauna în consideraţie prezenţa şi calitatea comentariilor. în care operatorul + este plasat între două şiruri. Expresia şir1+şir2. reprezentata prin operatorul +. /** Aplicatie in care se exemplifica folosirea celor trei tipuri de comentarii permise in limbajul Java */ class Comentarii { // aici incepe definitia clasei Comentarii /* metoda main este metoda principala a clasei. Şiruri Şirul se reprezintă în program printr-o succesiune de caractere cuprinsă între ghilimele. 28 .

println("ab"+("cd"+"ef")). iar obiectul out al acestei clase reprezintă dispozitivul de ieşire standard al sistemului. ca urmare a asociativităţii: "ABC"+"DEF"+"GH" ("ABC"+"DEF")+"GH" "ABC"+("DEF"+"GH") "ABCDEFGH" În schimb.out.out. pe aceeaşi linie. metoda println transmite şi comanda de trecere la linie nouă.print("xyz\n"). De exemplu. cu deosebirea că adaugă la sfârşitul şirului afişat caracterul de control \n care constituie comanda de trecere la linie nouă (New Line).out. Exemplu Considerăm urmatoarea aplicaţie. // nu se trece la linie noua System.println("sirul 1").out. care este de obicei unitatea de afişare de la consolă (ecranul).out.println(<şir>) la care vom adăuga acum şi metoda În este un şir de caractere. Deosebirea dintre ele constă în faptul că. pe o singura linie. după afişarea şirului. // se afiseaza in continuare System. am folosit deja pentru afişarea şirurilor de caractere metoda System.java: /* Exersarea metodelor print si println */ class AfisareSiruri { public static void main(String args[]) { System.println("sirul 2").print("UVW").out. în timp ce metoda printnu transmite o astfel de comandă.out. Metode pentru afişarea pe ecran a şirurilor În capitolul precedent. argumentul <şir> 29 . dar nu este comutativă. iar la afişarea cu print afişarea următoare se va face în continuare. // echivalent cu println("xyz") /* Trecerea la linia urmatoare se face datorita prezentei System. // asociativitate System. în timp ce expresia "ab"+"uvw" este echivalentă cu "abuvw". */ System. deci concatenarea nu este comutativă.println(("ab"+"cd")+"ef"). care se afişeaza pe ecran. // se afiseaza abcdef System.println("AB"+"CDE"). în cazul afişării cu println.println("ab"+"cd"+"ef"). În consecinţă. expresia "uvw"+"ab" este echivalentă cu "uvwab".out. conţinută în fişierul AfisareSiruri.Programarea orientata pe obiecte în limbajul Java Operaţia de concatenare este asociativă. /* Urmatoarele trei instructiuni afiseaza in continuare.out. următoarea afişare se va face de la început de linie nouă. În limbajul Java. Metoda println actionează la fel ca metoda print. expresiile următoare sunt echivalente.out.print("pqrst"). System. care se traduce prin "tipăreşte o linie". Metodele println siprint aparţin obiectului out din clasa System.out. clasa System conţine metodele prin care se comunică cu sistemul de operare al calculatorului. // se afiseaza sub sirul 1 System. // se afiseaza ABCDE System.print(<şir>) ambele metode. Numele metodei println provine de la print line.

În limbajul Java.separatori: { } ( ) [ ] . . respectând anumite reguli. De exemplu. Acestea sunt simboluri. .out. însă acesta nu poate conţine spaţii libere sau alte caractere. Lungimea identificatorului nu prezintă importanţă. numite şi lexeme (engl. . comentarii şi spaţii. Exemple de identificatori valabili: 30 . static. "CDE". "ef".Severin Bumbaru caracterului \n in sirul "xyz\n" */ System. cuvinte cheie. "ab". print. care încep cu o literă. args. literali. variabile. lexeme) sunt construcţiile elementare ale limbajului ("atomii" acestuia).operatori. metode etc.println("ultima linie afisata"). "sirul 2".) se numesc identificatori.comentarii: /* Exersarea metodelor print si println */ // se afiseaza sub sirul 1 Vom analiza acum separat fiecare din aceste categorii de unităţi lexicale. Unităţile lexicale ale limbajului Java Unităţile lexicale. cifre şi caractere de subliniere ('_'). expresiile "ab"+"cd"+"ef".operator: +. unităţile lexicale sunt: identificatori. . System. decât cele menţionate aici. println. "AB".java distingem urmatoarele unităţi lexicale: . separatori. main. public.cuvinte cheie: class. în programul din fişierul AfisareSiruri. token. } } Compilând şi executând acest program. print("xyz\n") are acelasi efect cu println("xyz"). . "cd".literali: "sirul 1". identificatorii sunt şiruri formate din litere. out.identificatori: AfisareSiruri. . cuvinte rezervate. . ("ab"+"cd")+"ef" si"ab"+("cd"+"ef") dau rezultate identice. putem constata că:    după executarea fiecărei metode println se trece pe ecran la o linie noua. formate din unul sau mai multe caractere. După rolul îndeplinit. void. Identificatorii se aleg de către programator. String. Identificatori Numele date programelor sau componentelor acestora (clase. care au o anumită semnificaţie în limbaj.

dar se poate face şi prin caracterul de subliniere '_'. ci doar convenţii neobligatorii. Cuvinte cheie În orice limbaj de programare. cum ar fi v15XB7. args.Programarea orientata pe obiecte în limbajul Java PrimaClasa aplha viteza v15XB7 pretDeVanzare pret_de_vanzare Este clar acum că şi exemplele date anterior ( Afisari. out. identificatorii nu au nici o alta semnificaţie. print. numite cuvinte cheie. Desigur însă că folosirea unor identificatori care au semnificaţie pentru om. public. există un set de cuvinte. de asemenea. static. Acestea nu sunt însă reguli sintactice. În limbajul Java. deci. care sunt considerate simboluri sintactice şi nu pot fi folosite în program ca identificatori. cum ar fi viteza sau PretDeVanzare este preferabilă celor fără semnificaţie. Programatorul poate adopta orice identificatori care respectă regulile şi convenţiile de mai sus şi care nu sunt cuvinte cheie sau cuvinte rezervate. Se obişnuieşte ca numele de clase să înceapă cu literă majusculă. deoarece uşurează înţelegerea şi urmărirea programului. dar ele au fost introduse în tabela cuvintelor cheie în vederea unei eventuale utilizări viitoare. Observăm acum că toate exemplele de cuvinte cheie date la începutul acestei secţiuni (class. se obisnuieşte ca separarea între cuvinte. există următoarele cuvinte cheie: abstract boolean break byte case catch char class const continue default do double else extends final finally float for goto if implements import instanceof int strictfp super switch synchronized this throw throws transient try void volatile while interface long native new package private protected public return short static Dintre acestea. De asemenea. System. Amintim însa că. void) sunt prezente în tabela de mai sus. toate exemplele de identificatori date aici sunt la fel de bune. în cadrul identificatorilor compuşi din mai multe cuvinte ale limbajului natural. const şi goto nu sunt folosite în prezent. din acest punct de vedere. să se facă incepând fiecare cuvant nou cu literă majusculă. identificatori. String. 31 . println) sunt. pentru calculator. main.

care se aplică unui singur operand. de regula. utilizarea operatorului unar se face.în expresia -x.numere reale: 12.numere întregi: 14726. uneori însă se foloseste şi forma "postfix" operand operator în care operatorul se pune după operand. '5'. În afară de acestea. . Operatorul poate fi format din unul sau mai multe caractere.şiruri de caractere: "sir de caractere". . Aproape toţi aceşti separatori au fost deja folosiţi în exemplele date în acest capitol.7389. null.05673. De fapt. 32 . Exemple de literali: . . în care operatorul se pune în faţa operandului. Entitatea asupra căreia se aplică operatorul se numeşte operand. Spaţiul liber şi operatorii indeplinesc. 'A'.28#^z". false. iar al treilea are semnificaţia de referinţă nulă. După numărul de operanzi deosebim: operatori unari. având semnificaţii speciale. în limbajul Java există urmatoarele cuvinte rezervate: true.3075E12. deci în programul scris în limbaj de nivel superior (în cazul nostru în limbajul Java). În limbajul Java se folosesc următorii separatori: { } ( ) [ ] . . Cuvintele cheie sunt şi ele considerate în majoritatea limbajelor. . Am folosit deja simbolul + ca operator de concatenare (deci simbol al operaţiei de concatenare). Vom arăta ulterior că forma de reprezentare a aceloraşi valori în memoria internă a calculatorului (forma internă) este diferită de cea externă. inclusiv Java. rolul de separatori.Severin Bumbaru Cuvinte rezervate Se consideră cuvinte rezervate acele cuvinte.referinţa nulă: null. După numărul de operanzi. .valori logice: true. . 2.caractere: 'a'. Am subliniat faptul că literalul este forma sub care o anumita valoare este reprezentată în fişierul sursă. sub forma "prefix" operator operand. false. de ex. '$'. -1. Primele două sunt valorile logice adevărat şi fals. Literali Literalii sunt reprezentările în fişierele sursă ale valorilor constante. Separatori Separatorul este un caracter care delimitează formele sintactice sau le separă între ele. operatorii pot fi unari. Vom reveni asupra regulilor de scriere a literalilor când vom prezenta tipurile de date din limbajul Java. de asemenea.4237E-5. aceste cuvinte rezervate sunt forme speciale de literali. Operatori Operatorii sunt simboluri ale unor operaţii. '+'. "abc$79. operatorul . -25413. drept cuvinte rezervate. binari sau ternari. care nu pot fi folosite ca identificatori. -0.

iar ceilalti doi operanzi sunt expresii aritmetice sau logice (dar de acelaşi tip). cât şi binari (ca 33 . operatorul fiind situat între aceştia. care lasa valorile operanzilor nemodificate. care a fost folosit atât pentru operaţia de concatenare a şirurilor. Operatori unari: + () ++ [] -{} new ! ~ Operatori binari + == & && << = . care se aplică asupra a trei operanzi. În schimb. De exemplu. este un operator fără efect lateral. Astfel. Dăm aici o listă a operatorilor folosiţi în limbajul Java. operatorul + din exemplul anterior. iar a şi b sunt operanzi. operatorul de concatenare + în expresia "acesta este " + "un exemplu" sau operatorul de adunare a două numere + în expresia 17+28. Din punct de vedere matematic. observăm că semnificaţia unui operator poate să depindă de context. ca în cazul operatorului +. în limbajul Java există un singur operator ternar ( ? :) folosit în expresiile condiţionale. expresia a+b.Programarea orientata pe obiecte în limbajul Java operatori binari.Operatorii binari se folosesc sub forma "infix" operand1 operator operand2 în care operatorul este situat între cei doi operanzi. operatori ternari. <= | || >> += * >= ^ / != % >>> -= *= /= instanceof &= |= ^= ~= <<= >>= >>>= Operator ternar ?: Remarcăm că operatorii + şi . şi cu efect lateral. care modifică valorile operanzilor. Operatorul ternar se scrie sub forma operand1 ? operand2 : operand3 în care operand1 are o valoare logică (true sau false). valoarea operandului a creşte cu o unitate. este o funcţie de argumente a si b. de ex. operatorii sunt funcţii cu unul. în expresia ++a operatorul de incrementare ++ are efect lateral deoarece. în care + este un operator binar. operatorii pot fi fără efect lateral. două sau trei argumente (argumentele fiind operanzii). care se aplică asupra a doi operanzi. cât şi pentru cea de adunare a numerelor. în urma efectuarii operaţiei.pot fi atât unari ( ca în expresiile +a sau -a). Din exemplele de mai sus. care are ca valoare suma valorilor celor două argumente. După efectul operatorului asupra operanzilor.

în schimb variabila x primeşte o nouă valoare. Exemplul 1 In expresia x=a+2. iar valoarea variabilei trebuie să aparţină unui anumit tip de date.println(a) are ca efect afişarea pe ecran a valorii variabilei a. Operaţiile efectuate sunt următoarele: se adună valoarea variabilei a cu valoarea 2 (dată aici sub formă de literal). Valoarea variabilei trebuie să fie reprezentată în memoria calculatorului la o anumită adresă şi să ocupe acolo un anumit spaţiu (un anumit număr de biţi).out. în consecinţă. ci operaţia de atribuire a unei valori unei variabile. Spaţii Între unităţile lexicale ale programului pot fi introduse oricât de multe spaţii libere. care este ignorată de către compilator. Numele variabilei este un identificator. Comentarii După cum s-a aratat deja. x şi a sunt variabile. numim variabilă o zonă de memorie care poarta un nume şi care conţine o anumită valoare. Mai multe spaţii libere succesive sunt tratate de compilator ca şi când ar fi un singur spaţiu. apartinând unui tip de date. iar rezultatul se atribuie ca valoare variabilei x.care citeşte programul respectiv. anumite explicaţii necesare pentru o mai buna înţelegere a acestuia. Din punct de vedere sintactic. care au rolul de a da omului. Programatorul care foloseşte un limbaj de nivel înalt. întregul comentariu este privit ca o singură unitate lexicală. variabila este un simbol dat unei valori.Severin Bumbaru în expresiile a+bsaua-b). cum este şi limbajul Java. la care este plasată valoarea variabilei. Operatorul = nu exprima aici relaţia de egalitate. Variabile In matematică. În consecinţş. care aparţine unei mulţimi de valori ce constituie domeniul de definiţie al variabilei respective. fără ca acestea să aibă influenţă asupra sintaxei sau semanticii programului. valoarea variabilei a ramâne nemodificată. variabila este un nume căruia i se asociază o valoare. în fişierele sursă pot fi introduse comentarii. şi nici reprezentarea 34 . Exemplul 2 Expresia System. În programare. Semnificaţiile operatorilor vor fi arătate când se vor prezenta tipurile de date şi expresiile. Asupra valorilor variabilelor pot fi efectuate prin program anumite operaţii. nu trebuie să cunoască adresa de memorie. deci nu are efect asupra codului de octeţi generat de acesta.

variabilelor alpha si k li se dau valori iniţiale implicite corespunzătoare int (în cazul de faţă valoarea 0). care va fi specificată la descrierea fiecărui tip. iar operaţiile se fac asupra valorilor variabilelor şi nu asupra numelor acestora. asupra simbolurilor variabilelor şi nu asupra valorilor acestora. variabilei beta i se dă valoarea iniţiala 3702. Iată un exemplu de declaraţie de variabilă: int alpha.specificarea numelui unei variabile. aceasta nu este şi iniţializată în mod explicit. orice variabilă trebuie declarată înainte de a fi utilizată. când acesteia i se dă pentru prima dată o valoare şi deci i se alocă spaţiu în memorie. k. de valoarea Remarcam că:   declaraţia de tip este o instructiune care se termină obligatoriu prin simbolul . se observă că declaraţia de tip are urmatoarea formă: tip variabila_1. după caz. fiind suficient să-i cunoasca numele şi tipul. De exemplu. Iniţializarea variabilei se face atunci.. pentru compilator. să apară mai multe variabile. urmat opţional variabilei respective precedată de simbolul =. tipului Din exemplul de mai sus.numele tipului de date căruia îi aparţin variabilele declarate. Alocarea de spaţiu în memorie pentru fiecare variabilă se face. beta=3702. numele şi tipul variabilei trebuie declarate de către programator.. 35 . Remarcăm că în matematică operaţiile cu variabile se fac. Declararea şi iniţializarea variabilelor În limbajul Java. atunci ea este iniţializata cu o valoare implicită. . în acest caz. a tipului şi numelui acesteia. la nivel abstract. variabila_n. variabila_i . egalitatea fiind întotdeauna adevarată. variabila are întotdeauna o valoare (deoarece zona de memorie aferentă nu poate fi vidă). de către compilator sau interpretor. în care: tip . În schimb. la declararea variabilei.a nu are importanţa ce valoare are variabila a.Programarea orientata pe obiecte în limbajul Java internă a acesteia. în identitatea a+a=2. într-o singură declaraţie. de cele mai multe ori. atât timp cât ea exista în memorie. În programare se are în vedere faptul că. Aceasta este o instrucţiune din program. este posibil ca. (punct şi virgulă). beta şi k sunt numele unor variabile de tipul int.. Prin declararea variabilei se înţelege precizarea. prin care se specifică următoarele:    alpha. Dacă.

valoare. Tipuri de date primitive Tipul de date este unul din conceptele fundamentale ale programării calculatoarelor.Severin Bumbaru specificaţiile variabilelor respective sunt separate prin virgule. tipurile de date se împart în două categorii: tipuriprimitive şi tipuri referinţă. Acestea sunt deci.  În declaraţia de tip. numai că valoarea lor se dă o singură dată. serveşte pentru a specifică faptul că ALPHA şi BETA suntvariabile finale de tip int. Se obişnuieşte ca numele de variabile finale să fie scrise în întregime cu majuscule. declaraţia final int ALPHA=17. sa existe şi litere mari. vom da şi exemple de declarare a variabilelor de tipul respectiv. în interiorul numelui. nişte constante cu nume. de exemplu vitezaMedie. asociată cu o mulţime de operaţii care se pot face asupra valorilor respective. Ele se aseamănă cu variabilele propriu-zise prin faptul că sunt tot perechi nume . nişte constante). De exemplu. În ultimul caz. 36 . Aceasta se întamplă atunci când numele variabilei este format din mai multe cuvinte ale limbii naturale. În limbajul Java. ale căror valori nu pot fi modificate prin program. valoarea iniţială a variabilei poate fi dată sub forma unui literal sau a unei expresii. ale caror valori sunt. de fapt. se numesc variabile finale acele "variabile". 17 si -1453 şi nu mai pot fi ulterior modificate (deci ALPHA şi BETA sunt. deci toate variabilele pe care le conţine să aiba deja valori date anterior. Tipul de date este o mulţime de valori. Variabile finale În limbajul Java. BETA=-1453. este necesar ca expresia să fie calculabilă. sub forma de iniţializare în declaraţia de tip sau sub forma de atribuire. respectiv. Este permis însă ca. dar are in faţă modificatorul final. în limbajul Java numele de variabile încep întotdeauna cu literă mică. Prin convenţie. de fapt. Declaraţia de tip este la fel cu cea pentru variabile obişnuite. care este un cuvânt cheie. după care nu mai poate fi modificată. la descrierea fiecărui tip de date. Ulterior. indicarea valorii variabilei este opţională.

înţelegem regulile după care se scriu valorile datelor respective în programe. Exemplu Fie x o variabilă de tip int. de asemenea. în care a este o variabila. vom prezenta aici operaţia de atribuire şi operatorii relaţionali == şi != care se aplică tuturor tipurilor de date. 37 . Atribuirea este posibilă numai daca valoarea operandului b este de acelasi tip cu variabila a. O proprietate foarte importantă a reprezentării interne a datelor este că aceasta. Vom începe studiul cu tipul de date boolean. după care vom studia tipul char. apoi vom studia tipurile numerice propriu-zise (intregi şi reale). Pentru început. sau dacă se poate converti implicit la acest tip. Operaţia de atribuire Prin operaţia de atribuire se dă (se atribuie) unei variabile o nouă valoare. mulţimea de operaţii şi tipul rezultatului operaţiilor pentu fiecare tip primitiv sunt impuse prin limbaj şi. înţelegem forma sub care datele respective apar în memoria maşinii virtuale Java. fiind destinată maşinii virtuale Java. Expresia a=b. Expresia x=-17 se citeste "se atribuie lui x valoarea -17". Operaţii şi operatori Pentru fiecare tip primitiv de date vom arăta. reprezentarea internă. în acest caz. Aceasta înseamnă că numele. care o înlocuieşte pe cea deja existentă. Celelalte operaţii şi operatorii corespunzători se vor fi prezenta odată cu tipurile de date cărora li se aplică. nu depinde de calculatorul concret pe care se va executa programul. că valoarea anterioară a variabilei x se înlocuieşte în memorie prin noua valoare. deoarece produce modificarea valorii operandului situat în partea stânga a operatorului de atribuire. are semnificaţia "se atribuie variabilei a valoarea operandului b". o tipul char Pentru fiecare tip de date vom arăta reprezentarea externă. int. ca în cazul nostru. tipurile numerice o tipuri intregi: byte. Atribuirea este o operaţie cu efect lateral. deci. operaţiile şi operatorii corespunzători. care însă aici se citeşte "se atribuie") este un operator binar cu efect lateral. short. În partea dreaptă a operatorului de atribuire putea fi nu numai un literal. operaţiile specifice şi operatorii corespunzători. Reprezentarea externă a valorii într-un program se numeşte literal. iar b este un operand care poate fi un literal. nu trebuie definite şi nu pot fi modificate de programator. long. în documente sau pe ecranul calculatorului. o tipuri reale: float si double. mulţimea de valori. ca un tip numeric special. Prin reprezentare internă. ci orice altă expresie cu valoare de tip int. o variabilă sau o expresie.Programarea orientata pe obiecte în limbajul Java Tipurile de date primitive sunt predefinite în limbaj. Operatorul de atribuire este = (semnul egal. Tipurile de date primitive în limbajul Java se clasifică astfel:   tipul boolean. Prin reprezentare externă. Efectul operaţiei de atribuire este.

dacă operanzii au valori egale. în limbajul Java. care se dă variabilei la iniţializare (în momentul când i se alocă spaţiu în memorie). în limbajul Java se obişnuieşte ca numele de sub variabile să înceapă cu literă mică.Severin Bumbaru Operatorii == şi != Pentru toate tipurile de date se pot aplica operatorii relaţionali == si !=. variabile sau expresii. variabilaN. La aplicarea unui astfel de operator. deci fie ambii de tip boolean. valoare_initiala este o valoare de acelaşi tip cu variabila. deci valorile ambilor operanzi rămân neschimbate. Atragem atenţia asupra deosebirilor esenţiale dintre operatorul de atribuire = si operatorul de egalitate ==. indiferent de tipul operanzilor. în care: tip . unde a şi b sunt doi operanzi care pot fi literali. este terminatorul de 38 . declaraţiile de tip au forma: tip variabila1. dacă egalitatea nu este satisfacută. Operatorul != (se citeşte "este diferit de") exprimă relaţia de inegalitate a celor doi operanzi. fie ambii numerici. b/ Operatorul de atribuire = are efect lateral. variabila2. daca este necesar. Cei doi operanzi trebuie sa fie comparabili. numele şi.. iar la sfârşitul declaraţiei se pune simbolul . rezultatul operaţiei este valoarea booleană true (adevărat) sau false (fals). Expresia a==b. sau are valoarea logică true.tipul variabilelor care se declară. Declaraţii de tip Declararaţiile de tip sunt instrucţiuni prin care se specifică tipul. are valoarea logică (booleană) false dacă valoarile celor doi operanzi sunt diferite. în timp ce valoarea expresiei a==b este întotdeauna de tip boolean. Această valoare poate fi dată sub forma unui literal sau a unei expresii calculabile (în care toate variabilele au valori atribuite anterior).numele variabilei sau. unde a şi b sunt doi operanzi care pot fi literali. c/ Valoarea expresiei de atribuire a=b este identică cu valoarea atribuita variabilei a şi are deci tipul acesteia. În limbajul Java. în timp ce în cazul operatorului de egalitate == ambii operanzi pot fi expresii. a/ Operatorul de atribuire = impune ca operandul din partea stangă sa fie o variabilă. dacă este necesar. valoarea iniţială a variabilelor folosite în program. în timp ce operatorul == nu are efect lateral. numele şi valoarea iniţială date forma nume_variabilă = valoare_iniţială nume_variabila este un identificator.. sau are valoarea logică false. variabila. Expresia a!=b. care constă în modificarea valorii variabilei din partea stangă. Aceştia sunt operatori binari fără efect lateral. Remarcăm că specificaţiile variabilelor se separă între ele prin virgule. variabile sau expresii. are valoarea logică (booleana) true dacă valoarile celor doi operanzi sunt egale.. Operatorul == (se citeşte "este egal cu") exprimă relaţia de egalitate. deşi aceasta nu este o regulă de sintaxă. . (punct şi virgulă) care.

compilatorul Java verifică dacă. Această expresie este calculabilă. beta şi gamma sunt de tip int.în cazul operatorului &&. prin care se realizează operaţiile logice ŞI. Limbajul Java este strict tipizat.în care a şi b sunt operanzi de tip boolean. în care a şi b sunt operanzi de tip boolean. iar false înseamnă fals. iar celălalt fals). are valoarea false dacă şi numai dacă ambii operanzi au valoarea false. beta primeşte valoarea iniţială -723.Programarea orientata pe obiecte în limbajul Java instructiune. iar gamma primeşte ca valoare rezultatul calculării expresiei beta+7. altfel. se declară că variabilele alpha. . evaluarea celui de al doilea operand se face numai dacă primul operand are valoarea true. beta=-723. În celelalte cazuri expresia are valoarea false. se citeşte non-a şi se interpretează ca negaţia lui a: daca a are valoarea true. 39 . întrucât beta are deja o valoare. variabila are deja o valoare. are valoarea true dacă şi numai dacă cei doi operanzi au valori diferite (unul este adevărat. false}. Dacă cei doi operanzi au valori identice. Expresiile a|b şi a||b .Operatorul ^ realizează operatia logică SAU-EXCLUSIV. Variabila alpha nu este iniţializată. Expresia !a. în momentul primei ei utilizări într-o expresie. Ea conţine cele două valori admise de logica booleană: true înseamnăadevărat. Deosebirile între operatorii & şi &&. Operatorii logici binari sunt operatori fără efect lateral. are valoarea true(adevărat) dacă şi numai dacă atât a cât şi b au valoarea true. SAU şi SAU-EXCLUSIV. În plus.în cazul operatorilor & şi | se evaluează în mod obligatoriu ambii operanzi. În celelalte cazuri expresia are valoarea true. Exemplu Prin instrucţiunea int alpha. Asupra datelor din acest tip pot fi aplicate operaţiile de atribuire.Operatorii | si || realizează operaţia logică SAU. deci orice variabilă trebuie să fie declarată înainte de a fi folosită. se consideră că operaţia dă valoarea false. Tipul boolean Mulţimea de valori a acestui tip este {true. atunci !a are valoarea false şi invers. Expresia a^b . . fără a se mai evalua valoarea celui de al doilea operand. de comparaţie (== si !=) şi operaţiile algebrei booleene (operaţiile logice). în care a este un operand boolean. gamma=beta+7. . numit ŞI-condiţional. . în care a şi b sunt operanzi de tip boolean. Operatorii booleeni Operatorul de negaţie este un operator unar fără efect lateral şi se reprezintă prin simbolul ! (semnul exclamării). Expresiile a&b şi a&&b . valoarea expresiei este false.Operatorii & si && realizeaza operatia logica ŞI. respectiv între | şi || sunt următoarele: .

r=alpha||beta. System. s=alpha^beta.în cazul operatorului ||.out. a true true false false b true false false false a&b true false false false a&&b true false false false a|b true true false false a||b true true true false a^b false true true false În programul din fişierul TipBoolean. evaluarea celui de al doilea operand se face numai dacă primul operand are valoarea false. Vom reveni asupra acestor deosebiri când vom arăta cum sunt tratate în Java expresiile logice mai complicate. în care a şi b sunt doi operanzi logici. 40 . beta=false. altfel. fără a se mai evalua valoarea celui de al doilea operand.out. numit SAU-condiţional.s. p=!alpha. r. /* Testarea declararii variabilelor booleene si a efectului operatiilor logice */ class TipBoolean { public static void main(String args[]) { boolean alpha=true. System.println("alpha==beta: "+(alpha==beta)). Acţiunea operatorilor logici este prezentată sintetic în tabela de mai jos. System. } } Executând acest program se obţine următorul rezultat afişat pe ecran: alpha=true beta=false p=false q=false r=true s=true alpha&&beta=false alpha||beta=true alpha==beta: false alpha!=beta: true Se observă cu uşurinţă că rezultatele sunt corecte. q=alpha&&beta. se consideră ca operaţia dă valoarea true.Severin Bumbaru .println(" alpha="+alpha+" beta="+beta+" p="+p+ " q="+q+" r="+r+" s="+s). System. p.println("alpha!=beta: "+(alpha!=beta)).java se testează unele din aceste operaţii booleene.println("alpha&&beta="+(alpha&&beta)+ "alpha||beta="+(alpha||beta)).out. q.out.

conversia de tip. operatorii & si | nu sunt consideraţi operatori booleeni ci operatori logici pe biţi. sau poate fi cerută explicit prin program. vom prezenta unele operaţii care se aplică tuturor tipurilor de date numerice: atribuirea. se poate folosi conversia de tip explicită prin operatorul cast. dar nu se converteşte implicit la cel din stânga. Tipuri numerice Sub aspect conceptual.Programarea orientata pe obiecte în limbajul Java Pentru programatorii de C/C++ În limbajele C/C++ nu există tipul de date boolean. Din punct de vedere matematic. însă. în aceste limbaje. tipuri reale (în virgulă mobilă): float şi double. int. deci şi celor numerice. long. împărţire) şi operaţiile de comparaţie aritmetică (mai mic. În consecinţă. În expresia variabilă = expresie daca variabila din partea stângă aparţine unuia din tipurile numerice. aşa cum se întâmplă în C/C++. short. astfel că în locul acestuia se folosesc datele întregi. Dacă tipul operandului din dreapta este numeric. conversia se poate face implicit. mai mare. scădere. egal. Exemple pentru aplicarea acestor operaţii se vor da la studierea diferitelor tipuri concrete de date numerice. datele care aparţin acestor tipuri sunt numere. În acest caz. datele pot fi convertite dintr-un tip în altul. de asemenea. tipul char Inainte de a trece la studierea fiecărui tip de date în parte. Prin tip compatibil înţelegem fie acelaşi tip cu cel al variabilei din stânga. Tipurile de date numerice în Java sunt următoarele:    tipuri întregi: byte. numerică şi să aibă un tip compatibil cu cel al variabilei din partea stângă. atunci valoarea expresiei din partea dreaptă trebuie sa fie. Conversia de tip Dacă este necesar. aceste date pot fi numere întregi sau reale. Existenţa mai multor tipuri în cadrul fiecăreia din aceste două categorii se datoreşte particularităţilor de reprezentare a datelor în memorie. După caz. asupra cărora pot fi aplicate operaţiile aritmetice (adunare. Operaţia de atribuire Operaţia de atribuire se poate aplica tuturor tipurilor de date. diferit de). operatiile ariţmetice şi comparaţia. 41 . În Java nu este permis să se utilizeze expresii aritmetice în locul unor expresii logice (booleene). înmulţire. fie un tip numeric care poate fi convertit implicit la acesta. există pericolul ca valoarea să se altereze prin conversie.

Tipul rezultatului operaţiilor aritmetice depinde de tipul operanzilor şi va fi discutat la fiecare din tipurile numerice în parte. adică este format din numele tipului către care se face conversia. Operaţiile aritmetice Operaţiile aritmetice sunt cele care se aplică unor operanzi numerici. iar b este de tip short sau byte. însă valoarea expresiei (byte)a se obţine din cea a lui a prin convertirea ei la tipul byte. având ca rezultate tot numere. 42 . De exemplu. De exemplu. dacă în expresia a=b variabila a este de tip int. deci care nu modifică valoarea operandului. Utilizarea operatorului cast arată faptul că programatorul doreşte să se faca o anumită conversie. conversia implicită nu este posibilă. în situaţia respectivă. float sau double. În tabela de mai jos sunt indicate cu X toate conversiile de tip care se pot realiza inplicit. După numărul de operanzi. ele pot fi unare sau binare. Conversia de tip explicită se face prin operatorul unar numit cast. iar în capul tabelei (pe prima linie) tipul către care se face conversia. tipul int se poate converti implicit în oricare din tipurile long. În coloana din stânga este tipul datei care este supusa conversiei. valoarea variabilei b va fi automat convertită la tipul int înainte de atribuire. expresia (byte)a se va folosi pentru a converti valoarea operandului a la tipul byte.Severin Bumbaru În limbajul Java. care are forma (tip). Unele operaţii aritmetice unare au şi efect lateral. Nu este însă greşit dacă folosim acest operator chiar şi când conversia respectivă se poate face şi implicit. chiar dacă prin aceasta se poate pierde informaţie. Asupra efectelor pe care care le are conversia explicită vom reveni la prezentarea diferitelor tipuri de date numerice. conversia de tip implicită se face atunci când prin conversie nu se pierde informaţie. byte byte short char int long float short X int X X X long X X X X float X X X X X double X X X X X X De exemplu. cuprins între paranteze. Acesta este un operator fără efect lateral. Aceasta înseamnă că valoarea variabilei a rămâne neschimbată. Utilizarea operatorului cast se justifică atunci când. dar nu şi în tipurile byte sau short.

Operatorul de incrementare ++ are ca efect lateral creşterea cu o unitate a valorii variabileioperand. Acest efect are loc indiferent dacă operatorul este plasat înaintea operandului sau după acesta.are ca efect lateral micşorarea cu o unitate a acestei valori. În schimb. În limbajul Java există următorii operatori aritmetici: Operatori unari fără efect lateral: Operator + - Exemplu de expresie +a -a Valoarea expresiei aceeaşi cu valoarea operandului valoarea operandului cu semn schimbat Operatori unari cu efect lateral Operatorii de incrementare ++ şi decrementare -. operaţia de incrementare sau decremantare are loc înainte de a se stabili valoarea expresiei.deci nu modifică valorile operanzilor . Operator Expresie Operatie Valoarea expresiei + * / % a+b a-b a*b a/b a%b adunare scadere suma valorilor operanzilor diferenta valorilor operanzilor inmultire produsul valorilor operanzilor impartire catul (rezultatul impartirii) primului operand la al doilea modulo restul impartirii intregi a primului operand la al doilea 43 .Programarea orientata pe obiecte în limbajul Java În exemplele de expresii din această secţiune.şi sunt daţi în tabela de mai jos. Daca operatorul este plasat în fata operandului. vom considera că a şi b sunt doi operanzi numerici.au ca operanzi variabile numerice. însă. Efectul operaţiilor este prezentat în tabelul de mai jos. iar operatorul de decrementare -. poziţia operatorului faţă de operand are importanţă la stabilirea valorii expresiei rspective. Operator Expresie Operatie ++ ++ --++a a++ --a a-- Valoarea expresiei Efect lateral a+1 a a-1 a preincrementare postincrementare predecrementare postdecrementare valoarea variabilei a creste cu 1 valoarea variabilei a creste cu 1 valoarea variabilei a scade cu 1 valoarea variabilei a scade cu 1 Operatori binari Operatorii binari nu au efect lateral . valoarea expresiei se stabileşte înainte de a se face incrementarea sau decrementarea. operatorul este plasat dupa operand. dacă.

totodată. încât câtul sa fie un număr întreg (fără extragerea părţii fracţionare (situate dupa virgulă). la fel cu cei de atribuire.valoarea astfel atribuită (3.valoarea astfel calculată se atribuie ca noua valoare a variabilei din partea stânga. Operaţii de atribuire compusă Urmând tradiţia limbajului C. <<=. Expresia x+=y se calculeaza.91.91 (efectul lateral). Operatorii de atribuire compusă sunt următorii: +=. Expresia în variabila op= operand care op este un operator aritmetic binar. şi valoare a expresiei.72 si y=0. /=. este variabila = variabila op operand echivalentă cu expresia şi se evaluează astfel: . %=. |=. 44 . în care se compară două numere.se calculează mai întâi valoarea expresiei (variabila op operand)în care variabila intră cu valoarea sa anterioară. Operatorii prin care se efectuează comparaţia a două numere se numesc operatori relaţionali şi sunt daţi în tabela de mai jos. Aceasta nouaă valoare este. care este 3.19 două variabile de tip double. de exemplu să se compare o valoare de tip byte cu una de tip double sau cu una de tip char. . Exemplu Fie x=3. la fel ca expresia x=x+y. obţinându-se ca rezultat o valoare de tip boolean. în modul următor: .se calculează valoarea expresiei x+y. ^=. Comparaţia Comparaţiile sunt operaţii binare fără efect lateral.Severin Bumbaru Prin împărţire întreagă înţelegem împărţirea făcută astfel.se atribuie variabilei x valoarea 3. în care operaţia de atribuire este combinată cu una din operaţiile aritmetice. >>>=. Operator < <= > >= == != Semnificatie mai mic decât mai mic decât sau egal cu mai mare decât mai mare decât sau egal cu este egal cu este diferit de Operatorii relaţionali se aplică tuturor tipurilor de date numerice. inclusiv celor de tip char. Se observă că fiecare din aceşti operatori are forma op= în care op este un operator aritmetic binar. &=. >>=. . *=. . Se permite ca cei doi operanzi sa fie de tipuri diferite.91) este considerată şi drept valoare a expresiei x+=y. în limbajul Java există şi operatori de atribuire compusă. -=. Constatăm astfel că operatorii de atribuire compusă au efect lateral.

27-1.Programarea orientata pe obiecte în limbajul Java Să consideram. 9223372036854775807] Se observă. De exemplu. Avand în vedere că cu n cifre în baza 2 se pot reprezenta 2n valori. Primul bit al reprezentării interne este interpretat drept semn (0 pentru + si 1 pentru -). deci. se obţin domeniile de valori indicate în tabelul de mai sus. int. în limbajul Java asupra lor se pot aplica toate operaţiile pentru numere întregi. Mulţimile de valori ale tipurilor întregi Tipurile de date întregi propriu-zise sunt date în tabela de mai jos. Menţionăm că valorile logice true şi false sunt cele două valori ale tipului de date boolean Tipuri de date întregi Tipurile de date întregi sunt byte. Dacă valoarea operandului a este mai mică decât cea a operandului b. 264-1. Tipul Lungimea byte short int long 1 octet (8 biţi) 2 octeţi (16 biţi) 4 octeţi (32 biţi) 8 octeţi (64 biţi) Intervalul de valori [-128.. noi vom trata tipul char separat. Totusi. long şi char. datorită particularităţilor pe care le prezintă.. Reprezentarea internă a datelor de tip byte. expresia a<b. short.. Întrucât caracterele se codifică în memoria calculatorului prin numere întregi fără semn. Numerele întregi negative se reprezintă prin complementul la doi al modulului lor. short.. de exemplu. 127] [-32768. prin numere binare care încep cu cifra 0. 215-1. . Numerele întregi pozitive se reprezintă.tipul short: -215 . Conceptual.tipul byte: -27 . că deosebirea dintre diferitele tipuri de date întregi constă în lungimea reprezentării lor interne. Este evident că mulţimea de valori a fiecăruia din aceste tipuri este numai o submulţime a mulţimii numerelor întregi..tipul long: -264 . int şi long sunt numere întregi. ca rezultat se obţine valoarea false (fals). unde a şi b sunt operanzi de tipuri întregi. . cifre. Dacă însă valoarea lui a nu este mai mică decât cea a lui b. care condiţionează şi mulţimea de valori a tipului respectiv. 2147683647] [-9223372036854775808. în sistemul de numeraţie binar. 231-1. 45 . deci. în timp ce tipul char conţine caractere (litere. pentru tipul byte există 28=256 valori.tipul int: -231 . int si long se face sub forma de numere întregi cu semn.. .. short. 32767] [-2147483648. Limitele domeniilor de valori pentru fiecare tip întreg se pot exprima în binar în funcţie de numărul de biţi astfel: . semne de punctuaţie etc).. atunci valoarea acestei expresii este true (adevărat). datele care aparţin tipurilor byte.

Literalii de tip long se deosebesc de cei de tip int prin faptul ca se termină prin litera L sau l. 6. De exemplu. Exemple corecte de literali întregi în sistemul zecimal: . iar numărul -128 prin 10000000. Pentru reprezentarea numerelor negative se foloşeste complementul la 2. după care se adună 1 la valoarea astfel obţinută. care este în sistemul zecimal 27-1. Literali de tip întreg Literalii de tip întreg servesc pentru reprezentarea în program a valorilor numerice de tip întreg şi pot fi clasificaţi astfel:   după tipul de date: literali de tip int şi de tip long după sistemul de numeraţie: literali zecimali. scrise în sistemul de numeraţie octal (cu baza opt) şi care încep cu cifra 0. Amintim că cifrele sistemului octal sunt 0. 4.Severin Bumbaru Sa luăm ca exemplu numerele de tip byte. numarul -108 se va reprezenta astfel: se ia modulul acestuia. Se prefera litera majuscula L. Remarcam că numarul -1 se reprezinta intern pe 8 biţi prin 11111111. Înversând biţii se obtine 10010011. În sistemul zecimal.816 (conţine puncte). literalii întregi sunt şiruri de cifre zecimale care pot fi precedate de semn şi nu conţin în interiorul lor separatori. 5. 3'876'293 (conţine apostrofuri).653. adica 127. octali sau hexazecimali. 108.de tip int: 0 -5 276315 -176426 . care se obtine astfel: se ia modulul numărului respectiv (în binar) şi se inverseaza toti biţii (din 0 în 1 şi invers). Adunând 1 (în binar) la acest număr se obţine 10010100 care este reprezentarea internă a numarului negativ -108 şi are primul bit 1. cum sunt punctul. virgula sau apostroful (care se folosesc de noi în scrierea uzuală a numerelor) şi nu incep cu cifra 0. deoarece litera mică l se poate confunda cu cifra 1. Cel mai mic numar pozitiv este. iar cel mai mare numar pozitiv este01111111. 7. Nu există in limbajul Java literali de tip byte sau short. care se reprezinta în binar pe 8 biţi sub forma 01101100. 2. în acest caz. 5. 46 . 00000000 (deci 0 extins pe toţi cei 8 biţi). 3. literalii întregi sunt numere cu sau fără semn. care se reprezintă intern pe o lungime de 8 biţi.187 (conţine virgula). 1.de tip long: 0L -5L 3567286542987L Exemple de literali întregi scrişi greşit: 27. În sistemul octal. 069354 -084931 (încep cu cifra 0).

În mod corespunzător. scrise în sistemul de numeraţie hexazecimal (cu baza 16) şi care încep cu prefixul 0x. această conversie se poate face implicit. din binar în octal. se grupează biţii câte patru de la dreapta la stânga şi se înlocuieşte fiecare grup prin cifra hexazecimală corespunzătoare. E. eliminându-se octeţii din stânga care depăşesc noua lungime. la conversia de la o lungime mai mare la una mai mică. Exemplu Să considerăm urmatoarea aplicaţie din fişierul CastInt. iar fiecare cifră fexazecimală prin patru biţi. 3. după care se înlocuieşte fiecare grup de trei biţi prin valoarea corespunzătoare în octal. În schimb. operaţii de deplasare binară. la conversia din binar în hexazecimal. B. De exemplu. Conversia de tip şi atribuirea Diferitele tipuri de date întregi diferă între ele prin lungimea reprezentării lor interne. literalii întregi sunt numere cu sau fără semn. de comparaţie. programatorul trebuie să-şi asume raăspunderea folosind operatorul cast. operaţii logice pe biţi şi operaţii de atribuire compusă. Amintim că cifrele sistemului hexazecimal sunt: 0. se reţin numai octeţii situaţi în partea dreaptă a numărului. se grupează cifrele numarului binar câte trei de la dreapta la stânga. /* Verificarea actiunii operatorului (cast) in cazul numerelor intregi */ class CastInt { 47 . 1. conversia din aceste sisteme de numeraţie în binar pentru numerele pozitive se face simplu: fiecare cifra octală se reprezintă în binar prin trei biţi. operaţii aritmetice. 2. de conversie de tip. Operaţii şi operatori pentru date de tip întreg Asupra datelor de tip întreg se pot aplica operaţii de atribuire. 9. Din această cauză. Primele trei au fost discutate anterior şi vom indica aici numai unele particularităţi ale aplicării lor în cazul datelor de tipuri întregi.Programarea orientata pe obiecte în limbajul Java Exemple de literali corecţi în sistemul octal: 016724 -04507 În sistemul hexazecimal. Din această cauză. 6. 8. numărul octal 15132 (corespunzător literalului 015132) se va reprezenta în binar prin 001101001011010. iar numărul hexazecimal 6ac3 (corespunzator literalului 0x6ac3) se converteşte în binar prin 0110101011000011. În locul majusculelor se pot folosi şi minusculele corespunzătoare. A. F. Prin aceasta este posibil să se modifice valoarea numărului şi chiar semnul lui. Exemple de literali corecţi în sistemul hexazecimal: 0x37B2E -0x2ab7f3 Sistemele octal şi hexazecimal prezintă avantajul că au ca baze puteri ale lui 2. C. La conversia inversă. 4. la efectuarea unor astfel de conversii. De exemplu.java. numărul binar 0110110010110011 corespunde numerelor 066263 în octal şi 6cb3 in hexazecimal. D. La convertirea unui tip mai scurt în unul mai lung (de exemplu a unui byte sau short în int) valoarea numărului rămâne neschimbată. 5. 7. Din această cauză.

obţinându-se reprezentarea internă 11111111111111111111111110010101. b1 se reprezinta intern prin octetul 01001001. /* Afisarea rezultatelor */ System. /* Atribuiri care necesita conversie explicita de la int la byte */ b3=(byte)i1. b3. b4. b4=(byte)i2. luând în consideraţie reprezentările interne. i2=-103. dar reprezentat pe 4 octeţi. . 48 . Pentru cei interesaţi. deşi conversia s-a făcut prin (cast) de la lungimea de 4 octeţi la cea de 1 octet. b5. deşi în instrucţiunea b5=(byte)i3 variabila i3 are valoarea 22195. putem urmări cum s-au facut efectiv aceste conversii. . i5. Intrucât primul bit este 1. i5=b2. astfel că nu s-au alterat valorile. b2=-107. /* Atribuiri cu conversie implicita de la byte la int */ i4=b1. int i1=91. deoarece 22195 nu se încadrează în mulţimea de valori a tipului byte.valorile variabilelor b3 şi b4 au fost atribuite corect. a/ Atribuirea i4=b1 unde b1 are valoarea 73.Severin Bumbaru public static void main(String args[]) { /* Declararea si initializarea variabilelor */ byte b1=73. Prin conversie s-au modificat deci atât valoarea. obţinându-se tot numărul -107. b/ Atribuirea i5=b2 unde b2 are valoarea negativă -107. } } Compilând şi rulând pe calculator această aplicaţie obţinem următorul rezultat afişat pe ecran: i4=73 i5=-107 b3=91 b4=-103 b5=-77 Analizând aceste rezultate.out. i3=22195.valorile variabilelor i3 şi i4 au fost atribuite corect. cât şi semnul. b5=(byte)i3.în cazul variabilei b5 s-a atribuit valoarea -77. Când se face conversia de la byte la int se extinde aceasta reprezentare externa prin adaugarea la stânga a trei octeţi nuli. Explicaţia este că valorile atribuite se încadrau în intervalul de valori permise pentru tipul byte. i4.println("i4="+i4+" i5="+i5+"\nb3="+b3+" b4="+b4+ " b5="+b5). Se obţine astfel numărul de tip int 00000000000000000000000001001001 care este valoarea 73 pe 4 octeţi. b2 se reprezintă intern prin octetul 10010101 (folosind codul complementar pentru numere negative). când se face conversia de la byte la int se adaugă la stânga trei octeţi completaţi în întregime cu cifra 1. În acest fel s-a conservat semnul. constatăm că: . deoarece conversia s-a făcut de la lungimea de un octet la cea de 4 octeţi.

deci. Prin conversia de la int la byte se elimină cei trei octeţi din stânga. atunci rezultatul este de tip long. rezultatul este de tip int. Prin conversie la tipul byte se elimină cei trei octeţi din stânga. atunci când se face o operaţie de împărţire (/) între două numere întregi. În acest caz. Vom prezenta aici numai unele particularităţi ale operaţiilor aritmetice cu numere întregi şi vom da exemple. 49 . Operaţii aritmetice cu numere întregi Asupra datelor de tip întreg se pot aplica toţi operatorii aritmetici prezentaţi anterior. al doilea operand (împărţitorul) să fie egal cu zero. d/ Atribuirea b4=(byte)i2 unde i2 are valoarea negativă -103. Prin conversie la tipul byte se elimina cei trei octeţi din stânga. cât şi semnul. iar la eliminarea celor trei octeţi din partea stangă s-au pierdut cifre semnificative. în operatia de împarţire întreagă. după caz). Remarcăm. care face parte din clasa ArithmeticException. numai partea întreagă a câtului. dar reprezentat pe un singur octet. Reprezentarea internă a lui i1 este 00000000000000000000000001011011 şi se extinde pe 4 octeţi. aceasta se interpreteaza ca valoarea negativă -77. Excepţia de împărţire la zero Este posibil ca. Aceasta s-a întâmplat întrucât valoarea de la care a pornit conversia nu se încadra în mulţimea de valori a tipului byte. La împărţire se calculează. Tipul rezultatului operaţiilor aritmetice cu numere întregi se stabileste astfel: a/ în cazul operaţiilor de incrementare (++) şi decrementare (--) tipul rezultatului este acelaşi cu tipul operandului. deci. se testează o astfel de situaţie. În programul de mai jos. dacă cel puţin unul din operanzi este de tip long. Deoarece începe cu bitul 1. b/ pentru toate celelalte operaţii. Întrucât s-au eliminat numai zerouri din stânga. e/ Atribuirea b5=(byte)i3.java. din fişierul ImpartireZero. Reprezentarea internă a lui i2 este 11111111111111111111111110011001 fiind complementul lui 103 extins pe 4 octeţi. Împarţirea întreagă O consecinţă a modului de stabilire a rezultatului operaţiilor aritmetice este că. Constatăm astfel că prin conversie s-au modificat atât valoarea. obţinându-se reprezentarea pe un octet 01011011. altfel. maşina virtuală Java generează o excepţie de împărţire la zero.Programarea orientata pe obiecte în limbajul Java c/ Atribuirea b3=(byte)i1 unde i1 are valoarea 91. că singurele operaţii aritmetice care pot da rezultat de tip byte sau short sunt cele de incrementare sau decrementare. Reprezentarea internă a lui i3 pe patru octeti este 00000000000000000101011010110011. obţinându-se 10011001 care este tot numărul -103. valoarea a rămas neschimbată. rezultatul este un numar întreg (de tip int sau long. unde i3 are valoarea 22195. reţinându-se octetul 10110011 care se atribuie ca valoare a lui b5.

main(ImpartireZero. maşina virtuală Java testează numai împărţitorul. apariţia depăşirii binare nu este considerată o excepţie. dacă repetăm compilarea şi execuţia. c=0.println(a/b). ci calculul continuă. int i1=900000. atâţi cât corespund reprezentării interne a tipului de date respectiv (4 octeţi pentru int şi 8 octeţi pentru long). b4. Se poate constata cu uşurinţă că. la depistarea excepţiei de împărţire la zero. } } Se observă că în expresia a/b opeandul b are valoarea zero. Aşa dar. i3. Înlocuind în acest fişier operaţia a/b prin c/b (astfel încât ambii operanzi sunt nuli) caonstatăm că. m3.java se fac unele teste privind operaţiile cu numere întregi. Depăşirea binară La efectuarea unor operaţii cu numere întregi este posibil ca rezultatul să fie un numar binar mai lung decât spaţiul alocat în memorie pentru tipul de date respectiv. la fel ca în cazul conversiei de la un tip cu lungime mai mare la unul cu lungime mai mică. b5. deci. modificarea valorii şi chiar a semnului rezultatului. obţinem aceeaşi excepţie. La executarea acestui program se afişeaza pe ecran următorul mesaj: Exception in thread "main" java. excepţia constă în împărţire (/) la zero şi a apărut în metoda main a clasei ImpartireZero.java:6) Acest mesaj se interpretează astfel: s-a produs o excepţie din clasa ArithmeticException în firul de execuţie "main".Severin Bumbaru /* Testarea exceptiei de impartire la zero */ class ImpartireZero { public static void main(String args[]) { int a=5. m2=-200000000000L. 50 . i2=-1100000. nu şi deîmpărţitul. m4. De exemplu. long m1=10000000000L. b=0. În limbajul Java. System.java linia 6. b2=-109.ArithmeticException: / by zero at ImpartireZero. s3.out. În consecinţa se pierd octeţii cei mai semnificativi şi are loc. i5. O astfel de situaţie se numeşte depăşire binară. i4. Exemplu În următoarea aplicaţie din fişierul Intregi. fiind localizată în fişierul sursă ImpartireZero. short s1=9000. dacă se înmulţesc două numere de tip int (reprezentate pe 32 biţi fiecare). s2=-11000. dar se reţin numai octeţii din dreapta ai rezultatului. într-adevar. rezultatul poate fi un numar mai lung de 32 biţi.lang. class Intregi { public static void main(String args[]) { byte b1=73. b3. deci a cărui valoare nu se mai încadrează în mulţimea de date a tipului int. operaţia care a produs excepţia se găseşte în locul indicat. b3=(byte)(-b2).

. deoarece expresia ++b este de tip byte. Cauza este că valoarea depăşeşte marginea superioară a valorilor de tip int. deci rezultatul este întreg (împărţire întreagă). În schimb. deoarece expresia m2/m1 este de tipul long. în care se compară diferite numere întregi şi se 51 .. m3=m2-m1.out.java se da un program. deoarece valorile expresiilor din paranteze din partea dreaptă a operandului de atribuire sunt de tip int. Din acelaşi motiv s-a obţinut i5=-222222 si nu -222222.println("m3="+m3+" m4="+m4). Se poate constata cu usurinţă.out. System. nu a fost necesar să se recurgă la cast la calcularea valorii lui b5. s4=(short)(s2%s1). suprimând din program operatorii cast din expresiile respective. în fişierul ComparInt. Comparaţia Operatorii de comparaţie pot fi aplicaţi pentru orice fel de operanzi numerici.println("i3="+i3+" i4="+i4+" i5="+i5). ci valoarea 2137445376. i5=(int)(m2/i1). Tot o depăşire binară s-a produs şi la calcularea lui m4 (de data aceasta pentru tipul long).out.println("b3="+b3+" b4="+b4+" b5="+b5). În mod similar s-a folosit castul la calcularea lui i5.valorile produselor b5*b2 şi s1*s2 au fost calculate şi afisate corect.222222. s3=(short)(s2/s1)... respectiv de tip short.println("b5*b2="+(b5*b2)+ "s1*s2="+(s1*s2)). Executând acest program. în timp ce variabilele din partea stânga sunt de tip byte sau short. } } Remarcăm că la calcularea valorilor variabilelor b3.. că dacă nu se folosesc aceşti operatori sunt semnalate erori de compilare. System. deci s-a produs o depăşire binară şi s-au trunchiat octeţii cei mai semnificativi.println("s3="+s3+" s4="+s4). m4=m2*m1. i4=i1*i2. Aceasta s-a produs deoarece expresiile respective sunt de tip int. System.la calcularea lui i4 nu s-a obţinut valoarea corectă -990000000000. // restul impartirii s2/s1 i3=i1+i2. System. b5=++b1.Programarea orientata pe obiecte în limbajul Java b4=(byte)(b1+b2). b4 şi s3 a fost necesar să se folosească conversia explicită (cast)..out.s-a obţinut s3=-1 si nu s3=-1. . Ca exemplu.222222. se obţin pe ecran următoarele rezultate: b3=109 b4=-36 b5=74 s3=-1 s4=-2000 i3=-200000 i4=2137445376 i5=-222222 m3=-210000000000 m4=-7751640039368425472 b5*b2=-8066 s1*s2=-99000000 Din aceste rezultate constatăm că: . deoarece în expresia s2/s1 ambii operanzi sunt de tipuri întregi.out. deşi ele depăşesc limitele mulţimilor de valori de tip byte. System. .

System.out. System. i3=-12970. i2=48. b2=-17. System.out. s2=-12970.println(s2<i3).out. long m1=876432906528L.println(b1==b2).out. int i1=762983.println(b1==i2). /* Testarea operatorilor de comparatie in cazul tipurilor de date intregi */ class ComparInt { public static void main(String args[]) { byte b1=48. System.println(i2!=m2). System. short s1=2765.println(s1!=i2). m2=48.out. } } Executând acest program se obţin pe ecran următoarele rezultate sub forma de valori booleene: false true true talse true talse true 52 .out.out.println(m2>=i2).Severin Bumbaru afişează rezultatele. System. System.println(m2>i2).println(i3<=s2). System.out.

out. int i1=1024. Deplasarea biţilor la dreapta cu s pozitii cu operatorul >>> are asupra numerelor pozitive acelaşi efect ca cel al operatorului >>. În schimb. iar false înseamnă fals. Operaţii de deplasare binară Urmând "tradiţia" limbajului C. System. Remarcăm. /* Testarea operatiilor de deplasare binara */ class Deplasari { public static void main(String args[]) { byte b1=15. în cazul operatorului >>> nu se mai conservă semnul. Operator Expresie Efect << >> >>> a<<s a>>s a>>>s deplasare la stânga cu s poziţii binare deplasare la dreapta cu s poziţii binare.println("i1<<4="+(i1<<4)+" i1>>4="+(i1>>4)+ " i1>>>4="+(i1>>>4)). în care a şi s sunt operanzi care aparţin unor tipuri întregi. Deplasarea la dreapta cu s poziţii cu operatorul >> este echivalenta cu împărţirea întreagă la 2s. i2=-1024. Tipul rezultatului operaţiei se stabileşte la fel ca în cazul operaţiilor aritmetice cu numere întregi. nu şi de tipul acestora. Exemplu În fişierul Deplasari. Valoarea rezultată se stabileşte astfel: se ia reprezentarea internă a primului operand şi se deplasează la stânga sau la dreapta cu un numar de poziţii binare egal cu cel de al doilea operand.java se dă un exemplu de aplicaţie. că rezultatul comparaţiei depinde numai de valorile numerelor comparate. cu conservarea semnului deplasare la dreapta fără semn. în cazul operanzilor negativi.Programarea orientata pe obiecte în limbajul Java Având în vedere că true înseamnă adevărat. b2=(byte)(b1<<3). se poate constata cu uşurinta că aceste rezultate sunt corecte. Dacă s este suficient de mare. iar modulul numărului se modifică. System.println("b1="+b1+" b2="+b2). 53 .out. Aceştia sunt operatori binari (cu doi operanzi) fără efect lateral. Aceasta se întâmplă. întrucât pe poziţiile eliberate din partea stângă se înserează bitul 0. poate avea loc o depăşire binară. în care se testează acţiunea operatorilor de deplasare binară. cu s poziţii binare Deplasarea la stânga cu s poziţii este echivalenta cu înmulţirea numărului cu 2s. la fel ca în cazul înmulţirii aritmetice (cu operatorul *). limbajul Java conţine şi operatori de deplasare binară. Operatorii de deplasare şi efectele lor sunt prezentate în tabela de mai jos. de asemenea. b2.

în limbajul Java se pot utiliza pentru tipurile de date 54 .pentru operaţia i1<<4: 00000000000000000100000000000000 .Severin Bumbaru System.out. rezultatele obţinute pot fi verificate cu uşurinţă. După aplicarea operatorului >>> (deplasare la dreapta fără conservarea semnului) se obţine: . -26=-64. respectiv. reprezentările interne ale operanzilor i1 şi i2 sunt următoarele: i1=00000000000000000000010000000000 i2=11111111111111111111110000000000 După aplicarea operatorului << (deplasare binară la stânga cu inserare de zerouri pe spaţiile libere din dreapta) obţinem: .pentru operaţia i2>>4: 11111111111111111111111111000000 ceeace reprezintă în sistemul zecimal numerele 26=64 şi.println("i2<<4="+(i2<<4)+" i2>>4="+(i2>>4)+ " i2>>>4="+(i2>>>4)). să urmărim ce se întâmplă în exemplul de mai sus la nivelul reprezentării interne a datelor (în binar). Operaţii logice pe biţi Tot urmând "tradiţia" limbajelor C/C++. Operatorul >>> nu există în limbajul C. Pentru a inţelege mai bine efectul operatorilor de deplasare. el fiind introdus numai în Java.pentru operaţia i1>>4: 00000000000000000000000001000000 . Remarcăm că în cazul operandului negativ i2. la deplasarea la dreapta s-a înserat pe poziţiile libere bitul 1 pentru a se conserva semnul.pentru operaţia i2<<4: 11111111111111111100000000000000 ceeace reprezintă în zecimal numerele 214=16384 si. -214=-16384. Constatăm ca singura deosebire dintre efectele operatorilor >> şi >>> apare când primul operand este negativ. în cazul operandului negativ i2. După aplicarea operatorului >> (deplasare la dreapta cu conservarea semnului) se obţine: .pentru operaţia i2>>>4: 00001111111111111111111111000000 Pentru operandul pozitiv i1 s-a obţinut un rezultat identic cu cel precedent. pe poziţiile eliberate din partea stângă s-a înserat bitul 0. respectiv. Având în vedere că 1024=210. ceeace a dus la schimbarea semnului şi a valorii rezultatului faţă de cazul deplăsarii cu conservarea semnului.pentru operaţia i1>>>4: 00000000000000000000000001000000 . } } Rezultatele afişate la executarea acestui program sunt următoarele: b1=15 b2=120 i1<<4=16384 i1>>4=64 i1>>>4=64 i2<<4=-16384 i2>>4=-64 i2>>>4=268435392 Având în vedere că 23=8 şi 24=16. În schimb.

&. Aceasta se poate constata cu usurinţa dacă încercăm să eliminăm castul din instrucţiunea în care se calculează b3. adică între fiecare bit al operandului din stânga şi bitul corespunzător al operandului din dreapta. deci înlocuirea lui 0 cu 1 şi invers.Programarea orientata pe obiecte în limbajul Java întregi şi operatorii logici pe biţi ~.java este dat un exemplu de program. Acţiunea operatorilor este dată în tabela de mai jos. Pentru a se verifica manual mai uşor. Operatorul unar ~ exprimă negaţia logică. Operaţiile logice se fac la nivel de bit. în care a şi b sunt cei doi operanzi. am considerat că opraţiile se fac asupra datelor de tip byte. Operatorii binari &. // este necesara conversie de la int la byte System. numai că se aplică la nivel de bit. b2=-95. iar 1 este echivalent cu true. în care se testează operaţiile logice pe biţi.println("~b1="+(~b1)+" b1&b2="+b3+" b1|b2="+(b1|b2)+ " b1^b2="+(b1^b2)). ai 0 0 1 1 bi 0 1 0 1 ~a 1 1 0 0 a&b 0 0 0 1 a|b 0 1 1 1 a^b 0 1 1 0 Exemplu În fişierul LogicaBiti. | si ^. În tabelă se dă efectul fiecărei operaţii asupra bitului i al rezultatului. } } Rezultatele afişate la executarea acestui program sunt următoarele: ~b1=-18 b1&b2=1 b1|b2=-79 b1^b2=-80 Iată şi cum decurg operaţiile din exemplul de mai sus la nivel de bit: b1: 00010001 b2: 10100001 ~b1: 11101110 echivalent cu 17 echivalent cu -95 echivalent cu -18 55 . iar ai si bisunt biţii de pe pozitia i a acestor operanzi. b3=(byte)(b1&b2). Este bine să avem însă in vedere că rezultatele operaţiilor sunt de tip int. /* Testarea operatiilor logice pe biti */ class LogicaBiti { public static void main(String args[]) { byte b1=17. Aceştia sunt operatori fără efect lateral. considerându-se ca 0 este echivalent cu false.out. | si ^ acţionează la fel ca în cazul tipului boolean. b3.

Severin Bumbaru echivalent cu 1 echivalent cu -79 echibalent cu -80 Bineînţeles că toate aceste rezultate ar trebui exprimate pe 32 biţi.println(m+" "+(m+=b)+" "+m).valoarea variabilei m înainte de evaluarea expresiei m+=b.out.println(b+" "+(b<<=2)+" "+b). prin prelungire la stânga cu cate 18 cifre de 0 sau de 1 după caz. %=.println((m/=d)+" "+m). -=. Recomandăm sa explicaţi în mod similar şi celelalte linii afişate. . |=. System. >>=. *=. .out. ^=. b1&b2: 00000001 b1|b2: 10110001 b1^b2: 10110000 Aplicarea operatorilor de atribuire compusă Pentru operanzii de tipuri întregi se pot aplica toţi operatorii de atribuire compusă +=. System.valoarea variabilei m după calcularea acestei expresii.println(c+" "+(c|=b)+" "+c). System.out. d=-28. /=.out. <<=. Exemplu În programul din fişierul AtribComp.valoarea expresiei m+=b. b=-15. } } La executarea programului se obţin pe ecran următoarele rezultate: 176 161 161 -5 -5 -15 -60 -60 16 -44 -44 Prima linie afişată conţine: . astfel încât să se conserve semnul. System. &=.java se testează unele operaţii de atribuire compusă. Iată acest program: /* Testarea operatorilor de atribuire compusa */ class AtribComp { public static void main(String args[]) { int m=176. >>=. ea este egală cu m+b adică cu 176-15. 56 . c=16.

Cifrele semnificative sunt cifrele mantisei numărului. 0. format din litera e sau E urmata de un numar intreg. În limbajul Java există două tipuri de date reale (numite şi tipuri de date flotante sau în virgulă mobilă): Tipul float double Lungimea Intervalul de valori 4 octeti (32 biti) [-3. Menţionăm că numerele de mai sus.23015E1. De exemplu.3015f. în care un număr întreg sau unul real fără exponent.7976931348623157e+308. care încep de la prima cifră diferită de zero şi se termină cu ultima cifra diferita de zero.402347e38f] 8 octeti (64 biti) [-1. 1.3015. Acelaşi număr poate avea diferite reprezentări externe. Aceasta depinde de numărul de biţi alocaţi mantisei în reprezentarea internă. 10.402347e+38f..Programarea orientata pe obiecte în limbajul Java Tipuri de date în virgulă mobilă Mulţimile de valori pentru tipurile de date în virgulă mobilă Conceptual. dar cele care depăşesc lungimea admisă nu vor fi luate în consideraţie la conversia din forma externă în cea internă. este urmat de un exponent zecimal. 0. b/ ca numere reale cu exponent..023015E2. deşi au numai 7 cifre semnificative. pentru datele în virgulă mobilă sunt prevăzute şi următoarele valori speciale: 57 . numit mantisa sau coeficient. vor fi reprezentate intern ca numere de tip double.1023015E3. numărul 000102. iar cele de tip double cel mult 16 cifre semnificative. datele de tip float pot avea cel mult 7 cifre semnificative. O caracteristică importantă a numerelor în virgulă mobilă este precizia. În reprezentarea externă a numărului se pot folosi şi mai multe cifre. 3. Pentru toate aceste numere. de exemplu: 102.01023015E4 etc. În afară de valorile numerice. Pentru a fi reprezentate intern ca date de tip float (pe 4 octeti) trebuie scrise cu litera f sau F la sfârşit. În cazul limbajului Java.7976931348623157e308] Reprezentarea internă a datelor în virgulă mobilă adoptată pentru maşina virtuală Java corespunde standardului ANSI/IEEE 754-1985. Se numeşte precizie numărul maxim de cifre semnificative pe care îl poate avea mantisa pentru tipul de date respectiv. .3015000 are 7 cifre semnificative (cele subliniate). deci pe 8 octeţi fiecare. Semnificaţia este că mantisa se înmulteşte cu 10 ridicat la o putere egală cu exponentul. deoarece zerourile de la început şi de la sfârşit nu influenţează valoarea numărului.. de exemplu 102. datele care aparţin acestor tipuri sunt numere reale. 1. în care partea întreagă este separată de cea fracţionara prin punct. Reprezentarea externă a numerelor în virgulă mobilă se poate face în următoarele moduri: a/ ca numere reale fără exponent. . reprezentarea internă va fi aceeaşi..

-3401.0x1023) Atât la tipul float. nu putem face atribuirea x=Infinity.0 cât şi -0. aceste valori sunt scrise sub forma +0.9104x10 ) c/ literali de tip double fără exponent: 154236789. conform căreia. Operaţia 0. sub forma unui şir de 4 sau 8 octeţi. Exemple de literali în virgulă mobilă a/ literali de tip float fără exponent: 123.075428x10 ) 3 -3. Operaţii şi operatori pentru date în virgulă mobilă Asupra datelor în virgulă mobilă se pot aplica operaţii de atribuire. -Infinity şi NaN sunt formele externe sub care acestea se afişează pe ecran. ci doar forme externe de afişare a valorilor interne corespunzătoare.0f şi -0. iar operaţia a/(-0.0 dă rezultatul NaN. reprezintă ceva care nu este număr (Nota Number). De exemplu.9104e3f (echivalent cu -3. ele nu pot fi folosite în programele sursă.87628091e-12 -1. operaţia a/0.0.28765e12f (echivalent cu 7. corespunde valorii minus infinit. valoarea 0. Un 0 fără semn este echivalent cu +0.0f. -1876. daca x este o variabilă în virgulă mobilă. dacă sunt interpretate ca numere în virgulă mobilă. în timp ce literalii de tip double nu au un astfel de sufix. -Infinity şi NaN nu sunt literali. Atenţie: valorile Infinity. În consecinţă. Valorile speciale Infinity. operaţii aritmetice şi de comparaţie. Aceste reprezentări interne respectă regula. se tipăresc la imprimantă sau se scriu într-un fişier de text. d/ literali de tip double cu exponent: 2935.0. -Infinity este mai mică decât orice valoare de tipul respectiv.0754286e-8f (echivalent cu 5. de conversie de tip.0) da rezultatul -Infinity. În acest fel. 58 . Pentru tipul float. În consecinţă.28765x1012) -8 5.7f.76398653.53f.20937543872E23 12e23 (echivalent cu 12. în cazul datelor de tipuri reale.Severin Bumbaru corespunde valorii plus infinit. Infinity -Infinity NaN - Literalii în virgulă mobilă Literalii în virgulă mobilă sunt reprezentările valorilor reale în programele Java.0 dă ca rezultat Infinity. valorile menţionate păstrează consistenţa operaţiilor de comparaţie. îndeplinesc următoarele condiţii: Infinity este mai mare decat orice valoare de tipul respectiv. dacă a este un numar real pozitiv. b/ literali de tip float cu exponent: 7.0 are semn: poate exista atât +0. cu precizarea ca literalii de tip float se termina cu litera f sau F. corespunzător tipului float sau double. La scrierea literalilor se respectă formele externe de numere reale fără exponent sau cu exponent prezentate mai sus.0/0. Fiecăreia dintre ele îi corespunde o reprezentare internă.20973. Acestea au fost deja prezentate. atribuirea compusă. cât şi la tipul double.

System. are loc conversie implicită de la float la double. d=-0.java. În consecinţă.Programarea orientata pe obiecte în limbajul Java astfel că vom indica aici numai unele particularităţi ale aplicării lor în cazul datelor în virgulă mobilă. Amintim că la numerele în virgulă mobilă în Java şi valoarea zero are semn. r=0.out. folosirea conversiei explicite (cast) este necesară atunci când se trece de la double la float.println("a/c="+(a/c)+" b/c="+(b/c)).0.0f. System. ci numai la pierderea de precizie. conversia explicită de la date în virgulă mobilă la oricare din datele de tip întreg poate duce la denaturarea valorii şi a semnului numărului. decrementare (--) şi restul împărţirii întregi (%). Conversia de tip şi atribuirea S-a arătat deja ca orice dată numerică de tip întreg se poate converti implicit în oricare din tipurile în virgulă mobilă. c=0. întrucat se trece de la o mantisă de 52 de biţi la una de 24 biţi . Aceasta se produce. rezultatul împărţirii este Infinity cu un semn care se stabileşte după semnele celor doi operanzi: + (plus) dacă au acelaşi semn. 59 . b=-158. De asemenea. O particularitate importantă a operaţiilor aritmetice în virgulă mobilă în limbajul Java este că împărţirea la zero nu mai este considerată o exceptie. q=0. deci de la cca 17 cifre semnificative la numai cca 7 cifre semnificative în sistemul zecimal.0. se testează diferite operaţii aritmetice în virgulă mobilă. System. ci este o operaţie permisă. Unei variabile în virgulă mobilă i se pot atribui orice valori de tipuri numerice. s=-0.println("a/b="+(a/b)+" b/a="+(b/a)+" b%a="+(b%a)).15f. la fel ca în cazul tipurilor intregi. În schimb. inclusiv cele care au ca rezultate valori speciale. Conversia din double în float nu conduce niciodata la alterarea valorii.println("a/d="+(a/d)+" b/d="+(b/d)). Rezultatul împărţirii la zero depinde de valoarea deîmpărţitului şi de semnele celor doi operanzi. pe care îl reproducem mai jos. inclusiv operatorii de incrementare (++). Rezultatul împărţirii 0/0 este NaN (Not a Number. inf1. inf2.7865. deci există +0.0. Exemplu În programul din fişierul VirgulaMobila. float p=3476. n. sau de la un tip în virgulă mobilă la unul întreg. Aceasta se întâmplă atunci când valoarea care trebuie convertită nu se încadrează în mulţimea de valori specifică tipului în care se face conversia.(minus)dacă semnele operanzilor sunt diferite.out.00237621f. sau .0 si -0. deci o valoare nedefinită). /* Testarea operatiilor aritmetice cu numere in virgula mobila */ class VirgulaMobila { public static void main(String args[]) { double a=12.07.out. Dacă deîmpărţitul este diferit de zero. Vom prezenta aici numai unele particularităţi ale operaţiilor aritmetice în virgulă mobilă şi vom da exemple.0f. Operaţii aritmetice cu numere reale Asupra datelor în virgulă mobilă se pot aplica toţi operatorii aritmetici prezentaţi anterior.

in care [b/a] este partea intreagă a câtului b/a. %=. *=.println("a/inf1="+(a/inf1)+" a/inf2="+(a/inf2)).out. n=c/d.out. dacă ambii operanzi sunt în simplă precizie (float).0 inf1/inf2=NaN inf2/inf1=NaN a*inf1=Infinity c*inf1=NaN Din aceste rezultate constatăm că: .println("p/q="+(p/q)+" q/p="+(q/p)+" p%q="+(p%q)).println("a/q="+(a/q)+" p/b="+(p/b)).835752E-7 p%q=0.println("c/d="+(c/d)+" d/c="+(d/c)).048097062204 p/b=-21. inf1=a/c.out. System.out. iar b%a este restul împărţirii întregi a lui b la a. rezultatul este float. iar 0/0. .println("a*inf1="+(a*inf1)+" c*inf1="+(c*inf1)).001879394 p/r=Infinity p/s=-Infinity a/q=5381. System.Severin Bumbaru System.0 a/inf2=-0. 60 . rezultatul este în dublă precizie. infinit impartit la infinit şi zero înmulţit cu infinit sunt nedeterminări).631999999999991 a/c=Infinity b/c=-Infinity a/d=-Infinity b/d=Infinity c/d=NaN d/c=NaN p/q=1462896.se verifică egalitatea [b/a]*a+(b%a)=b.operaţiile cu infiniţi şi nedeterminări respectă regulile cunoscute din matematică (împărţirea la zero dă rezultat infinit. System.out. System. inf2=a/d. /=. . System. System.println("inf1/inf2="+(inf1/inf2)+" inf2/inf1="+ (inf2/inf1)).632=158. -=.991205809728285 a/inf1=0.out.println("p/r="+(p/r)+" p/s="+(p/s)). } } La executarea acestui program se afişează următorul rezultat: a/b=-0. de exemplu.7865-4.out. Atribuirea compusă În cazul tipurilor de date reale se aplică următorii operatori de atribuire compusă:+=.07. (-12)*12.dacă cel puţin un operand este în dublă precizie (double).08089137723793256 b/a=-12. Comparaţia Pentru datele in virgula mobilă se aplică aceiaşi operatori de comparatie (relaţionali) ca şi pentru numerele întregi.362257068001407 b%a=-4.8 q/p=6.

codul numeric al caracterului (format din patru cifre hexazecimale) este precedat de \u. etc. deci prin numere întregi fără semn în intervalul [0.Programarea orientata pe obiecte în limbajul Java Tipul char Tipul de date char Datele de tip char sunt caractere. Peste tot unde întâlneşte în textul sursă caracterul \ (bara inversă. CR) ghilimele (double quote) apostrof (single quote) bară inversă (backslash) '\u0009' '\u000a' '\u000c' '\u000d' '\u0022' '\u0027' '\u005c' Datele de tip char pot fi folosite în operaţii numerice. caracterele pot fi reprezentate şi în alte coduri. '3'. In acest sistem. în care caz ele sunt interpretate drept numere intregi fără semn. etc. semne de punctuaţie. secvenţele escape pot fi folosite pentru a reprezenta caracterele în orice loc din textul sursa. În limbajul Java. conform cu reprezentarea lor internă prin numere binare. 65535]. b/ folosind o secvenţă escape. reprezentarea internă a caracterelor se face pe 2 octeţi (16 biţi). c/ folosind o secventa escape pentru caracterele speciale din urmatorul tabel: Caracterul '\b' '\t' '\n' '\f' '\r' '\"' '\'' '\\' Reprezentarea in Unicode '\u0008' Semnificatia deplasare la stânga cu o poziţie (backspace) tabulare orizontală (horizontal tab) trecere la linie nouă (line feed. '+'. cifre. adică simboluri tipografice elementare: litere. într-o astfel de secvenţă. în Unicode. simboluri matematice. '('. NL) salt la pagina nouă (form feed) întoarcerea carului (carriage return. Din acest motiv. în care reprezentarea caracterelor se face pe un singur octet. compilatorul consideră că urmeaza o secvenţă escape. backslash). Reprezentarea externă a caracterelor se face în una din următoarele forme: a/ punând caracterul respectiv între apostrofuri: 'a'. în care apare codul numeric hexazecimal al caracterului respectiv. în sistemul Unicode. 255]. 'B'. pe care o înlocuieşte cu caracterele Unicode corespunzătoare. mulţimea de valori a acestui tip de date fiind intervalul de numere naturale [0. în limbajul Java datele de tip char sunt incluse în categoria celor de tipuri întregi. Exemplul 1 Şirul de caractere "abc\"def" conţine secventa escape \". 65535]. caracterele sunt codificate în memoria internă prin numere întregi pozitive în intervalul [0. Codul cel mai frecvent folosit în aceste scopuri este ASCII. În programele Java. Remarcăm ca datele de tip char sunt singurul tip de date întregi fără semn din limbajul Java. care se va inlocui cu codul 61 . de ex: '\u006c' sau '\uffff'. În fluxurile de date de intrare/ieşire şi în fişiere.

rezultatele afişate pe ecran sunt cele de mai jos: A a 1 * b 65 97 10 49 42 162 6305 k 2 50 3 51 101 62 .println(c1*c2).out. toate operaţiile care se aplică tipurilor întregi se aplică şi asupra tipului char.println((int)c1+" "+(int)c2+" "+(int)c6+" "+ (int)c4+" "+(int)c5). evident. cu reprezentarea internă a caracterului respectiv. cum sunt caracterul de trecere la lini noua '\n' şi altele. Acelasi şir de caractere putea fi scris sub forma "abc\u0022def". Desigur că o astfel de înlocuire a caracterelor prin secvenţe escape nu este justificată în cazul caracterelor obişnuite. în care în loc de secvenţa escape \" s-a folosit direct cea care conţine valoarea numerica din Unicode a caracterului ". Exemplul 2 Ştiind că reprezentările în Unicode ale literelor e şi t sunt. tratată ca numar natural. /* Operatii cu date de tip char */ class TestChar { public static void main(String args[]) { char c1='A'. System.prin\u0074ln("Ex\u0065mplu").out. c4='1'. dar este utilă în cazul folosirii caracterelor speciale. Exemplu În programul de mai jos. Atunci când un caracter se foloseşte ca numar întreg se operează. c5='*'.println("Exemplu"). System. obţinându-se şirul abc"def.println((char)107).out. respectiv. tipul char este considerat tip de date întregi. c2='a'.ou\u0074. respectiv \u0022.println(c1+" "+c2+" "+c6+" "+c4+" "+c5+" "+c3).println(c1+c2). dat in fişierul TestChar.Severin Bumbaru caracterului ". System. instrucţiunea System.out. System.out. c6='\n'. System. \u0074. se testează unele operaţii cu date de tip char.println('2'+" "+(int)'2'+" "+'3'+" "+(int)'3'+ " "+('2'+'3')). În consecinţă.out.java. System. Operaţii şi operatori pentru date de tip char În limbajul Java. \u0065 şi poate fi scrisă sub forma Sys\u0074\u0065m.out. } } La executarea acestui program. c3='b'.

Ce este operaţia de atribuire? 63 . caracterul '\n' prin 10 etc. * şi b.Programarea orientata pe obiecte în limbajul Java După afişarea caracterelor A şi a s-a transmis către dispozitivul de afişare caracterul '\n'. După aceasta au fost afşsate caracterele 1. Pe următoarele două linii sunt afişate rezultatele operaţiilor 'c1'+'c2' si 'c1'*'c2'. Pe linia următoare sunt afişate caracterele deja afişate anterior. ci prin numărul întreg 50. Prin ce metode se afişează un şir de caractere pe ecran? 6. Ce tipuri de date primitive există în limbajul Java? 19. Ce sunt operatorii? 11. În mod corespunzator. Suma codurilor numerice ale celor doua caractere este. asupra cărui tip de date se aplică şi ce efect are? 21. caracterul '3' se reprezinta intern prin numarul 51. Ce sunt operatorii logici | si ||? 23. În consecinţă. caracterul 'a' prin numarul 97. Ce este un literal? 9. Ce sunt identificatorii şi cum se alcătuiesc ei în Java? 7. Cum se reprezintă un şir în program? 4. Ce este numele variabilei? 15. Se observă că în Unicode caracterul 'A' este reprezentat prin numarul 65. Care este mulţimea de valori a tipului boolean? 20. Ce este o variabilă finală? 17. întrucât caracterele au fost folosite ca operanzi ai unor operatori aritmetici. Pe linia următoare se afişează numărul 107 convertit din int în char şi interpretat deci drept 'k'. evident. obţinându-se respectiv valorile numerice 162 si 6305. convertite în numere întregi. Întrebări Nivel 1 1. Pe ultima linie putem observa deosebirea dintre forma externă a caracterului (literalul de tip char) şi codificarea lui interna. Ce sunt operatorii logici & si &&? 22. numărul 101. care a fost interpretat drept comanda de trecere la linie nouă. Literalul de tip char '2' este caracterul 2 si nu numarul 2. Care este operatorul de negaţie. Ce se înţelege prin declararea variabilei? 16. acest caracter nu se reprezinta intern prin numarul întreg 2. Ce sunt variabilele? 14. Ce este un comentariu? 2. Ce este un tip de date? 18. Ce este efectul lateral al operatorului? 12. Se observă că. Ce este concatenarea şi care este operatorul prin care se realizează? 5. Care sunt tipurile de date numerice? 24. Ce fel de comentarii pot să apară în fişierele sursă Java? 3. rezultatele obţinute sunt numerice (de tip int). Toţi operatorii au efect lateral? 13. Ce sunt cuvintele cheie? 8. Ce separatori se folosesc în limbajul Java? 10.

Severin Bumbaru 25. Ce operatori de comparaţie se folosesc în cazul datelor de tipuri întregi? 32. Ce valori speciale pot avea literalii în virgulă mobilă? 40. Care sunt operatorii aritmetici unari? 21. Ce operaţii se pot face supra datelor de tip char? 46. Ce sunt tipurile de date derivate? 15. Ce deosebiri există între operatorii = şi ==? 19. Daţi o definiţie conceptului de variabilă. Ce operaţii aritmetice se poa efectua asupra numerelor în virgulă mobilă? 41. 45. Ce sunt tipurile de date primitive? 13. Se poate oare folosi metoda print() în loc de println()? 4. împărţitorul are valoarea zero? 42. Cum se plasează operatorii unari în raport cu operanzii lor? Dar cei binari? 8. În ce situaţii este obligatorie folosirea castului la conversiile datelor de tipuri primitive? 20. Cum acţionează operatorii == şi !=? 26. Ce sunt literalii în virgulă mobilă? 39. Ce tipuri de date în virgulă mobilă există în Java? 38. Ce proprietăţi are operatorul de concatenare? 2. Cum se scriu literalii in sistemul hexazecimal? 35. Ce fel de date conţine tipul char? 43. Care sunt operatorii de atribuire compusă şi ce efect au? Nivel 2 1. De câte feluri sunt operatorii după numărul de operanzi? 7. Ce deosebire există între modurile în care acţionează operatorii logici | şi ||? 18. Ce se întâmplă dacă. În ce mod se iniţializează o variabilă? 12. Ce deosebire este între literali şi identificatori? 6. Ce este o clasă şi în ce fel de limbaje se foloseşte? 16. Ce este castul şi care este forma lui sintactică? 30. Ce contine o declaraţie de tip? 28. Ce este conversia de tip? 29. Ce se stabileşte la definirea unui tip de date primitive? 14. Este concatenarea asociativă? Dar comutativă? 3. Cum se reprezintă literalii de tip char? 44. Cu ce fel de caracter încep în Java numele de clase? 5. la o împărţire în virgulă mobilă. Care sunt operatorii de incrementare şi decrementare? 31. Există operatori ternari? 9. Cum se scriu literalii în sistemul octal? 34. Pot avea semn literalii octali şi cei hexazecimali? 36. Ce deosebire este între aşezarea operatorului de incrementare sau decrementare în faţa operandului şi după acesta? 64 . Cum se reprezintă intern datele de tipuri întregi? 33. Prin ce simbol se termina o declaraţie de variabile? 11. Ce deosebire există între modurile în care acţionează operatorii logici & şi &&? 17. Ce sunt datele în virgulă mobilă şi ce corespondent au ele în matematică? 37. Ce este o secvenţă escape? daţi exemple. Ce efect are operatorul logic ^? 27. 10.

Cum se reprezintă intern datele de tip char? 65 . Ce deosebire este între operatorii >> şi >>>? 32. Cum se stabileşte tipul rezultatului operaţiilor aritmetice cu numere intregi? 25. Ce este depăşirea binară şi în ce situaţii poate să apară? 29. | şi ^ când operanzii sunt de tipuri întregi? 33.Programarea orientata pe obiecte în limbajul Java 22. Ce avantaj prezintă folosirea literalilor hexazecimali sau octali faţă de cei zecimali? 24. Cum acţionează operatorii ~. Ce este excepţia de împărţire la zero şi în ce situaţii poate să apară? 28. Cum acţionează operatorul <<? 30. Cum se reprezinta intern datele în virgulă mobilă? 34. Cum acţionează operatorul >>? 31. În ce situaţii rezultatul unei operaţii în virgulă mobilă are valoarea infinit? 36. Ce sunt cifrele semnificative ale unui număr în virgulă mobilă? 35. Ce este împărţirea întreagă? 27. În ce caz rezultatul unei operaţii aplicate asura unui operand de tip byte este tot de tip byte? 26. Care sunt domeniile de valori pentru date de tipuri intregi? 23. &.

while). Structurile de control fundamentale. Tipul expresiei este acelaşi cu tipul valorii ei. variabile. Structuri repetitive Ciclul cu test iniţial (while). Tehnica rafinărilor succesive. expresii de tip boolean.Severin Bumbaru Expresii. Instrucţiuni structurate (structuri de control) Blocul ca realizare a structurii secvenţiale. Tratarea excepţiilor în limbajul Java (try . int. 66 . expresia poate conţine literali. Tratarea excepţiilor Expresii cu date primitive.. variabile locale şi domenii de vizibilitate. operatori.. Expresia condiţionala Instrucţiuni simple Principiile programării structurate. Fiecare limbaj de programare are regulile sale. float. deci. catch) Întrebari 66 70 71 74 74 78 79 79 81 85 86 86 89 90 93 93 95 97 Expresii cu date primitive În programare. operanzi. Ciclul cu test final (do . long. else). Putem avea. În limbajul Java. funcţii şi paranteze şi trebuie să poată fi evaluată (calculată). corectă) de simboluri. prin care se stabileşte ce expresii sunt permise sau nepermise. expresia este o combinaţie permisă ("legală". Ciclul for Instrucţiuni etichetate. astfel încât să se obţină o valoare. Structura alternativă (if . Instrucţiuni simple şi instrucţiuni structurate. care reprezintă o valoare. double etc.. Structura de comutare (switch). precedenţa operatorilor. Terminarea abruptă a execuţiei instrucţiunilor structurate.

tipul şi valoarea acestei expresii sunt cele ale literalului sau variabilei respective. care are ca argumente valorile variabilei alpha şi literalului 3.765) . Exemple de astfel de expresii sunt: true -176 1. evaluarea expresiei alpha+3. De exemplu: (-176) (alpha++) (alpha+3.un literal sau o variabilă constituie o expresie. a cărei valoare este identică cu cea a expresiei din interior.o expresie cuprinsă între paranteze constituie o nouă expresie. de fapt. De exemplu: alpha+3.765 este.765 şi are ca valoare suma acestora. De exemplu. Utilizarea funcţiilor în expresii va fi discutată ulterior. Mernţionăm însă că şi operatorii acţionează tot ca nişte funcţii. se pot construi expresii din ce în ce mai complicate. De exemplu: (alpha+3.un operator împreună cu operanzii lui constituie o expresie.Programarea orientata pe obiecte în limbajul Java Construirea expresiei se face pas cu pas.valoarea unei expresii poate fi folosită ca operand într-o altă expresie. având în vedere că: .765)*(alpha++) Se observă că. 67 .358746E-12 "sir de caractere" beta . calcularea unei funcţii.765 (s-a folosit operatorul binar +) alpha++ (s-a folosit operatorul unar postfix ++) -alpha (s-a folosit operatorul unar prefix -) . procedând astfel.

iar ca rădăcină are valoarea expresiei.Severin Bumbaru Expresia poate fi reprezentată ca un arbore sintactic.operatorii unari se aplică înaintea celor binari. care are ca frunze literali sau variabile. Tabela de precedenţă a operatorilor în limbajul Java 68 . la stabilirea ordinii operaţiilor se aplica următoarele reguli: . De exemplu. De exemplu. operatorii de pe un nivel superior se aplică înaintea celor de pe nivelurile inferioare. într-o expresie. prezinta o importanţă deosebită ordinea în care se aplică operatorii pe care îi conţine. adică un nivel de prioritate în aplicarea operatorului respectiv. dacă operaţia este binară. În toate limbajele de programare. deoarece are precedenţa superioară. Fiecare nod al arborelui sintactic conţine un operator sau o funcţie. ei se aplică de la stânga la dreapta. Fiecărui operator i se asociază o precedenţă. aceasta expresie se va calcula ca şi când ar fi scrisă sub forma a+(b*c). expresia a*b+3*c corespunde următorului arbore: Precedenţa operatorilor La evaluarea unei expresii. . în expresia a+b*c operatorul * se va aplica înaintea operatorului +. toţi operatorii au acelaşi nivel de precedenţă. în care se folosesc expresii.expresiile din interiorul parantezelor se evaluează înaintea celor din exterior. În consecinţă.dacă.nivelul de precedenţă al operatorilor se stabileşte conform cu tabela de mai jos. în care:   toţi operatorii din aceeaşi celulă a tabelei au acelaşi nivel de precedenţă. În limbajul Java. care are ca operanzi valorile subexpresiilor din nodurile-fii.operanzii unui operator se evalueaza înainte de a se aplica operatorul respectiv (deci operatorul se aplică întotdeauna asupra valorilor operanzilor săi). deoarece de această ordine poate să depindă valoarea expresiei. . . se stabilesc şi anumite reguli de precedenţă şi de asociativitate. . pe baza cărora se stabileşte ordinea de evaluare. operandul din partea stângă se evaluează înaintea celui din partea dreaptă.

out. /* Evaluarea expresiilor */ class EvExpresii { public static void main(String args[]) { int a=23. } } La executarea acestui program. System.out. se calculează unele expresii cu numere întregi şi se afişează rezultatele.out.println((d<1 & ++d<c)+" "+c+" "+d).java.unar (<tip>) % .println((a+b*c)+" "+((a+b)*c)+" "+(b/a*c)+ " "+(b/(a*c))).println((d<1 && c--==0)+" "+c+" "+d). deoarece operatorul 69 .out. b=500. c=17. . ++ -+ unar ! * + binar << < <= >> > instanceof != & ^ | && || ?: = <<= += -= >>= |= *= /= %= >>>= &= ^= [] ~ new / () . efectuându-se mai întâi înmulţirea b*c.s-a evaluat expresia (a+b*c). d.binar >>> >= == . System. System. se obţin pe ecran următoarele rezultate: 8523 8891 357 1 2812 17 2 false 17 2 false 17 3 Sa urmărim acum desfăşurarea calculelor care au condus la aceste rezultate. System. Exemplu În programul de mai jos. a cărui sursă se găseşte în fişierul EvExpresii.Programarea orientata pe obiecte în limbajul Java .println((-a+b*c++/3+(d=c--%4))+" "+c+" "+d).

operand2 şioperand3 . Evaluarea expresiei decurge astfel: . astfel: . Întrucît operatorii / şi * au acelaşi nivel de precedenţă. . s-a convertit numarul 8523 într-un şir (trecându-se de la forma internă a acestuia la cea externă) şi s-a obţinut şirul "8523". s-a efectuat înmulţirea 21*c. obţinându-se şirul "8523 ". . astfel că variabila d a fost incrementată. rezultând şirul "8523 8891 ".s-a calculat expresia (b/(a*c)).s-a calculat expresia ((a+b)*c) obţinându-se numărul întreg 8891.s-a concatenat forma externă a numărului 357 cu şirul obţinut anterior şi cu şirul " ". +. se exemplifică mai multe cazuri de utilizare a expresiei condiţionale. Exemplu În programul de mai jos.java.expresie booleană. are ca operanzi numărul întreg 8523 şi şirul de caractere " ". obţinându-se şirul "8523 8891 357 ".s-a convertit numărul 8891 din forma internă în cea externă şi s-a concatenat cu şirul obtinut anterior şi cu sirul " ". dat şi în fişierul ExprCond. altfel. În consecinţă. calculul s-a făcut de la stânga la dreapta. la aplicarea operatorului && nu s-a mai evaluat al doilea operand.expresii de tipuri compatibile: fie ambii operanzi de tip boolean. obţinându-se valoarea 21.avand în vedere că valoarea expresiei d<1 este false. Recomandăm să urmăriţi în acelaşi mod cum s-au calculat şi afisat celelalte expresii. . în limbajul Java există operatorul ternar (cu trei operanzi) ?: numit operatorul condiţional. .următorul operator.Severin Bumbaru * are precedenţa superioară operatorului +. este cea care se obţine evaluând operand3. Menţionăm că: . obţinându-se şirul "8523 8891 357 1" care a fost afişat pe ecran. . Expresia condiţională Urmând "tradiţia" limbajului C. deci variabila c a rămas la valoarea ei anterioară. atunci valoarea expresiei condiţionale este cea care se obţine evaluând operand2. care s-a concatenat cu şirul " ". s-a efectuat împărţirea întreagă b/a. şi s-a obţinut ca valoare numărul întreg 8523. care este utilizat în cadrul următoarei expresii condiţionale: operand1 ? operand2 : operand3 unde: operand1 .dacă operand1 are valoarea true. 70 . fie ambii de tipuri referinţă. fie ambii de tipuri numerice. . . apoi împărţirea întreagă a valorii lui b la rezultatul înmulţirii şi s-a obţinut valoarea 1.se evaluează operand1 obţinându-se o valoare booleană.la evaluarea expresiei (-a+b*c++/3+(d=c--%4))prezinta interes cu ce valori intră în calcul variabila c şi ce valoare are operandul din dreapta al ultimului operator +. obţinându-se rezultatul 357.s-a concatenat forma externă a acestei valori cu şirul obţinut anterior. . deoarece este între paranteze.s-a calculat expresia (b/a*c). . in timp ce la aplicarea operatorului & a fost evaluat şi al doilea operand. după care s-a trecut la linie nouă. . de data aceasta. s-a calculat mai întâi subexpresia a+b. efectuându-se acum mai întâi înmultirea a*c.

Executarea metodei constă în executarea acestor instrucţiuni într-o ordine determinată.Programarea orientata pe obiecte în limbajul Java /* Testarea expresiei conditionale */ class ExprCond { public static void main(String args[]) { int m=17. La scrierea lor se respectă următoarele reguli: 71 . instrucţiunile pot fi simple sau structurate.out.out.println(m<=n ? 3*m : m-n). Instrucţiuni simple În limbajul Java. System.out.println(m>p ? (n<0? m+1 : m-2) : (m>n ? m : n)). Corpul oricărei metode este constituit dintr-o succesiune de instrucţiuni. /* Se evalueaza numai operandul 3 */ System. n=-6. După structura lor.println(m>n ? m+1 : 2*n-2). procesul de calcul este controlat de instrucţiuni (enunţuri). q=0. } } Executând acest program. Instrucţiunile pot fi grupate în blocuri. În ultima instrucţiune se ilustrează şi un caz de utilizare drept operanzi a unor expresii condiţionale. Instrucţiunile simple nu conţin în interiorul lor alte instrucţiuni. p=0. Fiecare instrucţiune indică una sau mai multe acţiuni pe care trebuie să le execute calculatorul. care erau necesari în evaluarea expresiei condiţionale. instrucţiunileexpresie şi instrucţiunea vidă.out.out. System. /* Se evalueaza numai operandul 2 */ System.: n++)+" "+m+" "+n). Există trei categorii principale de instrucţiuni (enunţuri) simple: declaraţiile de variabile locale.println((m>=6 ? ++p*n : ++q-m)+" "+p+" "+q). /* Un exemplu in care operanzii 2 si 3 sunt tot expresii conditionale */ System. obţinem pe ecran urmatoarele rezultate: 18 23 -6 1 0 -6 17 -5 18 Din aceste rezultate putem constata cu uşurinţă că s-au evaluat de fiecare dată numai acei operanzi.println((m<n+3 ? m-.

Severin Bumbaru    toate instrucţiunile simple se termină cu caracterul '. De exemplu. în care la sfârşitul expresiei de atribuire s-a pus terminatorul punct şi virgulă. Instrucţiunea de atribuire este o expresie de atribuire sau de atribuire compusă urmată de caracterul '.tipul variabilei corespunde contextului în care este folosită variabila respectivă. Notă pentru programatorii în alte limbaje În limbajul Java. În consecinţă: . urmată de caracterul '. astfel că la evaluarea expresiilor prin care se calculează valoarea iniţială a unei variabile.'. astfel că acţiunea care se efectueaza la executarea instrucţiunii de atribuire constă numai în efectul lateral al acesteia. numele şi (opţional) valoarea iniţială a variabilelor.' (punct şi virgulă).variabila respectivă a fost declarată. . În limbajul Java declaraţiile sunt. În majoritatea limbajelor compilate. Valoarea acestei expresii se ignoră. atunci a=b+7 este o expresie de atribuire. de asemenea. de incrementare/decrementare sau de invocare de metodă. Forma sintactică şi utilizarea declaraţiilor au fost prezentate anterior. se consideră cunoscute valorile iniţiale ale variabilelor declarate anterior. declaraţiile de variabile locale sunt considerate instrucţiuni executabile. verifică la fiecare apariţie a unei variabile locale în programul sursă dacă: . Se pot face atribuiri în lanţ. deci sunt considerate instrucţiuni neexecutabile. Instrucţiunile de atribuire sunt instrucţiuni prin care unei variabile i se atribuie o nouă valoare."executarea" declaraţiei are loc de la stânga la dreapta şi de sus în jos. modificându-se astfel valoarea avută anterior. . este o instrucţiune de atribuire. de incrementare/decrementare sau de invocare de metodă.' (punct şi virgulă) deci are următoarea formă sintactică: expresie_de_atribuire. Instrucţiunile-expresie pot fi instrucţiuni de atribuire. luate în consideraţie de compilator.variabila are deja o valoare. declaraţiile de variabile locale servesc pentru a specifica tipul. dacă a şi b sunt variabile numerice. 72 . Instrucţiunea vidă este formată numai din acest caracter.declaraţiile de variabile pot fi plasate oriunde în interiorul unui bloc (pot fi puse la începutul acestuia sau pot fi intercalate cu alte instrucţiuni). . ca în exemplul următor: a=b=c=d=3. instrucţiunile-expresie sunt formate dintr-o expresie de atribuire. adică în modificarea valorii variabilei din partea stânga. deci ele au efect la executarea programului. de asemenea. în timp ce a=b+7. Efectul declaraţiilor de variabile locale din programele Java constă în faptul că în momentul execuţiei se alocă în memorie (pe stivă) spaţiu pentru variabilele respective şi se introduc valorile iniţiale. care verifică dacă declaraţia este corectă sintactic şi. declaraţiile de variabile locale sunt luate în consideraţie numai la compilare.

transmiţându-i-se parametrul "şir de caractere". Singura restricţie este ca trecerea de la o linie la alta să se facă la nivelul unui operator sau separator (să nu se rupă in doua un simbol format din mai multe caractere. două instrucţiuni de atribuire. scrierea mai multor instrucţiuni pe o singură linie sau. c=2*a-b. transmiţându-i-se acesteia valorile parametrilor. d.java se dă un exemplu simplu de program care conţine o secvenţa de instrucţiuni simple: o declaraţie de variabile. menţinându-se numai efectele laterale ale metodei respective. Instrucţiunile de invocare de metodă sunt instrucţiuni prin care se cere executarea unei metode. Instrucţiunea constă din numele metodei. a++ este o expresie de postincrementare. o instrucţiune de incrementare şi o invocare de metodă. valoarea funcţiei se ignoră. De exemplu: System. însă.' (punct şi virgulă). } } Pentru mai multa claritate. un identificator sau un literal). // instructiune de atribuire b++.76. /* Exemple de instructiuni simple */ class Instructiuni { public static void main(String args[]) { double a=3. 73 .' (punct şi virgulă). // declaratie de variabile d=3*a-7.out. b=-15. fiecare instrucţiune a fost scrisa pe o linie de program separată şi a fost însoţită de un comentariu. urmată de caracterul '. invers. Daca metoda este o funcţie. // instructiune de incrementare e=b-17. Se permite. în timp ce a++. e. este o instrucţiune prin care se invocă metoda println a câmpului out din clasa System. Remarcăm că la declararea variabilei c s-a luat în consideratie faptul că variabilele a şi b au deja valori iniţializate anterior.Programarea orientata pe obiecte în limbajul Java Instrucţiunile de incrementare/decrementare sunt instrucţiuni formate dintr-o expresie de incrementare sau decrementare.println("a="+a+" b="+b+" c="+c+" d="+d+" e="+e).println("şir de caractere").out. // instructiune de atribuire /* invocare de metoda */ System. Exemplu În fişierul Instructiuni. Acţiunea care se realizează astfel constă din afişarea pe ecran a şirului primit ca parametru. o instrucţiune se poate extinde pe mai multe linii. Acţiunea cerută de instrucţiune constă în executarea metodei respective. este o instrucţiune de postincrementare. urmat de o pereche de paranteze care conţine valorile parametrilor şi se termină prin caracterul '. De exemplu.

Severin Bumbaru Principiile programării structurate Programarea structurată este o orientare în conceperea şi alcătuirea programelor. Conform "teoremei de structură". Structurile de control fundamentale Aceste structuri se referă la modalităţile în care se pot înlănţui instrucţiunile dintr-un program. conform schemei logice din figura 1. la conceperea unui program. Totuşi. Este deci util ca şi programatorii în Java sa cunoască principiile fundamentale ale programării structurate. având ca obiectiv o mai bună gestionare a complexităţii acestora. se consideră că instrucţiunile se execută în ordinea în care acestea figurează în program. Structura secvenţială În mod "natural". deci în care se transmite "controlul" de la o instrucţiune la alta în timpul executării programului. 2. modulele de program sunt mici şi rolul programării structurate este sensibil redus. numită şi tehnica rafinărilor succesive. fiecare metodă din limbajul Java este un mic program. la elaborarea căruia se aplică principiile programării structurate. pentru rezolvarea problemei realizării creşterii eficienţei muncii programatorilor s-a adoptat concepţia modernă a programării orientate pe obiecte. sunt suficiente trei astfel de "structuri de control": 1. Înlănţuirea instrucţiunilor (transmiterea "controlului" de la o instrucţiune la alta) se face. 3. ţinând cont de particularităţile gândirii umane. La conceperea programelor se recomandă să se aplice tehnica de elaborare descendentă (în engleză Top-Down). structura alternativă şi structura repetitivă. In consecinţă. ceeace s-a avut în vedere şi la adoptarea instrucţiunilor de bază oferite de acest limbaj. Domeniile de valabilitate (de vizibilitate) ale variabilelor şi structurilor de date trebuie să fie limitate. este recomandabil să se respecte următoarele principii: 1. În limbajul Java. 74 . Conform metodei programării structurate. Teorema de structură: orice program poate fi întocmit folosind numai trei structuri de control fundamentale: structura secvenţială. în acest caz.

aceeaşi secvenţă de program se scrie astfel: <instrucţiunea_1> <instrucţiunea_2> . Structura alternativă (condiţională. un număr oarecare (n) de instrucţiuni. deci. În această schemă logică.. <instrucţiunea_n> Există. 2. Executarea acestui fragment de program decurge astfel: se verifică mai întâi dacă este satisfăcută condiţia.Programarea orientata pe obiecte în limbajul Java În pseudocod. care se execută una dupa alta. iar în caz contrar se execută Instrucţiunea 2. Dacă ea este satisfăcută. In pseudocod.. Schema logică a structurii de control alternative este dată în figura 2.. în funcţie de modul în care este satisfăcută sau nu o anumită condiţie. în ordinea în care sunt scrise în program. atunci când se alege una din două căi posibile. Toate exemplele de programe date în capitolele şi secţiunile anterioare au structura secvenţială. Condiţie este o expresie booleană. deci expresia Condiţie are valoarea true. acest fragment de program se scrie astfel: Dacă <condiţie> atunci <instrucţiunea_1> 75 . de decizie) Un fragment de program are structura alternativă (numită şi structură condiţională sau de decizie). se execută Instrucţiunea 1.

instrucţiunea astfel aleasă este executată. În ambele cazuri se verifică dacă este satisfacută o condiţie şi . altfel (deci dacă condiţia nu este satisfacută) se merge pe ramura NU şi se iese din ciclu. o instrucţiune sau o secvenţă de instrucţiuni se repetă cât timp este satisfacută o anumită condiţie. iar rezultatul obţinut este efectul (lateral) produs de executarea acestei instrucţiuni. 2. În pseudocod. este cea de ciclu cu test iniţial. deci condiţia este satisfacută. această structură de control se programează astfel: cât_timp <condiţie> execută <instrucţiune> sfârşit_ciclu 76 . acceptată în teoria programării structurate.Severin Bumbaru altfel <instrucţiunea_2> Sfarşit_dacă În unele convenţii de pseudocod. Structura repetitivă fundamentală. în loc de Instrucţiunea_1 şi Instructiunea_2 pot fi puse secvenţe de instrucţiuni. 3. cât timp este satisfăcută condiţia. se merge pe ramura DA şi se executaă instrucţiunea din corpul ciclului. se evaluează expresia booleană care reprezintă Condiţia. după care se trece la punctul 1. dacă valoarea acestei expresii este true.în cazul structurii de control alternative se alege una din cele doua instrucţiuni conţinute în această structură. Se observă că există o asemănare între instrucţiunea alternativă şi expresia condiţională. iar rezultatul obţinut este valoarea expresiei astfel alese.în funcţie de rezultatul obtinut se alege una din două variante posibile. . că se va executa instrucţiunea în mod repetat. Structura repetitivă (ciclu. Deosebirea este următoarea: . Executarea acestei structuri are loc astfel: 1. deci. Se observă. buclă) În cazul structurii de control repetitive. Schema logică a acestei structuri de control este dată în figura 3. 3.în cazul expresiei condiţionale se alege una din cele două expresii conţinute în aceasta.

în timp ce la ciclul cu test final instrucţiunea din corpul ciclului va fi executată cel puţin o dată. dar nu şi invers. este posibil ca instrucţiunea să nu se execute niciodată (dacă chiar de la prima evaluare condiţia nu este satisfacută). ciclul cu test final reprezentat prin schema logică din figura 4 se scrie sub forma generală: execută <instrucţiune> cât_timp <condiţie> În unele limbaje (de exemplu în Pascal) pentru ciclul cu test final se adoptă o schemă logică în care singura deosebire faţă de cea din figura 4 este doar prin faptul că cele două ramuri DA şi NU işi schimbă locurile între ele. în timp ce cel cu test final este o structură de control admisă. din punct de vedere al teoriei programării structurate. deoarece. Deosebirea dintre cele două forme de cicluri este că. ciclul cu test final poate fi înlocuit prin unul echivalent cu test iniţial. ciclul cu test iniţial este considerat ca structură de control fundamentală. în teoria programării structurate. cât timp este satisfacută condiţia.Programarea orientata pe obiecte în limbajul Java În unele versiuni de pseudocod. dar nu fundamentală. Se observă că. în această schemă logică. executarea instrucţiunii se repetă. Iată dece. ciclul cu test iniţial este suficient ca structură repetitivă. în multe limbaje de programare (inclusiv Java). Schema logică a acestui ciclu este dată în figura 4. condiţia este evaluată înainte de a se executa instrucţiunea din corpul ciclului. în loc de o singură <instrucţiune> se poate pune o secvenţă de instrucţiuni. Aceasta este o deosebire importantă. în timp ce în ciclul cu test final evaluarea condiţiei se face după ce instrucţiunea a fost deja executată. numită ciclu cu test final. Deşi. în ciclul cu test iniţial. Aşa dar. În pseudocod. ca şi în cazul ciclului precedent. ceeace în pseudocod se scrie sub forma: execută <instrucţiune> până_când <condiţie> 77 . în cazul ciclului cu test initial. din motive de comoditate a programării se admite şi o a doua formă de astfel de structură.

de înalt 78 . Datorită acestei proprietăţi. Tehnica rafinărilor succesive oferă o cale de a parcurge acest drum de la CE la CUM în mai mulţi paşi.iniţial se consideră că programul este alcatuit dintr-o singură pseudoinstrucţiune. De cele mai multe ori. care va fi prezentată succint în cele ce urmează. care arată CUM trebuie acţionat pentru a se obţine aceste rezultate. cu numeroase ramificaţii şi cicluri.fiecare din aceste instrucţiuni se descompune în mai multe instrucţiuni de nivel de abstractizare mai coborât (mai "concrete"). specifică tehnicii rafinărilor succesive: . va fi extrem de greu sau chiar imposibil să fie depanat (să se corecteze eventualele erori de programare) şi să fie modificat ulterior. se poate aplica următoarea cale de elaborare a programului. aşa cum se va arăta ulterior. instrucţiunea din corpul ciclului se va repeta cât timp NU este satisfacuta condiţia. în unele variante de pseudocod instrucţiunea din corpul ciclului poate fi înlocuită printr-o secvenţa de instrucţiuni.Severin Bumbaru În acest caz. în care se precizează CE trebuie sa facă programul respectiv (CE problemă trebuie rezolvată. Ca urmare. Din examinarea structurilor de control prezentate în acest capitol. aşa cum se va arăta în secţiunea următoare. dacă nu se procedează sistematic. abstractizarea este calea prin care omul stapâneşte complexitatea. deoarece ea se poate înlocui printr-o singură instrucţiune compusă. putem constata o proprietate importantă: schemele logice ale tuturor structurilor de control admise de metoda progrămarii structurate au fiecare un singur punct de intrare şi un singur punct de ieşire. cât şi structurile de control admise de metoda programarii structurate au fiecare un singur punct de intrare şi un singur punct de ieşire. deci până când se va constata pentru prima oară că ea este satisfăcută. În ambele cazuri. permise de metoda programării structurate. programul elaborat conţine un număr mare de instrucţiuni. Tehnica rafinărilor succesive Adoptarea metodei programării structurate a făcut posibilă elaborarea programelor prin tehnica rafinărilor succesive (engl. Scrierea unui astfel de program poate fi o sarcină extrem de dificilă şi greu de îndeplinit. Dupa cum arăta E.: stepwise refinement).Dijkstra. până când se ajunge la instrucţiuni scrise direct în limbajul de programare folosit (de exemplu în Java).W. dacă programul nu este suficient de clar şi de bine documentat. dacă se modifică specificaţia.la fiecare pas de rafinare . Se pune deci un accent deosebit pe abstractizarea datelor si a instrucţiunilor. după care . constatăm cu uşurinţă că atât blocurile care conţin instrucţiuni. CE rezultate trebuie obţinute) şi se ajunge în final la programul propriu-zis. În plus. Dacă se are în vedere utilizarea limbajului Java. cunoscută şi sub numele de tehnica descendentă (engl. ele pot fi folosite la elaborarea unor programe complexe prin tehnica rafinărilor succesive. utilizarea unei secvenţe nu este necesară. Aceasta înseamnă că orice bloc care conţine o instrucţiune poate fi înlocuit în schema respectivă printr-o structură de control. Dacă privim schemele logice ale structurilor de control fundamentale. La elaborarea unui program se porneşte de la specificaţia acestuia. astfel încât să se pornească de la un număr mic de enunţuri (pseudoinstrucţiuni) de nivel de abstractizare ridicat.:top-down).

Instrucţiunile din această secvenţă pot fi atât simple.la pasul de rafinare următor. Aceasta inseamnă că instrucţiunile dintr-un bloc se execută una dupa alta. instrucţiunea switch . următoarea: { secvenţă_de_instrucţiuni } unde secvenţă_de_instrucţiuniconstă dintr-un număr oarecare de instrucţiuni succesive.se continuă acest proces de rafinări succesive. . blocul este realizarea structurii de control secvenţiale. Instrucţiuni structurate Limbajul Java a fost alcătuit astfel. . încât programatorul este obligat sa respecte principiile programării structurate. while şi for . care nu are corespondenta directă în limbajul de programare utilizat. instrucţiunile while. do .prin care se realizează structura de comutare (de selecţie).. instrucţiunile if si if .prin care se realizează structura alternativă. menţinut sub formă de comentariu. în limbajul Java există o structură de control dedicată tratării excepţiilor care apar în timpul executării programului. care constă chiar din specificaţia problemei pe care o va "rezolva" programul respectiv.la paşii de rafinare următori. inclusiv alte blocuri. aceasta înseamnă că unica pseudoinstrucţiune existentă iniţial se înlocuieşte prin una din structurile admise de metoda programării structurate (structura secvenţială. de asemenea.. în ordinea în care ele sunt scrise în program. deci. astfel încât să se înţeleagă mai uşor programul. putând fi şi vidă. . Forma sintactică a blocului este. alternativă sau repetitivă).prin care se realizează structurile repetitive. totusi. se inlocuieşte. else . Tocmai de aceea se şi foloseşte termenul secvenţă 79 . până când toate instrucţiunile astfel obţinute au corespondent în limbajul de programare utilizat. catch Blocuri Blocul este o secvenţă de instrucţiuni cuprinsă între acolade. această structură conţine în ea una sau mai multe instrucţiuni sau pseudoinstrucţiuni. textul pseudoinstrucţiunii înlocuite poate fi.. În plus. această "problemă" se descompune în două sau mai multe "subprobleme".Programarea orientata pe obiecte în limbajul Java nivel de abstractizare. cât şi structurate. Aceasta se datoreşte faptului ca instrucţiunile structurate ale limbajului sunt cele prevăzute de această metodă de programare. fiecare pseudoinstrucţiune. Există următoarele instrucţiuni structurate:     blocul . realizată prin instrucţiunile try . Din punct de vedere al programării structurate. prin una din structurile de control admise.prin care se realizează structura secvenţială.

} // aici se termina blocul C } // aici se termina blocul B } // aici se termina blocul A (corpul metodei main) } // aici se incheie corpul clasei Blocuri La executarea acestui program se afişează următoarele rezultate: m=8 n=-3 u=60.în expresiile prin care se calculează valoarea iniţială a variabilei u s-a luat în consideraţie valoarea variabilei m determinată anterior. se confirmă astfel că iniţializarea variabilelor nu se face la compilare. continut in A int a=5.Severin Bumbaru de instrucţiuni pentru a indica ce conţine blocul. Domeniul de vizibilitate al unei variabile locale începe în locul din program în care aceasta a fost declarată şi se încheie la sfârşitul blocului care conţine declaraţia respectivă. Variabila este deci "vizibilă" (poate fi utilizată) în propriul său bloc şi în toate blocurile interioare acestuia. n=-3.println("m="+m+" n="+n+" u="+u+" v="+v+" w="+w). când aceste valori nu sunt cunoscute. Remarcăm că însuşi corpul metodei main (şi al oricărei alte metode) este tot un bloc. double u=m*3. System.5. q=n*p-a. m++. se exemplifică folosirea unor blocuri imbricate (cuprinse unul în altul).5 Remarcăm că: . la calcularea valorii iniţiale a variabilei p s-au folosit valorile variabilelor m si w calculate la executarea unor instrucţiuni-expresie anterioare.5 q=-13008. în domeniul de vizibilitate. cât şi instrucţiuni-expresie /* Exemplu de program care contine blocuri imbricate */ class Blocuri { // aici incepe corpul clasei Blocuri public static void main(String args[]) { // aici incepe blocul A int m=8.0 v=2. w=m*u+v.println("m="+m+" a="+a+" p="+p+" q="+q). Variabile locale şi domenii de vizibilitate Variabilele declarate într-un bloc sunt variabile locale ale blocului respectiv. Exemplu În programul de mai jos.în blocul B. Prin comentarii s-a semnalat începutul şi sfârşitul fiecărui bloc. ci la executarea declaraţiei. v=2.out.5+32. conţinut în fişierul Blocuri. { // aici incepe blocul B. deşi aceasta nu se face în mod curent. Fiecare bloc conţine atât declaraţii de variabile. // s-a folosit n din blocul exterior { // aici incepe blocul C continut in B System. w.0 m=9 a=5 p=4334. double p=m*w-3. 80 .0 w=482. q.out. .java.

care se termină ea însăşi prin punct şi virgulă. 2. variabilele sunt vizibile şi deci pot fi utilizate. Structuri alternative Instrucţiunea if Instrucţiunea if serveşte pentru realizarea structurii alternative din programarea structurată. Când se ajunge la sfârşitul blocului în care au fost declarate. atuncivariabileix i se atribuie valoarea expresiei aritmetice 2*alpha+beta. instrucţiune este instrucţiunea-expresie x=2*alpha+beta. iar altfel nu se execută nimic. Altfel (dacă expresia booleana are valoarea false) variabila x rămâne la valoarea pe care a avut-o anterior. cât şi în blocurile interioare B şi C. x=2*gamma. atunci se execută instrucţiune. Fie instrucţiunea if(alpha<beta) { int gamma=alpha-3*beta. continuându-se programul. u. La executarea unei instrucţiuni-declaraţie. Înstrucţiunea if se interpretează astfel: dacă expresia booleană alpha<beta are valoarea true. variabilele m. variabilele sunt scoase de pe stivă. Semnificaţia instrucţiunii if este următoarea: dacă valoarea expresiei booleene din paranteză este true. variabilele conţinute în aceasta sunt puse pe stivă. În memoria maşinii virtuale Java. Cât timp se află pe stivă. dat ca exemplu mai sus. Remarcăm ca după acolada prin care se închide blocul nu s-a mai pus punct şi virgulă. Sub forma ei cea mai simplă. în ordinea în care ele apar în declaraţia respectivă. În acest caz. } În acest caz. Dacă instrucţiune este o instrucţiune simplă. Exemple 1. Fie instrucţiunea if(alpha<beta) x=2*alpha+beta.Programarea orientata pe obiecte în limbajul Java Exemplu: În programul din fişierul Blocuri.' (punct şi virgulă). în care sunt declarate. ea include şi acest simbol. În schimb variabilele a. inclusiv un bloc sau un alt if. şi în blocul C situat în interiorul acestuia. 81 . Remarcăm că în forma generală de mai sus nu am pus la sfârşit caracterul '. n. variabilele locale sunt plasate pe stiva procesului curent. p şi q pot fi utilizate numai în blocul B. v şi w sunt declarate în blocul A (în însuşi corpul metodei main) şi sunt vizibile (pot fi utilizate) atât în acest bloc. y=gamma-3.java. instrucţiune este un bloc. care se execută numai dacă expresia booleană alpha<betaare valoarea true. această instrucţiune se scrie astfel: if(expresie_booleană) instrucţiune unde instrucţiunepoate fi orice instrucţiune valabilă în limbajul Java: instrucţiune simplă sau structurată.

în specificaţia limbajului Java această instrucţiune se numeşte if-then-else. Remarcăm că după acolada închisă a blocului nu s-a mai pus punct şi virgulă. Deşi cuvântul then nu apare explicit.println(alpha+" "+beta). instrucţiune este un alt if. iar altfel se execută instrucţiune_2. y=b. Fie instrucţiunea În if(alpha<beta) if(beta>0) System. atunci. else Instrucţiunea if . Fie instucţiunea În termină prin punct şi virgulă.else este următoarea: dacă expresie_logică are valoarea true. y=a+1. în specificaţia limbajului Java această forma a lui if este cunoscută sub denumirea "instrucţiunea if-then" (if-then statement). 2... else realizează ambele ramuri ale structurii alternative şi are forma if(expresie_booleană) instrucţiune_1 else instrucţiune_2 în care instrucţiune_1 şi instrucţiune_2 pot fi instrucţiuni simple sau structurate. cât şi instrucţiune_2 sunt instrucţiuni-expresii şi se În şi instrucţiune_2 sunt blocuri.Severin Bumbaru 3.. atât instrucţiune_1. Fie instrucţiunea if(a<b) { x=2*a-b. Instrucţiunea if . } acest caz. acest caz. 82 .atunci se execută instrucţiune_1. Remarcăm că această instrucţiune realizează un caz particular al structurii alternative. else x=a+b. } else { x=a+b. acest caz. Exemple 1. Deşi cuvântul then nu apare explicit. Interpretarea acestui if.. care se traduce prin dacă .out. instrucţiune_1 if(a<b) x=2*a-b. unde pe ramura altfel nu se efectuează nici o acţiune.

conform căruia fiecare structură de control trebuie să aibă un singur punct de intrare şi un singur punct de ieşire.println("B"). cât şi if..else.. care are următoarea formă generală: switch (expresie) { case valoare_1: secvenţă_1 [break...else interioară sub formă de bloc....println("A").alegerea depinzând de valoarea unei expresii numită comutator sau selector.. } else System.else. Pentru a nu se produce astfel de confuzii. Această structură se poate întări scriind instrucţiunea astfel: if(a<b) { if(b<c) System. else System. iar ultimul else aparţine primului if.. else imbricate Atât instrucţiunea if. Aceste structuri permit să se aleagă una din mai multe ramuri paralele. în sensul că interpretarea dată de compilatorul Java poate fi diferită de cea avută în vedere de programator. astfel că se încadrează în această metodă de elaborare a programelor.out. este suficient să se folosească structura de control alternativă..] case valoare_2: secvenţă_2 [break. în practica programării se admit şi structuri de comutare sau de selecţie. pentru a realiza programe cu structură ramificată..out. else System.else.. că primul else aparţine celui de al doilea if. else System. structura de comutare se realizează prin instrucţiunea switch. cel mai bine este să se grupeze instrucţiunile în blocuri. În acelaşi timp. pot conţine alte instrucţiuni if sau if.out.println("B")..... Interpretarea corectă este...println("A"). Instrucţiunea switch Deşi în teoria programării structurate se demonstrează că.out... Exemplu Fie instrucţiunea if(a<b) if(b<c) System. O programare neatentă poate conduce la greşeli. care sunt prezente in diferite limbaje de programare. în acest caz.. realizată în limbajul Java prin instrucţiunea if..out. Întrucât s-au folosit acoladele pentru a pune instrucţiunea if.out.. În limbajul Java.. În acest caz se pune problema cărui if îi aparţine un anumit else.Programarea orientata pe obiecte în limbajul Java Instrucţiuni if ..] . case valoare_N: secvenţă_N [default: secvenţă ] } 83 .println("C").... a devenit clar pentru oricine cărui if îi apartine fiecare din cei doi else.println("C")... ele respectă principiul de bază al programării structurate.

65535]. până la prima instrucţiune break întalnită sau. int sau char. că în al doilea caz. System.Severin Bumbaru în care: . La sfârşit.println("B "+u).secvenţaeste o secvenţă de instrucţiuni simple sau structurate. short. după cuvantul cheie switch.switch. Remarcăm. case 2: u+=a.java se dă programul de mai jos. .expresie este o expresie de tip byte. switch(a) { case 143: u++. iar în al doilea caz este pusă această instrucţiune la sfârşitul secvenţei de instrucţiuni corespunzătoare fiecărui caz. în care se testează instrucţiunea switch în două situaţii: în primul caz nu este utilizată instrucţiunea break.3782. După ce s-au epuizat toate cazurile. urmat de o valoare de tip întreg. întrucât comutatorul este de tip char. 84 . Dacă s-a găsit o astfel de valoare. . în care există mai multe "cazuri".valoare este fie un literal de tip byte. există o expresie de tip int sau compatibilă cu aceasta (deci poate fi şi de tip char. Se deschide apoi acolada corpului instrucţiunii. atunci se execută instrucţiunile care urmează după cuvântul cheie default sau. a cărei valoare serveşte drept "comutator". Exemplu În fişierul TestSwitch. short. . adică să fie caractere sau numere întregi pozitive în intervalul [0. . int sau char. Fiecare "caz" începe prin cuvantul cheie case.parantezele drepte roşii []nu apar în program. până la acolada de închidere a corpului instrucţiunii switch. nu se execută nimic. se închide acolada corpului instrucţiunii switch. se execută toate instrucţiunile care încep de la cazul respectiv. până când se găseşte prima valoare care coincide cu cea a comutatorului. de asemenea. pe rând de sus în jos. În limba engleză. fie o expresie constantă de tip int. opţional se poate scrie cuvântul cheie default urmat de una sau mai multe instrucţiuni.println("A "+u). valorile numerice corespunzătoare fiecărui caz au trebuit să se încadreze în acest tip. char c='@'. System.out. care serveşte drept comutator. Executarea instrucţiunii switch decurge astfel: se evaluează mai întâi expresie şi se obţine o valoare de tip întreg. byte sau short. Conform acestei forme generale. dar nu de tip long). Această valoare se compară. cu fiecare din valorile indicate după cuvintele cheie case. /* Testarea instructiunii switch */ class TestSwitch { public static void main(String args[]) { int a=7. în lipsa acestuia. case si default sunt cuvinte cheie ale limbajului Java.out. adică o expresie care conţine numai literali sau variabile finale din tipurile menţionate. ci indică faptul că conţinutul lor este opţional (poate sa lipsească). System.println("Switch fara break si cu cazuri vide"). în lipsa acesteia. switch înseamnă comutator. după care apar una sau mai multe instrucţiuni (simple sau compuse) şi opţional intrucţiunea break. Dacă însă nici unul din cazuri nu conţine valoarea potrivită a comutatorului.out. double u=15.

out. break.out.3782 E 51. System.println("C "+u). System.Programarea orientata pe obiecte în limbajul Java case 7: case case case case u--. System.out.out.out.println("E "+u).out. "+u).println("E case 'F': u%=a. case 'F': u%=a. break. System. System.println("F default: u=15. break.out.out.3782 D 7. System. case '@': case 148: case 15: case 87: u-=a. break. System.3782 85 . '@': 148: 15: -87: u-=a.println("A "+u).println("G "+u). System. System.3782. case 12: u*=a.println("G } "+u).out. System. default: u=15. System.6473999999999975 G 15.println("Switch cu break dupa fiecare caz nevid").println("C "+u).println("D case -12: u*=a. case 7: u--.println("F "+u). } } } Rezultatul rulării acestui program este următorul: Switch fara break si cu cazuri vide C 14.out. System.out.out. System.out. "+u). case 2: u+=a.println("B "+u). break.println("D "+u).6474 F 2. switch(c) { case 143: u++. break.3782 Switch cu break dupa fiecare caz nevid D 8.3782. "+u).

iar programul devine: <#1. de tip intreg> /* #2. ieşirea s-a făcut la întalnirea acestei instrucţiuni.1k-0.instrucţiunea do. de tip intreg> <#2.35ksin(0.. Se introduce valoarea lui n. unde n este dat. instrucţiune. sau structurată) a limbajului Java.după care se revine la evaluarea condiţiei. Exemplul 1. În cele ce urmează se vor prezenta instrucţiunile menţionate mai sus. programul corespunzător se poate scrie astfel: <#1. acest ciclu se repetă cât timp este satisfacută condiţia. astfel încât să poată fi folosită şi la realizarea ciclului cu contor.25ksin(0.while. La rafinarea pseudoinstrucţiunii #2 luăm în consideraţie caracterul repetitiv al acţiunii solicitate. Se calculează şi se afisează valoarea expresiei */ k=0. Instrucţiuni pentru structuri de control repetitive În limbajul Java. deci condiţia este satisfacută . În pseudocod. s-a început executarea secvenţei de instrucţiuni în punctul "case 7" şi s-a continuat până la sfârşitul blocului instrucţiunii switch (inclusiv cazul default). Se introduce valoarea lui n. prin care se programează ciclul cu test iniţial. Executarea acestei instrucţiuni se face astfel: se evaluează expresia booleană condiţie şi dacă valoarea acesteia este true. structurile de control repetitive se realizează prin trei instrucţiuni: . astfel că putem folosi structura de ciclu cu test iniţial. în primul caz (fără instrucţiuni break). care este o varianta modificată a ciclului cu test iniţial. . Când s-a folosit instrucţiunea break. // Se iniţializează k la prima sa valoare 86 .Severin Bumbaru Se observă cu uşurinţă că.08) pentru valori întregi ale variabilei k de la 0 la n.08) pentru valori ale lui k de la 0 la n > Rafinarea pseudoinstrucţiunii #1 se poate face direct în program.17k0.instrucţiunea while. prin care se programează ciclul cu test final. Se calculează şi se afişează valoarea expresiei 2e-0. Se va calcula în mod repetat valoarea expresiei 2e-0. Instrucţiunea while (ciclul cu test iniţial) Această instrucţiune are forma generală while (condiţie) instrucţiune în care condiţie .poate fi orice instrucţiune (simplă inclusiv altă instrucţiune while. .se execută instrucţiune.este o expresie de tip boolean.instrucţiunea for.

pentru valori ale lui k de la 0 la n.+xk/(k!)+. Considerăm că se cere să se calculeze suma în care sunt date valorile variabilelor a şi b. Pentru rafinarea pseudoinstrucţiunii #2.java.08). Calcularea sumei unei serii convergente. în care k! este factorialul lui k. Fie S suma seriei convergente S=1+x+x2/(2!)+x3/(3!)+. Se afişează valoarea lui S> Rafinarea pseudoinstrucţiunilor #1 şi #3 se poate face direct în program.Programarea orientata pe obiecte în limbajul Java cât_timp k<=n afişează_valoarea_expresiei 2e-0. Aplicând tehnica rafinărilor succesive. Se calculează suma S> <#3..java. noi ştim că această serie este 87 . Întrucât.35ksin(0. // se trece la valoarea următoare a lui k sfârşit_ciclu Programul corespunzător în limbajul Java se găseşte în fişierul Repetare1. Se introduc datele de intrare n de tip întreg şi a. remarcăm că suma S se poate calcula în modul următor: se porneşte de la valoarea iniţiala S=0 şi se adaugă la aceasta succesiv toţi termenii sumei.1. Exemplul 3.b de tip real> /* #2. Programul corespunzător în limbajul Java se găseste în fişierul Suma1. deci se poate folosi în acest scop un ciclu cu test iniţial. vom da pentru început programului următoarea structură secvenţială: <#1. de tip real şi n de tip întreg. // Se trece la valoarea următoare a lui k sfârşit_ciclu afisează S. Se calculează S */ S=0. însă.17k-0. // Se atribuie lui k valoarea iniţială cât_timp k<=n <#2. Se calculează termenul curent al sumei şi se adaugă la valoarea precedentă a lui S > k=k+1. Exemplul 2. // Se atribuie lui S valoarea iniţială k=0. Acţiunea are un caracter repetitiv. k=k+1. Demonstrarea existentei acestei sume (deci a convergenţei seriei) este de domeniul analizei matematice.. Calcularea unei sume cu număr finit de termeni.. Se introduc datele de intrare n de tip întreg şi a.b de tip real> <#2.. Se obţine astfel programul următor în pseudocod: <#1.

Se introduce valoarea lui x. În consecinţă. În cazul seriei noastre. // Se iniţializează suma S la valoarea 0 k=0.se calculează noua valoare t a termenului următor> sfârşit_ciclu afişează S. adica 32. dacă reprezentarea numerelor reale s-ar face în sistemul zecimal cu 6 cifre semnificative. programul de calculare a sumei seriei devine: <#1. adică luând în consideraţie numai un număr finit de termeni. pentru calcularea sumei. Vom considera deci că termenul t este semnificativ. Pentru a rafina pseudocondiţia #2 avem în vedere că. Pentru a rafina #3. De exemplu. // Se iniţializează indicele termenului curent la valoarea 0 88 . în memoria calculatorului. deoarece cifrele de la rezultat situate după cea de a 6-a cifra semnificativă se pierd. numerele reale au lungime finită. dacă adunăm două numere foarte diferite ca ordin de mărime.+xn/(n!) cu observaţia că numărul de termeni n nu este dinainte cunoscut. Se ştie (si se observă cu uşurinţă) că termenii seriei sunt descrescători ca modul. Cu observaţiile de mai sus. // Se iniţializează suma S la valoarea 0 k=0. la un moment dat termenul curent t va deveni atât de mic ca modul.termenul curent t este semnificativ>) S=S+t. Ne putem deci opri din evaluarea sumei. Se introduce valoarea lui x. următorul program în pseudocod: <#1.Severin Bumbaru convergentă. încât adunat la suma deja calculata S nu o va mai modifica. Totuşi. <#3. observăm că între valorile termenului t la doi paşi succesivi k şi k-1 exista relaţia: tk=tk-1*x/k. Putem deci adopta. înmulţită cu raportul x/k. Seria are un număr infinit de termeni. // Se trece la indicele termenului următor. Întrucât în program nu este necesar să folosim indicii paşilor. // Se iniţializează indicele termenului curent la valoarea 0 t=1. prin adunarea lor.. "suma" lor va fi egală cu cel mai mare dintre ele. de fapt. în momentul în care constatăm că valoarea termenului curent este mult mai mică decât suma parţială deja calculata.7628. suma parţială: Sn=1+x+x2/(2!)+x3/(3!)+. de tip real> S=0.. atunci suma 32. // Se iniţializează termenul curent la valoarea 1 (cea a primului termen) /* Se calculează suma S a seriei */ cât_timp (<#2. // Se adaugă la suma precedentă S valoarea termenului curent // şi se obţine noua valoare a sumei S k=k+1.7628+0. de tip real> S=0. deci valoarea ei exactă nu poate fi calculată direct.00006924 ar fi egala cu numarul cel mai mare. valoarea aproximativă a sumei S se poate obţine prin "trunchiere". adică se atribuie ca nouă valoare a termenului curent t valoarea precedentă a acestui termen. putem să scriem un program pentru calcularea sumei S. cât timp se îndeplineşte condiţia (S+t este_diferit_de S). vom scrie această relaţie sub forma t=t*x/k. Vom calcula deci.

// Se iniţializează termenul curent la valoarea 1 (cea a primului termen) /* Se calculează suma S a seriei */ cât_timp (S+t este_diferit_de S) S=S+t.java. Remarcăm că la sfârşitul acestei instrucţiuni (după condiţie) se pune obligatoriu '. În programul din fişierul DeosCicluri.java se reiau exemplele din secţiunea precedentă (şi realizate în fişierele Repetare1. corpul ciclului va fi executat cel puţin o dată.Suma2. unde. dar folosind de data aceasta ciclul cu test final. // se calculează noua valoare t a termenului următor sfârşit_ciclu afişează S. prin care se realizează în limbajul Java ciclul cu test final este următoarea: do instrucţiune while (condiţie). În programele din fişierele Repetare2.condiţie este o expresie de tip boolean.java). Principala deosebire faţă de instrucţiunea while pentru ciclul cu test iniţial este că testarea condiţiei se face după ce a fost executată instrucţiunea din corpul ciclului. Suma1.Programarea orientata pe obiecte în limbajul Java t=1.. În consecinţă. recomandăm să calculaţi 3-4 termeni manual pentru a urmări cum se înlănţuie aceştia. iar instrucţiune este orice instrucţiune (simplă sau structurată) din limbajul Java. 89 . t=t*x/k.java.java se face o comparaţie între funcţionarea ciclurilor cu test iniţial şi cu test final în condiţii similare. Instrucţiunea do. // Se adaugă la suma precedentă S valoarea termenului curent // şi se obţine noua valoare a sumei S k=k+1.java şi Serie1. Programul corespunzător în limbajul Java este dat în fişierul Serie1.while (ciclul cu test final) Forma generală a instrucţiunii de control.java şi Serie2.' (punct şi virgulă).java. // Se trece la indicele termenului următor. Pentru a înţelege mai bine acest program. la fel ca în cazul instrucţiunii while.

această instrucţiune poate fi scrisă în modul următor: pentru variabila de_la val_init la val_fin [cu_pasul pas] execută <instrucţiune sau secvenţă de instrucţiuni> sfârşit_ciclu în care..+31 se pot folosi instrucţiunile S=0. k=5. de regulă. În mod similar. numită "ciclu cu contor". Astfel. pentru aceleaşi calcule. prin care se trece la 90 . k=k+1. În pseudocod. primul din aceste exemple. iar pas este pasul de variaţie la fiecare parcurgere a ciclului. Pasul implicit este 1. numită şi contorul ciclului. pentru realizarea ciclurilor la care numărul de paşi este dinainte cunoscut. s-au introdus următoarele instrucţiuni suplimentare: . pentru a calcula suma S=7+10+13+16+. dar ea a fost necesară pentru a da valoarea iniţială a variabilei P. instrucţiunea P=1 nu face parte din ciclu. variabila este o variabilă (de regulă de tip întreg). .. în acest exemplu. s-a pus instrucţiunea k=5.la sfârşitul corpului ciclului s-a introdus instrucţiunea k=k+1.val_init şi val_fin sunt respectiv valorile iniţială şi finală ale acestei variabile. se pot folosi şi ciclurile cu test iniţial sau cu test final. De exemplu. pentru j de_la 7 la 31 cu_pasul 3 execută S=S+j. pentru k de_la 5 la n execută P=P*(a+k).. sfârşit_ciclu Remarcăm că. cât_timp k<=n execută P=P*(a+k).*(a+n) se vor scrie următoarele pseudoinstrucţiuni: P=1.înainte de intrarea în ciclu. sfârşit_ciclu Remarcăm că. prin care se atribuie variabileicontor valoarea iniţială. se foloseşte o instrucţiune de control specială. sfârşit_ciclu Remarcăm că.. pentru a calcula produsul P=(a+5)*(a+6)*(a+7)*. poate fi rescris folosind ciclul cu test iniţial astfel: P=1. la trecerea de la ciclul cu contor la ciclul cu test iniţial.Severin Bumbaru Instrucţiunea for (ciclul cu contor generalizat) În unele limbaje de programare.

} Observăm că. instrucţiunea for poate fi scrisă sub diferite forme echivalente. După cum se vede în forma generală. urmând tradiţia limbajului C de la care acesta a preluat o bună parte a regulilor de sintaxă.instrucţiune]* . Această instrucţiune are forma: for ([iniţializare]. astfel că sunt folosite. se foloseşte o instructiune generalizată. În limbajul Java. pe care lar fi avut instrucţiunea while(k<=n). [condiţie] . condiţie .este Respectând aceasta formă generală. prin care se realizează atât ciclul cu contor. k<=n. separate prin virgule. pentru iniţializarea acestuia.una sau mai multe instrucţiuni. că cei doi separatori '.k<=n. de asemenea. de data aceasta. apoi cât timp este satisfacută condiţia k<=n se execută instrucţiunea P*=a+k. chiar dacă lipsesc zonele de iniţializare şi de 91 .k<=n. astfel că sunt. de regulă. după care se execută instrucţiunea k++ (se trece la următoarea valoare a lui k). de exemplu: a) P=1.' din interiorul parantezei au fost mentinuţi.este o expresie de tip boolean folosită drept condiţie de continuare a ciclului cu test iniţial (condiţia este testata înainte de a se executa corpul ciclului. [trecere_la_pasul_următor] ) [<instrucţiune_corp_ciclu>] în care: formată din una sau mai multe instrucţiuni.) are exact acelaşi efect. care se execută după ce a fost executat corpul ciclului. k=5.instructiune]*. diferitele componente ale acesteia sunt opţionale. în general. cât şi ciclul cu test iniţial. trecere_la_pasul_următor := instrucţiune[.o instrucţiune (simpla sau structurată) care constituie corpul ciclului. calcularea produsului dat ca exemplu mai sus în pseudocod. iniţializare ::= instructiune[. for(. <instrucţiune_corp_ciclu>.in instrucţiunea while s-a pus drept condiţie compararea variabilei-contor cu valoarea ei finală. în consecinţă.){ P*=a+k. Remarcăm.k=5.Programarea orientata pe obiecte în limbajul Java valoarea următoare a variabilei-contor. Se observă ca se iniţializează P la valoarea 1 şi k la valoarea 5. separate prin virgule. k++) P*=a+k. folosind ciclul cu test final. care se execută înainte de intrarea în ciclu. folosite pentru pregătirea trecerii la următoarea parcurgere a ciclului. k++. Lăsăm cititorului ca exerciţiu să scrie acelaşi program. se programează în limbajul Java în modul urmator: for(P=1. instrucţiunea for(. .

variabila k a fost atât declarată. dar folosind instrucţiunea for în loc de while. int k=0. putând fi redefinite. inclusiv în corpul ciclului. cu condiţia ca acesta să înţeleaga corect modul ei de funcţionare.k<=n. exemplul anterior poate fi modificat după cum urmează: x=0. k<n. Tot acolo se arată că variabila care serveşte drept contor al ciclului poate fi.java si să explicaţi deosebirile constatate. iar creşterea acesteia de la o parcurgere la alta a ciclului poate fi de asemenea de tip real şi nu este obligatoriu să fie constantă.' pus dupa paranteza închisă. k++.java se reiau exemplele date in fisierele Repetare1. în exemplul precedent nu ar fi fost permis. în limbajul Java. Aceste variabile sunt tratate drept variabile locale ale ciclului for respectiv şi deci nu sunt vizibile (disponibile) după ieşirea din ciclu. corpul ciclului este constituit numai dintr-o instrucţiune vidă. b) for(P=1. k++) S+=a*k.i=9. Astfel. Astfel. for(int k=0.P*=a+k. for(int k=0. Considerăm că exemplele din acest program sunt suficiente pentru a arăta ca instrucţiunea for permite programatorului posibilităţi de utilizare foarte diverse. ea trebuie să fie singura instrucţiune din această zonă.java şi Serie1. k++) S+=a*k. Iată un astfel de exemplu: x=0. Este însă permis să se declare în zona de iniţializare mai multe variabile de acelaşi tip. Declararea unor variabile în zona de iniţializare a ciclului for Este permis ca în zona iniţializare a ciclului for să fie incluse şi unele declaraţii de variabile. Daca în zona de iniţializare apare o declaraţie. să se scrie for(x=0. reprezentată prin carecterul '.Severin Bumbaru incrementare. Suma3. În ultimul caz. cât şi iniţializată. dar îşi pierde valabilitatea la ieşirea din acest ciclu. k<n.k++).k=5. în zona de iniţializare a instrucţiunii for. Vă recomandăm să comparaţi în mod special programele din fişierele Serie1.java. Aceste exemple sunt date şi în programul din fişierul TestFor.java şi Serie3. În acest caz.java). Exemple de programe în care se foloseşte ciclul for În fişierele Repetare3. 92 . i--) S+=(a+i)*k. k<n. şi de tip real. Aceste exemple şi altele similare se găsesc în programul din fişierul TestFor1.java. În consecinţă această variabilă este disponibilă în interiorul acestei instrucţiuni.java.java.java si Serie3. Suma1. de exemplu.

deoarece compilatorul face distincţie între etichete şi nume în funcţie de contextul în care acestea sunt utilizate. metode etc. că astfel de excepţii sunt instructiunile switch. Iată acum un exemplu de folosire într-un ciclu cu test iniţial: k=1. unde etichetăeste eticheta unei instrucţiuni şi este un identificator.. care constă în folosirea instrucţiunilor break şi continue şi a instrucţiunilor etichetate.Programarea orientata pe obiecte în limbajul Java Instrucţiuni etichetate În principiu. Am arătat deja.while sau for şi are ca efect ieşirea forţată (abruptă) din structura de control în care se găseşte instrucţiunea respectivă. instrucţiuneeste o instrucţiune simplă sau structurată. fară a se crea prin aceasta confuzii. având în vedere experienţa practică şi pentru a veni în ajutorul programatorilor. În consecinţă.while şi for. fără a încălca însă principiul de bază al acesteia. while(S+t!=S) { 93 . Instructiunea break se poate folosi în corpul unei instrucţiuni switch. S=0. din precauţie. Eticheta este opţională (de aceea a fost scrisă de noi între paranteze drepte). autorii limbajului Java au admis şi anumite abateri de la structurile de control fundamentale acceptate de teoria programării structurate. iar instrucţiunea goto nu există. orice instrucţiune în limbajul Java poate purta o etichetă. do. cuvântul cheie gotoa fost menţinut în limbaj. clase. s-a arătat că limbajul Java respectă principiile programării structurate. Se permite să se folosească drept etichete chiar şi identificatori care mai sunt folosiţi în acelasi program ca nume de variabile.. Terminarea abruptă a execuţiei instrucţiunilor structurate În secţiunile anterioare.. while. conform căruia fiecare asemenea structură trebuie sa aibă un singur punct de intrare şi un singur punct de ieşire. Exemplu alpha: x=2*a+b. Instrucţiunile etichetate au forma etichetă : instrucţiune unde etichetă este un identificator. Ne vom ocupa acum de o alta abatere de la programarea structurată pură. el nu este încă efectiv folosit.do. instrucţiunile de control au fost concepute în conformitate cu aceste principii. Cu toate acestea. Chiar dacă. continue [etichetă]. S-a arătat deja cum se foloseşte instrucţiunea break în corpul unei instrucţiuni switch. Folosirea instrucţiunilor break şi continue Instructiunile break şi continue au forma generală următoare: break [etichetă].

94 . următorul fragment de program: s=0.) va fi "sărită" pentru valori ale lui k mai mici decât 16. k++. Iată şi un exemplu similar. S=0. efectul este că se trece peste restul instrucţiunilor din corpul ciclului. chiar dacă condiţia principală de continuare a ciclului (S+t!=S) este încă satisfacută. Instrucţiunea continue se poate folosi numai în corpul ciclurilor (while.0e-10*S) break. ca în exemplul urmator: ciclu1: while(w>0. începând din punctul în care se găseşte instrucţiunea continue până la sfârşitul acestuia. Să considerăm. if(S+t==S) break. k++) { x*=a. for).) { t*=a/k. în paranteza lui for toate cele trei zone au ramas vide. } În acest caz. System. iar noi dorim ca prin break să se iasa forţat din cea exterioară.out.Severin Bumbaru t*=a/k. dar instrucţiunea System. iar condiţia de ieşire din ciclu şi pregatirea continuarii ciclului se găsesc în corpul acestuia.. S+=t.05){ w/=a. for(. k++. if(k<16) continue. dar se continuă executarea ciclului.. în care se iese forţat din instrucţiunea for: k=1. do. Dacă instrucţiunea continue nu are etichetă. if(t<1. } Întrucât iniţializarea ciclului s-a făcut înainte de instructiunea for. corpul ciclului se va repeta pentru valori ale lui k de la 0 la 19. } În acest caz.while. s+=x.println("k="+k+" x="+x+" s="+s).0e-10*S) din instructiunea if se iese forţat din ciclu. în momentul în care este satisfacută condiţia (t<1. astfel că afişările se vor face numai începand cu k=16. for(k=0..println(. trecându-se direct la acolada de închidere a corpului ciclului. k<20. adică se reia executarea corpului acestuia cât timp este satisfacută condiţia de continuare.. Folosirea etichetei în instrucţiunea break Necesitatea utilizării unei etichete apare atunci când există două astfel de structuri imbricate una în alta.out. S+=t. de exemplu.

pentru valori ale variabilei i cuprinse între 1 şi 5. System. dar s-ar fi reluat execuţia ciclului exterior (while).println("Control 3: i="+i+" j="+j).out. se generează o excepţie sau o eroare prin care se semnalează incidentul care a avut loc. iar celalalt este ieşirea prin break. se va trece forţat la sfârşitul corpului ciclului exterior.out.println("Control 4: i="+i). de regulă. deci. Dacă nu ar fi conţinut eticheta ciclu1.out. Folosirea etichetei în instrucţiunea continue Să considerăm acum următorul fragment de program: ciclu1: for (int i=0. i<6. În ultimul exemplu.println("Control 2: i="+i+" j="+j). Remarcam.java. Programul de testare pentru instrucţiunea continue se găseşte în fişierul TestCont. Când apare o astfel de situaţie. Excepţiile şi erorile pot fi generate atât de echipamente (excepţii sau erori hardware). cât şi de programe (excepţii software). că eticheta conţinută în instrucţiunea break indică faptul ca se va ieşi forţat din structura de control care poartă aceeaşi etichetă. y+=w*s } } Instrucţiunea break se găseşte. } // Sfarsitul ciclului interior System. Desigur că pot să existe mai multe instrucţiuni de control cuprinse una în alta şi fiecare dintre ele poate avea o etichetă. care poate fi utilizată într-o instrucţiune break. if(s>b) break ciclu1.println("Control 1: i="+i). pot apare anumite situaţii care altereaza desfăşurarea normală a acestuia. k++) { s+=w. k<n. j--) { System. 95 . } // Sfarsitul ciclului exterior Instrucţiunea conţinue eticheta ciclu1. i++) { System. în cazul de faţă din ciclul exterior. Daca luam însă în consideraţie ciclul exterior.out. implicand. Dacă însă este prezenta eticheta din break. desigur. conform căruia fiecare structură de control trebuie sa aibă un singur punct de intrare şi un singur punct de ieşire. constatăm ca acesta respectă principiul menţionat. în acest exemplu.Programarea orientata pe obiecte în limbajul Java for(int k=0. if(i>1 && i<5) continue ciclu1. se va ieşi forţat din instrucţiunea de control care poartă această etichetă. j>0. În consecinţă. ciclul interior are două puncte de ieşire: unul este ieşirea normală din ciclul for.această instrucţiune ar fi provocat numai ieşirea dim ciclul interior (for). care aparţine ciclului exterior. Aceasta înseamnă că instrucţiunea break cu etichetă constituie o abatere locală de la principiul de bază al programării structurate. for(int j=3. deci nu se vor mai executa instrucţiunile de afişare "Control 3" şi "Control 4".java. Tratarea excepţiilor În timpul executării programului. Testarea a diferite situaţii de utilizare a instructiunii breakse face în programul din fişierul TestBreak. şi reluarea ciclului interior continut de acesta. în corpul ciclului interior.

una după alta. unele incidente din subsistemele de intrare/ieşire etc.. iar informaţia conţinută în el poate fi utilizată pentru a decide calea pe care se va merge în continuare în derularea programului. la executarea programului.. până se ajunge la cea care are între paranteze numele clasei excepţiei care s-a produs şi se execută secvenţa din corpul acestei clauze. iar acesta afişeaza excepţia survenită şi opreşte executarea programului. în limbajul Java. Se parcurg apoi. programatorul poate să prevadă căi alternative de continuare a executării programului... În corpul instrucţiunii try se pune secvenţa de instrucţiuni în care este posibil ca. Deosebirea dintre excepţii şi erori este că excepţiile sunt considerate că pot fi tratate prin program.. care conţine informaţia despre excepţia respectivă. În mediul de lucru Java.. adică după ce a fost tratată excepţia prin una din clauzele catch. Acest obiect poate fi captat prin program.java se testează apariţia unei excepţii de împărţire la zero. Dacă excepţia a apărut într-un punct situat în corpul unei instrucţiuni try.. Întrucât în programul nostru nu există instrucţiuni prin care să se trateze această excepţie. clauzele catch.. catch (ClasaExceptieN variabilaN) { secventaN } [finally { secventa_finalizatoare }] În engleza. Tratarea prin program a excepţiilor se face.Severin Bumbaru Exemple de excepţii hardware pot fi întreruperile. Excepţiile software sunt mult mai diverse. de o clauză finally sub forma urmatoare: try { secventa } catch (ClasaExceptie1variabila1) { secventa1 } catch (ClasaExceptie2 variabila2) { secventa2 } .. în timp ce erorile sunt considerate mai curând nerecuperabile. folosind instrucţiunea try urmată de una sau mai multe clauze catch şi. există posibilitatea de a se trata prin program diferitele excepţii care apar în timpul execuţiei. programul se întrerupe. În programul din fişierul TestExcept1. trecându-se controlul asupra sistemului de operare al calculatorului.. Întrucât variabila b are valoarea zero.. la executarea împărţirii a/b procesorul calculatorului generează o excepţie aritmetică. iar catch înseamnă prinde. să apară excepţii. depinzând de specificul programelor care le generează.. excepţia de împărţire la zero. sau dacă nu a fost tratată prin 96 . astfel că restul instrucţiunilor nu se mai execută. opţional. În acest fel. aceasta instrucţiune se termină în mod abrupt. Toate obiectele de excepţie care se referă la acelaşi tip de incident formează o clasă de excepţii. fără a mai fi necesară oprirea executării lui. În limbajul Java.. Clauza finally este opţională şi conţine o secvenţă de instructiuni care se vor executa în final. trecându-se direct la acolada de închidere a blocului. la apariţia unei excepţii se generează un obiect special numit excepţie. try înseamnă încearcă..

Întrucât se ştia că este posibilă apariţia unei excepţii aritmetice. s-a prevăzut şi o clauza catch pentru clasa Exception. dar a fost suprimată prima din clauzele catch. În ce constă teorema de structură din metoda programării structurate? 14. însa de clauza catch(Exception e). se poate observa că şi de data aceasta excepţia aritmetică a fost captata. după cea care a generat excepţia. Exemplul 1: În fişierul TestExcept2. instrucţiunile existente în blocul try. dar s-a modificat valoarea numitorului fracţiei. În ce ordine se aplică operatorii cu acelaşi nivel de precedenţă? 6. Cum se stabileşte tipul unei expresii? 3.java s-a reluat acelaşi program. În ce ordine se evaluează operanzii unui operator binar? 7. Care sunt categoriile de instrucţiuni de control admise de metoda programarii structurate? 97 . a*c. în care excepţia este tratată prin instrucţiunea try. 4. atunci când s-au tratat excepţiile prin instrucţiunea try. Exemplul 3: În fişierul TestExcept4. Comparând rezultatele executării celor două programe menţionate. Ca rezervă. Care sunt tipurile următoarelor expresii: a+b. u de tip float şi v de tip double. Mai mult. c de tip int. Ce este o instrucţiune? 9. u-2*v. Fie a si b variabile de tip byte. a*c+u. Executând acest program.java este dată o modificare a programului din fişierul TestExcept1.java. nu au mai fost executate. ci s-a executat blocul clauzei catch(ArithmeticException e1).Programarea orientata pe obiecte în limbajul Java nici una dintre acestea.java se reia programul din exemplul anterior. Ce este instrucţiunea vidă şi cum se scrie? 11. Ce deosebire este între instrucţiunile simple şi cele structurate? 10. constatăm că. Ce deosebiri există între o expresie şi o instrucţiune-expresie? 13. În schimb. astfel că nu mai are loc o împărţire la zero. Ce este o instrucţiune-expresie? 12. s-a încercat să se capteze mai întai această excepţie. Se observă ca secvenţa din clauza finallyeste executată şi în acest caz.java se reia programul din Exemplul 1. Exemplul 2: În fişierul TestExcept3. Ce este precedenţa operatorilor? 5. Ce este o expresie? 2. care va capta orice alta excepţie. în fişierul TestExcept5. Ce forma sintactică are expresia condiţională şi care este semnificaţia acestei expresii? 8. Se observă ca secvenţa din aceasta clauză este executată chiar daca excepţia a fost captată prin catch. Întrebări Nivel 1 1. după care s-a continuat executarea normală a programului. programul nu a mai fost oprit anormal. dar după captarea excepţiei s-a introdus si clauza finally.

Ce sunt excepţiile? 19. Ce este o etichetă şi ce formă sintactică are o instrucţiune etichetată? 18. 6. 4. La ce serveşte clauza finally şi unde se plasează? 1.java. Ce rol are instrucţiunea break în cadrul unui bloc switch? 17. Care este forma sintactică a instrucţiunii de tratare a exceptiilor şi cum trebuie ea interpretată? Nivel 2 Construiţi arborele sintactic al următoarei expresii: (a+2*b/c)*(2*d-3)+3*e+5 Construiţi arborele sintactic al următoarei expresii: a=(b+=2*a)-c++*(d-=c+1) Construiţi arborii sintactici ai tuturor expresiilor din fişierul EvExpresii. 5. Care este schema logică a structurii de control secvenţiale şi cum trebuie interpretată? 9. Cum acţionează o instrucţiune continue fără etichetă în corpul unui ciclu? 21. Care este schema logică a ciclului cu test final şi cum trebuie interpretată? 12. Ce deosebire este între excepţii şi erori? 20. Care este forma sintactică a instrucţiunii switch şi cum este ea interpretată? 16. Poate o etichetă să aibă acelaşi identificator cu cel al unui nume de variabilă sau de metodă? 19. Cum acţionează o instrucţiune break fără etichetă în corpul unui ciclu? 20. 3. Ce fel de structură de control este un bloc şi care este forma lui sintactică? 16. Ce este o instrucţiune de atribuire şi care este efectul ei? Care este deosebirea dintre valorile expresiilor de preincrementare şi postincrementare? Dar între efectele instrucţiunilor de preincrementare şi postincrementare? 7. Cum se stabileşte cărui if îi aparţine clauza else în cazul instructiunilor if imbricate? 15. 2. Explicaţi rezultatele obţinute la executarea programului din fişierul ExprCond. Prin ce instrucţiuni se realizează structura de control alternativă şi care este forma lor sintactică? 18. Când sunt eliminate din memorie variabilele locale? 14. Ce sunt variabilele locale şi care este domeniul lor de vizibilitate? 17. În ce situaţie se foloseşte o instrucţiune continue cu etichetă? 23. Care este schema logică a ciclului cu test iniţial şi cum trebuie interpretată? 11.java. În ce situaţie se foloseşte o instrucţiune break cu etichetă? 22. La ce serveşte clauza catch şi unde se plasează? 24. Ce este o instructiune de invocare de metodă şi care este efectul ei? 8. Unde sunt plasate variabilele locale în memoria maşinii virtuale Java? 13. 98 .Severin Bumbaru 15. Care este schema logică a structurii de control alternative şi cum trebuie interpretată? 10.

câmpuri. ierarhia de clase Java. Constructori. Tablouri Tablouri unidimensionale. Atribuirea de valori variabilelor-referinţă. Pachetele de clase din Java API. Clasa Class.Programarea orientata pe obiecte în limbajul Java Tipul referinţă. ci doar numele.lang Clasa Object. Clasele de excepţii. Tablouri multidimensionale. în sensul că numele. Moştenirea şi polimorfismul.lang. Utilizarea claselor din pachetul java. 99 101 102 102 103 104 105 105 107 108 111 112 119 120 121 122 126 133 134 Tipul referinţă În limbajul Java există două categorii de tipuri de date: tipuri primitive şi clase. declaratia import. Clasa System. Clasele String şi StringBuffer. metode. mulţimea de date. Clasele acoperitoare de tip. datele de tipuri primitive apar sub forma de variabile. Tipurile primitive sunt predefinite în limbaj. Utilizarea parametrilor din linia de comandă Întrebări. În program. Pe programator nu il interesează insă adresa de memorie la care se găseşte variabila. Clasa Math. crearea obiectelor prin operatorul new. Clase. tipul şi valoarea acesteia. Utilizarea claselor din pachetul java. mulţimea de operaţii şi reprezentarea datelor în memoria internă a maşinii virtuale Java pentru fiecare tip sunt definite în insăşi specificaţia limbajului Java şi nu mai pot fi modificate de programatori. Tablouri. declararea variabilelor referinţă. Fiecare variabilă are un nume. 99 . un tip şi o valoare şi este plasată într-o anumita locaţie de memorie. În locaţia de memorie respectivă se găseşte chiar valoarea variabilei. Utilizarea parametrilor din linia de comandă Tipul referinţă.

ci şi pe cele ale unor variabile simple. Există. cum sunt Pascal şi C. numite variabile referinţă. deosebiri importante: . Singura deosebire constă în faptul că. Deosebirea este că o variabilă simplă este o locaţie de memorie care conţine o valoare primitivă. sau poate creea propriile sale clase. Referinţele din Java sunt similare pointerilor din unele limbaje de programare tradiţionale. s2 si s3 sunt variabile referinţă către obiecte din clasa String. ceeace nu este permis asupra referinţelor în Java. egalitate (==) şi inegalitate (!=) care au aceleaşi semnificaţii şi mod de utilizare ca pentru toate celelalte tipuri de date.valorile variabilelor-pointer sunt adrese din memorie care pot fi cunoscute de programator (de exemplu pot fi afişate) De asemenea. care conţine însă o structură de date. s3. În schimb. unei variabile-pointer i se poate atribui ca valoare o adresa dată explicit. programatorul poate utiliza clasele din pachetele deja existente. obiectele sunt plasate într-o zonă de memorie specială. Din această cauză. Comparând clasele cu tipurile primitive. Obiectul propriu-zis nu se găseşte în memorie în acelaşi loc 100 . se foloseşte un nume de clasa.Severin Bumbaru Clasele sunt tipuri de date structurate specifice programării orientate pe obiecte. Aceasta înseamnă că valoarea fiecăreia deintre ele nu este un obiect. s2. Atentie: s1. constatăm că clasa este o extensie a conceptului de tip. Declararea variabilelor referinţă Declararea variabilelor referinţă se poate face la fel cu declararea variabilelor de tipuri primitive. Mulţimea de valori a acestui tip este mulţimea referinţelor. ci o referinţă la acest obiect. arată că s1. declaraţia String s1. fiecare clasă poate avea mai multe instanţe. totuşi. în timp ce obiectul este tot o zonă de memorie. adică "gramadă"). se consideră că variabilele referintă aparţin unui tip de date numit tip referinţă. . . s2 si s3 nu sunt şiruri de caractere (adică obiecte din clasa String) ci sunt doar referinţe către şiruri de caractere. adresele la care se găsesc în memorie obiectele indicate de referinţele din Java nu pot fi cunoscute de utilizator. adică din clasa şirurilor de caractere. referinţele pot fi folosite numai pentru obiecte. iar obiectul este o extensie a conceptului de variabila. numită memorie dinamică (în engleză: heap. Operaţiile permise asupra datelor de tip referinţa sunt cele date de operatorii de atribuire (=). În program. adică mulţimea locaţiilor (adreselor) din memoria dinamică.în limbajele traditionale (de exemplu în C/C++) se pot face asupra pointerilor operatii aritmetice.în limbajele tradiţionale. pointerii pot indica nu numai adresele în memorie ale unor structuri de date. Valoarea unei variabile referinţă nu este obiectul însuşi. ci o referinţă la obiect. în locul tipului primitiv. De exemplu. În java. În memoria maşinii virtuale Java. Clasele se definesc de programatori şi se grupează în pachete de clase. numite obiecte. Localizarea în memorie a obiectelor se face cu ajutorul unor variabile speciale. La crearea unui program nou.

nume_metodă(parametri_efectivi) deci numele metodei nu mai este calificat prin (însoţit de) numele clasei. de exemplu int i1. Invocarea unei metode nestatice (a instanţei) se face sub forma referinţa_la_obiect. În acest caz. în timp ce metodele nestatice pot invoca atât câmpurile statice. metode.i3. Câmpurile pot fi statice (ale clasei) sau nestatice (ale instanţei). O astfel de invocare de funcţie poate fi deci folosită ca o componentă într-o altă expresie. de exemplu x=2*Math. Ca şi câmpurile. valoarea întoarsă de metodă (valoarea expresiei) este ignorată.nume_metoda(parametri_efectivi) a cărei valoare este valoarea întoarsă de funcţia respectivă. Obiectul conţine numai câmpuri nestatice. Când clasa este instanţiată. efect lateral. sau prin o expresie care are ca valoare o astfel de referinţă. De exemplu. daca r1 este o variabilă referinţă care indică un anumit obiect din memorie. ci undeva în memoria dinamică. Vom arăta ulterior şi modul în care pot fi iniţializate variabilele referinţă. Datele unei clase se numesc câmpuri. folosindu-se numai 101 .Programarea orientata pe obiecte în limbajul Java cu variabila. Metoda este o funcţie. metoda respectivă este o procedură şi trebuie să aibă obligatoriu efect lateral. care este rezervat clasei respective. în cazul declararii unor variabile primitive. de asemenea.sqrt(a) serveste pentru a calcula rădăcina patrată a lui a. Dacă valoarea întoarsă de metodă este void. cât şi pe cele nestatice (ale unei instanţe a clasei respective). adică au ca valori astfel de numere. asociată cu o colecţie de proceduri sau funcţii. Putem folosi această invocare de metodă într-o expresie mai complicată. care întoarce o valoare şi poate avea. i2 si i3 sunt numere de tip int.met(a) are ca efect invocarea metodei met pentru obiectul indicat de r1. Clase. variabilele i1. care este o metodă statică a clasei Math (clasa funcţiilor matematice uzuale). câmpuri. În acest fel. ci prin cel al variabilei referinţă la obiectul respectiv. urmată de punct_şi_virgulă. Câmpurile statice se păstreaza în memorie într-un singur loc. metoda met(a) va folosi atât câmpurile (nestatice ale) obiectului indicat de referinţa r1. în care scop este invocată funcţia sqrt. Metodele statice pot invocă numai câmpurile statice ale clasei respective. metode Clasa este o structură de date. Invocarea unei metode statice (a clasei) se face printr-o expresie de forma nume_clasa. care utilizează datele din această structură. cât şi câmpurile (statice ale) clasei căreia îi aparţine acest obiect. De exemplu. atunci r1. ea poate fi invocată şi sub forma de instrucţiune. expresia Math. Dacă o metoda are efect lateral. iar met(a)este o metodă nestatică a clasei căreia îi aparţine acest obiect. Această instrucţiune constă numai din expresia de invocare a metodei. metodele pot fi statice(ale clasei) şi nestatice (ale instanţei). sau variabile membre. Prin contrast.i2.sin(a)+3. în memoria maşinii virtuale Java se construieşte un obiect (o instanţă a clasei respective).

care pot să difere între ei prin numărul şi/sau tipul argumentelor. Constructori Constructorul este o procedură specială. este o instrucţiune de atribuire. o clasă poate avea mai mulţi constructori. în care variabilei s2 i se atribuie valoarea expresiei new String("alpha"). Constructorul alocă în memoria dinamică spaţiul necesar pentru un obiect din clasa căreia îi aparţine şi iniţializează câmpurile acestui obiect cu valori care depind de argumentele sale. prin care se construiesc obiecte dintr-o anumită clasă. se alocă în memorie şirul "abcd_1234" şi se atribuie ca valoare iniţială a variabilei s1 referinţa la acest şir. De exemplu. iar clasele derivate se numesc şi subclase. se obţine ca efect lateral alocarea în memorie a şirului "alpha". Să considerăm acum următoarele două instrucţiuni: String s1=new String("abcd_1234"). Este evident că metodele care întorc void (procedurile) pot fi invocate numai sub formă de instrucţiuni.println(sir). În schimb. Crearea obiectelor prin operatorul new Invocarea unui constructor se face prin operatorul new. prin care se specifică faptul că s1 şi s2 sunt variabile referinţă. urmat de numele constructorului respectiv şi de lista de argumente a acestuia.out. Operatorul new este unar. ale căror valori sunt referinţe la obiecte din clasa String. iar operandul lui este un constructor. expresia new String("acesta este un sir") are ca efect (lateral) construirea în memorie a şirului de caractere "acesta este un sir". Prima dintre ele este o declaraţie. Un exemplu cunoscut deja este instrucţiunea System.Severin Bumbaru efectul lateral al metodei respective. s2=new String("alpha"). fiind folosite pentru efectul lor lateral. iar valoarea acestei expresii este referinţa la obiectul nou construit. Clasa de baza se mai numeste şi superclasă. La executarea acestei expresii. iar referinţa la acest şir se atribuie ca valoare a variabilei s2 Moştenirea şi polimorfismul Moştenirea este una din proprietăţile fundamentale ale claselor în programarea orientată pe obiecte. s2. Totodată. Ea constă în faptul că dintr-o clasă se pot deriva alte clase. Efectul lateral al acestei expresii este construirea în memorie a unui obiect din clasa căreia îi aparţine constructorul. 102 . iar valoarea expresiei este referinţa către acest şir. A doua dintre instrucţiunile de mai sus. Constructorul are întotdeauna acelaşi nume cu clasa. deci forma generala a expresiei de invocare a unui constructor este new nume_constructor(parametri_efectivi) Valoarea acestei expresii este o referinţă la obiectul nou construit.

în care există metoda double arie(). de asemenea. adică o clasă poate avea mai multe superclase. de exemplu. Polimorfismul este o alta proprietate fundamentală a claselor. care a fost creat folosind operatorul new. variabilei-referinţă ob i se atribuie valoarea variabilei-referinţă s. acum variabila ob din clasa Object are ca valoare o referinţa către obiectul "abcd" din clasa String. dar va avea un comportament diferit. Această ierarhie de clase este unică. a cărei valoare este aria poligonului. adică orice clasă are obligatoriu o superclasă şi numai una. De exemplu. Să considerăm. Atribuirea de valori variabilelor-referinţă Unei variabile referinţă i se pot atribui ca valori referinţă la obiecte din clasa variabilei respective sau din clasele derivate. având în vedere că clasa String este derivată din clasa Object. s-au declarat variabilele-referinţă ob din clasa Object şi s din clasa String. în programarea orientată pe obiecte este permisă moştenirea multiplă. dar în aceasta din urmă pot exista. String s=new String("abcd"). ultima fiind iniţializată cu o referinţă către şirul "abcd". În primele două instrucţiuni. Singura excepţie o constituie clasa Object. Aceasta metodă este o funcţie. În a treia instrucţiune. În consecinţă. cu atât mai mult. 103 . de modul de calcul al ariei unui poligon oarecare. ob=s. Ierarhia de clase Java În general. care este rădăcina ierarhiei de clase Java şi nu are superclasă. Aceasta înseamnă că toate câmpurile şi metodele existente în superclasă sunt utilizabile şi în subclasă. că exista clasa Poligon. În limbajul Java este permisă numai moştenirea simplă. Aceasta înseamnă că ea va avea în subclasă acelaşi nume şi aceeasi lista de parametri şi acelaşi tip de valoare întoarsă ca în superclasă. dar este evident că modul de calcul al ariei triunghiului diferă de cel al calculării ariei patratului şi. urmatoarele instrucţiuni sunt corecte: Object ob. câmpuri şi/sau metode suplimentare. deci fiecare clasă poate avea numai o singură superclasă.Programarea orientata pe obiecte în limbajul Java Fiecare clasă derivata moşteneşte câmpurile şi metodele superclasei. Sa considerăm acum că Triunghi şi Patrat sunt doua clase derivate din clasa Poligon. În limbajul Java este posibil ca o metodă a superclasei să fie redefinită în subclasă. Vom arata ulterior că lipsa moştenirii multiple este compensată în Java prin faptul că fiecare clasa poate avea mai multe interfeţe. În ambele clase derivate va exista metoda double arie().

ci numai acele clase care sunt utilizate efectiv în program.NumeClasa. care sunt puse la dispoziţia programatorului sub formă compilată (bytecode). Ea nu are semnificaţia că se importă toate clasele din pachetul (subpachetul) respectiv. dar autorii platformei Java au preferat denumirea de pachet.Severin Bumbaru Pachetele de clase din Java API Clasele sunt grupate în pachete (engleză: package). Principalele pachete de clase sunt: java.*.lang nu este necesară o declaraţie de import. java. Pachetul este o colecţie de clase reutilizabile destinate unui anumit domeniu de utilizare. la începutul fişierului respectiv trebuie pusă declaraţia în al pachetului respectiv. pentru a utiliza orice clase din pachetul java.lang . Acest subpachet poate avea.la firma Sun Microsystems. se numeşte declaraţie de import la cerere.*. Declaraţia import Pentru a putea utiliza într-un fişier-sursa Java un anumit pachet (subpachet) de clase.io se foloseşte declaraţia Declaraţia import nume_pachet. necesare în diferite domenii de aplicaţie. acestea fiind importate implicit. Daca pachetul p are subpachetul q.swing . 104 . java. Ar putea fi numit şi "bibliotecă de clase". alte subpachete.conţine clasele de bază necesare programării în limbajul Java. atunci p.io.conţine clasele necesare pentru programarea operaţiilor de intrare/ieşire.3/docs/api/index.awt si javax.io .applet .*.conţine clase pentru anumite structuri de date tipice (listă.pentru programarea appleturilor. java.q este numele complet (numele calificat) al subpachetului q. pachetul java.conţin clase necesare pentru realizarea interfeţelor grafice. pentru a importa clasa File din import java.File. Pentru pachetele conţinute în Platforma Java 2 Standard Edition (J2SE) această documentaţie poate fi gasită pe Internet la urmatoarea adresă: java. Pentru a importa numai o anumita clasă dintr-un pachet.sun. java. care nume_pachet este numele calificat Pentru clasele din pachetul java. la rândul sau.com/products/j2se/1. Pachetul poate avea subpachete.io.util . import nume_pachet. De exemplu. De exemplu. se foloseste declaraţia import nume_pachet. stivă etc) şi alte clase utile.html .io se pune declaraţia import java.interfaţa de programare de aplicaţii) este descrierea unui set standard de pachete necesare programării în Java. Java API (Application Programming Interface . Există însă şi multe alte pachete.

pentru a efectua acţiuni specifice acestor clase.Programarea orientata pe obiecte în limbajul Java Utilizarea claselor din pachetul java. Noi vom prezenta aici numai o parte dintre ele. Metodele clasei Object Clasa Object nu are date membre. Clasa Object Clasa Object este rădăcina ierarhiei de clase a platformei Java. fără atribute precizate. În schimb.equals(b) în care a şi b sunt două obiecte. 105 . valoarea întoarsă (valoarea obţinută la evaluarea acestei funcţii) este de tip boolean. Clasa are un singur constructor. ceeace se poate scrie şi sub forma expresiei a==b. adică au aceeaşi adresă în memorie. În clasa Object sunt declarate. Obiectele acestei clase nu conţin date. această metoda poate fi redefinită. Lista completă a claselor din pachetul java. Expresia a. În clasele derivate. Noi vom prezenta aici câteva clase mai frecvent utilizate. chiar dacă ele nu au aceeaşi referinţă. clasele sale fiind importate implicit. respectând principiul polimorfismului. toate celelalte clase posedă metodele clasei Object. obiectele acestei clase nu au stare (cu excepţia faptului ce ele există sau nu). care nu are parametri. Orice altă clasa este derivată direct sau indirect din clasa Object. de asemenea. În consecinţă. astfel încât să compare cele două obiecte după conţinut. Pentru acest pachet nu este necesară declaraţia import. se consideră că lor li se pot da ca valori referinţe la orice fel de obiecte. Unele din aceste metode vor trebui redefinite în clasele derivate. Object(). întoarce valoarea true dacă a este identic cu b şi valoarea false în caz contrar. care vor fi utilizate în cele ce urmează. Este singura clasă care nu are o superclasă.lang şi descrierea lor se găsesc în documentaţia Java API de pe Internet. Conceptual. Conform cu principiul moştenirii. clasa dispune de un set de metode. Metoda equals() este declarată sub forma: public boolean equals(Object obj) ceeace înseamnă că nivelul de acces este public. instanţele clasei Object sunt obiecte oarecare. metoda equals() întoarce valoarea true numai dacă cele doua obiecte comparate sunt cu adevărat identice.lang Pachetul java. metode care se consideră ca trebuie să existe în toate celelalte clase. Metodele clasei Object sunt descrise în Java API. iar unicul argument aparţine clasei Object. la elaborarea programului. indiferent de clasa căreia îi aparţin.lang conţine clasele fundamentale şi există pe orice platformă Java. Variabilele referinţă la Object se folosesc atunci când. Aşa cum este ea definită în clasa Object.

expresia a. dar situat la o altă adresă de memorie şi deci având o altă referinţă.toString(). .util. în care a şi b sunt referinţe la obiecte. atunci codurile de dispersie obţinute aplicând metoda hashCode() fiecăruia în parte trebuie să fie. aceasta metodă întoarce un şir de forma java. În consecinţă.util. astfel încât să se obţină o reprezentare sub formă de şir a conţinutului obiectului respectiv. în care a este un obiect. aplicând metoda hashCode() la doua obiecte diferite. întoarce reprezentarea sub forma de şir a obiectului a. 106 . Asa dar.clone().Hashtable şi java.HashMap. deoarece cele două obiecte comparate au conţinuturi identice. Metoda clone() este declarată sub forma: protected Object clone() şi are rolul de a întoarce o clonă a obiectului căruia i se aplică.este posibil ca.Severin Bumbaru Metoda hashCode() este declarată sub forma public int hashCode() şi întoarce codul de dispersie al obiectului căruia i se aplică. să se obţină coduri de dispersie egale. Metoda toString() este declarată sub forma public String toString() şi întoarce reprezentarea sub forma de şir de caractere (de obiect din clasa String) a obiectului căruia i se aplică.Object@<cod_dispersie> în care <cod_dispersie> este codul de dispersie al obiectului respectiv. expresia a==b va avea valoarea false. după ce se execută instrucţiunea b=a. deci întoarce un obiect identic cu acesta. . cum sunt cele care fac parte din clasa java.equals(b) va întoarce în mod normal valoarea true.dacă se aplică de mai multe ori aceluiaşi obiect. Codul de dispersie (engleză: hash code) este un număr întreg (de tip int) care are următoarele proprietăţi: . în timp ce expresia a. În clasele derivate aceasta metodă este redefinită. În cazul obiectelor aparţinând clasei Object. de asemenea. Metoda hashCode() este utilă atunci când obiectele trebuie plasate în tabele de dispersie.dacă două obiecte sunt egale între ele în sensul definit prin metoda equals(). exprimat în hexazecimal. metoda hashCode() întoarce de fiecare dată acelaşi cod de dispersie.lang. deoarece valorile variabilelor referinţă a şi b sunt diferite. egale. însa este preferabil ca această situaţie să se întâlnească cât mai rar cu putinţă.

astfel încât sa devină publică. metoda clone()) sunt testate în programul din fişierul TestObject. În consecinţă. în care a este o referinta la un obiect. Întrucât metoda clone() este protejată (are nivelul de acces protected) ea nu poate fi utilizată decât pentru obiectele din clasa Object. 107 .. în timp ce erorile sunt incidente grave. adică o situaţie anormală în procesul de calcul. astfel că expresia a==b întoarce valoarea true. În limbajul Java se face distincţie între excepţie şi eroare.lang există şi numeroase clase de excepţii. adica a şi b vor indica acelaşi obiect din memorie. desigur. În schimb.getClass(). variabila b va avea ca valoare aceeaşi referinţă ca şi variabila a.java. Metodele prezentate aici (exceptând.java. Metoda getClass() este declarată sub forma public final Class getClass() O expresie de forma a.de regulă . Instanţele acestor clase sunt creeate de către maşina virtuală Java atunci când se produce o excepţie. Toate aceste clase sunt descrise în documentatia Java API. Se consideră ca excepţiile sunt incidente care pot fi captate prin mecanismul try . ca în ultimele trei instrucţiuni ale programului din fişierul TestObject. Clase de excepţii În pachetul java. ea poate fi redefinită la clasele descendente. după ce se execută instrucţiunea b=a. care conţine informaţii despre clasa obiectului indicat de variabila a. Clasa are doi constructori: public Exception() creează un obiect din clasa Exception (deci "o excepţie") care nu conţine nici un mesaj. care . Clasa Exception Această clasă este rădăcina ierarhiei claselor de excepţii.Programarea orientata pe obiecte în limbajul Java În schimb. atunci când dorim ca in clauza catch sa fie captată orice fel de excepţie. celelalte urmând să fie indicate la descrierea claselor care conţin metode care pot genera excepţii. catch şi pot fi deci tratate prin program. întoarce ca valoare un obiect din clasa Class.nu pot fi tratate prin program ci produc oprirea executării acestuia. scriem această clauză sub forma catch(Exception e) { instructiuni_de_tratare_a_exceptiei e } unde e este numele simbolic (identificatorul) dat excepţiei captate. Deocamdată vom folosi această metoda numai pentru a afişa numele clasei. Vom menţiona aici numai două dintre ele.

atât pentru clasa Exception.Totuşi. Obiectele din această clasă sunt constante. rezultat din punerea celor două unul în continuarea celuilalt. În particular. Instanţa respectivă conţine un mesaj care indică ce fel de excepţie s-a produs. cum ar fi. Dacă este necesar să se folosească şiruri modificabile. Clasa Exception nu are propriile ei metode. Clasa ArithmeticException Instanţele acestei clase sunt generate de maşina virtuală Java atunci când are loc o situaţie anormală la efectuarea unei operaţii aritmetice. Dăm aici o parte din constructorii şi metodele mai frecvent utilizate ale clasei String. există în pachetul java. Exemple de utilizare a claselor de excepţii s-au dat deja în capitolul "Tratarea excepţiilor". se recurge la clasa StringBuffer. adică şirurile conţinute în ele nu pot fi modificate. Acest şir conţine. Clasele String şi StringBuffer Pentru şirurile de caractere. Clasa String Toate şirurile în limbajul Java. Prin concatenarea a două şiruri se obţine un nou şir. clasa String conţine şi suportul necesar pentru operatorul de concatenare'+'. ce incident a condus la generarea excepţiei respective. de regulă. De exemplu. cât şi pentru toate celelalte clase de excepţii se pot folosi metodele superclasei Object. iar cele ale clasei StringBuffer conţin zone tampon pentru şiruri.lang doua clase: String şi StringBuffer. pe care le vom numi în viitor simplu "şiruri". de exemplu "ABCdef123". Vom arăta ulterior cum putem folosi aceşti constructori pentru a genera propriile noastre excepţii. expresia "ABC"+"defg" are ca valoare şirul "ABCdefg". 108 . Amintim că prezentarea completă se găseşte în documentaţia Java API de pe Internet. În afară de metodele pe care le oferă. împărţirea la zero a unui număr întreg. care pune instanţa respectivă sub forma unui şir de caractere.Severin Bumbaru public Exception(String s) creează un obiect din clasa Exception. care conţine un mesaj sub forma şirului s. Obiectele clasei String conţin şirurile propriu-zise. Prin acest mesaj se indică. O prezentare mai amplă există în indexul de clase. Vă recomandăm să o consultaţi. pentru a cunoaşte ce constructori şi metode conţine. sunt obiecte ale clasei String. un mesaj privind felul exceptiei respective. inclusiv literalii-şir. de regulă. de exemplu. se poate folosi pentru instanţele oricărei clase de excepţii metoda toString().

int lastIndexOf(int ch. String trim() Întoarce un nou şir. int indexOf(String str. iar daca îi succede lui anotherString întoarce o valoare pozitivă. dar căutarea înapoi se face de la poziţia fromIndex. ignorând deosebirea dintre literele majuscule şi cele minuscule. int indexOf(String str) Întoarce indicele poziţiei de la care în acest şir apare prima dată subşirul str.Programarea orientata pe obiecte în limbajul Java Construirea unui obiect din clasa şir se face cel mai frecvent cu constructorul String(String s). int indexOf(int ch. dar căutarea in sir începe de la poziţia fromIndex. int fromIndex) Similar cu metoda precedentă. int length() Întoarce lungimea acestui şir (numărul de caractere conţinute). întoarce -1. int lastIndexOf(int ch) Întoarce indicele ultimei poziţii pe care apare caracterul ch în acest şir. int fromIndex) Întoarce indicele ultimei poziţii pe care se găseşte caracterul ch. int fromIndex) Similar cu metoda precedentă. întoarce 0 (zero). dar căutarea în acest şir începe de la poziţia fromIndex. int fromIndex) Similar cu metoda precedentă. Dacă acest şir îl precede pe anotherString întoarce o valoare negativă. Dacă cele două şiruri sunt identice. Compararea şirurilor se face în ordine lexicografică (în ordinea în care ar fi plasate într-un dicţionar). int lastIndexOf(String str) Întoarce indicele ultimei apariţii în acest şir a subşirului str. începând de la poziţia fromIndex. int compareToIgnoreCase(String str) Compară lexicografic acest şir cu sirul str primit ca argument. Dintre metodele foarte utile menţionăm aici următoarele: int compareTo(String anotherString) Compara acest şir cu şirul anotherString primit ca argument. Dacă acest caracter nu există în şir. String substring(int beginIndex) 109 . dacă se face căutarea înapoi. obţinut din acest şir prin eliminarea spaţiilor de la început şi de la sfârşit. int lastIndexOf(String str. int indexOf(int ch) Întoarce indicele la care se găseşte în şir prima apariţie a caracterului ch. Acest constructor creeaza în memorie o copie a şirului s primit ca argument.

Un obiect StringBuffer (zona tampon pentru caractere) se caracterizează prin lungime şi capacitate. char c) . public StringBuffer insert(int offset. append(Object obj). începând de la poziţia beginIndex. ca urmare a aplicării unor metode. public String toString() . Clasa StringBuffer Obiectele clasei StringBuffer implementează şiruri care pot fi modificate atât ca lungime. Lungimea este numărul de caractere conţinut efectiv. prin care se poate adăuga un şir nou în coada celui existent. Există. public StringBuffer append(char c) . iar capacitatea este dimensiunea la un moment dat a tabloului de caractere conţinut în obiectul respectiv. o familie de metode append(). StringBuffer(int length) sau StringBuffer(String str). Primul dintre ei construieşte o zonă tampon de caractere. În engleză buffer înseamnă zonă tampon.append(String str). Construirea unui nou StringBuffer se poate face cu unul din constructorii StringBuffer().întoarce un şir care are acelaşi conţinut cu cel din acest StringBuffer. append(double d). având o capacitate iniţială predefinită. care diferă între ele prin tipul argumentului: append(boolean b). Cele mai importante metode sunt: public int length() .însereaza în buffer caracterul c pe pozitia offset. Exemplu În programul din fişierul TestStr. append(byte b).întoarce capacitatea curentă a buffer-ului. cât şi sub aspectul caracterelor pe care le conţin. 110 . Principalele operaţii asupra unei astfel de "zone tampon" sunt metodele append() şi insert(). sau se înserează acest şir nou în interiorul celui existent.Severin Bumbaru Întoarce un nou şir.adaugă la buffer caracterul c. de fapt. append(float f). int endIndex) Întoarce subşirul situat între pozitiile beginIndex şi endIndex-1 inclusiv. append(int i). până la sfârşit. public int capacity() .întoarce lungimea curentă a şirului (numărul de caractere existente efectiv în buffer). append(char c). în care se pot adăuga noi caractere la şirul existent şi în care se pot înlocui total sau parţial caracterele existente cu altele. append(long l). append(short s). care conţine caracterele acestui şir. Aşa dar.java se exemplifică utilizarea clasei String. String substring(int beginIndex. Ambele se pot modifica în timp. iar al treilea construieşte o zonă tampon care conţine iniţial şirul str. un "StringBuffer" este modelul unei zone tampon de memorie. al doilea una de capacitate iniţială length.

java este dat un program de testare a obţinerii obiectelor Class şi a aplicării unora dintre metodele acestora.întoarce o instanţă a clasei Class care reprezintă superclasa obiectului căruia i se aplică această metodă. float f). pe poziţia offset. Exemplu În fişierul TestStrB. Object obj). cel de al doilea argument convertit în şir. Acestea sunt conţinute sub forma de câmpuri statice în clasele acoperitoare ale tipurilor primitive respective. putem obţine un obiect din această clasă folosind metoda getClass() a clasei Object. insert(int offset. În schimb. În consecinţă. primită ca argument. O prezentare mai amplă a clasei StringBuffer este dată în indexul de clase. se pot obţine în timpul executării unui program informaţii despre clasele cărora le aparţin obiectele din memorie. Există. boolean b). insert(int offset. Toate aceste metode înserează în zona tampon.java este dat un exmplu de program în care se testează clasa StringBuffer. public Class getSuperclass() .întoarce true dacă clasa căreia i se aplică metoda este o superclasă a clasei cls. long l).Programarea orientata pe obiecte în limbajul Java Toate aceste metode adaugă în coada zonei tampon argumentul lor. Există şi instanţe ale clasei Class pentru tipurile de date primitive. short s). insert(int offset.întoarce true dacă metoda este aplicată unei instanţe a clasei Class care reprezintă o interfaţă. insert(int offset. byte b).întoarce true dacă metoda este aplicată unui obiect din clasa Class care reprezintă un tip de date primitiv. insert(int offset. public boolean isPrimitive() . public boolean isAssignableFrom(Class cls) . Clasa Class nu are un constructor public. Descrierea completă a clasei Class este dată în documentaţia Java API. insert(int offset. care diferă prin tipul celui de al doilea argument: insert(int offset. Iată câteva dintre metodele clasei Class: public String getName() . insert. interfeţe. int i). de asemenea. sub forma de instanţe ale clasei Class. o familie de metode insert(). int offset. 111 . iar descrierea completă se găseşte pe Internet în documentaţia Java API. double d). tip primitiv) reprezentată de un obiect din clasa Class. Clasa Class O caracteristică importantă a limbajului şi platformei Java este că clasele şi interfeţele utilizate în program sunt prezente în memoria maşinii virtuale Java în timpul executării programului. insert(int offset.întoarce numele calificat al unei entităţi (clase. convertit într-un şir. insert(int offset. În fişierul TestClass. char c). String str). public boolean isInterface() .

cât şi metode necesare pentru a lucra cu tipul de date respectiv. conţine valoarea logică true sau false. clasele acoperitoare de tip sunt reprezentate cu negru. un obiect din clasa Double conţine un câmp de tip double în care există un număr în virgulă mobilă în dublă precizie. un obiect din clasa Boolean conţine un câmp de tip boolean care. în care se păstrează diferite constante (variabile finale) specifice tipului de date corespunzător. numele claselor acoperitoare încep (ca la orice alte clase) cu majuscule. În afară de câmpul de date nestatic. Clasa Number este o clasa abstractă. compară obiectul propriu cu obiectul obj primit ca argument şi întoarce true dacă acestea sunt identice. În mod similar. întoarce valoarea primitivă conţinută în obiectul respectiv.Figura 1 În aceasta figură. Toate clasele acoperitoare sunt clase finale. care sunt scrise cu litere mici. Unele dintre metode sunt prezente în toate clasele acoperitoare. convertită într-un şir de 112 .este o redefinire a metodei equals()din clasa Object . Prezentăm aici succint principalele metode prezente în toate clasele: public boolean equals(Object obj) . Clasele acoperitoare de tip formează ierarhia din figura 1. altele sunt specifice fiecărei clase sau unui grup de astfel de clase. Fiecare din celelalte clase acoperă un anumit tip de date primitiv. deci din ele nu mai pot fi derivate alte clase. . pentru fiecare din tipurile de date primitive există o clasă acoperitoare de tip (engleză: Type Wrapper).Severin Bumbaru Clasele acoperitoare de tip În pachetul java. Aceste clase pun la dispoziţia programatorului atât variabile finale (constante).este o redefinire a metodei toString() din clasa Object . din care sunt derivate toate clasele acoperitoare pentru tipuri de date numerice. iar clasa Integer acoperă tipul int. Spre deosebire de numele tipurilor primitive. public String toString() . Fiecare instanţă a unei clase acoperitoare conţine un câmp de date nestatic în care se pastrează o valoare aparţinând tipului primitiv de date corespunzator clasei respective.lang. Clasa Character acoperă tipul char. sau false în caz contrar. la rândul lui. fiecare clasă acoperitoare conţine mai multe câmpuri de date statice finale. Toate celelalte clase acopera tipul primitiv al carui nume îl poartă. De exemplu.

113 .Programarea orientata pe obiecte în limbajul Java caractere. Clasele acoperitoare oferă. Clasa are doi constructori publici: Boolean(boolean value) şi Boolean(String s). clasa Boolean mai oferă următoarele metode specifice: public boolean booleanValue() . care au fost deja menţionate. Clasa Boolean moşteneşte. toString() şi hashCode(). care conţine forma externă a unei valori de tip boolean.întoarce numarul convertit la tipul primitiv double.Contine următoarele metode: public abstract byte byteValue() . de asemenea. public static Boolean valueOf(String s) . ceeace poate avea ca efect rotunjirea.întoarce numarul convertit la tipul primitiv float. corespunzătoare şirului s: dacă şirul s este "True" întoarce TRUE.întoarce o noua instanţă a clasei boolean.java este testată clasa Boolean. public int hashCode() .întoarce valoarea primitivă de tip boolean conţinută în obiectul propriu. În programul din fişierul TestBoolean. public abstract float floatValue() . altfel întoarce FALSE. metodele clasei Object.întoarce numărul convertit la tipul primitiv byte. cu excepţia tipului char. public abstract long longValue() . ceeace poate avea ca efect rotunjirea. Clasa Boolean Clasa Boolean acoperă tipul primitiv boolean. metode prin care se pot converti datele din tipurile respective din forma externă (de şiruri de caractere) în cea interna şi invers. reprezentând forma externă a valorii respective. public abstract short shortValue() . Are. public abstract int intValue() . În afara de metodele equals().întoarce numărul convertit în tipul primitiv int. ceeace poate avea ca efect rotunjirea sau trunchierea. Clase acoperitoare pentru tipurile de date numerice Clasa abstractă Number Este superclasa tuturor tipurilor de date numerice. iar al doilea primeşte un şir de caractere.întoarce numărul convertit la tipul primitiv short.este o redefinire a metodei hashCode() din clasa Object. public abstract double doubleValue() . Primul primeşte ca argument o expresie cu valoare de tip boolean. ceeace poate avea ca efect rotunjirea sau trunchierea. acelaşi efect cu aplicarea operatorului new cu constructorul Boolean(String s). de asemenea.întoarce numărul convertit la tipul primitiv long. intoarce codul de dispersie al obiectului propriu. practic.

public static final int MIN_VALUE int. Între aceste clase există o mare asemănare în ce priveăte câmpurile de date statice şi metodele.Severin Bumbaru Remarcăm că aceste metode se aplica tuturor claselor acoperitoare pentru numere. utile în diverse operaţii cu numere întregi: public static int parseInt(String s) . Remarcăm deci că se face analiza sintactică a şirului s pentru a se verifica dacă acesta este cu adevărat un număr întreg. realizând conversia numărului conţinut într-o instanţă a unei clase acoperitoare numerice către tipul primitiv dorit de utilizator. Clasa oferă un numeroase metode. Menţionăm că majoritatea metodelor statice din clasa Integer nu există în celelalte clase acoperitoare pentru tipuri de date intregi. c/ metode statice.face analiza sintactică a şirului s. short. shortValue(). se 114 . cât şi statice. . int şi long. adică valoarea 2147483647. cât şi pentru informaţii privind celelalte clase. şi întoarce valoarea de tip int corespunzatoare. considerat ca forma externă a unui număr întreg în sistemul de numeraţie zecimal. care sunt utile când se lucrează cu numere întregi. deoarece se pot folosi aceste metode şi cu argumente efective de tip byte sau short. atât de instanţă. se obţine excepţia NumberFormatException. Clasa Integer este clasa acoperitoare pentru tipul primitiv int. Clasa conţine următoarele câmpuri de date statice: public static final int MAX_VALUE .converteşte şirul s. dacă şirul s nu reprezintă forma externă a unui număr întreg. public Integer(String s) . Short.conţine valoarea maximă pentru tipul de . Vom prezenta aci principalele facilităţi oferite de clasa Integer. Dintre acestea menţionăm: a/ metodele equals(). Pentru o prezentare completă a acestei clase.construieşte instanţa clasei Integer care conţine valoarea primitivă value. toString() şi hashCode() existente în toate clasele acoperitoare. adică -2147483648. floatValue()si doubleValue() existente în toate subclasele clasei Number. longValue(). dar nici nu este necesar. Integer şi Long Instanţele acestor clase acoperă valori din tipurile primitive byte. intValue(). b/ metodele byteValue(). public static final Class TYPE despre tipul primitiv int.conţine un obiect din clasa Class cu informaţii Clasa are doi constructori: public Integer(int value) . recomandăm consultarea documentaţiei originale Java API. într-un număr de tip int şi construieşte obiectul Integer care conţine acest număr. primit ca argument. dacă şirul s nu are forma corectă a unui număr întreg.conţine valoarea minimă pentru tipul de date date int. Clasele Byte.

întoarce numărul întreg i convertit într-un şir în sistemul de numeraţie octal.întoarce numărul întreg i convertit într-un şir care îl reprezintă în sistemul de numeraţie binar. iar dacă este mai mare întoarce o valoare pozitivă.java testează utilizarea unora dintre metodele clasei Integer. public static Integer valueOf(String s. Executând acest program se poate constata că analiza sintactică a şirului primit ca argument decurge în acelaşi mod la metodele parseInt(String). hexazecimal (incepe cu 0x) sau octal (incepe cu 0).compară propriul obiect din clasa Integer cu obiectul anotherInteger primit ca argument. adică este forma externă a unui număr întreg în unul din sistemele zecimal. altfel. că la conversia de la Integer către byte sau short este posibil să se piardă cifrele cele mai semnificative prin trunchiere. întoarce o valoare negativă. public static String toString(int i) . public static String toHexString(int i) . atunci această metodă acţionează la fel cu cea precedentă. public int compareTo(Object obj) . prin faptul ca nu este o metodă a instanţei. metode de conversie a şirurilor în 115 . public int compareTo(Integer anotherInteger) Exemplu: Programul din fişierul TestInt. Dacă ele sunt egale. altfel. faţă de cele menţionate la punctele a/ şi b/): . de asemenea.dacă obiectul-argument obj este tot un Integer. Clasele Float şi Double Instanţele claselor Float şi Double "acoperă" valori ale tipurilor primitive corespunzătoare. int radix) .analizează şirul s şi îl decodifică.întoarce numărul întreg i convertit într-un şir în sistemul de numeraţie zecimal (se deosebeşte de metoda toString(). valueOf(String) şi la constructorul Integer(String). public static String toBinaryString(int i) . daca întregul propriu este mai mic decât argumentul.întoarce un şir care conţine numărul intreg i convertit în sistemul de numeraţie cu baza radix.acţioneaza asemănător cu metoda precedentă. întoarce zero. public static String toString(int i. ci una statică). dar întoarce un obiect din clasa Integer. Se admite ca numărul să fie precedat de semnul . dar nu de semnul +. dar se consideră că şirul s este un număr întreg în baza de numeraţie radix. int radix) .Programarea orientata pe obiecte în limbajul Java obţine excepţia NumberFormatException. atunci il converteşte în valoare internă de tip int şi întoarce obiectul de clasa Integer care contine aceasta valoare. public static Integer valueOf(String s) . dacă acesta respectă unul din formatele admise pentru numere întregi.întoarce numărul întreg i convertit într-un şir hexazecimal. Se observă.acţionează asemănător cu metoda parseInt(String s). de asemenea. întoarce excepţia NumberFormatException. public static Integer decode(String s) . cu deosebirea că se consideră că şirul s este un număr în sistemul de numeraţie cu baza radix. int radix) .(minus). Se acceptă numai şirurile care reprezintă cu adevărat numere întregi cuprinse în domeniul de valori al tipului int. moştenită de la clasa Object. Ele oferă. public static String toOctalString(int i) . respectiv float şi double. d/ metode ale instanţei (în plus. se obţine excepţia ClassCastException. public static int parseInt(String s.similara cu metoda precedentă.

dar intoarce un obiect din clasa Double.converteşte în sir numărul primitiv primit ca argument. se obtine excepţia NumberFormatException.cea mai mare valoare pozitivă de tip double. b/ metodele byteValue(). longValue(). public static final double POSITIVE_INFINITY .Severin Bumbaru numere reale (cu analiza sintactică corespunzătoare) şi a numerelor reale în şiruri. toString() si hashCode() existente în toate clasele acoperitoare. shortValue(). c/ metode statice. altfel generează excepţia NumberFormatException. dacă acest şir nu este corect sintactic. dar aceleaşi facilităţi există şi în clasa Float.cea mai mică valoare pozitivă de tip double. Câmpuri de date statice: Clasa Double (şi similar clasa Float) oferă următoarele câmpuri de date statice: public static final double MAX_VALUE .construieşte o instanţă a clasei Double care conţine valoarea primitivă de tip double a cărei formă externă este şirul s primit ca argument.dacă este corect . 116 .construieşte o instanţă a clasei Double care conţine valoarea primitivă value.analizează sintactic şirul s primit ca argument şi . Metode: Clasa Double oferă numeroase metode utile în lucrul cu date de tip double. public static final double NEGATIVE_INFINITY . public static Double valueOf(String s) .valoarea Infinitypentru tipul double. Vom prezenta aici clasa Double. public static final double MIN_VALUE .acţioneaza asemănător cu metodă parseDouble(String). floatValue() si doubleValue() existente în toate subclasele clasei Number. utile în diverse operaţii cu numere reale: public static double parseDouble(String s) .un obiect din clasa Class cu informaţii despre tipul primitiv double. Double(String s) . public static final double NaN . Constructori: Clasa Double are doi constructori: Double(double value) .întoarce valoarea primitivă double corespunzatoare.valoarea -Infinity pentru tipul double.valoarea NaN (Not a Number) pentru tipul double. public static String toString(double d) . dintre care mentionăm: a/ metodele equals(). intValue(). public static final Class TYPE .

public static boolean isNaN(double v) .întoarce true dacă valoarea conţinuta în obiectul propriu este NaN. faţă de cele menţionate la punctele a/ şi b/): public int compareTo(Double anotherDouble) . Cele mai multe dintre ele sunt coduri numerice ale diferitelor categorii de caractere (litere majuscule.Programarea orientata pe obiecte în limbajul Java public static long doubleToLongBits(double value) . Remarcăm că. 117 . Câmpuri statice: Clasa Character conţine numeroase câmpuri de date statice. public int compareTo(Object obj) . a cărei reprezentare ca long (întreg pe 64 biţi) conform standardului IEEE 754 este cea primită ca argument. În plus. Clasa Character Fiecare obiect al clasei Character "acoperă" o valoare primitiva de tip char. în sistemul Unicode. clasa Character oferă metode utile în lucrul cu caractere. dacă ele sunt egale.întoarce o valoare de tip double. în limbajul Java.întoarce true dacă argumentul v este NaN.dacă obiectul-argument obj este tot un Double. folosite în metodele care verifică dacă un anumit caracter corespunde categoriei respective. în acest caz. caracterele sunt reprezentate pe 16 biţi. public boolean isInfinite() . cifre zecimale. a numărului de tip double primit ca argument. atunci această metodă acţionează la fel cu cea precedentă.întoarce true dacă valoarea conţinută în obiectul propriu este infinită. Reamintim că. public static double longBitsToDouble(long bits) . Pentru reprezentarea formatului intern al numărului s-a folosit metoda doubleToLongBits(). a fost considerat corect şi un sir care reprezintă un număr real precedat de semnul +. Exemplu: Programul din fişierul TestDouble. d/ metode ale instanţei (în plus.java testează principalele metode ale clasei Double. Printre ele există însă şi câmpul care public static final Class TYPE conţine un obiect din clasa Class cu informaţii despre tipul primitiv char. simboluri matematice etc). dacă numărul propriu este mai mic decât argumentul întoarce o valoare negativă. conform standardului IEEE 754.întoarce o valoare de tip long care este reprezentarea pe 64 biţi. altfel. combinată cu metodele toBynaryString() şi toHexString()din clasa Long. iar dacă este mai mare întoarce o valoare pozitivă. întoarce zero.întoarce true dacă argumentul v este infinit. se obţine excepţia ClassCastException. litere minuscule. prezentate în documentaţia Java API. public static boolean isInfinite(double v) .compară propriul obiect din clasa Double cu obiectul anotherDouble primit ca argument. public boolean isNaN() .

clasa Character oferă. dacă nu este literă. public static boolean isSpaceChar(char ch) .verifică dacă ch este caracterul spaţiu.întoarce caracterul prin care este reprezentată cifra de valoare digit în sistemul de numeraţie cu baza radix.întoarce valoarea numerică a caracterului ch considerat ca cifra a sistemului de numeraţie cu baza radix. public static boolean isUpperCase(char ch) . dintre care menţionăm: public static boolean isDigit(char ch) . de asemenea. întoarce caracterul nul ('\u0000'). de tabulare orizontală sau verticală. îl lasă neschimbat. îl lasă neschimbat. următoarele metode: public char charValue() . public static boolean isWhitespace(char ch) . public static boolean isLetterOrDigit(char ch) . de separare a fişierelor sau înregistrărilor etc (vezi documentaţia). dacă nu este literă. public static boolean isLowerCase(char ch) .întoarce caracterul ch convertit în litera majusculă. public static char toUpperCase(char ch) . de întoarcere a carului. public static boolean isLetter(char ch) .întoarce valoarea numerica Unicode a caracterului ch ca un întreg nenegativ. dacă în sistemul respectiv nu există o astfel de cifră.verifică dacă ch este literă sau cifră. de exemplu caracter de trecere la linie nouă.întoarce true daca ch este literă majusculă. Metode nestatice: În afara de metodele generale equals().întoarce true dacă ch este literă mică. daca în sistemul respectiv nu exista o asemenea cifră. public static char toLowerCase(char ch) . public static int getNumericValue(char ch) . Metode statice: Clasa Character oferă numeroase metode statice utile în lucrul cu caractere.întoarce true dacă argumentul ch este cifră. public static char forDigit(int digit. întoarce -1.construieşte un obiect al clasei Character care conţine caracterul primit ca argument.întoarce true dacă argumentul este literă.întoarce caracterul primitiv conţinut în obiectul propriu din clasa Character. public int compareTo(Character anotherCharacter) .verifică dacă ch este un spaţiu liber sau un alt caracter asimilabil acestuia.compară caracterul din propriul obiect cu cel primit ca argument şi întoarce valoare nulă dacă sunt egale.Severin Bumbaru Constructori: Clasa Character are un singur constructor public Character(char value) . int radix) . int radix) . public static int digit(char ch.întoarce caracterul ch convertit în litera mică. toString() şi hashCode(). negativă daca primul este mai mic decât al doilea şi valoare pozitivă dacă este mai mare. 118 .

altfel generează excepţia ClassCastException. public static final double PI . Lista completă a funcţiilor este dată în indexul claselor. Ea conţine numai un singur câmp static public static final Class TYPE care conţine un obiect din clasa Class cu informaţii despre tipul primitiv void. Ea conţine un număr mare de funcţii matematice (funcţii trigonometrice. Constantele sunt reprezentate sub forma următoarelor două câmpuri statice finale ale clasei: public static final double E . Menţionăm aici numai câteva din aceste funcţii.sinusul trigonometric sin a.PI.numărul e (baza logaritmilor naturali). Aceste constante se folosesc în expresiile din program sub forma Math. cu precizarea că arcele (unghiurile) se exprimă în radiani: public static double sin(double a) . logaritmice.cosinusul trigonometric cos a.funcţia exponentială e . public static double atan(double a) .numarul pi (raportul dintre perimetrul şi diametrul cercului). public static double cos(double a) . public static double asin(double a) . public static double sqrt(double a) .arcsin a. public static double acos(double a) . public static double log(double a) .Programarea orientata pe obiecte în limbajul Java .arctg a.tangenta trigonometrică tg a.dacă argumentul obj este un obiect din clasa Character. public int compareTo(Object obj) Exemplu: În fişierul TestChar.radacina patrată a lui a.java este dat un program de testare a metodelor oferite de clasa Character. public static double tan(double a) .arccos a.E şi Math. actionează similar cu metoda precedentă. Clasa Void Clasa Void nu este instanţiabilă (nu poate avea obiecte) şi "acoperă" tipul primitiv void. Funcţiile matematice se prezintă în această clasă sub forma de metode statice.logaritmul natural ln a. 119 . exponenţiale etc) şi două constante matematice: numărul e şi numărul pi. a public static double exp(double a) . Clasa Math Clasa Math este foarte utilă în calcule ştiinţifice şi inginereşti.

public static final PrintStream out .schimbă unitatea de intrare standard. dar poate fi şi alt dispozitiv indicat de utilizator. Această clasă nu poate fi instanţiată. Descrierea completă a tuturor metodelor clasei System poate fi gasită în documentaţia Java API.schimbă unitatea de ieşire standard pentru erori. ca la toate metodele statice. De regulă este unitatea de afişare standard (ecranul) dar poate fi şi alt dispozitiv indicat de utilizator. sin(2*u+3) se va scrie Math. Clasa System Clasa System conţine câmpuri şi metode utile pentru realizarea legăturii dintre aplicaţie şi sistemul de execuţie Java (cel care implementează maşina virtuală Java). Prin convenţie. De exemplu. De regulă.unitatea standard de ieşire pentru erori.out. Argumentul acestei metode este un cod de stare care se transmite maşinii virtuale Java.. Metoda se foloseşte în program sub forma instructiunii System.schimba unitatea de ieşire standard pentru date. iar un cod diferit de zero indică încheiere anormală (cu cod de eroare).out.Severin Bumbaru Utilizarea în expresiile din program a acestor funcţii se face.este ieşirea standard a sistemului.sin(2*u+3). Noua unitate de ieşire va fi obiectul din clasa OutputStream dat prin argumentul out. public static void setIn(InputStream in). Afişarea datelor pe ecran se face. Câmpuri statice: Clasa System are trei câmpuri statice care reprezintă unităţile standard de intrare/ieşire ale sistemului: public static final InputStream in . aceasta este tastatura. De regulă este aceeaşi ca pentru obiectul out. Noua unitate de intrare standard va fi obiectul din clasa InputStream dat prin argumentul in.println(sir) sau System. Acesta este un număr de tip long.provoaca incheierea executării programului. public static void setErr(PrintStream err).este intrarea standard a sistemului. 0 înseamnă încheiere normală a executării aplicaţiei. public static void setOut(PrintStream out). Noua unitate de iesire va fi obiectul din clasa OutputStream dat prin argumentul err. calificând numele funcţiei prin numele clasei. de regulă folosind metoda System. public static void exit(int status).print(sir).exit(stare). care exprimă timpul în milisecunde măsurat cu începere de 120 .întoarce timpul curent în milisecunde. dar poate fi şi alt dispozitiv indicat de utilizator. Metode: Dăm aici numai metodele care sunt utilizate de noi în acest curs. public static long currentTimeMillis(). public static final PrintStream err .

pagina în care se găseşte componenta respectivă. ca şi numele fiecărui element al ei. Astfel. Iată un exemplu de matrice cu 4 linii şi 5 coloane: a00 a10 a20 a30 a01 a11 a21 a31 a02 a12 a22 a32 a03 a13 a23 a33 a04 a14 a24 a34 În acest exemplu. Tablouri Conceptul de tablou Tabloul (în engleză Array) este o structură de date de acelasi tip. Matricea este un tablou bidimensional. indicii incep de la zero. iar al doilea coloana în care se găseşte componenta respectivă. în care componentele sale sunt aşezate în ordinea crescătoare a indicilor. primul indice specifică linia. în acest caz. dar se disting prin indici. .. iar al treilea . se consideră că tabloul ocupă o zonă compactă de memorie. Întrucât componentele vectorului sunt dispuse pe o singură direcţie în spaţiu. cel de al patrulea fiind numărul volumului în cadrul seriei. Pot exista şi tablouri cu mai mult de două dimensiuni. La nivel conceptual. În limbajul Java. Putem. desigur. De exemplu x=[x0. la fel ca în limbajele C/C++. În mod similar. continua raţionamentul şi pentru tablouri cu mai mulţi indici. care sunt specificate prin indici. numele matricei. un tablou cu patru dimensiuni poate fi privit ca o serie de volume. din care cauză mai este numit şi masiv. un tablou tridimensional poate fi imaginat ca un volum (o carte). numite componente ale tabloului. Exemple tipice de tablouri sunt vectorul şi matricea din matematică. În programare. . tabloul poate fi privit ca o colecţie indexată de variabile de acelaşi tip. având mai multe pagini. este a. x1. Componentele matricei sunt ordonate pe două direcţii în spaţiu. Componentele au acelaşi "nume" cu vectorul.Programarea orientata pe obiecte în limbajul Java la data de 1 ianuarie 1970 ora 0. are patru indici. 121 . fiecare componentă. fiecare pagină fiind un tablou bidimensional (o matrice). iar poziţia fiecărei componente este indicată prin doi indici: primul specifică linia.. Un vector este o colecţie indexată de componente cu un singur indice. spunem că este un tablou unidimensional. care specifică poziţia componentei respective în cadrul tabloului.coloana. Conform convenţiei de indexare din limbajul Java. În acest caz. Poziţia componentei în cadrul matricei este specificată prin cei doi indici. indicii încep de la 0. xn-1] este un vector cu n componente. al doilea .

: Arrays) sunt considerate obiecte care aparţin unor clase descendente din clasa Object. a. c[] şi e[] sunt variabile referinţă la tablouri de tip int (tablouri la care toate componentele sunt de tip int). b. s2. pentru a nu face confuzie cu obiectele clasei Vector din pachetul java. String[] ww. deci ele pot primi valori simple de acest tip. Ca exemplu. variabilele care au ca valori tablouri sunt variabile referinţă. iar alocarea tablourilor în memorie se face dinamic. v. float []u. de asemenea. separate prin virgule şi cuprinse între acolade. Iniţializarea tablourilor unidimensionale se poate face. String s1. length-1]. În schimb. c[]. Tabloul unidimensional este constituit dintr-un ansamblu de componente indexate (cu un singur indice). j. iar s1 şi s2 sunt variabile referinţă la obiecte din clasa String (la şiruri de caractere). long [] k. d. e[]. ts1[]. b. prin operatorul new. căruia i se asociază şi o variabila de tip int numita length. sau unor clase. să considerăm declaraţiile următoare: int a. variabilele i. De exemplu. Componentele pot aparţine unor tipuri de date primitive. Mai mult. în două moduri: a/ indicând valorile componentelor tabloului. tablourile (engl. Indicii elementelor de tablou sunt cuprinşi în intervalul [0.Severin Bumbaru Tablourile în limbajul Java În limbajul Java. iar ts1[] este o variabilă referinţă la un tablou cu componente din clasa String. ca în exemplele următoare: 122 . Întrucât tablourile sunt obiecte. j.util. În aceste declaraţii. u. deci şi a oricarui tip de tablou. care reprezintă lungimea tabloului (numărul de componente). În consecinţă. Tablouri cu un singur indice (unidimensionale) Aceste tablouri corespund conceptului matematic de vector. m. Remarcăm că nu are importanţă dacă parantezele sunt puse imediat după numele tipului sau clasei (fară spaţiu liber) sau între acestea există unul sau mai multe spaţii. ww sunt referinţe la tablouri cu componente de tipuri corespunzătoare fiecarei declaraţii. Tipul tabloului coincide cu tipul componentelor sale. în declaraţiile int[] i. la fel ca în cazul celorlalte obiecte. b/ Parantezele se pun după numele tipului de date sau al clasei. pentru indicarea lor în program se folosesc variabile referinţă. în care caz toate variabilele din declaraţia respectiva sunt considerate drept referinţe la tablouri. deoarece clasa Object este superclasa oricărei alte clase. k. unor variabile referinţă la Object li se pot da ca valori referinţe la tablouri. Declararea şi iniţializarea tablourilor cu un singur indice Variabilele referinţă la tablouri cu un singur indice pot fi declarate în două moduri: a/ într-o declaraţie de variabile se pune simbolul [] (o pereche de paranteze drepte) după numele variabilei referinţă la tablou. m. şi d sunt variabile simple de tip double. Utilizarea unui indice situat în afara acestui interval generează o excepţie. v. Nu le vom numi totuşi astfel.

b=-15.Programarea orientata pe obiecte în limbajul Java int a=27. Se observă că. în timp ce variabilele tab2 şi tab3 sunt iniţializate cu referinţe la tablouri de şiruri.16f}. iar variabilei aa i se dă ca valoare referinţa la acest tablou. "sirul 1".java se testează declaraţiile şi iniţializările de mai sus şi altele similare şi se afişează valorile componentelor tablourilor iniţializate.876e7f}. în declaraţia Object tab1[]=new Object[2]. se alocă în memorie un tablou de variabile referinţă la obiecte din clasa String. fie printr-o expresie care are ca valoare o referinţă la un tablou de tip corespunzator deja existent în memorie. cât şi din clase descendente ale acesteia.-21}.7698E-12f. însoţit de dimensiunea tabloului (numărul de elemente din tablou) scrisă între paranteze drepte. String s1="un sir".72. Atribuirea de valori variabilelor referinţă la tablou Unei variabile referinţă la tablou i se poate atribui ca valoare o referinţă la un tablou de acelasi tip. tab2[]=new String[3]. În primul caz. float[] u={-1. componentele acestora se iniţializează la valorile lor implicite: 0 pentru date numerice şi null pentru obiecte. String str[]=new String[2].e[]={231. Iniţializarea unei variabile referinţă la tablou cu componente aparţinând unei anumite clase se poate face atât cu tablouri din clasa respectivă. în cazul folosirii operatorului new pentru alocarea de tablouri. ts1[]={"sirul 0". 27. deoarece ele apar după numele tipului. tab3[]={"aaa". iar variabilei str i se dă ca valoare referinţa la acest tablou. b/ folosind operatorul new. v={2.03254f. urmat de numele tipului sau al clasei. În programul din fişierul Tab1.-98}. sau dintr-o clasă descendentă a acestuia. "sirul 2"}. ca în exemplele următoare: double aa[]=new double[3].java se dau astfel de exemple."ccc"}. s2="alt sir". clasa String(ca orice alta clasă) fiind descendentă a clasei Object. 123 . variabila tab1 este initializata cu o referinţă la un tablou de componente din clasa Object. Această referinţă poate fi obţinută prin operatorul new (în care caz se alocă în memorie un nou tablou). În programul din fişierul InitTab1.d=-5."bbb". se alocă în memorie spaţiu pentru un tablou cu 3 componente de tip double. În al doilea caz. De exemplu. c[]={-3. 0. Remarcăm că în ultima declaraţie nu s-au mai pus paranteze după numele variabilelor. -3.24076f.

s-au creat variabilele referinţă la tablouri de tip String ts1[] si ts2[] şi un tablou de tip String cu două componente. ts2=ts1. cu condiţia ca valoarea acesteia să nu iasa din cadrul domeniului de indici admis pentru tabloul respectiv.Severin Bumbaru Utilizarea tablourilor Componentele tablourilor pot fi utilizate ca orice variabile simple. Ştim însă că variabilele de tipuri primitive au ca valori chiar date primitive. 1 În figura 1 sunt reprezentate datele din memorie după executarea instrucţiunilor double a[]={3. De exemplu.java .8}. Prin a doua declaratie. de fapt. deci componentele lui sunt. componentele tabloului sunt tratate ca nişte variabile al căror tip este corespunzător declaraţiei. În figura 2 este reprezentată situaţia creeată după ce s-au executat instrucţiunile de atribuire 124 . Primul dintre ele are drept componente date de tip primitiv. b[]. Un exemplu de utilizare a variabilelor indexate s-a dat deja în programul din fişierul InitTab1."bb"}. b=a. În ambele cazuri. iar prin ultima instrucţiune s-a atribuit variabilei ts2[] acceaşi valoare-referinţă ca a lui ts1[]. de asemenea. Prin prima declaraţie s-au creat în memorie variabilele referinţă la tablouri de tip double a[] şi b[]. Este instructiv să urmărim în figurile următoare cum evoluează datele din memorie în timpul executării acestui program. s-a creat. . în timp ce pentru obiecte se folosesc variabile referinţă. când au fost afişate valorile componentelor tablourilor. insoţit de indicele componentei pus între paranteze drepte. În consecinţă. String ts1[]={"aa". "celulele" tabloului conţin chiar valorile de tip double ale componentelor corespunzătoare. În schimb. variabile referinţă la obiecte String. u[3] este componenta de indice 3 a tabloului u. -5. iar aceste obiecte sunt reprezentate în memorie separat. Alte exemple se dau în programul din fişierul Tab1. iar variabilei ts1 i s-a dat ca valoare o referinţă la acest tablou. Prin instrucţiunea b=a i s-a atribuit variabilei b[] aceeaşi valoare-referinţă ca cea din a[]. Remarcăm deosebirea importantă dintre tabloul de tip double şi cel de tip String. ts2[].java.276. cel de al doilea este un tablou de obiecte din clasa String.83. Referinţa la o componentă de tablou se face prin numele tabloului. Indicele poate fi orice expresie de tip întreg. iar aa[i] este componenta de indice i a tabloului aa. 12. un tablou cu trei componente de tip double şi s-a dat ca valoare variabilei a referinţa la acest tablou.Fig.

un tablou cu componente double (deci care a fost declarat ca double[]). În schimb. valoarea variabilei referinţă a[] a ramas aceeaşi.Fig. iar lui b[] i s-a dat ca valoare referinţa la acest tablou. Acestor componente putem sa le dăm acum valori prin program. b. . ceeace se constată şi din afişarea prin program a datelor respective.Fig. de asemenea.. un tablou cu componente dintr-o anumită Clasa este considerat ca aparţinând clasei Clasa[] care. este 125 . 3 Prin operatorul new s-a alocat în memorie un nou tablou cu 4 componente double.ArrayIndexOutOfBoundsException. b[1]=283. care conţine tablourile de obiecte). În acelaşi program se testează şi situaţia în care se încearcă accesul la tabloul b[] cu un indice care iese din domeniul admis [0 ..lang. care este descendentă a clasei Object (nu a clasei Object[].lenght-1]. pe care a avut-o anterior.7. aparţine clasei double[]. Conversii de tip pentru referinţe la tablouri Tablourile cu componente aparţinând unor tipuri de date primitive sunt considerate că sunt obiecte ale unor clase cu numele tip[] De exemplu. 2 Întrucât variabilele referinţă a[] şi b[] indică acelaşi tablou. Imediat după iniţializare componentele noului tablou au valoarea zero. Se constată că se produce excepţia java.Programarea orientata pe obiecte în limbajul Java b[0]=-12. . În mod asemanător.6. este normal ca valorile componentelor a[i] sunt şi acum aceleaşi cu ale componentelor b[i]. În figura 3 este reprezentată situaţia creată după executarea instrucţiunii b=new double[4]. deoarece aceasta este valoarea implicită pentru tipurile de date numerice.

toate liniile unei matrice au acelaşi număr de componente. În următoarele două cazuri. În primul caz. Exemplele de mai sus. ((String[])ob3)[j]. Vom exemplifica aceasta pentru cazul tabloului cu doi indici (bidimensional) şi vom extinde apoi conceptul la tablouri cu mai mult de două dimensiuni. ((String[])ob3). Tablouri cu doi indici Tablourile bidimensionale din limbajul Java sunt o generalizare a conceptului de matrice. ob3=str1. se testează şi numele claselor-tablouri întoarse de metoda getName() a clasei Class.Severin Bumbaru descendenta a clasei Object. str3[]. ((int[])ob1)[k]. deoarece ob1 siob3 nu au fost declarate ca tablouri. iar clasa Object este superclasă a clasei String. deci permisă referinţa tob1[k]. facuta conversie explicită în cazul componentelor tabloului referit prin tob1[]. Se va scrie deci: ((int[])ob1). b[]. În matematică. str3=(String[])ob3. String str1[]={"abc".length. În acelaşi program. Pentru a face referinţă la componente din tablourile referite de variabilele ob1 sau ob3 este necesară. de asemenea. ob1=a. conversie explicită.length. Explicarea codificărilor respective este dată în documentaţia java API. 23. si altele. insa. De exemplu. atribuirile următoare necesită conversie explicită (prin cast). iar str1 este referinţă la un tablou cu componente din clasa String. Object ob1. tob1 este o referinţă la un tablou cu componente din clasa Object. respectiv. iar tablourile a[] şi str1[] aparţin claselor int[] şi. deoarece vsrisbila tob1 a fost declarată ca referinţă la tablou. sunt testate în programul din fişierul ConvTip1. în timp ce în Java 126 . b=(int[])ob1. care este descendenta a clasei Object. sunt permise fara conversie explicită atribuiri de forma: tob1=str1. ob1 si ob3 sunt referinţe la Object. -17}.java."def"}. ob3. tob1[]. String[]. care sunt şi ele descendente ale clasei Object. str2[]. daca s-au făcut declaraţiile int a[]={54. la descrierea acestei metode. Tablouri cu doi sau mai mulţi indici (multidimensionale) Tabloul cu N indici este considerat în limbajul Java drept un tablou de referinţe la tablouri cu N-1 indici. deoarece se fac de la superclasă la clasă: str2=(String[])tob1. Nu trebuie. În schimb. Este.

să ne imaginăm un "tablou coloană" care conţine în fiecare componentă o referinţă către un "tablou linie". tipul componentelor "liniilor" acestuia. Tabloul cu doi indici este privit ca un tablou ale cărui componente sunt referinţe la tablouri cu câte un singur indice. "Tipul tabloului" este. 127 .Programarea orientata pe obiecte în limbajul Java numărul de componente poate fi diferit de la o linie la alta (deci liniile "matricei" pot avea lungimi diferite). Putem. variabila length a "tabloului coloană" reprezintă lungimea acestui tablou. În schimb. Fiecare din aceste "tablouri linie" are propria sa variabilă length şi deci propria sa lungime. adică numărul de linii. de fapt. deci.

{}. la forma de iniţializare cu acolade. următoarele declaraţii: double u.'$'}}. de ex. Acestea din urmă reprezintă "liniile" tabloului bidimensional şi pot avea lungimi diferite. v[]. w[][]. cât şi numărul de coloane.{"AB". . int[] a={3.29}}. deocamdată. 2. Iniţializarea tablourilor bidimensionale se face. având drept componente referinţe la String. urmând sa fie atribuite ulterior.{-1."defg"}. b/ se indică numai numărul de linii. -3."CD".3127. 128 . de exemplu. Remarcam ca."GH"}}. String ts[][]={{"abc". . ambele cu componente de tip double. ea se aplică tuturor variabilelor din declaraţia respectivă.2.6. ca în cazul liniei a doua a tabloului b.-12.'*'}. dar punând după numele variabilei două perechi de paranteze drepte. Rămâne valabilă şi regula că. tabloul bidimensional este tratat ca un tablou (acoladele exterioare) care are drept componente alte tablouri (acoladele interioare). h2=new char[2][3].7}.h1 şi h2 sunt tablouri bidimensionale cu componente de tip char.28. de fapt.6}. se iniţializează o matrice. toate cele 7x4=28 componente fiind iniţializate cu valorile implicite ale tipului respectiv (în cazul de faţă zero)."EF". .2}. int[] a. iar w un tablou bidimensional. new int[7][4].92.15}. de asemenea. matricea are 7 linii şi 4 coloane. numai "vectorul coloană" care contine referinţe (deocamdata nule) către linii care. char[][] h1={{'a'. iar b un tablou bidimensional. ambele cu componente de tip int.-573. . String ts[][]. având însă şi unele trăsături specifice. În figura 1 este reprezentată matricea w dupa iniţializare.25.12.17. Fie.9}}. La folosirea operatorului new există urmatoarele posibilităţi de iniţializare: a/ se indică atât numărul de linii. Iată cum putem introduce în declaraţiile de mai sus iniţializări folosind forma cu acolade sau operatorul new: double u=5.-4.v este un tablou unidimensional.ts este un tablou bidimensional. În exemplul nostru. b[]. b[]={{43. v[]={1.{'+'. în acest caz. nu există.{10. h2. h3=new char[4][]. de exemplu: new int[7][].35.31.{0. Conform acestor declaraţii: .Severin Bumbaru Declararea şi iniţializarea tablourilor cu doi indici Tabloul bidimensional poate fi declarat în mod asemănător celui unidimensional. în care toate liniile au acelaşi număr de componente. dacă perechea de paranteze drepte se pune după numele tipului sau al clasei. char[][] h1. În acest caz se iniţializeaza.a este un tablou unidimensional. w[][]={{2.-6}.u este o variabilă simplă de tip double. asemănător cu a celor unidimensionale. unele din ele putând avea chiar lungimea zero (în acest caz acoladele respective nu conţin nimic).

. Iniţializările de mai sus sunt testate în programul din fişierul Tab2. Întrucat w. Operaţii cu tablouri bidimensionale Numărul de componente Ştim că fiecărui tablou unidimensional îi este asociată o variabilă length.Programarea orientata pe obiecte în limbajul Java ."CD". In aceasta situaţie. Pentru a le distinge mai uşor. care are ca valoare "lungimea" tabloului."GH"}}. Ce reprezintă variabila length în cazul unui tablou bidimensional? Sa privim din nou figura 1."EF".Figura 1 Se observă că variabila w conţine numai o referinţă către un tablou cu trei componente care. de fapt. la rândul lor. numărul de componente 129 . ale cărui componente sunt valori primitive de tip double.java. un tablou compact. fiecare "linie" este."defg"}.Figura 2 Componentele tabloului sunt aici. conţin referinţe către trei tablouri care conţin cele trei linii ale tabloului bidimensional indicat de variabila w. referinţe la obiecte din clasa String. În schimb.{"AB". în acest caz. Să considerăm acum tabloul String ts[][]={{"abc". Acest tablou este reprezentat in figura 2. La nivel conceptual însă. fără a mai forma o zonă compactă. noi privim acest tablou ca şi când ar avea drept componente însăşi aceste obiecte. în figura 2 obiectele din clasa String au fost trasate cu culoare albastră. adică numărul de componente ale acestuia. înseamnă că el este egal cu numărul de linii al tabloului bidimensional. În schimb.length este numărul de componente din tabloul unidimensional referit de variabila w. cele trei "linii" ale tabloului bidimensional pot să fie situate în locuri diferite din memorie.

Să urmărim acum un exemplu.java se determină astfel numărul de linii şi numărul de componente din fiecare linie pentru fiecare din tablourile bidimensionale iniţializate în programul respectiv. Iată doua exemple de instrucţiuni. Componentele de tablou astfel referite pot fi folosite în orice expresii din program.length.length. Dacă folosim însa variabila referinţă la un tablou bidimensional însoţită de un singur indice. în caz contrar. în care se ilustrează folosirea acestor referinţe în instrucţiuni de atribuire. Referirea la tablou şi la liniile tabloului Variabila referinţă la tablou. w[i][j] este componenta situata în linia i şi coloana j a tabloului referit de variabila w.17. 130 . De exemplu. De exemplu. Variabilele w şi w[i] pot fi folosite şi ele în diferite expresii. Se fac mai intâi următoarele declaraţii cu iniţializări de tablouri: int a[][]={{-5.-4}. neînsoţită de indici. vor apare excepţii la executarea programului. În acelaşi program se poate urmări şi cum sunt afişate componentele tablourilor. De exemplu. w[i] este o referinţă la linia i a tabloului indicat de variabila w.cos(3. Referirea la componentele tabloului Pentru a indica o anumită componentă a unui tablou bidimensional. la fel ca variabilele simple. Bineînţeles. trebuie avut grijă ca indicii să nu iasă din domeniile admise pentru fiecare din ei deoarece. Indicii pot fi literali întregi. făcând şi schemele tablourilor din memorie in diferite etape de execuţie a acestuia.12.Severin Bumbaru din linia referită de componenta w[i] a tabloului w este dat de variabila w[i].{8. se foloseşte variabila referinţă la tablou.{}.{105}}. Să urmarim programul din fişierul Tab2a. de exemplu w[2*k-1][j-3].java. însoţită de indicii componentei respective. Astfel s-a procedat mai sus. în expresiile w.5*w[1][1]-0.52}. variabile sau expresii de tip întreg. în programul din fişierul Tab2. numărul de componente din linia de indice 0 este w[0].24} Rezultatul aceztor initializari este reprezentat in figura 3.length. Referirile la componentele de tablou au fost folosite. În programul din fisierul Tab2. este o referire la întregul tablou. în care se folosesc componentele tabloului bidimensional w: t=2*w[1][0]*Math.length si w[i].java la afişarea tablourilor. în cazul tabloului bidimensional w. aceasta este o referinţă la o linie a tabloului respectiv. în situaţia când liniile acestor tablouri au lungimi diferite. b[]={31. w[j][k+1]=2*w[j-1][k]-w[j][k-1].-3. de exemplu.23).

Toate aceste modificari pot fi verificate executând programul din fişierul Tab2a. modificarile au fost făcute cu culoare roşie."bb". Conversii de tip la tablouri cu doi indici Regulile aplicate pentru conversii la tablourile bidimensionale sunt aceleaşi cu cele pentru tablouri unidimensionale. Situatia creată în memorie după această secvenţă de atribuiri este reprezentată in figura 4.java .{10. . formată numai dintr-o singură componentă cu valoarea 105. b=a[1].21. iar tabloul unidimensional indicat de variabila referinta b este acum acelasi cu linia a[1].java. A fost creat. care a devenit noua linie a[2]. care este testat în programul din fişierul Tab2b. prin operatorul new. ob2. String ts[][]={{"aa". iar componenta a[2][1] a rămas la valoarea implicită 0 cu care a fost iniţializată. a[3]=b. a[2]=new int[3].Programarea orientata pe obiecte în limbajul Java .ti2[][]."cb"}}. int ti1[][]={{0. b[1]=88. S-au atribuit valori pentru a[2][0] si a[2][2]. Noua linie a[3] este acum fostul tablou b. pentru a fi urmărite mai uşor.11. Fie declaraţiile: Object ob1. 131 ."bc"}.ts1[][].22}}."ab"}.{"ca". Să urmărim următorul exemplu.{"ba".1}. un nou tablou cu trei elemente.Figura 3Se fac apoi urmatoarele atribuiri: a[0][2]=2*b[1]-a[1][1].{20.13}. tob2[][].12. a rămas fără referinţă şi va fi eliminată de către colectorul de reziduuri de memorie.Figura 4 În aceasta figură. a[2][2]=a[3][0]. a[2][0]=b[3]. Fosta linie a[3].

Se are în vedere ca tabloul cu N indici conţine referinţe la tablouri cu N-1 indici. Totuşi. totusi. deoarece în momentul compilării nu are informaţie despre adevarata clasa căreia îi aparţine obiectul indicat de variabila ob2. inclusiv a claselor de tablouri.Severin Bumbaru Cu aceste declaraţii.length. în practică. Să încercăm acum atribuirea ti2=(int[][])ob2. ob2=ts. coloana. că variabilele ob1 şi ob2 conţin efectiv referinţe către obiecte din clasele int[][] şi respectiv String[][].length. ts1=(String[][])ob2. De exemplu un tablou cu trei indici (tridimensional) poate fi considerat că conţine mai multe "pagini". Numărul de linii al tabloului indicat de variabila referinţă ob1 este ((int[][])ob1). În programarea orientată pe obiecte. În acest caz. compilatorul nu poate sesiza eroarea. nu sunt corecte. structura de date din figura 5. de exemplu. ts1=ob2. permite să se creeze tablouri eterogene. 132 . Un tablou cu patru indici poate fi asemănat cu un set de "volume". următoarele atribuiri ob1=ti1. atribuirile ti2=ob1. Tablouri cu mai mulţi indici Modul de tratare al tablourilor cu doi indici poate fi extins şi la tablouri cu mai mulţi indici (tablouri multidimensionale). adică tablouri cu componente care aparţin unor clase foarte diferite. Putem sa ne imaginam astfel si semnificaţii ale unor tablouri cu mai mult de patru indici. În acest caz. componenta situată în linia i şi coloana j este((int[][])ob1)[i][j]. iar fiecare "pagină" este un tablou cu doi indici (bidimensional). realizate pornind de la structura de "tablou de obiecte". deoarece clasele ti1[][] şi ts[][] sunt descendente ale clasei Object. în care fiecare "volum" este un tablou cu trei indici. sunt corecte. iar cel de al patrulea indice specifica numarul "volumului" din acest set. la execuţie se constată că obiectul indicat de ob2 aparţine clasei String[][]. Acestea pot fi structuri complicate de date. iar al treilea indice specifica "pagina" în care se găseşte o anumită componentă. componentele unui tablou trebuie să fie toate de acelaşi tip. putem face conversii explicite sub forma: ti2=(int[][])ob1. iar numarul de componente din linia i a aceluiasi tablou este ((int[][])ob1)[i]. De asemenea. Ştiind. Să consideram. în timp ce variabila ti1 apartine clasei int[][]. în sensul că un tablou poate avea drept componente şi obiecte aparţinând claselor descendente din clasa de bază. primii doi indici specifica linia şi. cele mai frecvent folosite tablouri au cel mult trei indici. deoarece se fac în sens "descendent". În schimb. respeectiv. Tablouri eterogene Prin definiţie. această restricţie a fost "relaxată". În schimb. aşa că se va genera excepţia ClassCastException. Faptul că clasa Object este superclasă a oricărei alte clase din limbajul Java.

se afişează mesajul "Nu aţi introdus 133 .Programarea orientata pe obiecte în limbajul Java . dacă numărul de parametri este nul.println("Nu ati introdus parametri in linia de comanda"). Exemplu: să considerăm următorul program din fişierul Parametri. după cun ştim.out.length. La lansarea în execuţie a aplicaţiei. Utilizarea parametrilor din linia de comandă A venit timpul să ne ocupăm de argumentul args[] al metodei public static main(String args[]) Remarcăm ca argumentul formal args[] al acestei metode este un tablou unidimensional. În acest program.out. } } } Lungimea tabloului args (numărul de componente) este. args. astfel. for(int i=0. Aceşti parametri pot fi. else { System.java: class Parametri { public static void main(String args[]) { if(args.javase construieşte această structură de date eterogenă şi se afişează unele dintre componentele ei. i<args. ale cărui componente sunt din clasa String.Figura 5 În programul din fişierul TabEterogen.length.length==0) System.println("Aplicatia are urmatorii parametri:). acest argument preia drept componente de tablou parametrii din linia de comandă prin care s-a făcut lansarea.println(args[i]). i++) System. folosiţi în program după necesităţi. deci sunt şiruri de caractere.out.

Ce este o superclasă? 15. că unicul separator între parametri este spaţiul liber. pentru a urmări cum se comportă. Cum este invocată o metoda statică? 10. Care sunt operaţiile permise asupra variabilelor-referinţă? 4. Putem rula acum acest program în mod repetat cu diferite seturi de parametri. Ce este o metodă? 8. deci. Ce deosebire este între metodele statice şi nestatice? 9. iar numerele sunt preluate tot sub forma de şiruri de caractere. Unde sunt plasate în memorie obiectele? 3. Cum este invocată o metoda a instanţei? 11. Să considerăm că lansarea acestui program s-a făcut prin următoarea linie de comandă: java Parametri abcd EFG-HIjk 1376 7. Ce deosebire este între câmpurile statice şi cele nestatice? 7. ele sunt tratate ca şi un singur spaţiu.3086 -15 Constatăm. Ce deosebire este între tipul referinţă şi tipurile primitive? 2. Ce este un constructor? 12. Ce este Java API? 21. Putem constata de asemenea că. Care este rădăcina ierarhiei de clase în Java? 19. Ce este un pachet? 20. Ce fel de moştenire este permisă în Java? 18. Întrebări Nivel 1 1. Cum este invocat un constructor? 13. În caz contrar. dacă între doi parametri există mai multe spaţii libere succesive. Ce este moştenirea? 14. Ce este un câmp? 6.3086 -15 La executarea programului se afişează: Aplicatia are urmatorii parametri: abcd EFG-HIjk 1376 7. se afişează toţi parametrii. Cum se declara variabilele referinţă? 5. Ce conţine pachetul java.lang? 134 .Severin Bumbaru parametri în linia de comandă". Ce este polimorfismul? 17. Ce legatură este între o clasă şi clasele derivate din aceasta? 16.

Cum pot fi determinate valorile numerice ale parametrilor din linia de comandă? Nivel 2 1. Ce este clasa Exception? 28. Ce rol are metoda toString()? 26. Cum se poate determina numărul de elemente dintr-un tablou unidimensional? 60. b. c. Cum se declară în Java un tablou unidimensional? 55. Prin ce instrucţiune se crează în Java un tablou cu 7 componente de tip double? 59.lang? 24. Cum se compară două şiruri? 31. b[]. Cum se poate determina cea mai mare valoare pe care poate să o aibă un număr de tip int? 41. Ce semnificatie are declaratia int[] a. Ce este o excepţie? 27. Cum se determina lungimea unui şir? 33. Ce este ordinea lexicografică? 32. Ce este concatenarea şirurilor şi prin ce operator se realizează? 30. Care sunt principalele metode ale clasei StringBuffer? 37. Cum se iniţializează în Java un tablou unidimensional? 58. Care este clasa şirurilor de caractere? 29. Ce câmpuri statice conţine clasa Double? 43. Cum sunt preluaţi parametrii din linia de comandă? 61. Ce se găseşte în zona de memorie afectată unei variabile referinţă? 135 . Ce este clasa Math? 47. b şi c? 56. b şi c? 57. Cum se poate converti un numar întreg din forma externă în cea internă? 42. Ce este un tablou? 54. Ce câmpuri statice conţine clasa System? 52. Scrieţi în limbajul Java expresia prin care se calculeaza rădăcina patrată din 2u2+eu. Ce este o clasă acoperitoare de tip? 38. c.? ce sunt a. 51. Cum se poate calcula rădăcina patrată a unui număr? 49.Programarea orientata pe obiecte în limbajul Java 22. Cum se poate converti un număr în virgulă mobilă din forma externă în cea internă? 44. Ce deosebire este între a. În ce cod sunt reprezentate caracterele în Java? 45. Fie a şi b două obiecte.? ce sunt a. Cum se poate calcula sinusul trigonometric al unui număr? 48. 39.equals(b) şi a==b? 25. La ce serveste declaratia import si ce forma are? 23. Cum se poate calcula logaritmul natural al unui număr? 50. Care sunt subclasele clasei Number? 40. Ce fel de obiecte aparţin clasei StringBuffer? 35. La ce foloseşte metoda trim()? 34. Cum este importat pachetul java. Ce efect are metoda exit() din clasa System? 53. Ce deosebire este între lungimea şi capacitatea unui StringBuffer? 36. Ce este clasa Character? 46. Ce semnificaţie are declaraţia int a. Ce se găseşte în zona de memorie afectată unei variabile care aparţine unui tip primitiv? 2. Poate fi instanţiată clasa Number? Justificaţi răspunsul.

Ce sunt instanţele clasei Class? 17. Cum se poate verifica dacă un numar în virgula mobilă are valoarea infinită? 24. Cum se poate verifica dacă un caracter este cifră? 27. Cum se poate face conversia literelor dintr-un şir din minuscule în majuscule? 28. Fie declaratia int i1. Prin ce metoda se poate schimba dispozitivul de intrare standard? 33. Cum se poate verifica dacă valoarea unei variabile în virgulă mobilă este un număr? 25. Cum se determină poziţia unui caracter într-un şir? 13. Ce sunt i1 şi i2? 5. Prin ce metodă poate fi obţinută forma externă octală a unui întreg? 23. Ce este codul de dispersie şi prin ce metodă se obţine? 10. Scrieţi în limbajul Java expresia: e-|u|sin(2u+3)cos4u+ln(|u|+1). Prin ce metoda se poate obţine reprezentarea externă în sistemul binar a unui întreg? 21. Cărei clase îi aparţine un tablou? 38. Ce deosebire există între o valoare primitivă şi un obiect? 4. Ce deosebire este în Java între excepţie şi eroare? 12. Cum se poate modifica în timpul execuţiei lungimea unei linii dintr-un tablou bidimensional? 136 . i2. Prin ce metode se poate face adăugarea de valori la un StringBuffer? 15. Cum se poate verifica dacă un caracter este literă? 26. Cum se poate face conversia literelor dintr-un şir din majuscule în minuscule? 29. Prin ce metode se poate face înserarea de valori într-un StringBuffer? 16. Cum se poate determina lungimea unei linii dintr-un tablou bidimensional? 41. Ce rol are metoda clone()? 11. 31. Prin ce metodă poate fi obţinută forma externă hexazecimală a unui întreg? 22. Este obligstoriu ca toate liniile unui tablou bidimensional să aibă aceeaşi lungime? 40. Ce este o declaratie de import la cerere şi cum acţionează? 9.Severin Bumbaru 3. Cum se construieşte o matrice cu 7 linii şi 3 coloane cu elemente de tip double? 39. Cărui concept matematic îi corespunde conceptul de tablou bidimensional? 36. Ce legatură există între conceptul de clasă şi cel de obiect? 37. Cum se poate determina în timpul execuţiei programului superclasa clasei unui obiect? 19. Ce este clasa Void? 30. Cum se determină poziţia unui subşir într-un şir? 14. Care este valoarea intoarsă de aplicarea operatorului new? 8. Ce sunt i1 şi i2? 6. Prin ce metoda poate fi convertit din forma externă în cea internă un numar scris întro bază oarecare? 20. Prin ce metodă se poate determina timpul curent şi în ce unităţi se exprimă acesta? 32. Prin ce metoda se poate schimba dispozitivul de ieşire standard? 34. i2. Fie declaraţia Integer i1. Cum se poate determina numele clasei căreia îi aparţine un obiect? 18. Cărui concept matematic îi corespunde conceptul de tablou unidimensional? 35. Care este efectul lateral al invocării unui constructor? 7.

Transferul parametrilor către metode la invocarea metodelor. Clase publice Un exemplu: clasa complex Declararea clasei complex Utilizarea clasei complex Distrugerea obiectelor de către colectorul de reziduuri. Declararea claselor Până în prezent.Programarea orientata pe obiecte în limbajul Java Declararea claselor Declararea claselor. signatura metodei. Câmpuri statice şi câmpuri ale instanţei. instrucţiunea throw şi clauza throws. Metode statice şi metode ale instanţei. Metoda finalize Întrebări. Metode care generează excepţii. Iniţializarea câmpurilor. comparaţie între iteraţie şi recursie. Metode cu acelaşi nume. Declararea metodelor. Valori iniţiale implicite. Metode care întorc o referinţă la un obiect construit în corpul lor. 137 . Metode recursive. s-a arătat modul în care putem utiliza în programul nostru clase existente în biblioteci (în pachetele de clase). Cea mai simplă formă a unei declaraţii de clasă este următoarea: class NumeClasa { declaratii_de_membri } Observăm că declaraţia începe cu cuvântul-cheie class. Declararea câmpurilor. Vom studia în continuare cum putem crea propriile noastre clase. Metode care au ca argumente şi/sau ca valori întoarse referinţe la tablouri. cuprins între acolade. urmat de numele clasei şi de corpul clasei.

numai că declaraţia respectivă nu apare în blocul unei metode. care este tot tip numeric!). În consecinţă.1. deci. fiecare din acestea începe cu majusculă. Câmpurile instanţei se declară la fel ca variabilele locale ale metodelor. v=2. În principiu. la iniţializarea câmpurilor statice se pot folosi numai valori ale altor câmpuri statice. cât şi ale altor câmpuri de instanţă.De exemplu: static double u=3.Severin Bumbaru Numele clasei este un identificator. Câmpurile statice (ale clasei) sunt plasate în memorie în zona rezervată clasei căreia îi aparţin şi nu în cea rezervata instanţelor. Valorile iniţiale implicite ale câmpurilor: dacă nu sunt iniţializate explicit.câmpurile referinţa primesc valoarea null. de exemplu. astfel că ele sunt distincte pentru fiecare instanţă. deşi astfel de situaţii apar foarte rar în practică. câmpurile clasei există în memorie într-un singur exemplar. La crearea câmpurilor. De exemplu: int m=172. că există o deosebire între crearea câmpurilor (variabilelor membre) şi crearea variabilelor locale. ci în corpul clasei. Declararea câmpurilor Declaraţiile de câmpuri servesc pentru a descrie structura de date specifică clasei respective. . Dacă numele este compus din mai multe cuvinte.declaraţii de constructori. În schimb. câmpurile instanţei sunt plasate în zona de memorie rezervată instanţei respective. Remarcăm.65. modificatorul static.câmpurile booleene primesc valoarea false. Se obisnuieşte ca numele clasei sa înceapă cu literă majusculă. clase în care apar numai declaraţii de metode. acestora li se atribuie implicit o valoare iniţială. Nu este obligatoriu ca într-o clasă să existe toate aceste categorii de declaraţii. r. dar declaraţia are în faţă. Se preferă denumirea de câmpuri. n=2*m-4.87*u-3. Aceste câmpuri pot avea valori diferite pentru fiecare instanţă a clasei respective. . . În consecinţă. La iniţializarea câmpurilor de instanţă se pot folosi atât valori ale câmpurilor statice. Declararea unor astfel de câmpuri se face asemănător cu cea a câmpurilor de instanţă. x. Acestea pot fi: . în timp ce la crearea variabilelor locale acestora trebuie sa li se atribuie valori în mod 138 . pot exista şi clase care conţin numai câmpuri şi nu conţin metode. Corpul clasei cuprinde declaraţii de membri ai clasei respective. în acest caz. . câmpurile statice şi cele nestatice primesc valori implicite astfel: .câmpurile numerice primesc valoarea 0 (chiar şi cele de tip char. Pot exista.declaraţii de câmpuri. Câmpurile se mai numesc şi variabile membre şi pot fi ale clasei sau ale instanţei (ale obiectului). care este accesibil fiecărei instanţe.declaraţii de metode. pentru a le deosebi de variabilele locale ale metodelor. Câmpurile clasei se numesc şi câmpuri statice.

în timp ce instanţele claselor sunt plasate în memoria 139 . O astfel de clasă este folosită. b. câmpurile c1 şi c2 de tip char şi câmpurile s1. d. şi clasa TestClasa1. În acest fişier sunt declarate două clase: clasa Proba1. S-au declarat. s2=s1+" extins". Dacă o variabilă locală apare într-o expresie fără să aibă o valoare atribuită anterior. conform căruia o clasă conţine atât date. Crearea unei clase fără metode nu corespunde principiului de baza al programării orientate pe obiecte. compilatorul Java semnaleaza această situaţie ca o eroare de programare.toate de tip int. Amintim o deosebire importantă între modul cum sunt plasate în memorie valorile primitive şi obiectele (instanţele claselor): valorile primitive sunt plasate chiar în zona de memorie rezervată variabilelor respective. s2 şi s3 care contin referinţe la instanţe ale clasei String. char c1='@'. Unele din aceste câmpuri sunt iniţializate. În exemplul din fişierul TestClasa1. care este o simplă structură de date fără metode proprii. c2. altele au valori iniţiale implicite. care conţine metoda main si serveşte ca aplicaţie în care se testează clasa Proba1. c. s-au definit câmpurile statice (ale clasei) m şi n şi câmpurile nestatice (de instanţă) a. Exemplu de clasă care nu conţine constructori expliciţi sau metode: Acest exemplu este dat în scop didactic. cât şi metodele prin care acestea sunt tratate. iniţializarea şi utilizarea câmpurilor. s3. int a=7. ca o structură din limbajele neorientate pe obiecte (cum este struct în C sau record în Pascal). Clasa Proba1 este declarată astfel: /* Declararea clasei Proba1 Clasa contine numai campuri de date */ class Proba1 { static int m=9.Programarea orientata pe obiecte în limbajul Java explicit. pentru a ilustra declararea. } În această clasă. declararea unor clase fără metode se evită în practica programării orientate pe obiecte. b=m*a+1. Câmpurile c şi d sunt iniţializate implicit cu valoarea 0. deci. În consecinţă. La iniţializarea câmpului de instanţă b s-a folosit şi valoarea câmpului static a. de asemenea. chiar dacă o astfel de declaraţie este permisă. în particular metodele clasei Object. ci numai câmpuri de date. chiar daca declaraţia de clasă nu conţine constructori sau metode. n=m-3. ea are un constructor implicit (fără parametri) şi moşteneşte metodele superclasei. c şi d .java se declară şi se utilizează o clasă care nu conţine constructori si metode. String s1="un sir". De altfel.

/* Afisarea campurilor statice calificandu-le cu numele clasei */ System.a=12.println("Campuri din p2: n="+p2.m+" a="+ p2. System.println("Dupa modificare: p1.a+" b="+p1.valorile câmpurilor primitive statice m şi n sunt plasate în memorie o singură dată.m+ " Proba1.c2+ " (int)p1. . p2.n+" m="+p2.m */ p1. /* Modificam campul static p1.b+" c="+p1. /* Se mai creaza o instanta si se atribuie lui p2 */ p2=new Proba1(). deci acestea vor avea câte o valoare pentru fiecare instanţă. în spaţiul rezervat clasei Proba1. p2.m si reafisam p1. System.s2+ " s3="+p2.c1+" c2="+p1. sunt tot nestatice.out.println("Afisarea campurilor statice: m="+Proba1.m="+p2. b.out.c).b+" c="+p2.m+" a="+ p1. în cazul nostru. s2 si s3 (care.s3).m="+Proba1.out.c2="+(int)p1.m+" p2.m si Proba1. iar prima din ele se si initializeaza */ Proba1 p1=new Proba1(). şirurile "un şir" şi "un şir extins" se vor creea în memoria dinamică. /* Programul in care se utilizeaza clasa Proba1 ca o structura obisnuita */ class TestClasa1 { public static void main(String args[]) { /* Se declara doua referinte catre instante ale clasei Proba1. Clasa Proba1 poate fi utilizată în alte clase Java la fel ca o structură de date (înregistrare) "tradiţională" cum ar fi struct în limbajul C.out.a si p2.c).out. d.a valori diferite.n+" m="+p1.Severin Bumbaru dinamică.b+" c="+p1.out.m+" a="+ p1. c1 şi c2 sunt plasate în câmpurile corespunzătoare ale instanţelor clasei Proba1.println("Campuri din p1: n="+p1.n+" m="+p1. este clasa TestClasa1 din fişierul TestClasa1.m="+p1. System. deci se plaseaza în fiecare instanţă). În consecinţă. ca valori se pun numai referinţe la instanţe ale clasei String.m+" a="+ p2.m. iar în câmpurile s1 şi s2 ale fiecărei instanţe a clasei Proba1 se vor pune numai referinţe la aceste şiruri.println("Campuri din p2: n="+p2.c2). pe care o reproducem în continuare.out.a=-9. 140 . sau record în limbajul Pascal.în campurile s1.s1+" s2="+p2.n+" m="+p2. Un exemplu de aplicaţie. în care se utilizează clasa Proba1.c+" c1="+p1.println("Dupa modificarea valorilor campurilor a:").a+" b="+p2. /* Se afiseaza unele campuri ale instantelor p1 si p2. c. */ System.b+" c="+p2.m). /* Modificam atribuim p1. Câmpul s3 va fi iniţializat cu referinţa null. System.m=-12. În consecinţă: .java. p2.c+"\n s1="+p2. apoi reafisam toate campurile */ p1.m+ " n="+Proba1.a+" b="+p1.println("Campuri din p1: n="+p1.a+" b="+p2. sub forma de obiecte ale clasei String. . System.n).valorile câmpurilor primitive nestatice a.

valorile câmpurilor nestatice pot fi utilizate numai calificând numele câmpului respectiv cu numele unei instanţe (de exemplu.n="+p2. p2.dacă se atribuie o nouă valoare unui câmp static.m=-12 Dupa modificare: p1. System. System.n=-25 p2.c="+p2. atât cu numele unei instanţe (de exemplu. Pentru executarea aplicaţiei se va folosi comanda java TestClasa1 Clasa Proba1 nu poate fi pusă în execuţie în acest mod.c+" p2. Această clasă poate fi folosită numai în cadrul altei clase.c=1234. 141 .out. ci şi metodele prin care se tratează aceste câmpuri. nu numai câmpuri de date.dacă se atribuie o nouă valoare unui câmp nestatic al unei instanţe. . numite în mod corespunzător Proba1.m).class şi TestClasa1.c=1234 p2.n="+p1. în mod normal.println("Dupa modificare: p1.c2=0 Campuri din p2: n=6 m=9 a=7 b=64 c=0 s1=un sir s2=un sir extins s3=null Afisarea campurilor statice: m=9 n=6 Dupa modificarea valorilor campurilor a: Campuri din p1: n=6 m=9 a=12 b=64 c=0 Campuri din p2: n=6 m=9 a=-9 b=64 c=0 Dupa modificare: p1. . clasa conţine.println("Dupa atribuire: p1.c="+p1. .c). .n si afisam */ Proba1. Proba1. această modificare se constată în toate înstanţele.c */ p1. cât şi calificandu-le cu numele clasei (de exemplu. deoarece ea nu conţine metoda main.n=-25 Dupa atribuire: p1.c=0 Urmărind aceste rezultate.m=-12 Proba1.a). p1. câte unul pentru fiecare clasă. deoarece câmpul respectiv este unic (există numai în cadrul clasei). Rezultatele afişate pe ecran la executarea acestei aplicaţii sunt următoarele: Campuri din p1: n=6 m=9 a=7 b=64 c=0 c1=@ c2= (int)p1.valorile câmpurilor statice pot fi utilizate calificând numele câmpului respectiv.n+" p2.m).n=-25 Proba1. valorile câmpurilor cu acelaşi nume ale celorlalte instanţe rămân nemodificate. vor fi create două fişiere bytecode.java.m=-12 p2. } } La compilarea fişierului sursă TestClasa1.n="+Proba1. /* Atribuim o valoare campului de instanta p1.n). Declararea metodelor În programarea orientată pe obiecte.câmpurile numerice neiniţializate explicit (inclusiv cele de tip char) sunt iniţializate implicit la valoarea zero.Programarea orientata pe obiecte în limbajul Java /* Modificam campul static n folosind expresia Proba1. putem constata că: .n+ " Proba1.class.out.n=-25.

chiar dacă după instrucţiunea return mai apar în corpul funcţiei respective şi alte instrucţiuni. aceasta se indică prin instrucţiunea return expresie. cât şi câmpurile clasei căreia îi aparţine metoda respectivă. o funcţie (sau procedura) foloseşte ca date argumentele sale şi variabilele globale. . După această listă de argumente se deschide acolada unui bloc. cât şi câmpurile clasei căreia îi aparţine metoda respectivă. în timp ce metoda nu întoarce o valoare.este nume_argument. acestea nu vor mai fi executate. metoda este o funcţie sau o procedură. Fiecare declaraţie de argument are forma tip_argument nume_argument în care tipul sau clasa argumentului respectiv. Lista declaraţiilor de argument este cuprinsă între paranteze rotunde.este Instrucţiunea return Dacă funcţia întoarce o valoare (diferită de void). Acesta este un artificiu pentru a indica faptul că o asemenea "funcţie" nu întoarce o valoare. din punct de vedere sintactic.. fiecare metodă poate folosi ca date atât argumentele saleşi variabilele locale. folosirea instrucţiunii return nu este absolut necesară.. care conţine corpul metodei. încheierea execuţiei făcându-se când se ajunge la acolada prin care se 142 . adică secvenţa de instrucţiuni prin care se calculează valoarea funcţiei respective şi/sau dacă este cazul . deosebirea dintre funcţie şi procedură este că funcţia "întoarce" o valoare. Dacă metoda nu întoarce o valoare (întoarce void). declaratii_de argumente .Severin Bumbaru Sub aspect conceptual.este o listă de declaraţii de argument separate prin virgulă. la fel ca funcţiile. În principiu. întorcând valoarea astfel obţinută. ci are numai efect lateral. În limbajele de programare tradiţionale.se efectuează acţiunile care constituie efectele laterale ale acesteia. începe cu literă mică. tip_argument . dar se consideră că ele intorc o valoare specială numită void. În schimb. declaratie_argument2. în mod uzual.este un identificator care. Cea mai simplă formă sintactică a declaraţiei de metodă este următoarea: tip_valoare_intoarsa nume_metoda(declaratii_de_argumente) { corpul_metodei } în care: tip_valoare_intoarsa . începe cu literă mică şi constituie numele metodei.este tipul valorii primitive sau clasa valorii-referinţă întoarsă de aceasta metodă. declaratie_argumentN dar poate fi şi vidă. În limbajele C/C++ şi Java. Efectul acestei instrucţiuni este următorul: se evalueaza expresia expresie şi se încheie executarea funcţiei respective. deci ea poate avea forma: declaratie_argument1. care foloseşte drept date atât valorile argumentelor sale. un identificator care. În limbajul Java nu există variabile globale şi nici funcţii independente (care să nu fie metode ale unor clase). în mod uzual. procedurile se scriu. nume_metoda. O funcţie fără efect lateral este realizarea în program a conceptului matematic de funcţie şi este folosită în expresiile de calcul numai pentru valoarea ei. În consecinţă.

Metodele care conţin în declaraţie acest modificator se numesc statice sau ale clasei. nu au argumente. şi clasa Cerc2.141592653589793. se poate folosi instrucţiunea return fără expresie. 143 . care conţine metode statice. în timp ce raza cercului diferă de la o instanţă la alta. în faţa tipului valorii întoarse se pune modificatorul static. static double arie(double r) { return PI*r*r. double r. } } /* Declararea clasei Cerc2 cu metode ale clasei (statice) */ class Cerc2 { static final double PI=3. } static double circumferinta(double r) { return 2*PI*r. În corpul metodelor statice se pot folosi numai câmpurile statice ale clasei respective şi se pot invoca numai alte metode statice ale acestei clase.141592653589793. arie() şi circumferinta(). spre deosebire de metodele obişnuite care sunt ale instanţei. /* Declararea clasei Cerc1 cu metode ale instantei */ class Cerc1 { static final double PI=3. dacă este necesar să se încheie în mod abrupt executarea corpului funcţiei. } double circumferinta() { return 2*PI*r.Programarea orientata pe obiecte în limbajul Java sfârseşte blocul funcţiei. Totuşi. Aceasta întrucat numărul PI este o constantă valabilă pentru orice cerc. } } Clasa Cerc1 conţine câmpul static final PI şi câmpul de instanţă r (raza cercului). Metode statice La declararea metodelor statice. Exemplu În fişierul Cercuri. Cele doua metode de instanţă. dar folosesc ca date câmpurile statice şi de instanţă declarate în clasa respectivă.java se declară două clase pentru cercuri: clasa Cerc1. în care aria şi circumferinţa se calculeaza prin metode ale instanţei. double arie() { return PI*r*r.

circumferinta()).circumferinta()). System. . Invocarea acestor metode se face calificându-le cu numele clasei. . Iată această aplicaţie: /* Aplicatia in care se utilizeaza cele doua clase de cercuri declarate mai sus */ class Cercuri { public static void main(String args[]) { double r1=1.class si Cercuri. în care se folosesc clasele Cerc1 şi Cerc2 declarate anterior.instanţierea clasei Cerc1 s-a făcut folosind constructorul implicit Cerc1(). dar nu conţine câmpul de instanţă r.circumferinta(r2)).la compilarea fişierului sursă Cercuri.println("Folosind metodele de instanta din clasa Cerc1:"). câmpul static final PI. vom explica aceasta la capitolul "declararea constructorilor". cu condiţia ca ele să difere prin numărul şi/sau tipul argumentelor. Metode cu acelaşi nume. System. } } Remarcăm că: .out.java se obţin trei fişiere de bytecode: Cerc1.println("Pentru cercul c1: aria="+c1. de exemplu în instrucţiunea de atribuire c1.println("Pentru raza r1: aria="+Cerc2. r2=7.out.arie() calculează aria cercului cu referinţa c1 si. .r=r2. System.out.arie()+ " circumferinta="+c2. System.32. Clasa Cerc2 conţine. System. c2. de exemplu Cerc2.println("Pentru raza r2: aria="+Cerc2.println("Folosind metodele statice din clasa Cerc2:"). System. 144 . metodele sale sunt statice şi primesc raza cercului ca argument.invocarea metodelor de instanţă s-a făcut calificând numele metodei cu referinţa la instanţa respectivă: de exemplu c1. În schimb.arie(r2)+ " circumferinta="+Cerc2.atribuirea de valoare razei r a instanţelor din clasa Cerc1 s-a făcut calificând numele câmpului cu numele referinţei la instanţă. deci.println("Pentru cercul c2: aria="+c2. În fişierul Cercuri. c2=new Cerc1().out.arie(r1).out.java există şi clasa Cercuri.out. .arie(r1)+ " circumferinta="+Cerc2. Signatura metodei În aceeaşi clasă pot exista mai multe metode cu acelaşi nume.class. c1. Cerc1 c1=new Cerc1().r1. va folosi implicit raza c1.Severin Bumbaru Invocarea acestor metode se face calificându-le cu numele instanţei. corespunzătoare celor trei clase declarate. de asemenea.invocarea metodelor statice ale clasei Cerc2 s-a făcut calificându-le cu numele clasei şi transmiţându-le valoarea razei cercului ca argument.class.r=r1.circumferinta(r1)). s-a introdus conceptul de signatură.r=r1. Pentru a deosebi între ele astfel de metode. Cerc2.arie()+ " circumferinta="+c1.

sin(a). iar al doilea argument este o valoare primitivă de tip int. Putem da exemple din clasele existente în pachetele deja studiate. .dacă argumentul aparţine unui tip de date primitiv. este necesar să se transmită de la metoda care invocă la metoda invocată parametrii (argumentele) acesteia.de fapt . se transmite chiar valoarea primitivă a argumentului respectiv.transmitere prin nume: de la programul apelant către funcţie (procedură) se transmit numele argumentelor. De exemplu. . dacă se invocă această metodă sub forma indexOf("abc". a. Exemplu Să considerăm metoda int indexOf(String str. În consecinţă. la executarea invocării Math. transmiterea parametrilor (argumentelor) metodelor se face prin valoare. este necesar să se transmită către metoda sin argumentul acesteia. cei doi parametri str si fromIndex sunt consideraţi variabile locale ale metodei indexOf. int fromIndex) Se observă imediat că prima şi a doua diferă prin numărul argumentelor. int fromIndex) indexOf(String str) indexOf(String str. Aceasta înseamnă că: . . variabilei-referinţă str i se atribuie ca valoare referinţa la sirul "abc" (şi nu insuşi şirul "abc". de exemplu. iar transmiterea parametrilor este echivalentă cu operaţia de atribuire. Primul argument al acestei metode este o referinţă la un obiect din clasa String. În limbajul Java. se transmite .Programarea orientata pe obiecte în limbajul Java Signatura metodei constă din numele acesteia. două metode pot avea acelaşi nume. În teoria şi practica programării se cunosc diferite moduri în car se poate face transmiterea argumentelor către o funcţie sau procedură: . iar a doua şi a patra diferă prin tipul unuia din cele două argumente. În consecinţă. dacă diferă între ele prin signatură. însoţit de lista de argumente.o referinţă către un obiect din clasa respectiva sau dintr-o clasa derivată din aceasta.transmitere prin valoare: de la programul apelant către funcţie (procedură) se transmit valorile argumentelor. Transferul de parametri către metode La invocarea unei metode. int fromIndex) din clasa String. care rămâne la locul lui în memoria 145 . În limbajul Java.transmitere prin referinţă: de la programul apelant la funcţie (procedură) se transmit referinţe către argumente. prima şi a treia diferă prin tipul unicului argument. . 3). următoarele metode ale clasei String: int int int int indexOf(int ch) indexOf(int ch. Să considerăm.dacă argumentul aparţine unui tip-referinţă (este instanţă a unei clase).transmitere prin adresa: de la programul apelant către funcţie (procedură) se transmit adresele la care se găsesc în memorie valorile argumentelor.

În teoria programării. k=-111. începand căutarea de la poziţia de indice 7. j. şi valoarea lui k sunt parametri efectivi. argumentele (parametrii) care apar în declaraţia unei metode (funcţii. în cazul unui argument-referinţă. in timp ce "abc". // S-a modificat valoarea parametrului k de tip int p1. Evaluarea metodei indexOf va decurge astfel: se transmit de la programul apelant către metoda indexOf valorile argumentelor s2 si k.a+" p2. 3.k).a="+p1.java este dat următorul program.a="+p1. Proba2 p1. această atribuire nu modifică valoarea argumentului efectiv corespunzător din programul apelant. Astfel. valoarea lui s2. În schimb. } 146 .out. String s1="un exemplu de sir". în timp ce variabilei fromIndex de tip int i se atribuie valoarea primitivă 3. catre // o noua instanta a clasei Proba2 p2. valoarea variabilei k este chiar valoarea primitivă 7. Daca însă. str şi fromIndex sunt parametri formali ai metodei indexOf.a=-333. dar nu insasi referinta p1 p2=new Proba2(). modificarea respectivă se va transmite şi la programul apelant. Exemplu În fişierul TestParam. // S-a modificat valoarea unui camp al obiectului cu // referinta p1. Proba2 p2) { System.out. proceduri) se numesc parametri formali. se va căuta subşirul a cărui referinţă este s2.a=-222.Severin Bumbaru dinamică). continand un camp a */ class Proba2 { int a. în exemplul de mai sus. deci valoarea ei este referinţa la şirul "exem" şi nu însuşi acest şir. s2="exem". } class TestParam { /* O metoda in care se modifica valorile propriilor parametri formali */ static void modParam(int k. constituind efectul lateral al metodei respective.a). în care se testează un caz de metodă care îşi modifică parametrii: /* Testarea modului de transmitere a parametrilor catre metode */ /* O clasa oarecare. ci valorile câmpurilor obiectului indicat de către aceasta.a).println("La intrarea in modParam k="+k+" p1.a="+p2. // S-a modificat insasi referinta p2. // S-a atribuit valoare campului a al noii // instante referite prin p2 System.indexOf(s2.a="+p2. j=s1.println("In modParam dupa modificarile de parametri:\n"+ "k="+k+" p1. în şirul indicat de s1. Numai că s2 este o variabila-referinţă. Consecinţa faptului că parametrii metodelor se transmit prin valoare este următoarea: chiar dacă în corpul unei metode se atribuie unui argument formal al acesteia o nouă valoare. Să considerăm acum că într-un program există instrucţiunile: int k=7. nu se modifica referinţa însăşi. iar valorile prin care se substituie aceşti parametri formali la invocarea metodei respective se numesc parametri efectivi. În consecinţă.a+ " p2.

valoarea câmpului pr1.a s-a modificat.a+" pr2. Este deci normal să constatăm că.a=-333. pr1. adică se poate considera că variabilei locale k din modParam i s-a atribuit valoarea lui m.out. adică o referinţă către obiectul din clasa Proba2 care a fost creat în main şi are câmpul a=333. pr1.a="+pr2. În consecinţă. obţinem afişate pe ecran următoarele rezultate: In main inainte de a invoca modParam: m=123 pr1. pr2. System. } } Executând acest program. la revenirea din modParam. 3/ Parametrul formal p2.println("In main inainte de a invoca modParam:\n"+ "m="+m+" pr1. adică o referinţă la obiectul în care campul pr1.a=-222 p2.println("In main dupa ce s-a invocat modParam:\n"+ "m="+m+" pr1.a si p2.a.a din modParam) au rămas cele anterioare invocării acestei metode. Proba2 pr1=new Proba2(). La intrarea în modParam.a=333 pr2. lui p2 i se atribuie valoarea parametrului efectiv pr1 din main.a (care corespund respectiv lui k şi p2.a=-333 In main dupa ce s-a invocat modParam: m=123 pr1. valoarea variabilei m din main a rămas nemodificată. p1. 2/ Parametrul formal p1 este de tip referinţă la o instanţă a clasei Proba2.a a rămas la valoarea anterioară invocarii metodei modParam.a=444. acestui parametru i s-a atribuit valoarea variabilei referinţa pr1 din main. deoarece pr1.a==pr2. În consecinţă.a).a="+pr1. la revenirea din modParam în main valorile lui m şi pr2.a al obiectului referit iniţial. la invocarea metodei modParam. fără a se modifica valoarea câmpului pr2. În metoda modParam se modifică valoarea parametrului p2. În modParam se modifică valoarea câmpului a din acest obiect.a=333 p2.a. deşi în metoda modParam s-au modificat valorile lui k.out.a=333. pr2=new Proba2().Programarea orientata pe obiecte în limbajul Java /* Metoda principala */ public static void main(String args[]) { // Se declara si se initializeaza variabilele int m=123. adică se creeaza o nouă instanţă a clasei Proba2 şi se atibuie lui p2 ca valoare o referinţă la aceasta nouă instanţă. parametrul efectiv corespunzator se transmite prin valoare.a=444 Remarcăm că.a).a=-222 pr2. În schimb. pr2). respectiv 123.a (corespunzătoare lui p1.a="+pr2. în timp ce pr1. // Se invoca metoda modParam modParam(m. la fel ca p1.a=444 La intrarea in modparam k=123 p1. este o referinţă la o instanţă a clasei Proba2.a=444 In modParam dupa modificarile de parametri k=-111 p1. Când se face apoi atribuirea p2. La invocarea metodei modParam. // Se afiseaza valorile parametrilor dupa revenirea din modParam System. se modifică valoarea câmpului a din această nouă instanţă.a="+pr1.a are valoarea 444. la revenirea în main constatăm că pr2. Iată cum se explică cele constatate: 1/ Parametrul formal k este de tipul primitiv int. 147 .a) s-a modificat.a+" pr2.

} } În metoda1 se creează prin operatorul new un nou şir. return str. s=s1. după cum s-a arătat anterior. metoda2 nu a avut ca efect lateral transmiterea catre variabilareferinţă sir2 din main a referinţei către obiectul "alt sir" creat în această metodă deoarece. În metoda2 se creează de asemenea un nou şir. System. dar referinţa la acesta se atribuie argumentului s al metodei.Severin Bumbaru Metode care întorc o referinţă la un obiect construit în corpul lor În limbajul Java este posibil ca o metodă să întoarcă o referinţă la un obiect construit în interiorul ei. care conţine următorul program: /* Testarea unei metode care intoarce un sir */ class TestRef { static String metoda1() { String str=new String("un sir").println("In metoda2 s="+s). sir1=metoda1(). } static void metoda2(String s) { String s1=new String("alt sir").out.println("In metoda1 str="+str).println("In main sir1="+sir1+"\nsir2="+sir2). System. În schimb.out.java. metoda2(sir2). 148 . System. transmiterea parametrilor se face prin valoare şi deci modificarea în corpul metodei a valorii parametrului formal s nu afectează valoarea parametrului efectiv str2 prin care aces ta a fost substituit la invocarea metodei respective. } public static void main(String args[]) { String sir1=null. Un astfel de exemplu este dat în fişierul TestRef.out. iar referinţa str la acesta este "întoarsă" de această metodă la executarea instrucţiunii return. sir2=null. La executarea acestui program se obţin următoarele rezultate: In metoda1 str=un sir In metoda2 s=alt sir In main sir1=un sir sir2=null Se observă că metoda1 a întors corect referinţa către şirul "un sir" care a fost creat în interiorul ei.

out. De exemplu.out.out. for(int i=0. for(int i=0.length.2. de fapt. System.out.print(b[i]+" "). System. i<a. i++) System.out. 12. tot ce s-a prezentat în secţiunea anterioară cu privire la folosirea ca parametri formali a variabilelor. dacă parametrii formali ai unei metode sunt tablouri. double b[]) { System.print("\nTabloul b: "). q=alpha(p.java.out.referinţă este valabil şi pentru tablouri.length.1.print("\nTabloul w: ").out. a[1]=1001.print(p[i]+" "). 1.out.out. În consecinţă. System.out.length.length. i<q.out. i<b.w). System. a[2]=1002.6}. 1. ale cărui elemente aparţin clasei String (sunt şiruri de caractere).out.print(b[i]+" "). în signatura metodei main main(String args[]) parametrul formal args[] este o referinţă la un tablou.3. i<b. În consecinţă.5. i++) System. i++) System. i<c.out. System.print("Tabloul p: ").println("\nTabloul c alocat si initializat in aceasta "+ "metoda:"). return c. i++) System.println(). 1. double w[]={1. System. variabile-referinţă. /* Metode care au ca parametri si ca valori intoarse referinte la tablouri */ class TestTab { static int[] alpha(int a[]. din fişierul TestTab. considerăm programul următor.4. System.print(c[i]+" ").println("Inainte de iesirea din metoda alpha:"). for(int i=0. System. System.print("\nTabloul b: ").Programarea orientata pe obiecte în limbajul Java Metode care au ca argumente şi/sau ca valori întoarse referinţe la tablouri În limbajul Java. i++) c[i]=2*i+1.out.print(a[i]+" "). i++) System. numele lor sunt. 11. for(int i=0. i<p. b[1]=-999. iar referinta catre el se atribuie parametrului formal a: */ a=new int[3].length.99. for(int i=0. 13. a[0]=1000. System. 1. for(int i=0. 149 . for(int i=0.out. /* Se creaza tabloul c si se dau valori elementelor lui */ int c[]=new int[4].print(a[i]+" ").print("La intrarea in metoda alpha\n Tabloul a: "). } public static void main(String args[]) { int p[]={10. 14}.print("Tabloul a: ").length. /* Se modifica valorile primelor doua elemente ale tabloului b */ b[0]=-777. Pentru exemplificare.print("\nTabloul q: "). for(int i=0.println("In main dupa revenirea din alpha:").length. i++) System. i++) System.out. 1. i<a. i<c.print(q[i]+" "). /* Se creaza un nou tablou.out.77.out. tablourile sunt obiecte. q[].length.

aceleaşi funcţii pot fi calculate atât recursiv. Metode recursive. aceste modificări apar şi în metoda main în tabloul referit de parametrul efectiv corespunzatorw (deoarece b şi w sunt.6 In main dupa revenirea din alpha: Tabloul p: 10 11 12 13 14 Tabloul q: 1 3 5 7 Tabloul w: -777.5 1.6 Tabloul c alocat si initializat in aceasta metoda: 1 3 5 7 Inainte de iesirea din metoda alpha: Tabloul a: 1000 1001 1002 Tabloul b: -777. Două sau mai multe metode care se invocă una pe alta (metoda A invocă metoda B şi reciproc) se numesc mutual recursive.5 1. constatăm că: .referinţa la tabloul c.out. aceasta nu a afectat tabloul referit în metoda main prin parametrul efectiv corespunzător p.4 1.length. de regulă. de asemenea că. variabila locală c este eliminată de pe stiva sistemului. i<w. Vom ilustra aceasta prin exemple. Comparaţie între iteraţie şi recursie O metodă (funcţie sau procedură) care se invocă pe sine însăşi se numeşte metodă recursivă.1 1. În general. . Cu toate acestea.3 1.77 -999. Remarcăm că. i++) System.2 1. în timp ce în limbajele procedurale se prefera iteraţia. la ieşirea din metoda alpha. de fapt.4 1.99 1. Limbajul Java permite utilizarea metodelor recursive şi mutual recursive. 150 . referinţe la acelaşi tablou). creat în corpul metodei alpha. deoarece către el indică în continuare variabila-referinţă q din metoda main.6 Urmărind executarea programului. . deşi în unele dintre ele (cum este şi limbajul Java) se pot folosi atât iteraţia. în consecinţă.Severin Bumbaru for(int i=0.println().77 -999. c şi q sunt referinţe la acelaşi tablou.3 1.deşi parametrului formal a i s-a atribuit în interiorul metodei alpha o referinţă la alt tablou.5 1.întrucât în metoda alpha s-au modificat valorile elementelor tabloului referit prin parametrul formal b. a fost intoarsă de această metodă şi a fost atribuită în metoda main variabilei referinţă q. cât şi iterativ (folosind cicluri). în limbajele funcţionale se utilizează predominant funcţiile recursive. tabloul creat în metoda alpha şi referit de această variabilă locală nu este eliminat din memorie. System.print(w[i]+" "). } } Rezultatele afişate la executarea acestui program sunt următoarele: La intrarea in metoda alpha Tabloul a: 10 11 12 13 14 Tabloul b: 1.out.3 1. nou construit.4 1.99 1. Vom arăta. cât şi recursia.

cu cât numărul de invocari succesive. respectiv de repetări. stiva conţine numărul 4. metodele iterative sunt mai eficiente. factorial(2)=2*factorial(1). if(n==0) return 1. stiva conţine numerele 2 3 4. Dacă argumentul este valabil. la fel ca în cazul ciclurilor iterative. se pune 3 în stivă şi se invocă factorial(2).*n care poate fi definită recursiv astfel: factorial(0)=1. inclusiv adresa instrucţiunii care urmeaza celei care a făcut invocarea. stiva conţine numerele 3 4. Stiva (engleza: stack) este o structura de memorie în care ultima dată introdusă este prima extrasă (în engleză: LIFO . factorial(n)=n*factorial(n-1) pentru n>0. return n*factorial(n-1)..Programarea orientata pe obiecte în limbajul Java Remarcam că. fiind şi mai uşor de inţeles de către om decât cele iterative. mai întâi dacă argumentul n se încadrează în domeniul admis.Last In First Out). Deosebirea este cu atât mai mare. după care se transmit către metoda invocată argumentele şi i se dă acesteia controlul. Atunci când o metodă invoca alta metodă (fie ea recursivă sau nu). factorial(3)=3*factorial(2). deoarece solicită mai puţină memorie şi sunt mai rapide decât cele recursive. Pentru n<0 funcţia factorial nu este definită. Calcularea acestei funcţii poate fi facută prin metoda următoare: public static long factorial(int n) throws Exception { if(n<0) throw Exception("factorial(n): n<0"). Comparând metodele recursive cu cele iterative se constată că: . } În corpul metodei se verifică. în metodele recursive trebuie să existe o condiţie de oprire a repetării. Recursia se încheie când se ajunge la n==0. 151 . este mai mare.. Exemplul 1: Un exemplu tipic de funcţie recursivă este calcularea factorialului.din punct de vedere computaţional. Să urmarim acest proces în cazul invocării metodei factorial(n) pentru n=4: factorial(4)=4*factorial(3). se aplică formulele de calcul recursiv al factorialului date mai sus. La revenirea din metoda invocată se obţine valoarea întoarsă de aceasta şi se extrag din stivă datele puse acolo înainte de invocare. datele metodei care invocă. sunt puse întro structură de memorie numita stivă. În caz contrar recursia ar continua până la depăşirea spaţiului de memorie alocat pentru memorarea datelor intermediare (numit stivă). . se pune 2 în stivă şi se invocă factorial(1). iar în caz contrar se generează o excepţie.metodele recursive sunt "mai elegante". Din punct de vedere matematic. factorialul este o funcţie factorial(n) = 1*2*3*. continuându-se calculul. se pune 4 în stivă şi se invocă factorial(3).

Severin Bumbaru factorial(1)=1*factorial(0). în care factorialul se calculează printr-un ciclu for: public static long factorial(int n) throws Exception { long fact. Se poate constata că. factorial(3)=3*2=6. Cele două metode sunt apoi testate şi comparate în clasa TestRecursii. Se observa că. fibonacci(n)=fibonacci(n-1)+fibonacci(n-2) pentru n>1. S-a încheiat calculul lui factorial(1) şi se revine în factorial(2)cu valoarea intoarsa 1. care conţine metode iterative. if(n<0) throw new Exception("factorial(n): n<0"). Se continuă calculul fucţiei factorial(1)care a invocat-o pe factorial(0). folosind următoarea funcţie. În acest scop se scoate din stivă 1 şi se calculează factorial(1)=1*1=1. fact=1. este posibil ca stiva să nu aibă capacitate suficientă. În acelaşi fişier există şi clasa-aplicaţie TestRecursii. i++) fact*=i. În acest caz se obţine eroarea de depăşire de stivă StackOverflowError (atenţie: este o eroare. intorcându-se valoarea 24. factorial(4)=4*6=24. În fişierul TestRecursii. la valori mici ale 152 . şi alta iterativă. cu cât recursia este mai "profundă" (funcţia recursivă se invocă de mai multe ori pe sine însăşi). stiva conţine 3 4. deoarece funcţia nu se mai invocă pe ea însăşi. în clasa Recursii.java. stiva este vidă. factorial(0)=1. recursia s-a incheiat. stiva conţine 4. cu atât este necesară o stivă de capacitate mai mare. În acest fişier se declară două clase: clasa Recursii. care testează metodele din celelalte două clase. fibonacci(1)=1.currentTimeMillis(). Daca recursia este prea "profundă". nu o excepţie). Calcularea factorialului se poate face şi iterativ. deci calculul funcţiei recursive s-a incheiat.java sunt declarate două metode statice pentru funcţia Fibonacci: una recursiva. în aplicaţia TestRecursii s-a procedat astfel: înainte şi după invocarea fiecărei metode s-a determinat timpul sistemului în milisecunde. stiva conţine 2 3 4. apoi s-a făcut diferenţa. se pune 1 în stivă şi se invocă factorial(0). stiva conţine numerele 1 2 3 4. for(int i=2. i<=n. în clasa Iteratii. Pentru a se compara metodele din punctul de vedere al timpului de calcul. extrăgând din stivă pe 2: factorial(2)=2*1=2. return fact. Exemplul 2: Un alt exemplu tipic de funcţie recursivă este funcţia lui Fibonacci definită astfel: fibonacci(0)=0. } Ambele metode de calculare a factorialului sunt testate în aplicaţia din fişierul TestRecursii. care conţine metode statice recursive şi mutual-recursive şi clasa Iteraţii. se continuă factorial(2). folosind metoda System. Se constata astfel că timpul de calcul al factorialului pe cale recursivă este mai mare decat pe cale iterativă.

java sunt declarate şi două funcţii mutualrecursive: fct1(n.. "aruncă" o excepţie din clasa Exception.x)=2*fct2(n. În această instrucţiune. Exemplul 3: În clasa Recursii din fisierul TestRecursii. Exemplu Instrucţiunea if(a>1000) throw new Exception("Exceptie 102: a="+a). 0. 1. Este posibil ca programatorul să prevadă.4*x+0.3)+x pentru n>=0 fct2(0. În limba engleză. metoda recursivă este chiar mai rapidă decât cea iterativă. se foloseşte operatorul new pentru a genera un obiect al clasei de excepţii căreia îi aparţine constructorul invocat. Pentru a indica această proprietate. la declararea metodei.y)=y fct2(n. În schimb. la apariţia anumitor anomalii în executarea programului.Programarea orientata pe obiecte în limbajul Java argumentului n. throw este imperativul de la "a arunca". Metode care generează excepţii Instrucţiunea throw Cunoaştem deja că. maşina virtuală Java generează excepţii. catch şi tratat prin program..y)=y*fct1(n-1. Clauza throws În mod normal. în acest caz. Este însă posibil ca metoda respectivă să "arunce" mai departe excepţiile generate în corpul ei. excepţiile generate într-o metodă sunt tratate prin structuri try . care contine un mesaj sub forma argumentului furnizat constructorului. devenind sensibil mai mare decât al celei iterative. după care acest obiect este "aruncat". Excepţiile sunt obiecte din clasa Exception s-au dintr-o subclasă a acesteia. folosind în acest scop instrucţiunea throw. fie pentru a fi "prins" (captat) printr-o structura try .27*y-0. generarea unor excepţii. în anumite puncte ale programului. fie pentru a fi preluat de maşina virtuală Java care.89)-1 pentru n>0 Se observă că funcţia fct1() invocă funcţia fct2() şi reciproc. timpul de calcul al metodei recursive creşte foarte rapid. la valori mari ale lui n. catch. după paranteza care conţine lista declaraţiilor argumentelor formale se pune clauza 153 . care are forma următoare: throw new ConstructorExceptie(lista_argumente). opreşte execuţia programului. chiar în metoda în care au fost generate.

În metoda main se captează şi se afişează atât aceste excepţii. Lansarea in executie a aplicatiei se face prin comanda: java TestExceptie <numar_intreg> Daca <numar_intreg> este un numar intreg cuprins intre 0 si 12 se afiseaza factorialul acestui numar. } /* In metoda main se capteaza si trateaza exceptiile generate de metodele factorial si parseInt */ public static void main(String args[]) { if(args. În această metodă este folosită instrucţiunea throw de doua ori: pentru cazul în care argumentul este negativ şi pentru cel în care argumentul este prea mare (rezultatul depăşeşte valoarea maximă pentru tipul int al valorii întoarse). System.out. Altfel. return fact. } catch(Exception e) { System. în care se indică numele clasei excepţiei care este "aruncată" către metoda invocatoare (Cuvantul throws este persoana a treia singular a verbului to throw. } try { int n=Integer. for(int k=1. în instrucţiunea throw se foloseşte constructorul clasei Exception.parseInt(args[0]). se afiseaza un mesaj de eroare */ class TestExceptie { /* O metoda in care se genereaza exceptii prin clauza throw */ static int factorial(int n) throws Exception { if(n<0) throw new Exception("factorial: argument negativ n="+n). if(n>12) throw new Exception("factorial: argument prea mare: "+n).Severin Bumbaru throws ClasaDeExceptii. în declaraţia metodei factorial s-a folosit clauza throws.exit(1). int m=factorial(n). k<=n.println(e). System. /* Testarea unei metode care genereaza exceptii.out. cât şi excepţia NumberFormatException generată de metoda int Integer.println("Factorialul lui "+n+" este "+m). furnizându-i ca argument un mesaj care arată ce eroare s-a produs.parseInt(String s) atunci când argumentul acesteia nu este forma externă a unui număr întreg.java există metoda static int factorial(int n). "a arunca"). } 154 .println("Lipsa argument in linia de comanda"). În ambele cazuri. Exemplu În programul din fişierul TestExceptie. int fact=1. k++) fact*=k. care calculează factorialul argumentului n.out.length==0) { System. Întrucat aceste excepţii nu sunt tratate în metoda factorial.

Dăm în continuare ca exemplu clasa Complex.Programarea orientata pe obiecte în limbajul Java } } Clase publice Clasele publice sunt clase care pot fi utilizate şi în alte pachete. În declaraţia de clasă. 155 . în faţa numelui clasei se pune modificatorul public. Fiecare clasă publică se declară într-un fişier separat. care are obligatoriu acelaşi nume cu cel al clasei şi extensia java. decât cel din care fac parte.

După cum este cunoscut. im=z. // partea reala private double im. im=0. Complex z=new Complex(). } public Complex(Complex z) { re=z. } /* Metode */ public double real() { // intoarce partea reala return re.Severin Bumbaru Declararea clasei Complex Clasa Complex este un exemplu de clasă prin care se modelează conceptul matematic de număr complex.re). } public Complex(double parteaReala. im=parteaImaginara. numărul complex a+b. im=0.ieste compus din două numere reale a şi b. numite respectiv partea reală şi partea imaginară. În fişierul Complex. double argument) throws Exception { if(modul<0) throw new Exception("Complex: modul negativ: "+modul). } public double imag() { // intoarce partea imaginara return im. double parteaImaginara) { re=parteaReala. Iată această declaraţie: /* Clasa numerelor complexe */ public class Complex { private double re. 156 .atan2(im.java este dat un exemplu de declaraţie a clasei Complex.im. } public double modul() { // intoarce modulul numarului complex return Math. } public Complex(double parteaReala) { re=parteaReala. } public static Complex complex(double modul. // partea imaginara /* Constructori */ public Complex() { re=0.re. Simbolul i este numit unitatea imaginară şi are proprietatea i2= -1.sqrt(re*re+im*im). } public double arg() { // intoarce argumentul numarului complex return Math.

im.re=modul*Math.re+a.re=re-a. } public Complex minus(double d) { return new Complex(re-d.re. Complex z) { return new Complex(d*z.im).re-im*a.re. 157 . z.im*a.Programarea orientata pe obiecte în limbajul Java z.im.im=im-a. d*z. z.im=re*a. -z. return z.im=modul*Math. z. } public Complex minus(Complex a) { Complex z=new Complex(). return z. z. // patratul modulului numitorului if(w==0) throw new Exception("Complex impartitLa: impartire la zero"). } public static Complex plus(double d.im).re*a. im). z.re. im*d).re=re*a.im=im+a.re=re+a. } public Complex impartitLa(Complex a) throws Exception { Complex z=new Complex(). z. Complex z) { return new Complex(d-z.im. return z. } public Complex plus(Complex a) { Complex z=new Complex(). } public Complex inmultitCu(double d) { return new Complex(re*d. } public static Complex inmultitCu(double d. return z. z.im).cos(argument). } public Complex plus(double d) { return new Complex(re+d.im+im*a. Complex z) { return new Complex(d+z. } public static Complex minus(double d.im.re.re. im). z.sin(argument).re. } public Complex inmultitCu(Complex a) { Complex z=new Complex(). double w=a.

} public static Complex impartitLa(double d.toString(). deci este o clasa publică. } public String toString() { StringBuffer b=new StringBuffer("("+re). metode pentru 158 . -d*z. } public Complex impartitLa(double d) throws Exception { if(d==0) throw new Exception("Complex impartitLa: impartire la zero"). nu a mai fost posibil să se creeze încă un constructor. b.im)/w. equals şi hashCode ale superclasei Object. return new Complex(re/d. z. if(im>=0) b. reprezentând partea reală şi cea imaginară a numărului complex nou creat. care să aibă ca argumente modulul şi argumentul noului număr complex (acestea fiind tot numere reale). atât partea reală. el a fost înlocuit prin metoda statică public static Complex complex(double modul double argument) al cărei nume începe cu literă mică.re*z. return z. Din această cauză. } public boolean equals(Object obj) { if(this==obj) return true. return false.re+z. Având în vedere că s-a declarat un constructor cu două argumente de tip double.Severin Bumbaru z. S-au prevăzut mai mulţi constructori.im=(im*a.re)&&(im==(((Complex)obj).im))) return true.re=(re*a. } public int hashCode() { return (int)(100000*modul()+100*arg()). if(w==0) throw new Exception("Complex impartitLa: impartire la zero").im/w). de asemenea.re-re*a. im/d). Au fost declarate.im*z.im)/w. if(re==(((Complex)obj). Clasa conţine două câmpuri de tip double. } } Declaraţia clasei incepe prin public class Complex. cât şi cea imaginară sunt nule. Primul dintre aceştia nu are argumente şi creează un număr complex la care. return new Complex(d*z. Complex z) throws Exception { double w=z.re/w.append(im+"*i)"). Au fost redefinite metodele toString. reprezentând respectiv partea reală şi partea imaginară a numărului complex.append('+').im.getClass()) return false. pentru a ţine seama de specificul clasei Complex. return b.re+im*a. if(getClass()!=obj.

s-a construit un obiect cu acelaşi continut ca cel indicat de a. a="Sir nou". deoarece operandul din stânga nu aparţine clasei complex.java. în consecinţă. . s-a prevazut generarea de excepţii. În toate metodele. Ultimele au fost declarate ca metode statice. Colectorul de reziduuri Dacă un obiect nu mai este necesar.referinţei e i s-a atribuit aceeaşi valoare ca referinţei b. există un colector de reziduuri de memorie (engleză: garbage collector) care eliberează automat spaţiul de memorie ocupat de obiectele către care nu mai există nici o referinţă. ca în alte limbaje de POO. Utilizarea clasei complex Testarea diferitelor situaţii de utilizare a clasei complex este exemplificată în fişierul TestComplex. deci clasele nu mai conţin destructori. se execută instrucţiunile: e=b. faţă de situaţia din Figura 2. În programul din fişierul Referinte. programatorul nu mai este pus în situaţia să prevadă explicit în program distrugerea obiectelor şi.java se dă un exemplu de situaţie în care unele obiecte rămân fără referinţe. .Figura 3 S-au făcut. iar variabila c indică acum 159 . iar variabila aa primit ca valoare referinţa la acest obiect. între un număr complex şi unul real şi intre unul real şi unul complex. În maşina virtuală Java. c=new String(a). în care pot să apară situaţii anormale. adică eliminat din memorie.Programarea orientata pe obiecte în limbajul Java efectuarea de calcule între două numere complexe. următoarele transformări: . . el poate fi distrus. se ajunge în situaţia din Figura 3. după ce s-a ajuns în situaţia din Figura 2.s-a construit un obiect cu conţinutul "Şir nou". Dacă.

Programatorul nu are însă posibilitatea de a decide în ce moment se va produce eliminarea efectivă a acestor obiecte. Metoda finalize nu este apelată explicit în programul de aplicaţie. Exemplu În aplicaţia din fişierul Finalizari. după care se elimină referinţele către aceste obiecte. 3. Metoda finalize În clasa Object exista metoda protected void finalize() throws Throwable Aceasta metodă este invocată de colectorul de reziduuri.Severin Bumbaru acest nou obiect. 4. De exemplu. dacă obiectul respectiv a deschis anumite fişiere sau conexiuni externe. Întrebări Nivel 1 1. Apelarea metodei finalize se face numai de către colectorul de reziduuri (garbage collector). deci ele trebuie să fie eliminate. Nu mai există nici o cale în program de a folosi aceste obiecte. Metoda finalize poate fi redefinită în orice altă clasă. decizia aparţinand numai colectorului de reziduuri. Care este cea mai simplă formă a unei declaraţii de clasă? Ce sunt membrii unei clase? Ce este numele clasei din punct de vedere sintactic? Cu ce începe numele unei clase? 160 . În consecinţă. în metoda finalize se poate efectua închiderea lor. dar nu imdeiat ce un obiect a rămas fără referinţă. în care este redefinită metoda finalize() din clasa Object. În clasa Object. Având în vedere că imediat după aceea se încheie executarea aplicaţiei. Este posibil ca executarea aplicaţiei să se incheie înainte ca "finalizarea" unor obiecte să aibă loc. atunci când acesta determină că nu mai există referinţe către obiectul respectiv. În clasa Finalizari din acelaşi fisier se construiesc două obiecte din clasa ProbaFinaliz. Acest rol este îndeplinit de colectorul de reziduuri. două din obiectele "un şir" construite initial au rămas fără referinţe. ci abia atinci când acest obiect a "intrat în atenţia" colectorului. această metodă nu efectuează nimic.java este declarată clasa ProbaFinaliz. pentru a elibera resurse sau a efectua orice alte acţiuni necesare înainte de distrugerea obiectului respectiv. 2. cel mai probabil este că nu va avea loc invocarea de către colectorul de reziduuri a metodei finalize().

Ce este signatura metodei? 19. Cum pot fi generate excepţii în corpul unei metode? 22. Ce sunt clasele publice? 26.Programarea orientata pe obiecte în limbajul Java 5. În ce situaţie. Este posibil ca o metodă să întoarcă o referinţă la un obiect construit în corpul acesteia? 14. 2. Ce este o metodă statică? 17. Ce deosebire este între parametrii formali ai unei metode şi cei efectivi? 9. Ce asemănare este între câmpuri şi variabilele locale? 7. Ce se întâmplă dacă în corpul unei metode se modifică conţinutul unui obiect referit de către un parametru formal al metodei respective? 11. Cum se declară argumentele metodei? 14. Ce se întâmplă dacă. în corpul unei metode care are ca argument formal un tablou. în mod normal. 3. Ce se întâmplă dacă. Există în limbajul Java variabile globale? 8. Ce restricţii trebuie respectate la declararea unei metode statice? 18. Ce formă şi ce semnificaţie are instrucţiunea return? 16. la revenirea dintr-o metodă. Ce formă are instrucţiunea throw şi la ce serveşte? 23. Cum se declară tipul valorii întoarse? 15. Ce se întâmplă dacă în corpul unei metode se modifică valoarea unui argument formal? 10. Ce conţine corpul clasei? 6. Ce este numele metodei din punct de vedere sintactic? 12. o metodă prin care se realizează o funcţie propriu-zisă (a carei valoare întoarsă nu este void)? 6. În ce mod se invocă. în corpul unei metode care are ca argument formal un tablou. Pot exista clase care nu conţin metode? 10. Cum se declara o clasă publică? 27. Cum se face transferul argumentelor (parametrilor) de la metoda invocatoare la cea invocată? 21. Ce se întâmplă dacă în corpul unei metode se modifică valoarea unui parametru formal de tip referinţă (în sensul că i se dă ca valoare o referinţă la alt obiect)? 12. Care este cea mai simplă formă a unei declaraţii de metodă? 11. Ce deosebire este între throw şi throws? 25. se modifică elementele acestui tablou? 15. În ce mod poate fi invocata o metoda care întoarce void? 7. 4. poate să aibă loc un efect lateral? 13. Pot exista în aceeaşi clasă mai multe metode cu acelaşi nume? 20. i se 1. Ce sunt câmpurile statice şi prin ce se deosebesc de cele nestatice? 9. Ce este corpul metodei şi ce conţine el? 13. 161 . Ce este colectorul de reziduuri? Nivel 2 Care sunt valorile iniţiale implicite ale câmpurilor? Ce deosebire este între iniţializarea câmpurilor şi iniţializarea variabilelor locale? Ce deosebire este intre o funcţie şi o procedură? Prin ce se deosebeşte o metodă prin care se realizează o procedură de una care realizează o funcţie? 5. La ce serveste clauza throws? 24. Ce deosebire este între câmpuri şi variabille locale? 8.

În ce scop este redefinită metoda finalize()? 24. În ce scop se redefineşte într-o clasă metoda toString() a clasei Object? 20. Poate o metodă să întoarcă drept valoare o referinţă la un tablou creat în interiorul ei? 17.Severin Bumbaru dă acestui argument ca valoare o referinţa la alt tablou? 16. Ce deosebiri există între iteraţie şi recursie? 19. Ce este metoda finalize()? 23. Poate fi declarată o metodă care creează un obiect nou al clasei căreia îi apartine metoda respectivă? Prin ce se deosebeşte ea de un constructor? 22. Ce este o metodă recursivă? 18. În ce scop se redefineşte într-o clasă metoda equals(Object ob) a clasei Object? 21. În ce situaţii este invocată metoda finalize()? 162 .

Declararea clasei derivate. numite obiecte. Membrii protejati ai clasei. se consideră drept principale caracteristici ale obiectelor încapsularea. Declararea clasei Student. câmpuri şi metode publice şi private. Un exemplu: clasa Persoana şi subclasa Student. Clase imbricate Caracteristici ale obiectelor şi claselor şi reflectarea lor în declararea claselor: Încapsularea. Instanţierea clasei care conţine metoda main. Redefinirea metodelor. Interfeţe. Polimorfismul. Clase finale. Declararea clasei Persoana. cum sunt identitatea. Declararea constructorului clasei derivate. Declararea constructorilor. agregarea şi clasificarea. Interfeţe. Metode finale. Declararea propriilor clase de excepţii. Fiecare obiect din POO modelează starea şi comportamentul unui anumit 163 . moştenirea şipolimorfismul. Utilizarea celor două clase. Identitatea (engleză: Identity) se referă la faptul că datele sunt grupate în entităţi discrete. Ascunderea metodelor statice. Moştenirea. Clase imbricate şi clase interioare Întrebări 163 166 167 167 170 171 171 171 171 172 172 175 175 177 177 177 177 180 180 181 183 184 186 186 190 195 Caracteristicile obiectelor şi claselor În majoritatea surselor bibliografice asupra POO. Agregarea. Clase abstracte. Referinţele this şi super.Programarea orientata pe obiecte în limbajul Java Caracteristicile obiectelor şi claselor şi reflectarea lor în declararea claselor. Modificatori de acces pentru câmpuri şi metode. Ascunderea (acoperirea) câmpurilor. clauza extends. La acestea se mai pot adaugă şi alte caracteristici importante.

Figura 1 Obiectul se comportă ca şi când ar avea doua "învelişuri": unul "transparent". din exterior. chiar daca atributele lor (cum ar fi numele. Putem deci sa ne imaginăm obiectul ca fiind format din două straturi. Agregarea (engleză: aggregation) este proprietatea obiectelor de a putea încorpora alte obiecte. astfel că două obiecte sunt considerate distincte. culoarea etc. care permite accesul la datele şi metodele publice ale obiectului. Încapsularea (engleză: encapsulation) este proprietatea obiectelor de a-şi ascunde o parte din date şi metode. "datele" conţinute într-un obiect pot fi nu numai date primitive. Datorită faptului că partea încapsulată diferă. nume etc. astfel de obiecte pot avea comportament diferit. In consecinţă.). cât şi de cele încapsulate. ca urmare a accesului neautorizat din exterior. sunt identice. Este posibil ca două obiecte diferite să aibă interfeţe identice. Metodele publice ale obiectului au acces la datele şi metodele încapsulate (ascunse) ale acestuia. Aşa dar. starea obiectului poate fi modificata atât prin modificarea directă. furnal. adresă de memorie. Încapsularea obiectelor prezintă avantaje importante în programare. preferand ca accesul la date să se facă numai prin metode. deoarece măreşte siguranţa şi fiabilitatea programelor. a valorilor variabilelor publice. Partea vizibilă (publică) a obiectului constituie interfaţa acestuia cu "lumea exterioară". adică să prezinte în exterior aceleaşi date şi metode. ca în Figura 1. şi un al doilea inveliş "opac". care cuprinde datele şi metodele invizibile (inaccesibile) din exterior. important însă este că fiecare obiect are o singură referinţă şi nu există două obiecte distincte cu aceeaşi referinţă. animal etc. Se pot astfel crea obiecte cu structuri din ce în ce mai complexe. Din exteriorul obiectului sunt accesibile ("vizibile") numai datele şi metodele publice. programatorii evită în general să prevadă într-un obiect date publice. orar etc. om. Fiecare obiect are propria lui identitate. ci şi obiecte. calculator. fie prin utilizarea unor metode publice care modifica valorile variabilelor încapsulate. Modul în care este reprezentata această referinţă poate sa difere în diverse limbaje de programare (de ex. Starea obiectului depinde atât de datele publice. Pentru a face aceasta distincţie. .) sau unul conceptual (de exemplu figură geometrică. În mod similar.). care poate fi un obiect fizic (de exemplu automobil. valorile variabilelor încapsulate pot fi obţinute numai utilizand metode publice ale obiectului respectiv. Din această cauză. prin eliminarea posibilităţii modificării accidentale a valorilor acestora.). obiectul este indicat printr-o referinţă unică. 164 .Severin Bumbaru obiect din lumea reală.

şi le ignoră pe celelalte. Clasa A este rădăcina acestei ierarhii. Spre deosebire de agregare. iar clasa F este derivată din clasa B sau. greutatea etc. De exemplu. De exemplu. anul de studii. culoarea ochilor sau a părului. clasa Barbat şi clasa Femeie sunt subclase ale clasei Om. clasele pot forma o structura ierarhică. examenele promovate şi notele obţinute. Ion_Popescu este o instanţăa clasei Barbat (un obiect care aparţine acestei clase). navale şi aeriene. o realizare particulara a clasei respective). o subclasă este derivată din superclasa sa. Toate instanţele unei clase au aceleaşi atribute (aceleaşi "câmpuri"). de asemenea. care nu sunt necesare în aplicaţia respectivă. desigur. care este o relaţie între obiecte. Un obiect care aparţine unei clase se numeşte şi instanţă a clasei (este o instanţiere. cu atât ea este mai abstractă. În acelaşi timp. o clasă poate avea o infinitate de instanţe. Clasa mijloacelor de transport rutiere cuprinde clasele automobilelor şi autocamioanelor etc. clasa Student conţine astfel de atribute ca numele şi prenumele studentului. În schimb. De exemplu. deci descrie un număr mai mic de atribute ale obiectelor care îi aparţin. dar ignoră atribute ca înălţimea. În programarea orientată pe obiecte se spune. dar valorile acestora pot să difere de la o instanţă la alta. Fiecare subclasă a unei clase este ea însăşi o clasă. Clasa mijloacelor de transport terestre le cuprinde pe cele rutiere şi feroviare. în general. fiind situată pe cel mai înalt nivel de abstractizare. clasificarea este o relaţie între concepte reprezentate prin clase. iar aceasta este superclasă a clasei F.. În principiu. iar Maria_Preda este o instanţă a clasei Femeie. 165 . că clasa B este derivată din clasa A. iar clasele E si F sunt subclase ale clasei B. O astfel de ierarhie de clase este reprezentată în Figura 2. în aplicaţii privind situaţia profesională a studenţilor. Clasele B. clasa Aestesuperclasă a clasei B. care sunt importante într-o aplicaţie sau într-o categorie de aplicaţii. care conţine acele proprietăţi ale obiectelor. Practic. clasa mijloacelor de transport cuprinde subclasele mijloacelor de transport terestre. .Figura 2 Cu cat o clasă se afla în această ierarhie pe un nivel mai înalt. Clasa este o abstractizare.Programarea orientata pe obiecte în limbajul Java Clasificarea (engleză: classification) este proprietatea obiectelor care au aceeaşi structură de date şi acelaşi comportament (aceleaşi metode) de a putea fi grupate într-o clasă. C şi D sunt subclase ale lui A. facultatea. numărul lor este finit. În functie de nivelul de abstractizare.

că în clasa Figura_geometrica există metoda arie(). la calcularea ariei se va aplica metoda specifică clasei respective. Să considerăm.Figura 3 În această figură se observă că clasa D moşteneşte clasele A şi B. deci deţine atributele ambelor clase. în programarea orientată pe obiecte. Astfel. de exemplu. Polimorfismul (engleză: polymorphism) permite ca aceeaşi operaţie să se realizeze în mod diferit în clase diferite. Lipsa moştenirii multiple este compensată în limbajul Java prin introducerea conceptului de interfaţă care va fi prezentat ulterior. Triunghi. Câmpurile. dar fiecare din acestea are şi atribute specifice. Pentru a se evita astfel de situaţii. Încapsularea Încapsularea este una din proprietăţile fundamentale ale claselor în programarea orientată pe obiecte. aceasta creează unele dificultăţi. Pentru fiecare din instanţele acestor clase. Este însă evident că aria cercului se calculează în alt mod decât aria patratului sau cea a triunghiului. De exemplu. În cazul moştenirii multiple o clasă poate avea mai multe superclase. 166 . ca limbajul C++. Aceasta corespunde situaţiei din lumea reală în care. clasa Barbat şi clasa Femeie au ambele toate atributele clasei Om. în limbajul Java se admite numai moştenirea simplă. constructorii şi metodele dintr-o clasă pot fi încapsulate. metodele şi datele clasei B sunt moştenite de clasa H pe două căi: pe traseul BDH şi pe traseul BEH. trecerea de la clasă la subclasă se face prin adăugarea de atribute şi/sau de metode. ca în Figura 3. de exemplu. ca în Figura 2. constructorului sau metodei respective modificatorul private. deci. şi sportiv. moştentirea poate fi simplă sau multiplă. un student_sportiveste în acelaşi timp şi student. care calculeaza aria figurii respective. Clasele Cerc. Aceasta se realizează folosind la declararea câmpului. În general. care admit moştenirea multiplă. astfel încât să nu fie vizibile din exteriorul clasei sau instanţei în care se află. în exemplul din Figura 3. de la aceasta metoda arie(). În cazul moştenirii simple fiecare clasă are cel mult o superclasă. Deşi există limbaje de programare. În consecinţă. . iar clasa H moşteneşte clasele D. Patrat sunt subclase ale clasei Figura_geometrica si vor moşteni.Severin Bumbaru Moştenirea (engleză: inheritance) este proprietatea unei clase de a conţine toate atributele (câmpurile) şi metodele superclasei sale. E siF.

protected . pentru clasele declarate de către noi. o clasă poate avea mai multi constructori. Constructorii. Membrii protejati sunt accesibili numai din clasa în care se află sau din subclasele acesteia. constructorii prezintă următoarele trăsături specifice: .constructorii nu pot fi statici.pentru a specifica câmpuri sau metode protejate (care vor fi prezentate în secţiunea despre moştenire). În mod similar.private . sunt câmpurile şi metodele publice. că modul de acces este prietenos (engleză: friendly) sau de pachet (engleză: package). care sunt declarate folosind modificatorul public şi sunt vizibile din orice altă clasă. . b.Programarea orientata pe obiecte în limbajul Java De exemplu. Membrii privati ai claselor (câmpuri sau metode) sunt accesibili numai din clasa respectivă. } se declară metoda privată ex1. 167 .constructorul nu întoarce o valoare. acestea sunt considerate vizibile numai din clasele care sunt situate în acelaşi pachet cu clasa căreia îi aparţin. Se spune. . În opoziţie cu acestea.pentru a specifica câmpuri sau metode publice. În consecinţă. ca la metode. prin declaraţia de metodă private int ex1(int k) { return 2*k+1). . aceste câmpuri şi metode sunt vizibile numai din clasele situate pe disc în acelaşi director. ea are un constructor implicit. c care nu sunt vizibile din exteriorul instanţei în care se afla.public . Membrii publici sunt accesibili din orice clasă. la declararea constructorului nu se specifică tipul valorii întoarse. Constructorul implicit Dacă într-o clasă nu este declarat explicit nici un constructor. iar efectul lui constă în iniţializarea tuturor câmpurilor instanţei care se creează cu valorile implicite corespunzătoare tipurilor câmpurilor respective. în astfel de cazuri. Acest constructor nu are argumente. Modificatori de acces pentru câmpuri şi metode În limbajul Java există trei modificatori de acces pentru câmpuri şi metode: .pentru a specifica câmpuri sau metode private. b. sunt niste subprograme.numele constructorului este întotdeauna acelaşi cu al clasei căreia îi aparţine.invocarea constructorilor se face numai prin operatorul new. se creează câmpurile private a. În particular. Dacă la declararea câmpurilor sau metodelor nu se folosesc modificatori de acces. Câmpurile şi metodele declarate astfel se numesc private. Declararea constructorilor Constructorii sunt utilizati impreuna cu operatorul new pentru a creea instanţe ale claselor. care sa difere între ei prin signatură. Faţă de metode. prin declaraţia de câmpuri private double a. Constructorii pot fi impliciţi sau expliciţi. ca şi metodele. Ca şi în cazul metodelor. . c. .

Exemplu: în aplicaţia Cercuri din fişierul Cercuri. } public static double arie(double r) { return PI*r*r. Modificatorul de acces al constructorului este. 168 . public. sa lipsească dacă se consideră că instanţierea clasei se va face numai în metode ale claselor din acelaşi pachet. Constructori expliciţi Declararea constructorului se face sub forma modificator_acces nume_clasa(declaratii_de_argumente) { corpul_constructorului } Se observă imediat că declararea constructorului se face la fel cu a unei metode. private double r. El poate. În corpul constructorului pot fi programate orice fel de acţiuni care trebuie executate imediat după ce se alocă în memorie spaţiu pentru o instanţă a clasei respective. cel mai frecvent. Exemplu În fişierul Cercuri1. la crearea instanţelor clasei Cerc1 s-a folosit constructorul implicit al acestei clase.141592653589793.java. ea nu mai are constructor implicit.java este declarată clasa Cerc în modul următor: class Cerc { public static final double PI=3. totuşi. } public double circumferinta() { return 2*PI*r. } public double arie() { return PI*r*r. public Cerc(double raza) { r=raza. } public double raza() { return r.Severin Bumbaru ATENŢIE: dacă clasa are unul sau mai multi constructori declaraţi explicit. iar numele constructorului este cel al clasei. } public static double circumferinta(double r) { return 2*PI*r. cu deosebirea că lipseşte tipul valorii întoarse. Cel mai frecvent. în corpul constructorilor se iniţializează valorile câmpurilor instanţei nou create.

raza lui nu mai poate fi modificată.23)+ " circumferinta="+Cerc.Programarea orientata pe obiecte în limbajul Java } } Clasa Cerc are atât metodele de instanţă.out. r2=7. Întrucât clasa Cerc nu conţine nici o metodă prin care să se modifice valoarea acestui câmp.circumferinta(r1)). /* Utilizarea metodelor statice */ System. raza cercului nu mai poate fi modificată după ce acesta a fost creat. /* Instantierea a doua cercuri */ Cerc c1=new Cerc(r1). .out.23)).println("Utilizand metodele de instanta:").23)).câmpul r1 (raza cercului) a fost declarat privat.java. c2=new Cerc(r2).32.23: "+ c1.arie(9. În plus.arie(r2)+ " circumferinta="+Cerc2.out.23 aria="+Cerc. /* Acelasi calcul.circumferinta(r2)).out.arie()+ " circumferinta="+c1.arie(raza).println("Pentru raza r=9. System. facut calificand numele metodelor statice prin referinte la instante ale clasei Cerc */ System. aşa cum era posibil în cazul instanţelor clasei Cerc1.arie(9. Aria unui cerc oarecare poate fi calculată însă şi invocând metoda staticăCerc. cât şi metodele statice pentru calcularea ariei şi circumferinţei. În acelaşi fişier sursă. Calculara ariei cercului c1 se face invocând metoda c1. System.circumferinta(9. System.arie(9. în care se utilizeaza clasa Cerc.println("Pentru raza r2: aria="+Cerc.println("Pentru cercul c2:\n aria="+c2.raza()). /* Utilizarea metodelor de instanta */ System. 169 .println("Pentru raza r1: aria="+Cerc. deoarece se va folsi raza cercului c1.out.s-a declarat un constructor care. System.println("Pentru cercul c1:\n aria="+c1. System.println("Aria cercului cu raza 9. iniţializează câmpul r1. În acest caz. la crearea unui obiect din clasa Cerc. este declarata şi clasa Cercuri1. metoda nu are argumente.arie().arie(r1)+ " circumferinta="+Cerc2.circumferinta()+" raza="+c2.out.out. deci el nu este accesibil din exteriorul clasei. care existau în clasele Cerc1 şi Cerc2 din exemplul dat în fişierul Cercuri.arie()+ " circumferinta="+c2.out. remarcăm următoarele: . care aparţine instanţei c1.raza()).println("Folosind metodele statice ale clasei Cerc:"). Aplicaţia menţionată este declarată astfel: /* Aplicatia in care se utilizeaza cele doua clase de cercuri declarate mai sus */ class Cercuri1 { public static void main(String args[]) { double r1=1. } } Se observă că iniţializarea celor două cercuri (instanţe ale clasei Cerc) c1 şi c2 s-a făcut folosind constructorul Cerc(double raza).circumferinta()+" raza="+c1.23)+" "+c2. După ce a fost construit cercul.

prenumePers=prenume. cât şi ale instanţei să aibă ca valori obiecte din alte clase. Agregarea Agregarea este o caracteristică fundamentală a programării orientate pe obiecte. } String nume() { return numePers. În limbajul Java. prenumePers. Chiar dacă această metodă statică este invocată prin intermediul referinţei la o instanţă sub forma c1. aceste câmpuri nu mai pot fi modificate. Se observă că obiectele din clasa Pers conţin câmpurile nume şi prenume. } String prenume() { return prenumePers. iniţializarea lor se face folosind un constructor. } } Instanţele clasei Pers conţin datele unei persoane. care sunt referinţe la obiecte ale clasei String.Severin Bumbaru căreia însă i se dă ca argument raza cercului. Moştenirea Conceptul de moştenire 170 . Un exemplu de agregare este clasa Pers din fisierul Pers. După crearea obiectului.java. Testarea clasei Pers se face în aplicaţia din fişierul TestPers. anNasterePers=anNastere. pe care îl reproducem aici. şi construi pas cu pas clase cu structuri din ce in ce mai complicate. realizate prin agregarea claselor cu structuri mai simple. Pers(String nume. la declararea claselor. Se poate porni astfel de la clase simple. Compilatorul face distincţie intre metodele arie() şi arie(double raza) întrucât au semnături diferite.java. class Pers { private String numePers. întrucât câmpurile de date sunt private. int anNastere) { numePers=nume. Remarcăm de asemenea că. ci raza primită ca argument. private int anNasterePers. care au drept câmpuri date din tipuri primitive.arie(raza). conform căreia un obiect poate conţine alte obiecte. este permis ca atât câmpurile clasei. } int anNastere() { return anNasterePers. nu se va folosi în calcul raza instanţei c1. String prenume.

super . iar B se numeşte clasă derivată. conform căreia: . Declararea clasei derivate. în lipsa modificatorului de acces. Clauza extends În declaraţia clasei derivate (subclasei).Programarea orientata pe obiecte în limbajul Java Moştenirea este o trăsătură fundamentală a programării orientate pe obiecte. Acestea nu sunt accesibile din nici o alta clasă (nici chiar din subclasele propriei lor clase).public . . sau subclasă. clasa derivată poate fi declarată astfel: class NumeClasa extends NumeSuperclasa { declaratii_de_membri } 171 . Dacă din clasa A este derivată clasa B. Iată. Introducem acum şi modificatorul de acces protected. deoarece nu am declarat clase derivate. Referinţele this şi super În orice clasă pot fi utilizate două referinţe predefinite: this . sau superclasă.este o referinţă la "această" instanţă. atunci A se numeşte clasă de bază. cât şi la metode): public. dacă aceste metode au argumente sau variabile locale cu acelaşi nume.câmpurile unei clase pot fi ascunse chiar şi în metodele clasei respective.subclasa mosteneste câmpurile şi metodele superclasei.pentru câmpuri şi metode care sunt accesibile din orice clasă (inclusiv din clase aparţinând altor pachete).dintr-o clasă se pot deriva alte clase. .pentru câmpuri şi metode care sunt accesibile în propria clasă şi în subclasele acesteia. Acest mod de acces este cunoscut sub numele de prietenos (engleză: friendly) sau de pachet (engleză: package).metodele superclasei pot fi redefinite în subclasă prin alte metode cu aceeaşi signatură. .câmpurile superclasei pot fi ascunse în subclasă prin câmpuri cu acelaşi nume dar care pot avea. numele clasei care se declară este urmat de clauza extends.pentru câmpurile şi metodele care sunt accesibile numai din propria clasă.metodele statice ale superclasei pot fi ascunse în subclasă. . . care sunt cei trei modificatori de acces la membrii unei clase folositi în declaraţiile de clase: . Câmpurile sau metodele declarate cu acest modificator de acces sunt vizibile (accesibile) în propria clasă şi în clasele derivate din aceasta. adică la instanţa (obiectul) din care se face referinţa respectivă. eventual. Până în prezent am folosit numai modificatorii de acces public şi private. Membrii protejaţi ai clasei Există trei moduri de acces la membrii claselor (atât la câmpuri. alt tip. în care se indică numele superclasei.protected . . câmpurile şi metodele respective sunt accesibile din clasele aceluiaşi pachet.private . . Amintim că. În consecinţă.este o referinţă la superclasă. privat si protejat. deci. dar nu sunt vizibile din alte clase.

În lipsa ei. modificatorul de acces al acesteia poate fi menţinut. protected double b. care extinde clasa S1 (este. Redefinirea unei metode se face declarând în subclasă o metodă având aceeaşi signatură cu una din superclasă. Excepţie face clasa Object.Severin Bumbaru Amintim că în limbajul Java orice clasă are o superclasă şi numai una. double b. totuşi.a=a. va fi invocat constructorul fără parametri al superclasei. În subclasă pot fi folosite. ca într-un constructor să se invoce alt constructor al aceleeaşi clase. unde lista parametrilor efectivi este cea a constructorului superclasei. deci. public final static int alpha=12. Reproducem aici declaraţiile celor două clase: /* Clasa S1 din care vor fi derivate alte clase */ public class S1 { public int a. în declaraţia constructorului subclasei poate fi invocat constructorul superclasei prin instrucţiunea super(lista_parametri_efectivi). sau poate fi transformat în public. şi metodele superclasei care au fost redefinite. iar in fişierul CD1.b=b. this. int c) { // constructorul clasei S1 this.java este declarata clasa S1.c=c. Daca lipseşte clauza extends. superclasa implicită este Object. Declararea constructorului clasei derivate Pentru a se da valori iniţiale câmpurilor superclasei. derivată din aceasta). public S1(int a. sub forma this(lista_parametri_efectivi). } private double f1() { // o metoda privata return a*c+b.java este declarata clasa CD1. } 172 . de asemenea. this. Exemplu: În fişierul S1. Aceasta instrucţiune. private int c. Atunci când se redefineşte o metoda protejată. Este posibil. Redefinirea metodelor Metodele de instanţă (nestatice) ale unei clase pot fi redefinite în subclasele acesteia. care este rădăcina ierarhiei de clase. dacă la invocarea acestor metode se foloseste referinţa super. dacă există. trebuie să fie prima instrucţiune din corpul constructorului clasei derivate.

} public int f2() { // redefinirea metodei f2() din superclasa return 2*a. .metoda statică f4() din clasa S1 utilizează numai câmpul static alpha al acestei clase. prin care se invoca metoda f3 din superclasa S1. în metoda f3 din clasa CD1 există expresia super.f3(). astfel incât să se întoarca un şir care conţine valorile câmpurilor a.în clasa CD1 au fost redefinite metodele f2 şi f3 din superclasa S1 şi a fost iarăşi redefinită metoda toString.în metodele clasei CD1 nu au putut fi folosite câmpurile şi metodele private ale superclasei S1.în constructorul clasei CD1 a fost invocat constructorul clasei S1 sub forma super(a. dacă în expresia de invocare se foloseşte referinta super. în clasa CD1 se folosesc metodele f2 şi f3 redefinite în această clasă. Astfel. .Programarea orientata pe obiecte în limbajul Java protected int f2() { // o metoda protejata return a+2*c. b şi c. care se găseşte în fişierul TestD1.b. } } Remarcăm următoarele: .java.la redefinirea metodei f2.b. Este totuşi posibil ca în clasa CD1 să se apeleze metodele superclasei. } public double f3() { // o metoda publica in care se folosesc f1 si f2 return 2*f1()+f2(). pot fi invocate toate metodele din această clasă.în clasa S1 a fost redefinită metoda toString din clasa Object.în metodele clasei S1 pot fi folosite toate câmpurile declarate în această clasă.c). de asemenea. În acest mod au fost iniţializate toate câmpurile din superclasa S1.toString() return "(S1: "+a+" "+b+" "+c+")". modul de acces a fost modificat din protected in public. Iată aceasta clasă: 173 . in care se redefinesc unele metode */ class CD1 extends S1 { public CD1(int a. fie ele publice. int c) { super(a. . . } public double f3() { // redefinirea metodei f3() din superclasa return f2()+super. } public static int f4(int k) { return 2*k+alpha. Testarea claselor S1 si CD1 se face în clasa TestCD1. .în mod normal. double b. .f3(). } } /* O clasa derivata din S1. protejate sau private.c). . } public String toString() { // redefinirea metodei Object. care nu este direct accesibil din clasa CD1. inclusiv câmpul privat c.

f3()).f3()=460.f3()=11.f3()="+s.println("s="+s+" cd="+cd).println("s.2 20) s.f4(3)="+s.4 CD2. 2).f2()=5 s. Puteti compila cele trei fişiere menţionate şi pune în executie aplicaţia TestCD1 pentru a verifica respectarea afirmaţiilor de mai sus.metoda statică f4() din clasa S1 a fost invocată în patru moduri: calificând numele metodei f1 cu numele clasei S1 (căreia îi aparţine de fapt această metodă).f4(3)+" s. . .2. A doua oară ar trebui sa fie invocată metoda cd.f4(3)=18 cd.f4(3)=18 Remarcăm că: . este de două ori invocată implicit metoda toString. System.1. prima dată este invocată metoda s.f2() şi cd.out.f2()+" s.println("s="+s+" cd="+cd). careia îi aparţine s.println("CD2.f4(3)+" S1. 1. Puteţi. . cu numele subclasei CD1 (care moşteneşte această metodă) şi cu numele instanţelor s şi cd ale acestor clase. . System. de asemenea.f3()).out. pentru a converti în şiruri afişabile obiectele s şi cd.f2()=20 cd. } } Executând aplicaţia TestCD1 se obţin urmatoarele rezultate: s=(S1: 1 1.f2() si s.f4(3)="+CD2.out. System. iar in expresiile cd.Severin Bumbaru /* Testarea claselor S1 si CD1 */ class TestCD1 { public static void main(String args[]) { S1 s=new S1(1.f2()+" cd. a fost aplicată efectiv metoda toString() din superclasa S1.f4(3)="+cd. System.out.out.1 2) cd=(S1: 10 10.f2()="+s.crearea instanţelor claselor S1 şi CD1 s-a făcut aplicând operatorul new asupra constructorilor claselor respective. face modificări în metodele celor trei clase menţionate.f4(3)).2 cd. CD1 cd=new CD1(10.ce se întâmplă dacă într-o metoda a clasei CD1 se încearcă folosirea câmpurilor sau metodelor private ale superclasei S1.println("cd.în instrucţiunea System.println("cd.toString() din clasa S1. 10.f3() sunt invocate metodele corespunzătoare din clasa CD1.f3() sunt invocate metodele din clasa S1.f3()="+cd. 20). intrucât metoda nu a fost redefinită în aceasta clasă. System.ce se întâmplă dacă în clasa TestDC1 se încearcă folosirea câmpurilor sau metodelor private sau protejate din clasele S1 şi CD1. în toate cele patru cazuri s-a obţinut acelaşi rezultat.f4(3)="+S1.f2()="+cd. astfel încât să verificaţi: . Ascunderea câmpurilor 174 . Cum era de aşteptat.out.toString() din clasa CD1 dar.f4(3)).în expresiile s.

în clasa CD2 este declarată metoda statică f4(int h).println("Campuri din S1: a="+super. Aceasta înseamna că. double m2) { super(a1. şi nu cele cu acelaşi nume ale superclasei.java este declarată clasa CD2. double a2. În clasa CD2 există declaraţia public double a. care extinde clasa S1 din exemplul precedent. double b1. ea operează cu câmpurile a.a+" b="+super. De asemenea. dacă sunt calificate cu referinţa super. int c1. // initializarea campurilor din superclasa a=a2. Vom înţelege mai bine deosebirea dintre redefinire şi ascundere când vom studia polimorfismul. } public static int f4(int h) { // ascunde metoda statica f4() din // superclasa return h+alpha. prin care se creează câmpuri ale instanţelor acestei clase.out. în metodele clasei se folosesc câmpurile declarate în clasa respectivă.în constructorul clasei CD2 este mai întâi invocat constructorul superclasei. b şi m 175 .b). b. în mod normal. chiar dacă acestea au tipuri diferite. double b2. /* O clasa in care se ascund unele din campurile superclasei */ class CD2 extends S1 { public double a. care ascunde metoda statică cu aceeaşi signatura din superclasa S1. după care se iniţializează şi câmpurile din CD2. b. m. // initializarea campurilor proprii } public void afisare() { System. b le ascund pe cele cu // aceleasi nume din superclasa public CD2(int a1.b1.println("Campuri din CD2: a="+a+" b="+b+" m="+m). } } Remarcăm că: . m=m2. ci clasei. dacă într-o subclasă se declara o metoda statică cu aceeaşi signatură ca o metodă a superclasei. Din această cauză.întrucât metoda afisare() este declarată în clasa CD2. Modul de lucru cu metodele ascunse este similar cu cel în care se lucrează cu câmpurile ascunse.Programarea orientata pe obiecte în limbajul Java Câmpurile declarate într-o clasă pot fi ascunse prin câmpuri cu acelaşi nume declarate în subclasă. Ascunderea metodelor statice Metodele statice nu aparţin instanţelor. folosite şi câmpurile superclasei. m.out. totuşi. // campurile a. } public String toString() { return "(CD2: "+super. b=b2. Exemplu În fişierul CD2. atunci se spune că metoda din subclasă o ascunde pe cea din superclasă (nu o redefineşte). dintre care a şi b ascund câmpurile cu aceleaşi nume ale superclasei.c1). În subclasă pot fi. System. . prin care se iniţializează câmpurile din S1.toString()+" "+a+" "+b+" "+m+")".

System. System. 2. cd.java.f4(3)="+S1.f4(3)).5 17.toString(): "+cd.println("cd.toString()=(CD2: (S1: 1 2.out.toString()).în redefinirea metodei toString() s-a folosit expresia super.08).83 28. 3.9) S1.în metoda afişare() din clasa CD2 se operează corect atât cu câmpurile a şi b din clasa CD2. care are conţinutul următor: /* Testarea clasei CD2 */ class TestCD2 { public static void main(String args[]) { CD2 cd=new CD2(1.5 m=17. Observăm că pentru a utiliza în aceasta metodă în mod direct câmpurile a şi b din S1 (care sunt ascunse în clasa CD2).out.b=28. în timp ce în expresia CD2. 176 .f4(3)=15 CD1.out.45 cd. folosindu-se în mod corespunzător expresiile super.toString(): "+cd. .f4(3)+" CD1.08) dupa ce s-au schimbat valorile campurilor din CD2: Campuri din CD2: a=-17.toString() pentru a invoca metoda cu aceeasi signatură din superclasa S1.în metoda toString() din CD2 se operează direct cu câmpurile a şi b declarate în această clasă şi cu metodele declarate în CD2 şi se opereaza indirect (folosind referinţa super) cu câmpurile şi metodele din superclasa S1 care sunt ascunse sau redefinite în CD2.f4(3)=18 CD2. în acesastă metodă se poate lucra şi cu câmpurile a şi b din S1.f4(3) este invocată metoda statică a clasei S1.out.Severin Bumbaru declarate în CD2.out.toString()).în expresiile S1. System.a şi super.23 b=12.println("Imediat dupa ce s-a creat instanta clasei CD2:").45 3) 10.f4(3)=cd1.println("S1.b. System.23 12. cd.m=127.println("dupa ce s-au schimbat valorile "+ "campurilor din CD2:"). cd. Totuşi.f4(3)=18 Remarcăm că: .5.9 Campuri din S1: a=1 b=2.afisare(). .16 m=127.16 127.f4(3)="+CD2.f4(3) şi CD1. 12. ar fi trebuit utilizate expresiile super.08 Campuri din S1: a=1 b=2.afisare(). System. Testarea clasei CD2 se face în aplicaţia din fişierul TestCd2. cât şi cu cele ascunse de acestea din clasa S1.b.83.45 cd.println("cd.45 3) -17. . 17.toString()=(CD2: (S1: 1 2. cd.f4(3) este invocată metoda cu aceeaşi signatură a clasei CD2.a şi super.45. care o ascunde pe cea din clasa S1.a=-17.9.f4(3)+" CD2.83 b=28. 10.16.23. } } Executând aplicaţia TestCD2 obţinem următoarele rezultate: Imediat dupa ce s-a creat instanta clasei CD2: Campuri din CD2: a=10. cd.

Corpul declaraţiei clasei de excepţii conţine numai declaraţii de constructori. a2. uneori programatorul poate simţi nevoia să işi creeze propriile sale clase de exceptii. Exemplu: În fişierul TestExceptie. ob2. care este generată la calcularea funcţiei factorial(n). în care una sau mai multe metode ale superclasei au fost redefinite. Clase finale Dacă se doreşte ca o clasă să nu poată avea subclase. Unei variabile referinţă dintr-o clasă. De exemplu. a3. ob3. Aceasta se poate realiza derivând clasele respective din clasa Exception. De exemplu. ea trebuia declarata sub forma public final class CD1 extends S1 sau. Object ob1. altul având un argument din clasa String. În limbajul Java se consideră că metodele sunt legate dinamic (engleză: dynamic method binding). existentă în pachetul java. metoda getClass este o metoda finală. Când declarăm propriile noastre clase.java se dă ca exemplu declararea şi utilizarea clasei ExceptieDomeniuFactorial. iar B o subclasă a clasei A şi fie declaraţiile A a1. Astfel de metode se declară cu modificatorul final. fiind declarată sub forma public final Class getClass(). Aceasta înseamnă că stabilirea metodei care va fi invocată se face în momentul execuţiei. Dintre aceştia a fost folosit unul singur. Puteţi modifica programul pentru a-l utiliza şi pe al doilea. să fie finala. dacă se dorea ca clasa CD1. avem şi noi posibilitatea să declarăm că unele din metodele lor sunt finale. dacă argumentul acesteia n este negativ. Fie A o clasă. i se pot atribui ca valori referinţe la instanţe ale 177 . fiind invocată metoda din clasa căreia îi aparţine efectiv obiectul indicat de referinţa respectivă. S-au creat doi constructori: unul fără argument.Programarea orientata pe obiecte în limbajul Java Metode finale Metodele finale sunt metode care nu mai pot fi redefinite în clasele derivate. dacă nu se dorea sa fie publica. B b1. Aceasta inseamnă că în nici o altă clasă nu este posibil ca aceasta metodă să fie redefinită. Declararea propriilor clase de excepţii Deşi Java API oferă o varietate destul de mare de clase de excepţii. în care se apelează constructorul corespunzător al superclasei. dată ca exemplu mai sus. sub forma final class CD1 extends S1 Polimorfismul Polimorfismul se manifestă atunci când unei variabile-referinţă pentru superclasă i se atribuie ca valoare o referinţă către o instanţă a unei subclase a acesteia.lang. în clasa Object. la declararea acesteia se foloseşte modificatorul final.

Severin Bumbaru subclaselor sale. În consecinţă, pot exista instrucţiuni de atribuire de forma
a1=new A(); a2=new B(); b1=new B(); a3=b1; ob1=new B(); ob2=a1; ob3=b1;

Ultimele două atribuiri sunt posibile deoarece, în limbajul Java, toate clasele sunt subclase ale clasei Object. Se pune întrebarea: dacă o metodă din clasa A, fie aceasta metoda1(), a fost redefinită în clasa B, care din ele va fi executata în expresia a2.metoda1()? Observăm că, în această expresie, variabila a2 aparţine clasei A, în timp ce obiectul indicat de această variabilă aparţine efectiv clasei B. Conform principiului polimorfismului, va fi executata metoda1() din clasa B.

Atenţie: polimorfismul se aplică numai metodelor de instanţă. În cazul câmpurilor statice şi metodelor statice, care sunt redeclarate în subclasa, nu are loc o redefinire, ci o ascundere. În consecinţă, legarea acestora este statică (la compilare), iar la execuţie se vor folosi câmpurile şi metodele statice din clasa căreia ii aparţine variabila-referinţa, nu din clasa căreia îi aparţine instanţa indicată de aceasta. În atentia programatorilor de C++ În limbajul C++ polimorfismul se manifestă numai pentru metodele virtuale. Metodele care nu au fost declarate cu modificatorul virtual sunt legate static (la compilare), deci la execuţie se invocă în astfel de cazuri metoda clasei căreia îi aparţine variabila-referinţa (sau pointerul) şi nu cea căreia îi aparţine obiectul indicat. Folosind conceptele din C++, se poate considera că în limbajul Java toate metodele de instanţă sunt implicit virtuale (sunt legate dinamic), în timp ce metodele statice nu sunt virtuale (sunt legate static).

Conversia unei referinţe la clasă într-o referinţă la subclasă
Am arătat mai sus că atribuiri de forma ob1=new B() sau ob2=a1 (unde ob1 şi ob2 sunt variabile-referinţă la Object, iar a1 este variabila-referinţă la A) sunt permise, deoarece unei variabile referinţă dintr-o clasa i se pot da ca valori referinţe la instanţe ale unor subclase. În schimb, dacă încercăm să utilizăm expresia ob1.metoda1() sau ob2.metoda1() obţinem erori de compilare, deoarece metoda1() nu există în clasa Object. Pentru a evita astfel de erori, este necesar să convertim explicit (prin cast) referinţa la Object în referinţă la clasa A sau B, în care există metoda1(). În acest scop, vom folosi expresiile ((B)ob1).metoda1() sau, respectiv, ((A)ob2).metoda1(). Având în vedere că B este subclasă a lui A, iar variabila ob1 indică efectiv un obiect din clasa B, atât în expresia ((B)ob1).metoda1(), cât şi în expresia ((A)ob1).metoda1() se va invoca metoda1() din clasa B, adică din clasa căreia îi aparţine efectiv obiectul indicat de variabila-referinţă ob1.

Exemplu În fişierul Polimorf1.java se da următorul exemplu de aplicaţie în care se testează polimorfismul, folosind clasa S1 şi subclasele ei CD1 şi CD2 definite anterior:
class Polimorf1 { public static void main(String args[]) {

178

Programarea orientata pe obiecte în limbajul Java

Object ob1, ob2, ob3, ob4; S1 s1a, s1b, s1c; CD1 cd1a; CD2 cd2a; String s1="sirul1"; s1a=new S1(1, 2.5, 3); cd1a=new CD1(-1, -2.5, -3); cd2a=new CD2(10, 20.5, 30, 100, 200.5, 300); s1b=cd1a; s1c=cd2a; ob1=s1; ob2=s1a; ob3=cd1a; ob4=cd2a; System.out.println("s1a="+s1a+" s1b="+s1b); System.out.println("s1c="+s1c); System.out.println("s1a.f2()="+s1a.f2()+" s1a.f3()="+s1a.f3()); System.out.println("s1b.f2()="+s1b.f2()+" s1b.f3()="+s1b.f3()); System.out.println("s1c.f2()="+s1c.f2()+" s1c.f3()="+s1c.f3()); System.out.println("ob1="+ob1+" ob2="+ob2+" ob3="+ob3); System.out.println("ob4="+ob4); System.out.println("cd1a.f2()="+cd1a.f2()+" cd1a.f3()="+cd1a.f3()); System.out.println("cd2a.f2()="+cd2a.f2()+" cd2a.f3()="+cd2a.f3()); System.out.println("((S1)ob2).f2()="+((S1)ob2).f2()+ " ((S1)ob2).f3()="+((S1)ob2).f3()); System.out.println("((S1)ob3).f2()="+((S1)ob3).f2()+ " ((S1)ob3).f3()="+((S1)ob3).f3()); System.out.println("((CD1)ob3).f2()="+((CD1)ob3).f2()+ " ((CD1)ob3).f3()="+((CD1)ob3).f3()); System.out.println("((S1)ob4).f2()="+((S1)ob4).f2()+ " ((S1)ob4).f3()="+((S1)ob4).f3()); System.out.println("((CD2)ob4).f2()="+((CD2)ob4).f2()+ " ((CD2)ob4).f3()="+((CD2)ob4).f3()); } }

La executarea acestei aplicaţii se obţin pe ecran următoarele rezultate:

s1a=(S1: 1 2.5 3) s1b=(S1: -1 -2.5 -3) s1c=(CD2: (S1 10 20.5 30) 100.0 200.5 300.0) s1a.f2()=7 s1a.f3()=18.0 s1b.f2()=-2 s1b.f3()=-3.0 s1c.f2()=70 s1c.f3()=711.0 ob1=sirul1 ob2=(S1: 1 2.5 3) ob3=(S1: -1 -2.5 -3) ob4=(CD2: (S1 10 20.5 30) 100.0 200.5 300.0) cd1a.f2()=-2 cd1a.f3()=-3.0 cd2a.f2()=70 cd2a.f3()=711.0 ((S1)ob2).f2()=7 ((S1)ob2).f3()=18.0 ((S1)ob3).f2()=-2 ((S1)ob3)f3()=-3.0 ((CD1)ob3.f2()=-2 ((CD1)ob3).f3()=-3.0 ((S1)ob4).f2()=70 ((S1)ob4).f3()=711.0 ((CD2)ob4).f2()=70 ((CD2)ob4).f3()=711.0

Remarcăm următoarele: - atribuiri de forma s1b=cd1a sau ob1=s1 sunt corecte, întrucât unei variabile-referinţă dintro clasă i se pot da ca valori referinţe la instanţe ale subclaselor acesteia; - expresiile s1a.f2() şi ((S1)ob2).f2() au aceeaşi valoare (7), intrucat in ambele cazuri este invocata metoda f2() din clasa S1;

179

Severin Bumbaru - în expresia ((S1)ob2).f2() s-a folosit castul pentru a converti referinţa la Object intr-o referinţă la S1, întrucat în clasa Object nu există o metoda f2(); - expresiile s1b.f2(), cd1a.f2(), ((S1)ob3).f2() şi ((CD1)ob3).f2()au aceeasi valoare (-2), deoarece în toate cele trei cazuri metoda f2() se aplică asupra aceluiaşi obiect; - în expresia s1b.f2() nu a fost necesar să se folosească o conversie explicită (cast) de forma ((CD1)s1b).f2(), deoarece o metoda cu signatura f2() există şi în clasa S1, căreia îi aparţine variabila s1b. Totuşi, în momentul execuţiei, se aplică efectiv metoda f2() din clasa CD2, căreia îi aparţine obiectul indicat de s1b; - în mod similar, expresiile s1c.f2(), cd2a.f2(), ((S1)ob4).f2() si ((CD2)ob4).f2() au aceeaşi valoare (70); - în instrucţiunea System.out.println("s1a="+s1a+" s1b="+s1b); se foloseşte implicit metoda toString()pentru a se converti obiectele indicate de variabilele-referinţă s1a şi s1b în şiruri. Se foloseşte în ambele cazuri metoda toString() din clasa S1, deoarece în clasa CD1 nu a fost redefinită o astfel de metodă; - în instrucţiunea System.out.println("s1c="+s1c); se foloseşte implicit metoda toString() din clasa CD2, căreia îi aparţine efectiv obiectul indicat de variabila s1c;

Un exemplu: clasa Persoana si subclasa Student
Studentul are toate atributele unei persoane, dar are şi atribute şi metode specifice. În consecinţă, clasa Student poate fi derivată din clasa Persoana. În continuare dăm exemple de declarare şi de testare a celor două clase.

Declararea clasei Persoana
În fişierul Persoana.java, reprodus aici, este declarată clasa Persoana.
public class Persoana { private String nume, prenume; private int anNastere; public Persoana(String nume, String prenume, int anNastere) { this.nume=nume; this.prenume=prenume; this.anNastere=anNastere; } public Persoana(Persoana pers) { nume=pers.nume; prenume=pers.prenume; anNastere=pers.anNastere; } public String nume() { return nume; } public String prenume() { return prenume; }

180

Programarea orientata pe obiecte în limbajul Java
public int anNastere() { return anNastere; } public int varsta(int anCurent) { return anCurent-anNastere; } public String toString() { return nume+" "+prenume+" "+anNastere; } public int hashCode() { return nume.hashCode()+prenume.hashCode()/1000+anNastere%100; } }

Clasa contine trei câmpuri private: două referinţe la String (nume şi prenume) şi un câmp de tip int (anNaştere). Întrucât câmpurile sunt private, ele nu sunt vizibile din alte clase (nici chiar din subclasele clasei Persoana). Clasa Persoana are doi constructori. Primul constructor primeşte ca argumente valorile celor trei câmpuri: nume, prenume, anNaştere. Întrucât argumentele au aceleaşi nume cu câmpurile corespunzătoare, în corpul constructorului numele de câmpuri sunt calificate cu referinţa this. Aceasta se putea evita schimband numele argumentelor. Al doilea constructor are ca argument o instanţă a clasei Persoana, fiind ceeace se numeşte un "constructor de copiere". Vom vedea utilitatea lui in continuare, la declararea clasei Student. Metodele nume(), prenume() şi anNastere() au rolul de a întoarce fiecare valoarea câmpului corespunzator. Fiind publice, ele pot fi utilizate în alte clase. Aşa dar, este posibil să obţinem în altă clasă valorile câmpurilor unui obiect Persoana, dar nu putem modifica aceste valori. Remarcăm că este posibil ca numele unei metode să coincidă cu cel al unui câmp. Nu are loc nici o confuzie, întrucât numele metodei este insoţit întotdeauna de paranteze, ca în expresia p1.nume(), care are ca valoare numele persoanei p1. Metoda varsta(int anCurent) întoarce vârsta persoanei, fiind dat ca argument anul pentru care se calculează. Este un exemplu de metodă care întoarce un atribut al persoanei (vârsta), care nu este memorat într-un câmp, ci se obţine prin calcul. Metodele toString() şi hashCode() redefinesc metodele corespunzătoare ale superclasei Object.

Declararea clasei Student
Clasa publică Student este declarată în fişierul Student.java şi este reprodusă aici.
public class Student extends Persoana { private String fac, gr; private int anStudii; public Student(String nume, String prenume, int anNastere, String facultate, int an, String grupa) { super(nume, prenume, anNastere); fac=facultate; anStudii=an; gr=grupa;

181

Severin Bumbaru
} public Student(Persoana pers, String facultate, int an, String grupa) { super(pers); fac=facultate; anStudii=an; gr=grupa; } public Student(Student stud) { super(stud.nume(), stud.prenume(), stud.anNastere()); fac=stud.fac; anStudii=stud.anStudii; gr=stud.gr; } public String facultate() { return fac; } public int an() { return anStudii; } public String grupa() { return gr; } public String toString() { return super.toString()+" fac: "+fac+" an: "+anStudii+ " grupa: "+gr; } }

Clasa Student moşteneşte câmpurile şi metodele superclasei Persoana. În plus, conţine următoarele câmpuri private: două referinţe la String (fac - facultatea şi gr - grupa) şi un int (anStudii). Au fost declaraţi trei constructori. Primul are ca argumente valorile tuturor câmpurilor, atât ale celor moştenite de la superclasă, cât şi ale celor proprii. Întrucât câmpurile superclasei sunt private, nu a fost posibilă iniţializarea lor directă, prin operaţii de atribuire, ci prin apelarea constructorului superclasei sub forma
super(nume, prenume, anNastere);

Al doilea constructor are ca prim argument o referinţă la persoană, iar ultimele trei argumente sunt aceleaşi ca la constructorul precedent. Pentru iniţializarea câmpurilor superclasei a fost invocat constructorul acesteia sub forma
super(pers); în care pers este referinţa la o Persoana. S-a utilizat aici constructorul de copiere Persoana(Persoana pers). Remarcăm că nu am fi putut utiliza instrucţiunea super(pers.nume, pers.prenume, pers.anNastere);

deoarece câmpurile clasei Persoana sunt private şi nu sunt, deci, accesibile din clasa Student. În lipsa constructorului de copiere, am fi putut utiliza in schimb instructiunea
super(pers.nume(), pers.prenume(), pers.anNastere()); deoarece metodele nume(), prenume() şi anNastere() sunt publice.

Metodele publice facultate(), an() şi grupa() întorc valorile câmpurilor specifice clasei Student, respectiv fac, anStudii şi gr. Metoda toString() redefineşte metoda cu aceeaşi signatură a superclasei. 182

Programarea orientata pe obiecte în limbajul Java

Utilizarea claselor Persoana şi Student
Aplicaţia din fişierul TestStud.java are ca obiectiv testarea claselor Persoana şi Student.
class TestStud { public static void main(String args[]) { Persoana p1=new Persoana("Vasiliu","George",1981), p2; Student s1=new Student(p1, "NIE",2,"2221a"), s2=new Student("Ionescu","Maria", 1980, "NIE", 2, "2322b"), s3; Object ob1, ob2, ob3; Persoana tabPers[]=new Persoana[3]; ob1=s1; ob2=p2=s2; ob3=p1; System.out.println("p1="+p1); System.out.println("s1="+s1); System.out.println("s2="+s2); System.out.println("ob1="+ob1); System.out.println("p2="+p2); System.out.println("ob2="+ob2); System.out.println("ob3="+ob3); System.out.println("Numele lui p1: "+p1.nume()); System.out.println("Numele lui s1: "+s1.nume()); System.out.println("Numele lui ob1: "+((Persoana)ob1).nume()); s3=(Student)ob2; System.out.println("s3="+s3); System.out.println("In anul 2000, s3 are "+s3.varsta(2000)+" ani"); System.out.println("p2.hashCode()="+p2.hashCode()); System.out.println("s1.hashCode()="+s1.hashCode()); tabPers[0]=p1; tabPers[1]=s1; tabPers[2]=s2; System.out.println("Tabloul de persoane tabPers contine:"); System.out.println("Clasa lui p1: "+p1.getClass().getName()); System.out.println("Clasa lui ob2: "+ob2.getClass().getName()); for(int i=0; i<tabPers.length; i++) System.out.println(tabPers[i]); } }

Se testează funcţionarea metodelor polimorfe toString() din clasele Persoană şi Student, funcţionarea castului de la Object la Student si funcţionarea metodei hashCode(), redefinită în clasa Persoana şi mostenită de clasa Student. Se testează, de asemenea, metoda getClass(), moştenita de la clasa Object. Se construieşte şi se utilizează un tablou de referinţe la Persoana.

O variantă în care se utilizează câmpuri protejate
În fişierele Persoana1.java, Student1.java si Test1.java sunt date variante ale fişierelor comentate mai sus, în care sunt făcute următoarele modificări: - în clasa Persoana1 câmpurile nu mai sunt private, ci protejate; - în clasa Persoana1 s-a introdus în plus un constructor fără argumente. Acest constructor este necesar pentru a fi invocat implicit de constructorul clasei Student1, aşa cum vom arăta mai jos; - în primul constructor al clasei Student1 nu a mai fost invocat explicit constructorul clasei 183

Severin Bumbaru Persoana. Aceasta înseamnă că, la construirea instanţei Student1, a fost invocat implicit constructorul fără argumente Persoana1() al superclasei. Atribuirea de valori câmpurilor protejate ale superclasei se face, apoi, direct în corpul constructorului clasei Persoana1. S-au folosit, în acest scop, instrucţiuni de forma this.nume=nume, întrucât numele câmpului coincide cu cel al argumentului. Referinţa this este utilizată corect, intrucât câmpul superclasei Persoana1 a fost moştenit de clasa Student1, ne fiind acoperit în aceasta. Se putea folosi, însă, şi referinţa super sub forma super.nume=nume, deoarece câmpul nume aparţine, de fapt, superclasei; - în al doilea constructor al clasei Student1 nu a fost invocat explicit, de asemenea, constructorul superclasei. Atribuirea de valori câmpurilor protejate ale superclasei Persoana1 s-a făcut direct în corpul clasei Student1, prin instrucţiuni de forma nume=pers.nume, unde Pers este argumentul din clasa Persoana1; - s-au înlocuit peste tot, în cele trei fişiere, numele de clase Persoana şi Student prin Persoana1 şi Student1. Complilând fişierul TestStud1.java şi executând aplicaţia TestStud1 constatăm că se obţin aceleaşi rezultate ca în cazul aplicaţiei TestStud. Întrucât clasele Persoana1 şi Student1 sunt publice, compilarea explicită a fişierelor respective nu este necesară, deoarece ea se face automat când se compilează fişierul TestStud1.java.

Instanţierea clasei care conţine metoda main
Clasa care conţine metoda main este clasa principală a unei aplicaţii, deci este prima clasă care se încarcă în maşina virtuală Java la punerea în execuţie a aplicaţiei respective. În acelaşi timp, ea este o clasă ca oricare alta, care poate avea şi instanţe. Metoda main(), fiind statică, nu poate utiliza direct decât câmpurile statice şi metodele statice ale acestei clase. Totuşi, în metoda main() sau în alte metode, pot fi create instanţe ale acestei clase, putându-se astfel utiliza şi câmpurile şi metodele de instanţă ale acestora. Exemplu În fişierul Aplic.java este dat un exemplu de aplicaţie, în care clasa Aplic, care conţine metoda main(), are câmpuri şi metode statice şi de instanţă şi constructor.
/* O clasa care contine metoda main() si poate fi instantiata */ class Aplic { static int a=10; // un camp static (al clasei) double b; // camp al instantei String s; // camp al instantei Aplic(double b, String s) { // constructorul clasei Aplic this.b=b; this.s=s; } double f1(double x) { // o metoda (functie) de instanta return a*b+1; // se utilizeaza campul static si cel de instanta } static int f2(int m) { // o metoda (functie) statica return m+a; // se utilizeaza numai campul static

184

Programarea orientata pe obiecte în limbajul Java

} public static void main(String args[]) { String s0="sir implicit 0", s1="sir implicit 1"; Aplic a0, a1; // Doua referinte la instante ale clasei Aplic if(args.length>=1) s0=args[0]; if(args.length>=2) s1=args[1]; /* Se creaza doua instante ale clasei Aplic */ a0=new Aplic(12.47, s0); a1=new Aplic(-15.28, s1); /* Campul static a si metoda statica f2 pot fi utilizate direct, sau calificandu-le cu numele clasei sau cu referinta la o instanta */ System.out.println("a="+a+" Aplic.a="+Aplic.a+" a0.a="+a0.a+ " a1.a="+a1.a); System.out.println("f2(2)="+f2(2)+" Aplic.f2(2)="+Aplic.f2(2)+ " a0.f2(2)="+a0.f2(2)+" a1.f2(2)="+a1.f2(2)); /* Campurile si metodele de instanta se folosesc prin intermediul referintelor la instantele respective */ System.out.println("a0.b="+a0.b+" a0.s="+a0.s); System.out.println("a1.b="+a1.b+" a1.s="+a1.s); System.out.println("a0.f1(1.5)="+a0.f1(1.5)+ " a1.f1(1.5)="+a1.f1(1.5)); /* Modificam campul static a si il afisam in diferite moduri */ a=20; System.out.println("Dupa modificari:"); System.out.println("a="+a+" Aplic.a="+Aplic.a+" a0.a="+a0.a+ " a1.a="+a1.a); /* Modificam campul b din fiecare instanta si afisam */ a0.b=32.5; a1.b=-121.8; System.out.println("a0.b="+a0.b+" a1.b="+a1.b); } }

Remarcăm urmatoarele: - clasa Aplic are câmpuri statice şi de instanţă şi alte metode statice şi de instanţă, pe lângă metoda main(); - clasa Aplic are şi un constructor (putea avea chiar mai mulţi, sau numai pe cel implicit); - în metoda main() se creează două instanţe ale clasei Aplic, cu referinţele a0 şi a1; - în metodele statice main()şi f2(), câmpul static a şi metoda statica f2() pot fi utilizate direct, sau calificându-le cu numele clasei sau cu o referinţă la o instanţă a acesteia. În toate cazurile se obtine acelaşi rezultat; - câmpurile şi metodele de instanţă nu pot fi utilizate direct în metoda statică main(), dar pot fi utilizate cele ale instanţelor, calificandu-le cu referinţele la aceste instanţe, de exemplu a0.b sau a0.f1(1.5); - în metodele de instanţă pot fi utilizate direct atât câmpurile clasei, cât şi ale instanţei. Astfel, în metoda de instanţă f1() se foloseşte expresia a*b+1, în care apar câmpul static a şi câmpul de instanţă b.

185

Severin Bumbaru

Clase abstracte
Clasele abstracte conţin în declaraţia lor modificatorul abstract. Clasele abstracte nu pot fi instanţiate. Remarcăm însa că pot exista clase care nu pot fi instanţiate deşi nu sunt abstracte, cum sunt, de exemplu, clasele care nu au decât constructori privaţi. Cu toate că clasa abstractă nu poate fi instanţiată, se pot declara variabile aparţinând unor clase abstracte. Acestor variabile li se pot da însa ca valori numai referinţe către instanţe ale unor subclase concrete. De exemplu, daca A este o clasă abstracta, iar B este o subclasă concreta a clasei A, atunci este corectă declaraţia
A a1=new B();

Din punct de vedere conceptual, clasa abstractă modelează un concept general, care trebuie apoi dezvoltat prin subclase. Subclasele unei clase abstracte pot fi, la rândul lor, abstracte sau concrete. De exemplu, clasa abstractă FiguraPlana poate avea ca subclase clasele Cerc, Elipsa, Poligon etc. Din punct de vedere al progrămarii, clasa abstractă conţine cel puţin o metodă abstractă, adică o metodă pentru care s-a declarat numai antetul, fără să i se definească şi corpul. O clasă poate să conţină o metodă abstractă în mai multe moduri: a/ în corpul clasei este declarată explicit o metodă abstractă; b/ clasa mosteneşte de la superclasa ei o metodă abstractă, care nu este definita nici în corpul clasei curente; c/ clasa implementeaza o interfaţă, dar nu defineşte una sau mai multe din metodele acesteia. Dacă apare o astfel de situaţie, iar clasa nu este declarată în mod explicit abstractă, se genereaza o eroare la compilare. Declararea unei metode abstracte: - antetul metodei trebuie sa conţina modificatorul abstract; - corpul metodei se înlocuieşte prin caracterul ';' (punct şi virgulă).

Exemplu: În fişierul FiguriPlane.java sunt declarate clasa abstractă FiguraPlana şi clasele instanţiabile Cerc şi Patrat. Este declarată, de asemenea clasa-aplicaţie în care se testează aceste clase.

186

Programarea orientata pe obiecte în limbajul Java

Interfeţe
Conceptul de interfaţă
Conform principiului încapsulării, fiecare clasă are "interfaţa" sa intrinsecă, prin care poate fi accesata din exterior. Aceasta "interfaţă" conţine toate datele şi metodele publice ale clasei respective. Pentru a compensa lipsa moştenirii multiple, în limbajul Java s-a admis că o clasă poate avea mai multe interfeţe şi că mai multe clase pot implementa aceeaşi interfaţă. S-a introdus astfel o nouă categorie de componente, numite interfeţe, care se declară în mod asemănător cu nişte clase abstracte, dar nu sunt înglobate, aşa cum sunt clasele abstracte, în ierarhia unică de clase .

Interfaţa este o specificaţie care descrie metodele publice şi variabilele finale publice pe care trebuie sa le aibă o clasă care implementeaza interfaţa respectivă. Dacă o clasă implementează mai multe interfeţe, ea conţine toate metodele publice şi variabilele finale publice ale acestora. Interfaţa nu este o clasă, dar poate fi utilizată de programator ca şi când ar fi o clasă abstractă. Se pot declara variabile referinţă la o interfaţă în mod asemănător cu declararea variabilelor referinţa la obiecte aparţinând unei clase, adică sub forma:
interfaţa nume_variabila1[=initializare1], ..., nume_variabilaN[=initializareN];

în care interfaţa este numele unei interfeţe, iar celelalte elemente ale declaraţiei sunt aceleaşi ca în cazul declarării de referinţe la obiecte. Interfeţele pot fi şi ele organizate ierarhic, aplicându-se principiul moştenirii. În schimb, pentru interfeţe, ierarhia nu mai este unică, aşa cum este în cazul claselor, şi se admite moştenirea multiplă. Remarcam că, la fel ca şi clasele abstracte, interfeţele nu pot fi instanţiate. În schimb, unei variabile referinţă la o interfaţă i se pot da ca valori referinţe către obiecte din orice clasă care implementează acea interfaţă sau este descendentă a unei astfel de clase. Pentru a le distinge mai uşor, în documentaţia Java API numele interfeţelor sunt scrise cu litere cursive (stil italic), în timp ce numele claselor sunt scrise cu litere normale (drepte). De exemplu, în pachetul java.lang există interfaţa Cloneable care este implementată de toate clasele din SDK care implementează metoda clone(), deci ale căror obiecte pot fi clonate. Sa considerăm acum exemplul din Figura 1, în care clasele B şi C implementeaza interfeţele I1 şi I2, iar clasele C si D implementează interfeţele I2 şi I3.

187

C() si D() sunt constructori ai claselor respective: A v1=new A(). ştiind că variabila w1 are ca valoare o referinţă la un obiect din clasa B. v2=v5. v4=v3. B v3=new B(). în care A(). În această situaţie este necesară o conversie explicită (cast). w2=w4. w5=v6. Totodată. B(). w4=v3. de asemenea. deoarece v4 este referinţă la un obiect al unei clase. insă. cât şi pe traseul I0-I2-C nu mai produce dificultăţi. B şi C moştenesc datele şi metodele clasei A. deci conţine variabilele finale şi metodele interfeţei I1 şi pe cele mostenite de aceasta de la interfaţa I0. clasele A.Figura 1 În acest exemplu. date finale.w2. I2 w5.) sunt utilizate la fel ca şi variabilele referinta la obiecte ale claselor. I0 w1=new B(). interfetele I1 şi I2 sunt derivate din interfata I0 deci moştenesc variabilele finale şi metodele acesteia. v6. vom constata că apare o eroare de compilare. inclusiv pe cele moştenite de acestea de la interfaţa I0. Clasa B implementează interfaţa I1. Dacă. 188 . C v5=new C(). Constatăm că variabilele referinţă la interfeţe (w1. în timp ce w1 este o referinţă la interfaţă. deoarece implementarea efectivă a acestor variabile şi metode se face în clasa C şi nu in interfeţe. w6. Faptul că variabilele finale şi metodele interfeţei I0 se propagă la clasa C atât pe traseul I0-I1-C. Pentru exemplul din Figura 1. să considerăm acum următoarele declaraţii şi instrucţiuni de atribuire valabile. I1 w3=new C().Severin Bumbaru . v6=new C(). ca în cazul moştenirii multiple a claselor. astfel că vom folosi instrucţiunea v4=(B)w1. w2=new D(). w2. v2. v4. vom dori sa folosim instrucţiunea v4=w1. w3 etc. w4. Clasa C implementează interfeţele I1 şi I2. putând avea fiecare. câmpuri şi metode proprii. deci conţine variabilele finale şi metodele interfeţelor I1 şi I2.

Interfaţa este abstractă şi deci nu poate fi instanţiată. Cel mai important avantaj al folosirii interfeţelor este că mai multe clase. Exemplu: interface CuloareDeBaza { int ROSU=1. O clasă poate implementa mai multe interfeţe. Se obisnuieşte ca numele de câmp ale interfeţelor să fie scrise numai cu majuscule. unei variabile referinţă la interfaţă i se pot atribui ca valori referinţe la obiecte din orice clasă care implementează interfaţa respectivă.. Aceasta înseamnă că toate câmpurile unei interfeţe sunt publice. interfeţele se pot constitui in diverse ierarhii de interfeţe. deci ele trebuie să fie iniţializate la declarare şi nu mai pot fi modificate ulterior. numită şi declaraţie de constante. Modificatorii public. În consecinţă. Deşi nu se încadrează în ierarhia claselor. Se pot declara variabile referinţă la interfaţă la fel cum se pot declara variabile referinţă la clasă.NUME_CAMP2=valoare2. la care moştenirea multiplă este interzisă (o clasă poate avea numai o singura superclasă). ALBASTRU=4. VERDE=2. Declaraţia de interfaţă are forma generală următoare: [public] interface NumeInterfata [extends lista_superinterfete] { declaratii_de_membri_ai_interfetei } În afară de modificatorul public. ai cărui membri sunt câmpuri statice finale şi metode abstracte. în care tip este un tip primitiv. statice şi finale. în afară de una sau mai multe metode abstracte. } 189 .. care nu conţine decât metode abstracte şi câmpuri statice finale şi nu se încadrează în ierarhia unică de clase descendente din Object (amintim ca o clasa abstractă. deci folosirea lui este de prisos. poate conţine şi câmpuri de date şi metode concrete şi este descendentă a clasei Object). clauza extends poate conţine o listă de nume de interfeţe separate prin virgule. de pe diferite ramuri ale arborelui ierarhic al claselor. numai că acesta este implicit. .Programarea orientata pe obiecte în limbajul Java Declararea interfeţelor O declaraţie de interfaţă introduce un nou tip referinţă. static şi final pentru câmpurile interfeţei sunt impliciţi. Spre deosebire de clase. În schimb. În consecinţă.. interfaţa se aseamănă cu o clasa abstractă pură. în cazul interfeţelor moştenirea multiplă este permisă. deci folosirea lor este de prisos. se poate folosi şi modificatorul abstract. sub forma: tip NUME_CAMP1=valoare1. Corpul interfeţei conţine una sau mai multe declaraţii de membru al interfeţei. pot fi "văzute" printr-o singură interfaţă. Declaraţiile de membri ai interfeţei pot fi: a/ Declaraţia de câmpuri statice finale. aplicându-li-se principiul mostenirii. NUME_CAMP_N=valoareN.

care constă din antetul metodei urmat de simbolul '. cu următoarele observaţii: . Dacă clasa imbricată este statică. ORANGE=5. int metoda2(int a. putând avea şi modificatori de câmp (de exemplu static). Aşadar. . Ca şi ceilalţi membri. prin imbricare se creează o legatură strânsa între două clase. Orice clasă.modificatorul final nu poate fi folosit. deci folosirea lor este de prisos (dar este permisă). Remarcăm că declaraţia clasei imbricate este tratata ca oricare alta declaraţie de membru al clasei. O clasă care încorporează (imbrică) alte clase se declară astfel: [public] class NumeClasa { declaratii_de_membri_ai_clasei [modificatori_de_camp] class NumeClasaImbricata { declaratii_de_membri_ai_clasei_imbricate } declaratii_de_membri_ai_clasei } Se recurge la aceasta tehnică atunci când utilizarea unei clase are sens numai în cadrul altei clase.corpul metodei este înlocuit prin simbolul punct şi virgulă. clasele imbricate pot fi statice sau nestatice şi se declară în corpul clasei care le încorporează. double c). int b. desigur. chiar şi la cei privaţi. Clase imbricate şi clase interioare În limbajul Java se permite ca o clasă să aibă ca membri alte clase. folosirea identificatorului public este obligatorie. Clasele imbricate nestatice se numesc clase interioare (engleză: inner classes). Exemplu: interface Interf1 { double metoda1(). } b/ Declaraţia de metodă abstractă. INDIGO=6. VIOLET=7. Acestea se numesc clase imbricate sau clase încuibate (engleza: nested classes). } Ambele metode din exemplul de mai sus sunt implicit publice şi abstracte. Fiind membru al clasei. ca o clasa să conţină mai multe clase imbricate. Este posibil.' (punct şi virgulă). deoarece se declară o metodă abstractă. ca la orice metodă abstractă. care implementează aceasta interfaţă. Ea este deci la fel ca o declaraţie de metodă abstractă din corpul unei clase. clasa imbricată are acces la toţi membrii clasei care o conţine.modificatorii public şi abstract sunt impliciti. .Severin Bumbaru interface Culoare extends CuloareDeBaza { int GALBEN=3. La definirea acestor metode îm cadrul claselor. trebuie sa conţină declaraţii de metode cu aceeaşi semnătură cu cele din interfaţă. ea nu poate referi direct decât membrii statici 190 .

191 .f2(arg1. În fişierul Integrare. În acest scop. ca argument al metodei integrare(). aşa cum se face în fisierul Integrare1. accesul la membrii ei se poate face numai printr-o instanţă a clasei Integrare1.Programarea orientata pe obiecte în limbajul Java ai clasei care o conţine.class. Integrare1$Functie1. astfel că nu poate accesa direct un membru nestatic al clasei. Pentru comparaţie. se foloseşte pentru calificare numele clasei. După compilarea fişierului Integrare1. ci numai prin crearea unei instanţe a acesteia. toate clasele sunt declarate în mod obişnuit. Este deci preferabil să fie declarata ca o clasă interioară a acestei aplicaţii.arg2) . cât şi la cei de instanţă (nestatici). Procedeul de mai sus a fost necesar. clasa Funcţie1 este specifica numai unei singure aplicaţii.java. Clasa Functie1. numai în cadrul clasei care o conţine. Atragem atenţia asupra modului cum s-a făcut instanţierea clasei interioare Functie1: operatorul new a fost calificat cu referinta int1 la o instanţă a clasei Integrare1.class.class. a fost declarată ca o clasa interioară (clasă imbricată nestatică) a clasei-aplicaţie Integrare1. De asemenea. care o conţine. IntegrareTrapeze. În schimb.new Functie1(arg1. a fost dat un exemplu de aplicaţie (din fişierul Integrare.java). În consecinţă. s-a procedat astfel: a/ s-a creat în metoda main() o instanţă a clasei Integrare1 prin instrucţiunea Integrare1 int1=new Integrare1(). În consecinţă.class.class. Integrator. Integrare1. Clasa interioară are acces la toţi membrii clasei care o conţine.arg2. accesul la membrii ei se poate face folosind drept calificator referinţa la o instanţă. În consecinţă. FunctieReala.class. întrucat metoda main() este statică. deci are sens să fie declarată ca o clasa separată. la fel ca şi câmpurile sau metodele statice. Clasa IntegrareTrapeze poate fi folosită în diferite aplicaţii. Exemplu: În secţiunea Interfeţe a acestui curs. din acest exemplu.class. ca nişte clase autonome. Integrare. după compilare se obţin urmatoarele fişiere cu extensia class: Functie1.arg3. Clasa imbricată statică există. b/ s-a creat o instanţă a clasei Functie1 prin instrucţiunea Functie1 f1=int1. constatăm că au fost creeate următoarele fişiere cu extensia class: FunctieReala. Remarcăm că instanţierea acesteia s-a făcut în mod "obişnuit" prin instrucţiunea Functie2= func2=new Functie2(arg1.class. nu şi în instanţele acesteia.arg2. sub forma func2. Clasa interioară (clasa imbricată nestatică) are câte o instanţă în interiorul fiecărei instanţe a clasei care o conţine. atât la cei statici.arg3). utilizarea funcţiei nestatice f() a acestei clase s-a făcut "obişnuit". în acelaşi fişier s-a declarat (tot în clasa-aplicaţie Integrare1) şi o clasa imbricată statică numită Functie2.java. în care se face integrarea funcţiilor prin metoda trapezelor. pentru a referi membrii acestei clase. În consecinţă. c/ Referinţa f1 la o instanţă a clasei interioare f1 a fost apoi utilizată în mod obişnuit.arg4). iar instanţa func2 a fost transmisă şi ca argument al metodei de integrare.f(arg). iar utilizarea funcţiei statice f2() conţinute în aceasta s-a facut sub forma "obişnuită" Functie2.java.

urmat de caracterul $ şi de numele clasei imbricate (interioare) respective. fără să se creeze confuzii. devine posibil ca în două aplicaţii distincte să existe clase imbricate sau interioare cu acelaşi nume. În acest fel.Severin Bumbaru Integrare1$Functie2.class. IntegrareTrapeze.class. Integrator. 192 .class. Remarcam ca numele fişieror de bytecode care conţin clase imbricate sau interioare încep prin numele clasei care le conţine.

spre deosebire de limbajele de programare tradiţionale. care calculează prin diferite metode valoarea integralei pe intervalul [inf. vom implementa integrarea prin metoda trapezelor. În schimb. FunctieReala func) în care inf şi sup sunt. 193 . Să realizăm acum un integrator concret. în limbajul Java nu există posibilitatea ca o funcţie (metodă) să aibă ca argument o referinţa la altă funcţie (metodă). în oricare din aceste integratoare. în cazul nostru. cum sunt Pascal sau C/C++. Pentru simplitate. Dorim ca. Având în vedere că dorim ca integratoarele noastre să fie valabile pentru orice funcţie reală f(x). vom declara o interfaţă: interface FunctieReala { double f(double x). Ştiind că integrala poate fi interpretată geometric ca aria suprafeţei cuprinse între graficul funcţiei respective şi axa ox. Având în vedere că nu avem. Cu aceasta ocazie remarcam că. FunctieReala func). implementare şi utilizare a unor interfeţe Considerăm că dorim să realizăm diferite clase de integratoare numerice. în vedere o metoda de integrare numerică particulară. deocamdată. double sup. } care conţine metoda abstractă f(x) pe care trebuie să o conţină orice obiect pe care îl oferim ca argument metodei de integrare din interfaţa Integrator. vom declara interfaţa interface Integrator { double integrala(double inf. func este referinţă la un obiect care conţine funcţia de integrat f(x). putem să-i oferim ca argument o referinţa la un obiect care conţine funcţia respectivă. putem împărţi intervalul de integrare [inf. } în care metoda de integrare apare ca o metoda abstractă. sup] a funcţiei reale f(x). iar func este o referinţă la un obiect care contine funcţia de integrat f(x). ca în Figura 1. Astfel. marginea inferioara şi cea superioara a intervalului de integrare. pentru o anumita metodă particulară de integrare. double sup.Programarea orientata pe obiecte în limbajul Java Exemplu de declarare. respectiv. să existe metoda de calculare a integralei: double integrala(double inf. sup] în n subintervale de lungime egala h=(sup-inf)/n.

double sup. } /* Implementarea metodei abstracte din interfata Integrator */ public double integrala(double inf. 194 . pe care îl vom nota în continuare cu nrPasi. aproximăm aria de sub curbă prin suma ariilor celor n trapeze. this.Figura 2 Pentru calcularea integralei este necesar să se impună şi numărul de paşi n. . s. Se obţine astfel pentru calcularea integralei I cunoscuta formulă a integrării numerice prin metoda trapezelor dată în Figura 2. i++) s+=func. care implementeaza interfaţa Integrator. în modul următor: class IntegrareTrapeze implements Integrator { int nrPasi. FunctieReala func) { double h. h=(sup-inf)/nrPasi. obtinem n trapeze. // Numarul de pasi de integrare /* Constructorul initializeaza numarul de pasi de integrare */ public IntegrareTrapeze(int nrPasi) throws Exception { if(nrPasi<=0) throw new Exception("IntegrareTrapeze: nrPasi<=0"). Putem astfel declara clasa IntegrareTrapeze. i<nrPasi.Figura 1 Înlocuind pe fiecare din aceste subintervale curba f(x) prin coarda ei. this. // h este pasul de integrare /* Calcularea sumei ordonatelor s */ s=0. } /* Metoda de modificare a numarului de pasi de integrare */ public void puneNrPasi(int nrPasi) throws Exception { if(nrPasi<=0) throw new Exception("IntegrareTrapeze: nrPasi<=0"). for(int i=1. Considerand că ariile cuprinse între curbă şi coarda curbei în fiecare din subintervale sunt mici.Severin Bumbaru .f(inf+i*h).nrPasi=nrPasi.nrPasi=nrPasi.

Integratorul nostru are deci o utilizare foarte largă.d=d. Pentru aceasta vom creea o clasă care implementează interfaţa FunctieReala şi. double b.c=c. Să considerăm acum că dorim să integrăm funcţia f(x)=a*sin(b*x+c)+d*cos(b*x) în careparametrii a.b=b.a=a. c şi d sunt numere reale. } } La calcularea integralei s-a aplicat formula din Figura 2.javasunt date atât declaraţiile de interfeţe şi clase prezentate mai sus. 4. } } Putem acum să scriem o aplicaţie în care se calculează integrala acestei funcţii. } /* implementarea metodei abstracte din interfata */ public double f(double x) { return a*Math. 8. În fişierul Integrare. putând integra funcţia f(x) din orice obiect care implementează această interfaţă. cât şi cea a clasei-aplicaţie în care se folosesc acestea. de asemenea. 5. 2. // parametrii functiei /* Constructorul clasei introduce valorile parametrilor functiei */ public Functie1(double a. 7. dacă creem pentru fiecare din aceste metode o clasa care implementează interfaţa Integrator. Remarcăm. c. conţine drept câmpuri parametrii funcţiei: class Functie1 implements FunctieReala { private double a. d. Întrebări Nivel 1 1. b. this. care implementează interfaţa FunctieReala. this. this. că putem aplica şi alte metode de integrare numerică. double d) { this.f(sup))/2+s)*h.f(inf)+func. 3. luând în consideraţie că xi=inf+i*h. Ce este încapsularea? Care sunt modificatorii de acces pentru câmpuri şi metode? Ce sunt constructorii? Ce particularităţi prezintă declaraţiile de constructori? Poate avea o clasă mai multi constructori? cum se disting aceştia? Ce este constructorul implicit? Ce este agregarea? Ce este moştenirea? 195 .f(inf+i*h) că se foloseşte funcţia (metoda) f(x) a obiectului func. double c. Remarcăm că funcţia f(x) nu a fost încă precizată. totodată.Programarea orientata pe obiecte în limbajul Java /* Calcularea valorii integralei si intoarcerea rezultatului */ return ((func.cos(b*x). S-a indicat numai sub forma func. b. 6.sin(b*x+c)+d*Math.

4. 196 . Ce este polimorfismul? 22. 3. În ce situaţii se manifestă polimorfismul? 23. În ce situaţie o metoda poate fi ascunsă? 19. Ce se înţelege prin redefinirea metodelor? 15. Ce particularităţi prezintă constructorul unei clase derivate? 14. Ce este o clasă finală? 21. Cum poate fi invocată o metodă de instanţă? 17. Ce se înţelege prin ascunderea câmpurilor? 18. Ce se întâmplă dacă un argument sau o altă variabilă locală a unei metode are acelaşi nume cu un câmp al clasei respective? 11. Ce este o metoda statică? 14. Cum putem utiliza într-o metodă a unei clase un câmp ascuns al propriei clase? 12. Este posibilă declararea unei clase de excepţii proprie? 20. Poate fi instanţiata clasa care conţine metoda main()? 25. 2. în limbajul Java. Ce este o metodă abstractă? 27. Ce sunt this si super? 13. 9. Ce se întâmplă dacă într-o clasă se declară o metodă statică cu aceeaşi signatura ca a unei metode statice din superclasă? 15. Cum se declară o clasă abstractă? 28. Ce este o metodă finală? 17. 7. Sa considerăm că în subclasa B a clasei A a fost redefinită metoda met(). Ce sunt membrii protejaţi ai clasei? 12. nu sunt supuse polimorfismului? 1. 18. Ce efect are faptul că o clasă implementează o interfaţă? 30. Ce este o clasa interioară? Nivel 2 Enumeraţi caracteristicile obiectelor şi claselor Ce se înţelege prin identitatea obiectelor? Ce se înţelege prin clasificare. 8. ca proprietate a obiectelor? Ce este moştenirea? Ce fel de moştenire este permisă în limbajul Java în cazul claselor? Ce se înţelege prin ascunderea câmpurilor? Cum poate fi accesat dintr-o clasă un câmp ascuns al superclasei? Este posibil să utilizăm într-o clasă un membru privat al superclasei? Este posibil să declarăm într-o clasă o metodă cu aceeaşi signatură ca o metodă privată din superclasă? 10. Ce metode. Cum se face conversia unei referinţe dintr-o clasa în referinţă dintr-o subclasă? 24. 5. Cum poate fi invocată o metodă statică? 16. Ce este o interfaţă? 29. Câte superclase poate avea o clasă în limbajul Java? 11. cum putem utiliza în B metoda met() din A? 13.Severin Bumbaru 9. Daţi un exemplu de declarare a unei clase de excepţii. Ce relaţie există între o clasă şi superclasa ei? 10. Ce este o clasă abstractă? 26. Ce fel de metode pot fi redefinite? 16. 6. Ce este o clasa imbricată? 31.

Ce deosebire există între clasa imbricată şi clasa interioară? 197 . Poate exista moştenire multiplă în cazul interfeţelor? 24. Ce avantaj prezintă folosirea unei interfeţe ca argument al unei metode? 29. 27. cât şi un câmp nestatic a şi o metodă nestatica met().Programarea orientata pe obiecte în limbajul Java 19. În ce scop au fost definite în clasa Object metodele equals() şi toString()? 21. Care sunt proprietăţile implicite ale câmpurilor unei interfeţe? 25. Cum putem utiliza în main câmpul a şi metoda met()? 22. Daţi un exemplu de situaţie în care trebuie folosit castul pentru a converti o referinţă. Să considerăm că clasa A conţine atât metoda main(). Ce asemănări şi deosebiri există între interfeţe şi clasele abstracte? 23. Care sunt proprietăţile implicite ale metodelor unei interfeţe? 26. Ce avantaj prezintă declatrarea interfeţei Integrator ca o interfaţă şi nu ca o clasă? 28. 20. Poate fi declarată ca finală o metodă a unei interfeţe? Justificati răspunsul.

conceptul de interfaţă utilizator a apărut în legătură cu utilizarea programelor în regim interactiv. În prezent. 198 200 200 201 203 204 205 206 206 208 209 213 216 219 220 222 226 228 231 233 234 235 237 Interfeţe utilizator grafice Interfaţa utilizator. 198 .interfaţa prin linie de comandă. Un asemenea regim permite utilizatorului să comunice cu procesul de calcul în timpul desfăşurării acestuia. utilizarea clasei WindowAdapter Evenimente de mouse Evenimente de tastă Adăugarea unei componente la fereastra principală a aplicaţiei Gestionarea poziţionării componentelor Clasa BorderLayout Clasa FlowLayout Clasa GridLayout Clasa BoxLayout Poziţionarea absolută a componentelor (fără gestionar de poziţionare) Gruparea componentelor prin utilizarea containerelor auxiliare Clasele Panel si JPanel Clasa Box Întrebări. numită şi interfaţa om-maşină. se cunosc două tipuri principale de interfeţe utilizator: . În programare. este mijlocul de comunicare între un sistem informatic şi utilizator. Interfaţa utilizator grafică a unei aplicaţii Clasa Component Un exemplu introductiv de interfaţă utilizator grafică Programarea orientată pe evenimente Modelul de evenimente de pe platforma Java 2 Clase de evenimente Interfeţe şi clase adaptoare pentru ascultători de evenimente Evenimentele generate de o fereastră Terminarea aplicatiei la inchiderea ferestrei.Severin Bumbaru Interfeţe utilizator grafice şi programarea orientată pe evenimente Interfeţe utilizator grafice.

interfaţa grafică. În prezent. Acestea se completează şi cu alte subpachete ale pachetului java. Interfaţa utilizator grafică a fost introdusă pentru prima dată la Palo Research Center al firmei Xerox în anii 1970 şi a fost apoi aplicată de firma Apple pe calculatoarele Macintosh în 1984. diferitele obiecte grafice (butoane. pictograme.awt.awt. Un avantaj important al platformei Java 2 este că oferă pachete de clase. cele mai larg folosite constituie setul cunoscut sub numele de cod Swing (sau JFC/Swing). Aceasta înseamnă că.awt. Interfaţa utilizator grafică (engleză: GUI . pentru realizarea de interfeţe utilizator de calitate superioară.graphical user interface) este o interfaţă ommaşină care permite operatorului să dea comenzi şi să introducă date prin acţionarea asupra unor obiecte grafice vizualizate pe ecran: butoane. meniuri.swing şi javax. Principalele pachete din JFC/Swing sunt javax.swing descrise în documentaţia Java API. Exemplele cele mai cunoscute sunt limbajele de comandă ale sistemelor de operare MS-DOS şi Unix. operatorul uman transmite calculatorului comenzi.java. 2.) vor avea aspectul specific sistemului Windows. AWT (engleză: Abstract Windowing Toolkit . care extind posibilităţile oferite de AWT. Este important să menţionăm că pachetele din JFC/Swing nu se substituie. Dintre acestea.java. pe care le introduce de la tastatură sub forma unor linii de text.applet.swing. ci le completează pe cele din AWT. bare de defilare etc. care permit programatorului realizarea comodă şi eficientă a interfeţelor grafice. care sunt descrise în documentaţia Java API. În modul de comunicare prin linie de comandă. În prezent. la care se adaugă multe alte subpachete ale pachetului javax. dacă programul se execută .event.event. cele mai răspândite interfeţe utilizator grafice sunt sistemul Windows al firmei Microsoft şi cele de tip X-Window folosite în sistemele de operare din categoria Unix.awt. JFC (engleză: Java Foundation Classes . folosind un anumit limbaj de comandă. există două grupuri de pachete de clase pentru interfeţe grafice. În cursul de faţă ne vom referi în special realizarea interfeţei grafice utilizator folosind JFC/Swing şi vom folosi 199 .Programarea orientata pe obiecte în limbajul Java .sub Windows.color si java. care corespund la două principii diferite de realizare a interfeţei: 1. în timp ce dacă se executa sub X-Window vor avea aspectul specific acestui sistem.setul de dezvoltare de ferestre abstracte) este un set de clase care permit realizarea de interfeţe grafice în care se folosesc obiectele grafice specifice platformei pe care se execută programul. Modul de realizare al interfeţei grafice folosind AWT este prezentat destul de amplu in lucrarea "Interfaţa grafica utilizator în limbajul Java".de exemplu . meniuri etc. care oferă posibilitatea de a realiza interfeţe grafice al căror aspect nu depinde de platforma pe care se execută programul.clase de bază Java). Principalele pachete utilizate în acest set sunt: java. este un set de pachete de clase.

Unele din aceste clase le extind sau le dublează pe cele din AWT. Autorii setului de dezvoltare JFC/Swing au decis să realizeze un set de clase de interfaţă care sunt complet independente de platformă. Este drept insă că aceasta se plăteşte prin creşterea complexităţii interfeţei grafice şi a nivelului de competenţă cerut de la programator. toate componentele grafice fac parte din clase care constituie un arbore. aşa cum este el luat în consideraţie în AWT. atât setul de obiecte grafice utilizate. realizarea interfeţei grafice a ridicat probleme dificile deoarece. Mai mult. se caracterizează prin anumite atribute şi un anumit comportament. Componenta este un obiect grafic care este afişabil pe ecran şi poate interacţiona cu utilizatorul. Clasa Container este derivată din clasa Component. Clasa Component Având în vedere că întreaga ierarhie de clase de obiecte de interfaţă utilizator grafică folosite în Java (atât cele din AWT. a cărui rădăcină este clasa Component. Dezavantajul este că o astfel de interfaţă nu poate folosi decât obiectele grafice existente pe toate platformele (mulţimea de clase de obiecte grafice din AWT este "intersecţia" mulţimilor de clase grafice de pe diferite platforme). pe diferite platforme. În sistemele AWT şi JFC/Swing. La aceasta se adaugă şi faptul că AWT se înţelege şi se utilizează relativ usor. Containerele aparţin unor clase care formează o ierarhie. În acest scop. ceeace restrânge posibilitatea programatorilor de a realiza interfeţe utilizator diversificate şi originale. a cărei rădăcină este clasa Container. pot fi diferite. Containerele sunt componente grafice care conţin alte componente. Avantajul utilizării AWT este că utilizatorul vede pe ecran obiectele care compun interfaţa grafică sub forma cu care el este obişnuit pe platforma pe care lucrează. 200 . este util să începem studiul cu această clasă. Se ştie că autorii limbajului Java şi-au propus ca programele scrise în acest limbaj să poată fi executate pe orice platformă. se dă posibilitatea programatorului să dezvolte propriile sale clase de obiecte grafice prin extinderea celor existente. care sa fie comune tuturor platformelor. Obiectul grafic abstract. cât şi aspectul acestora. Deosebim componente atomice şi containere. s-a renunţat la metodele native. Sub acest aspect. clasele Swing fiind programate total în Java. Interfaţa utilizator grafică a unei aplicaţii Orice interfaţă utilizator grafică este un obiect grafic structurat. în alcătuirea căruia intră componente grafice. cât şi din JFC/Swing) are ca rădăcină clasa Component. deci un container poate să conţină alte containere.Severin Bumbaru clasele din AWT numai acolo unde va fi absolut necesar. Aceasta înseamnă ca orice container este o el însuşi componentă. iar altele sunt complet noi. dar aspectul său pe ecran poate sa difere de la o platformă la alta. La realizarea setului de dezvoltare AWT s-a acceptat ideea că în program se lucrează cu nişte obiecte grafice abstracte.

face componenta sa fie vizibilă sau nu. axa Ox este orientată către dreapta.swing. deocamdată. Selecţionarea opţiunilor sau acţionarea butoanelor din bara de titlu produce asupra ferestrei efectul corespunzător. Un exemplu introductiv de interfaţă utilizator grafică Întrucât interfaţa grafică conţine componente. public void setLocation(Point location) . interfaţa utilizator grafică a unei aplicaţii este o instanţă a clasei JFrame din pachetul javax. prezentăm aici numai câteva mai frecvent folosite: . public void setSize(int latime. public void setVisible(boolean visible) . Instanţele clasei Point conţin coordonatele unui punct. int inaltime) .setează noua poziţie a componentei în cadrul containerului părinte. Maximize şi Close din meniul menţionat.întoarce dimensiunea componentei.Size. Se consideră că originea sistemului de coordonate se află în colţul din stânga sus. În partea stângă a barei de titlu există un buton.awt. la apăsarea căruia se desfaşoară un menu cu urmatoarele opţiuni: Restore. care se foloseşte în aplicaţiile Java. ne vom opri asupra clasei JFrame. sau este o subclasă a acesteia. public Point getLocation() . Dintre numeroasele metode ale acestei clase. Descrierea completă este dată în documentaţia Java API. Fereastra poate fi deplasată pe ecran dacă punem cursorul mouse-lui 201 . atunci când este vizibil şi containerul în care se găseşte. Move. public boolean isVisible() În aceste metode se utilizează şi clasele auxiliare Point şi Dimension din pachetul java. după cum argumentul este true sau false. public Dimension getSize() . În mod obişnuit.setează noile dimensiuni ale componentei. ea este un container. O prezentare mai amplă a metodelor acestei clase este dată în indexul de clase. derivată direct din clasa Object. La partea dreaptă a barei de titlu exista trei butoane.testează dacă această componentă este vizibilă. care au acelasi efect ca opţiunile Minimize.determină dacă componenta este efectiv afişată pe ecran.Programarea orientata pe obiecte în limbajul Java Clasa Component este o clasă abstractă. Close. Instanţele clasei Dimension conţin dimensiunile componentei: lăţimea şi înălţimea.întoarce locaţia componentei (poziţia colţului din stânga sus în containerul-părinte) sub forma unei instanţe a clasei Point. instanţele clasei JFrame sunt ferestre care au la partea superioara o bară de titlu. În sistemul JFC/Swing. Vom studia ulterior diferite clase de containere dar. Minimize. Maximize. acste opţiuni pot fi selectate cu mouse-ul sau acţionând tasta corespunzătoare literei subliniate. public boolean isShowing() . iar axa Oy este orientata în jos. Cînd meniul este desfăşurat.

*. System. Pentru a o face vizibilă se foloseşte metoda public void setVisible(boolean visible) a clasei Component. import javax. urmând să revenim ulterior cu indicaţii suplimentare. Iată conţinutul acestui fişier: import java.JFrame.50)). atât proprii.API.Severin Bumbaru pe bara de titlu şi o tragem. ţinând butonul de mouse apăsat. Clasa are o structură destul de complicată şi este descrisă complet în documentaţia Java.getTitle()).java este dat un exemplu de aplicaţie care are o interfaţă utilizator din clasa JFrame. vom da.getLocation()). Exemplu: introducerea unui JFrame într-o aplicaţie În fişierul TestJFrame1. numai cateva informaţii strict necesare pentru folosirea acestei clase.out.getSize()).swing. deocamdată. public void setTitle(String titlu) . class TestJFrame1 { static JFrame iug. System.println("Titlul ferestrei este: "+iug.pune ferestrei un titlu (în locul celui existent). care sunt moştenite de la clasa Frame: public String getTitle() . System.setSize(300. Clasa JFrame are numeroase metode.setVisible(true).println("Dimensiunile ferestrei: "+iug. Descrierea completă se găseşte în documentaţia Java API.out. Dimensiunile ferestrei pot fi modificate trăgând cu mouse-ul oricare din laturile sau din colţurile ei. La crearea ei. deocamdată.out. iug.swing. vom mai menţiona aici numai două.awt. Modul cel mai simplu de a realiza o aplicaţie cu interfaţă grafică este să folosim direct o instanţă a clasei javax. public static void main(String args[]) throws Exception { iug=new JFrame("Exemplu de JFrame").println("Coltul din stanga sus este in punctul: "+ iug. Pentru a nu intra de la început în detalii. Constructorii şi metodele clasei Frame se gasesc în indexul de clase. cât şi moştenite de la superclasele ei. iug.*. instanţa clasei JFrame nu este vizibilă. care extinde clasa Frame din AWT. Principalul constructor este: JFrame(String titlu) unde titlu este titlul ferestrei.setLocation(new Point(100.întoarce titlul ferestrei. iug. } } 202 . În afară de metodele moştenite de la clasa Component.100).

Pentru a avea o interfaţă grafică functională. utilizează un dispozitiv de selecţie numit mouse. în plus. să o iconificăm (minimizăm). intrarea cursorului de mouse în câmpul activ al unui obiect grafic sau 203 .Programarea orientata pe obiecte în limbajul Java În prima linie este importat pachetul javax. În clasa TestJFrame1 (care este aplicaţia noastră). Putem. trăgând cu mouse-ul de marginile acesteia. să modificăm dimensiunile ferestrei. La sfârşit. deiconificăm. pentru a stabili dimensiunile ferestrei şi pozitia ei pe ecran şi a o face vizibilă. cu titlul "Exemplu de JFrame". apăsarea sau eliberarea unui buton al mouse-ului. putem da comanda Close (din meniul ferestrei sau apasând butonul marcat cu X) şi fereastra se închide. setLocation() şi setVisible() din clasa Component. efectuarea unui clic de mouse pe un obiect de control (buton..să asigurăm interacţiunea utilizatorului cu aceste componente şi cu însăşi fereastra aplicaţiei. Se folosesc apoi metodele setSize(). având grijă să nu dam comanda Close (nici din menu. la fel ca în cazul progrămarii tradiţionale. coordonatele şi dimensiunile ferestrei. La lansarea în execuţie a acestei aplicaţii. pe ecranul staţiei de lucru apar diferite obiecte grafice: ferestre. Ne vom ocupa de aceste aspecte în secţiunile următoare. fie în cea a obiectelor grafice de pe ecran: apăsarea sau eliberarea unei taste. s-a declarat câmpul static iug. care conţine principalele clase ale JFC/Swing. meniuri. Pentru a încheia executarea aplicaţiei. deplasarea mouseului. deschiderea sau închiderea unei ferestre. Operatorul poate utiliza tastatura staţiei de lucru. în colţul din stânga sus al ecranului apare o fereastră de dimensiuni 300x100 pixeli.swing. butoane. caseta de validare. Constatăm însă că închiderea ferestrei nu are drept consecinţa şi încheierea executării aplicaţiei: în fereastra terminalului din care am lansat aplicaţia nu a apărut promptul sistemului de operare.println(. maximizam. Se numeste eveniment orice modificare care are loc. bara de defilare etc. În prima instrucţiune din metoda main se creeaza o instanţă a clasei JFrame şi se dă câmpului iug ca valoare referinţa la instanţa nou creată.out. de asemenea. folosind metodele adecvate din clasele JFrame şi Component. Se afişeaza apoi în fereastra terminalului de la care s-a lansat aplicaţia (la ieşirea standard a sistemului) titlul. fie în starea dispozitivelor de intrare. este necesar: . restaurăm. trebuie să dăm de la terminal comanda <Control>-C. dar. Programarea orientată pe evenimente Când se lucrează cu o interfaţă grafică. bare de defilare etc. Putem acum să acţionăm asupra ferestrei cu mouse-ul. cu ajutorul căruia poate alege diferite obiecte grafice de pe ecran şi poate da anumite comenzi prin apăsarea unuia din butoanele acestui dispozitiv.să adaugăm la interfaţă componente grafice.). . inclusiv clasa JFrame. nici acţionând butonul din dreapta sus marcat cu X): putem să deplasăm fereastra tragând cu mouse-ul de bara de titlu..) din metoda main. care este o referinţă la JFrame. iar la ieşirea standard apar toate mesajele afişate prin instrucţiunile System.

dar aici ne interesează numai cele legate de interfaţa grafică a aplicaţiei. se trece la instrucţiunea următoare. deci să îşi trateze propriile evenimemte.evenimentele propriu-zise (engleză: Event). bazat pe delegare (engleză: Delegation Event Model). mouse-ului sau a altui dispozitiv de intrare. Este evident că un asemenea rol nu este deloc convenabil pentru om. În programarea procedurală tradiţională. Un eveniment generat de o sursă poate fi interceptat de mai mulţi ascultători. Modelul de evenimente de pe Platforma Java 2 In JDK 1.1 s-a introdus un nou model de evenimente. procesul de calcul este în întregime ghidat de instrucţiunile programului. Tocmai această legatură strânsa între sursele şi ascultătorii de evenimente este caracteristica esenţiala a "modelului delegării": ea constă în faptul că sursa transmite evenimentele generate de ea 204 . din motive de compatibilitate a programelor din JDK 1. initiaţiva privind ce date trebuie introduse şi în ce moment se introduc acestea aparţine programului. astfel. dar nu mai este recomandată. Chiar dacă programul este interactiv. numite ascultători de evenimente (engleză: Event Listener). . Există diferite modele de generare. Începând cu JDK 1. În lucrarea de faţă va fi prezentat modelul de evenimente specific platformei Java 2. Imediat ce s-a încheiat executarea unei instrucţiuni. astfel ca iniţiativa să îi revină operatorului uman. Pot exista. Această clasă este menţinuta în continuare. S-a trecut. care doreşte să aibă el iniţiativa acţiunilor. care sunt tot obiecte. Este posibil ca un obiect să se "asculte" pe sine însuşi. Acest mod de lucru impune o nouă concepţie în proiectarea programelor. iar programul să execute comenzile acestuia. desigur. .obiecte care captează şi tratează evenimentele. Aceasta se referă şi la interacţiunea dintre program şi utilizator. Conform acestui model.Severin Bumbaru părăsirea acestuia etc. numite surse de evenimente (engleza: Event Source). Apariţia interfeţelor grafice a permis introducerea unei noi concepţii în interacţiunea dintre operator şi aplicatie. acţionând asupra tastaturii.0 cu cele din versiunile ulterioare. generate de surse şi captate de ascultători. iar programul "răspunde" la acest eveniment prin executarea unei anumite acţiuni. respectând fluxul de instrucţiuni al programului respectiv. Operatorului uman nu îi rămâne decât să se conformeze solicitărilor programului şi să introducă date atunci când ele sunt cerute de acesta. numită programarea orientată pe evenimente.obiecte care generează evenimente.0 s-a folosit un model de evenimente bazat pe moştenire. şi alte tipuri de evenimente. captare şi tratare a evenimentelor. cunoscuta şi sub numele de programare ghidată de evenimente (engleză: Event Driven Programming). Interacţiunea dintre operator şi aplicaţie într-un sistem bazat pe evenimente decurge astfel: operatorul provoacă generarea unui eveniment. reprezentat prin clasa Event. de la programarea procedurală tradiţională la programarea orientată pe evenimente (engleză: Event-Oriented Programming). distingem trei catedorii de obiecte care au relaţii cu evenimentele: .

util. public String toString() obiectului. Fiecare ascultator trebuie "adăugat" la sursă. sau când facem click de mouse pe o componenta.event şi formează o ierarhie de clase. sursa "ştie" căror ascultători să le transmită evenimentele pe care le generează. etc. în funcţie de aceasta. Valoarea acestui câmp se poate obţine prin metoda public int getId() Evenimentele pot fi de nivel coborât (low level event) sau semantice.care întoarce o reprezentare sub forma de şir a evenimentul respectiv.EventObject din pachetul java.0 sursa transmitea evenimentele fără o destinaţie anume. evenimentul nu este generat direct de către tastă. deci.AWTEvent. decât sursa acestuia. că se aplică cu consecvenţă principiul programării orientate pe obiecte. când apăsăm sau eliberăm o tastă.swing. ci de către componenta respectivă a interfeţei. Clase de evenimente Clasele de evenimente se găsesc în pachetele java.event şi javax. evenimentul nu este generat direct de către mouse. Orice eveniment AWT (generat de componente AWT sau JFC/Swing) conţine un câmp protejat de tip int numit id. Orice eveniment conţine următoarele metodele declarate în clasa java.util. în acest model de evenimente. Remarcăm.). iar consumatorii de evenimente trebuiau sa depisteze singuri ce fel de evenimente sunt acestea şi de la ce sursă provin şi. fie dispozitivul de intrare care le-a generat. MouseEvent. Toate clasele de evenimente conţin câmpuri statice finale de tip int. WindowEvent. la rândul ei.EventObject: public Object getSource() . a cărui valoare indică tipul evenimentului. Când cursorul mouse-ului intră în interiorul unei componente sau iese din aceasta. al căror nume indică tipul de eveniment şi a căror valoare este valoarea corespunzătoare a câmpului id. Numele claselor de evenimente semantice indică mai curând tipul de eveniment.care întoarce o referinţă către obiectul care a generat . Putem spune că evenimentul este o nouă forma de mesaj. ci de către acea componentă a interfeţei grafice.awt. care are ca radacină clasa abstractă java. să decidă dacă interceptează sau nu evenimentul respectiv. Evenimentele pot fi generate de o componentă şi atunci când au loc modificari ale stării acesteia ca urmare a executării unor instrucţiuni din program (de exemplu când se deschide sau se închide o fereastră. 205 . extinde clasa java. În modelul de evenimente din JDK 1. În mod similar. de exemplu: ComponentEvent. care se transmite între obiectele-sursă şi obiectele-ascultători. în sensul că aplicaţia este constituită dintr-un ansamblu de obiecte care interacţionează. iar ascultătorul primeşte evenimente numai de la sursele la care a fost ataşat. Aceasta. care este activă în momentul respectiv. KeyEvent. sursele sunt întotdeauna componente ale interfeţei grafice. Este important sa reţinem faptul că. Numele claselor de evenimente de nivel coborât indică fie componenta. În acest fel.util.Programarea orientata pe obiecte în limbajul Java numai către ascultătorii care au fost ataşaţi la sursa respectivă.awt.

existente în clasele de surse. TextEvent. În schimb. pentru ComponentEvent există interfaţa ComponentListener. Aceasta este derivată din clasa java.awt. Pentru a se uşura munca programatorilor. ci doar interfeţele pe care trebuie să le implementeze aceste clase. Adăugarea ascultătoarelor la sursele de evenimente se face prin metode de adăugare corespunzătoare. pentru a putea trata evenimentele pe care le recepţionează. deci nu sunt programate de către programatorul de aplicaţie. Interfeţe şi clase adaptoare pentru ascultători de evenimente Evenimentele generate de surse. De exemplu.fereastra a fost deschisă public void windowClosing(WindowEvent e). programatorul de aplicaţie trebuie să creeze clasele de ascultători de evenimente specifice aplicaţiei pe care o dezvoltă. Există câte o interfaţă de ascultător pentru fiecare clasă de eveniment. sunt preluate din pachetele de clase ale platformei Java 2. ci doar utilizate de acesta. clasa WindowAdapter implementează interfaţa WindowListener. numite adaptoare. pentru a se adăuga la o instanţă a clasei Window sau a subclaselor acesteia (de exemplu JFrame) un ascultător de evenimente de fereastră.JFrame. de regulă. Vom folosi în acest scop o interfaţă din clasa javax. Evenimentele prezentate în această secţiune sunt generate de orice instanţă a clasei Window şi ale subclaselor sale. De exemplu. În consecinţă. clasa MouseAdapter implementează interfaţa MouseListener etc. De exemplu. se oferă şi prototipuri de clase care implementează interfaţa respectivă. Metodele acestor clase trebuie sa reacţioneze la apariţia evenimentelor şi să execute acţiunile corespunzătoare.swing.awt. pentru unele interfeţe care conţin mai multe metode. Sursele sunt componente ale interfeţei grafice care. conform cu obiectivele aplicaţiei. pentru WindowEvent exista intefaţa WindowListener etc.Frame care. Evenimentele generate de o fereastră Pentru a ne familiariza cu modelul de evenimente al platformei Java 2. sunt captate şi tratate de ascultători. Descrierea claselor de evenimente este dată complet în documentaţia Java API. în clasa Window există metoda public void addWindowListener(WindowListener l) Descrierea completă a interfeţelor şi adaptoarelor pentru clasele de ascultători de evenimente este dată în documentaţia Java API. Evenimentele generate de fereastră sunt instanţe ale clasei WindowEvent şi sunt ascultate de instanţe ale unor clase care implementează interfaţa WindowListener sau extind clasa WindowAdapter. la rândul ei.fereastra se închide 206 .event.Window. Toate aceste clase şi interfeţe se găsesc în pachetul java. este derivată din clasa java. Metodele interfeţei WindowListener sunt următoarele: public void windowOpened(WindowEvent e).Severin Bumbaru de exemplu: ActionEvent.awt. platforma Java 2 nu pune la dispoziţie clase ascultătoare predefinite. vom urmări acum evenimentele generate de o fereastră şi modul cum acestea pot fi tratate.

100).swing.println("Fereastra a fost dezactivata: "+e). Exemplu În fişierul Evenim1.50)). import javax. import java. 207 .awt.out.java este dat ca exemplu următorul program. în care se urmăresc evenimentele generate de o fereastră din clasa JFrame.fereastra a fost activată windowDeactivated(WindowEvent e). astfel încât acestea să execute acţiunile adecvate evenimentelor corespunzătoare.out.fereastra a fost dezactivată Pentru a se trata evenimentele generate de fereastră.fereastra a fost iconificată windowDeiconified(WindowEvent e).fereastra a fost inchisă windowIconified(WindowEvent e). // instantierea ascultatorului iug=new JFrame("Urmarire evenimente fereastra"). } } // se incheie clasa ascultatorului de fereastra /* Metoda principala */ public static void main(String args[]) throws Exception { af=new AscultFereastra().*. } public void windowDeiconified(WindowEvent e) { System.println("Fereastra a fost iconificata: "+e). // referinta la interfata grafica static AscultFereastra af.Programarea orientata pe obiecte în limbajul Java public public public public public void void void void void windowClosed(WindowEvent e).awt. } public void windowActivated(WindowEvent e) { System. este necesar să se declare o clasă care implementează interfaţa WindowListener.out. În această clasă se definesc toate metodele interfeţei.out.*. // referinta la ascultator /* Clasa imbricata pentru ascultatorul de fereastra */ static class AscultFereastra implements WindowListener { public void windowOpened(WindowEvent e) { System.setVisible(true).setLocation(new Point(100.println("Fereastra a fost activata: "+e). import java. iug.println("Fereastra a fost deschisa: "+e).println("Fereastra se inchide: "+e).println("Fereastra a fost deiconificata: "+e). iug.event. class Evenim1 { static JFrame iug.println("Fereastra a fost inchisa: "+e). } public void windowDeactivated(WindowEvent e) { System.fereastra a fost deiconificată windowActivated(WindowEvent e).setSize(300.*.out.out. iug. } public void windowClosed(WindowEvent e) { System. } public void windowIconified(WindowEvent e) { System. } public void windowClosing(WindowEvent e) { System.out.

La terminal putem urmări succesiunea evenimentelor care se produc. } } Pentru ascultătorul de fereastră a fost creată clasa imbricată statică AscultFereastra. Se stabilesc.awt. După ce a fost pusă aplicaţia în execuţie. a fost necesar ca. ieşirea din aplicaţie se face de la tastatura. pe ecran apare o fereastră cu titlul "Urmarire evenimente fereastra". este preferabil sa obţinem clasa AscultFereastra prin extinderea clasei WindowAdapter. class Inchidere { static JFrame iug. Această ultimă clasă conţine toate metodele interfeţei WindowListener. dimensiunea şi poziţia ferestrei şi se face fereastra vizibilă. în clasa derivată este suficient să redefinim numai metodele care ne sunt necesare.getTitle()). În cazul de faţă. System.swing. este necesar ca metoda windowClosing() a ascultătorului de fereastră să conţină invocarea metodei System.println("Dimensiunile ferestrei: "+iug. în exemplul de mai sus. Dacă ne sunt necesare numai unele din aceste metode.println("Titlul ferestrei este: "+iug.getSize()). să se definească toate metodele acesteia. se construiesc instanţele claselor JFrame şi AscultFereastra. vom deriva clasa de ascultare a ferestrei AF din clasa WindowAdapter. în care sunt implementate toate metodele interfeţei WindowListener.getLocation()). ca în exemplul din secţiunea următoare.java se dă o modificare a clasei Evenim1 din exemplul precedent. import java.out. aceste metode nu fac altceva. după care se adaugă ascultătorul af la fereastra iug prin metoda addWindowListener().*. // adaugarea ascultatorului System. Dacă nu dorim să utilizam şi alte metode de tratare a evenimentelor generate de fereastră. decât că afişează pe terminal un mesaj privind evenimentul care s-a produs. ci si aplicaţia.println("Coltul din stanga sus este in punctul: "+ iug.out.addWindowListener(af). în clasa care implementează interfata WindowListener. Remarcăm că.Severin Bumbaru iug.exit(0) din clasa System.*. import javax. de asemenea. import java.*. Acest mesaj conţine şi evenimentul interceptat e. System. // referinta la ascultator /* Clasa imbricata pentru ascultatorul de fereastra */ static class AF extends WindowAdapter { 208 .out. // referinta la fereastra static AF af.awt. convertit în şir. În metoda main(). deci metodele nu fac nimic.event. Terminarea aplicaţiei la închiderea ferestrei Pentru ca la acţionarea butonului de închidere din colţul din dreapta-sus al ferestrei să se închidă nu numai fereastra respectivă. În acest fel. dar corpurile lor sunt vide. Exemplu În fişierul Inchidere. Ca şi în exemplul precedent. prin comanda <Control>-C.

awt.event.awt. iug. } public void windowDeactivated(WindowEvent e) { System.println("Fereastra a fost dezactivata"). s-au mai făcut următoarele modificări: . prin extinderea claselor java.event. sau selectăm optiunea Close din meniu.getLocation()).println("Titlul ferestrei este: "+iug.setLocation(new Point(100. // adaugarea ascultatorului System.exit(0). deci implementează in mod indirect interfaţa WindowListener. Ascultătoarele de mouse se pot obţine. // incheierea executarii aplicatiei } } /* Metoda principala */ public static void main(String args[]) throws Exception { af=new AF().MouseAdapter.getSize()).out.swing.s-au definit numai trei din cele şapte metode ale intefeţei WindowListener.awt.awt.în metoda windowClosing()s-a introdus instrucţiunea System. System. Clasa MouseEvent este derivată din clasa java.event.java. .MouseMotionListener şi javax. .println("Dimensiunile ferestrei: "+iug. efectuarea unui click de mouse (simplu sau multiplu) pe suprafaţa componentei.InputEvent. În consecinţă. iug. mişcarea mouse-ului.Programarea orientata pe obiecte în limbajul Java public void windowActivated(WindowEvent e) { System. iug.event. Pentru ascultarea evenimentelor de mouse se folosesc interfeţele java.clasa de ascultare a evenimentelor AF extinde clasa WindowAdapter.out.println("Fereastra a fost activata").out. Evenimente de mouse Evenimentele de mouse sunt instanţe ale clasei java.setVisible(true).out. System. deci nu fac nimic.println("Coltul din stanga sus este in punctul: "+ iug. de asemenea.exit(0).100).MouseEvent şi sunt generate de către orice componentă a interfeţei grafice. System. atunci când asupra ei se acţioneaza cu mouseul.event.setSize(300. } public void windowClosing(WindowEvent e) { System. apăsarea unui buton de mouse sau eliberarea lui. celelalte metode sunt moştenite de la clasa WindowAdapter.MouseInputListener.java. Evenimentele de mouse sunt intrarea cursorului de mouse într-o componentă sau ieşirea din aceasta.event.MouseMotionAdapter şi 209 .getTitle()).awt.50)).out. în afară de modificarea numelor claselor. } } În acest program.println("Fereastra se inchide").event. se încheie executarea aplicaţiei. iug. prin intermediul acesteia.out. // instantierea ascultatorului iug=new JFrame("Urmarire evenimente fereastra").MouseListener. când acţionăm butonul de închidere al ferestrei.addWindowListener(af).awt.

MouseInputAdapter.a fost apăsat un buton al mouse-ului (MOUSE_PRESSED).*.exit(0). . adică un buton al acestuia a fost apăsat şi eliberat imediat (MOUSE_CLICKED). . class EvMouse { static JFrame iug. dar aceste metode nu fac altceva. import java. care ascultă ambele categorii de evenimente de mouse.awt.java este dat un exemplu de aplicaţie în care se ascultă evenimentele de mouse generate de o instanţă a clasei JFrame şi se afişează la terminal conţinutul acestor evenimente. în clasa imbricată AMouse au fost implementate toate metodele interfeţei MouseListener.*.s-a făcut click de mouse. Aceste evenimente sunt ascultate cu instanţe ale claselor care implementează interfaţa java. În acest scop.event.awt.a fost eliberat un buton al mouse-ului (MOUSE_RELEASED).event.event. // referinta la ascultator de fereastra static AMouse am. moştenind cele două interfeţe menţionate mai sus. a/ Evenimente de mouse .awt.Severin Bumbaru javax. Exemplu În fişierul EvMouse. În JFC/Swing s-a introdus în plus interfaţa javax. b/ Evenimente de mişcare a mouse-ului .cursorul mouse-ului a ieşit din componentă (MOUSE_EXITED). Ascultarea acestor evenimente se face cu instanţe ale claselor care implementeaza interfaţa java. // incheierea executarii aplicatiei } } 210 .swing.mouse-ul a fost "tras" pe suprafaţa componentei. import java. decât să afişeze la terminal evenimentul recepţionat.MouseListener.*. .event. import javax.MouseInputListener.awt.event.MouseMotionListener. . În AWT se face distincţie între evenimentele de mouse discrete şi evenimentele care caracterizează mişcarea continuă a mouse-lui. adică a fost mişcat ţinând un buton apăsat (MOUSE_DRAGGED).swing.cursorul mouse-ului a intrat într-o componentă (MOUSE_ENTERED). .mouse-ul s-a mişcat pe suprafaţa componentei (MOUSE_MOVED). // referinta la ascultator de mouse /* Clasa imbricata pentru ascultatorul de fereastra */ static class AF extends WindowAdapter { public void windowClosing(WindowEvent e) { System. // referinta la fereastra static AF af.swing.

setLocation(new Point(100. } public void mouseEntered(MouseEvent e) { System.event.50)). // instantierea ascultatorului am=new AMouse().println(e). în care fiecare bit are o anumită semnificaţie.100).setSize(300.out. } public void mouseReleased(MouseEvent e) { System. Exemplu În fişierul EvMouse1.awt. .numărul de ordine al ferestrei (în ordinea în care ferestrele au fost creeate).InputEvent. în care se urmăresc situaţiile în care este apăsat unul dintre butoanele mouse-ului.out.println(e).println(e). } public void mouseExited(MouseEvent e) { System.contorul de click-uri (util când au loc mai multe clickuri succesive).out.awt.coordonatele punctului în care s-a produs evenimentul.modul în care s-a produs evenimentul. iug.addMouseListener(am). . . // instantierea ascultatorului de mouse iug=new JFrame("Urmarire evenimente de mouse"). Acest număr poate fi decodificat cu ajutorul măştilor existente în clasa java. Aceste informaţii pot fi obţinute folosind metodele şi măştile din clasele java. clasa ascultătorului de mouse AMouse s-a creat prin extinderea clasei java.event.Programarea orientata pe obiecte în limbajul Java /* Clasa imbricata pentru ascultatorul de mouse */ static class AMouse implements MouseListener { public void mouseClicked(MouseEvent e) { System.event. Evenimentul de mouse conţine următoarele informaţii: .println(e).InputEvent.MouseAdapter. } public void mousePressed(MouseEvent e) { System.event. // adaugarea ascultatorului de mouse } } Executând acest program.out. } } /* Metoda principala */ public static void main(String args[]) throws Exception { af=new AF(). iug. . // adaugarea ascultatorului de fereastra iug.setVisible(true).addWindowListener(af). atunci când cursorul acestuia se găseşte pe suprafaţa ferestrei aplicaţiei. caracterizat printr-un numar întreg.tipul evenimentului (câmpul id).println(e).out.java este dat un exemplu de aplicaţie.MouseEvent şi java. putem urmări pe ecran succesiunea de evenimente care se produc atunci când acţionăm cu mouse-ul asupra ferestrei aplicaţiei. 211 . Întrucât nu se folosesc toate metodele interfeţei MouseListener.awt. iug.awt. iug.

invocând metoda getClickCount() a aceleeaşi clase. mod=e. se procedează astfel: .awt.BUTTON1_MASK & mod) != 0) buton=1. String mesaj="S-a apasat butonul ".100). // referinta la ascultator de mouse /* Clasa imbricata pentru ascultatorul de fereastra */ static class AF extends WindowAdapter { public void windowClosing(WindowEvent e) { System.se aplică asupra acestui cod măştile butoanelor. } } /* Metoda principala */ public static void main(String args[]) throws Exception { af=new AF(). iug.setSize(300.addMouseListener(am). // incheierea executarii aplicatiei } } /* Clasa imbricata pentru ascultatorul de mouse */ static class AMouse extends MouseAdapter { public void mousePressed(MouseEvent e) { int x=e.BUTTON2_MASK & mod) !=0) buton=2. Se determină numărul de apăsări succesive rapide.isShiftDown()) mesaj+=" Shift".out. import java.swing.setLocation(new Point(100.exit(0). class EvMouse1 { static JFrame iug. System.50)). folosind operatorul de intersecţie pe biţi 212 .*.println(mesaj).event. if(e. // adaugarea ascultatorului de fereastra iug. else if((InputEvent.*. // referinta la ascultator de fereastra static AMouse am.getClickCount().addWindowListener(af). Pentru a afla ce buton a fost apăsat. mesaj+=buton+" x="+x+" y="+y+" contor="+n+" mod="+mod.getY().getX(). .se determină codul modificatorilor. iug. if((InputEvent. iug. y=e. // instantierea ascultatorului am=new AMouse(). iug.getModifiers().isAltDown()) mesaj+=" Alt". n=e. // instantierea ascultatorului de mouse iug=new JFrame("Urmarire evenimente de mouse"). else if((InputEvent.isControlDown()) mesaj+=" Ctrl".*. invocând metodele getX() şi getY() ale clasei MouseEvent. import javax. buton=0. if(e. // adaugarea ascultatorului de mouse } } În metoda mousePressed() a clasei AMouse se determină coordonatele punctului în care s-e găseşte cursorul la apăsarea butonului.awt. if(e.BUTTON3_MASK & mod) !=0) buton=3. // referinta la fereastra static AF af. invocând metoda getModifiers() din clasa InputEvent.setVisible(true).Severin Bumbaru import java.

folosind măştile corespunzătoare acestor taste. în afară de codul tastei acţionate.awt. care sunt generate de fereastra aplicaţiei.java se dă un exemplu de aplicaţie. Aceste stări pot fi detectate cu metodele corespunzătoare ale interfeţei superclasei java. şi informaţii privind starea tastelor auxiliare Ctrl.awt.*.event. componenta activă a interfeţei grafice generează un eveniment de tastă din clasa java. Exemplu În fişierul EvTaste.InputEvent.a fost apasată o tastă (KEY_PRESSED). Aceste situaţii pot fi detectate cu metodele corespunzătoare ale interfeţei KeyListener.event.event.awt. Toate măştile folosite în această aplicaţie sunt definite în clasa java. // ascultatorul de taste static IUG iug=new IUG("Urmarirea evenimentelor de tasta").swing. în care se urmăreşte apariţia unor evenimente de tastă. dă rezultat nenul este cel apăsat.awt. era apăsată şi una din tastele auxiliare Ctrl. Acesta poate fi tratat cu un "ascultător de taste" care implementează interfaţa java. Alt sau Shift. în timp ce s-a apăsat butonul de mouse. .KeyListener sau care extinde clasa java.InputEvent.a fost "tipărit" un caracter. aici s-a preferat utilizarea metodelor isControlDown(). isAltDown() şi isShiftDown() ale clasei InputEvent. Totuşi.*. class EvTaste { static AF af=new AF().event. . import javax.awt.*. /* Clasa imbricata pentru interfata utilizator */ static class IUG extends JFrame { /* Constructorul interfetei utilizator */ 213 .event. Se disting următoarele evenimente generate la acţionarea tastelor: . adică a fost apasată şi eliberată o tastă care transmite un caracter tipăribil (KEY_TYPED).Programarea orientata pe obiecte în limbajul Java &. import java. Codul modificatorilor mod poate fi folosit şi pentru a determina daca. Evenimentul generat de tastă conţine.awt.awt. Alt şi Shift în momentul producerii evenimentului respectiv. atunci când ea este activă şi se actionează o tastă. import java.KeyEvent.KeyAdapter.event.a fost eliberată o tastă (KEY_RELEASED). Butonul de mouse a cărui mască. intersectată cu codul mod. // ascultatorul de fereastra static ATaste at=new ATaste(). Evenimente de tastă De câte ori se apasă sau se eliberează o tastă.

java este dat un exemplu de aplicaţie în care se folosesc metodele din clasele KeyEvent şi InputEvent pentru a detecta situaţiile în care au apărut evenimentele captate de către ascultătorul de taste.exit(0). Pentru a detecta în ce condiţii a fost generat evenimentul (codul tastei care a fost apasată.Severin Bumbaru IUG(String titlu) { super(titlu).out. că aceste evenimente sunt generate numai atunci când fereastra aplicaţiei este activă. setVisible(true). setLocation(new Point(100.println(e). // adaugarea ascultatorului de fereastra addKeyListener(at). addWindowListener(af).println(e). Punând în execuţie această aplicaţie. } public void keyPressed(KeyEvent e) { System.println(e). // adaugarea ascultatorului de taste } } /* Clasa imbricata pentru ascultatorul de fereastra */ static class AF extends WindowAdapter { public void windowClosing(WindowEvent e) { System. care implementează interfaţa KeyListener.100). metodele ascultătorului de taste afişează evenimentul respectiv la terminal. Aşa cum sunt ele redefinite aici.out. Acesta a fost realizat prin extinderea clasei 214 . // incheierea executarii aplicatiei } } /* Clasa imbricata pentru ascultatorul de taste */ static class ATaste implements KeyListener { public void keyTyped(KeyEvent e) { System. putem urmări la terminal succesiunea evenimentelor care sunt generate atunci când acţionam tastele.out.50)). inscripţia de pe tastă. Exemplu În fişierul EvTaste1. de asemenea. ce taste auxiliare erau apăsate). } public void keyReleased(KeyEvent e) { System. putem utiliza metodele claselor KeyEvent şi superclasei acesteia InputEvent. setSize(300. } } /* Metoda principala */ public static void main(String args[]) { } } Ascultătorul de taste este realizat prin clasa imbricată ATaste. Remarcăm.

awt. Pentru detalii privind metodele disponibile în clasele KeyAdapter. putem urmări la terminal evenimentele de apăsare a unei taste (KEY_PRESSED) şi de introducere a unui caracter (KEY_TYPED) afişate sub formă decodificată.out. class EvTaste1 { static AF af=new AF(). addWindowListener(af).getKeyCode().50)). 215 . // adaugarea ascultatorului de fereastra addKeyListener(at).getKeyText(cod).*.awt. setVisible(true). import java. // ascultatorul de fereastra static ATaste at=new ATaste().exit(0). mod=e.swing. // adaugarea ascultatorului de taste } } /* Clasa imbricata pentru ascultatorul de fereastra */ static class AF extends WindowAdapter { public void windowClosing(WindowEvent e) { System. setSize(300. // ascultatorul de taste static IUG iug=new IUG("Urmarirea evenimentelor de tasta"). System.*.println("S-a introdus caracterul "+e. setLocation(new Point(100. String mesaj="S-a apasat tasta de cod "+cod+" "+e.println(mesaj). } } /* Metoda principala */ public static void main(String args[]) { } } Punând în execuţie această aplicaţie. if(mod!=0) mesaj+=" cu modificatorii: "+e. } public void keyTyped(KeyEvent e) { System.*.100). import javax.out.event. import java. KeyEvent şi InputEvent se poate consulta documentaţia Java API. /* Clasa imbricata pentru interfata utilizator */ static class IUG extends JFrame { /* Constructorul interfetei utilizator */ IUG(String titlu) { super(titlu).getKeyChar()). // incheierea executarii aplicatiei } } /* Clasa imbricata pentru ascultatorul de taste */ static class ATaste extends KeyAdapter { public void keyPressed(KeyEvent e) { int cod=e.Programarea orientata pe obiecte în limbajul Java KeyAdapter.getKeyModifiersText(mod).getModifiers().

*. care conţin . folosită într-o metodă a clasei JFrame sau a subclaselor ei.add(comp). fereastra principală a aplicaţiei este o instanţă a clasei javax. la care se pot adăuga componente. static int contorActionari=0. casete de validare. existentă în clasa JFrame.awt. atunci expresia getContentPane().la rândul lor . În acest exemplu se arată: .swing.java este un exemplu de aplicaţie. O referinţă la acest Container se obţine prin metoda public Container getContentPane().Severin Bumbaru Adăugarea unei componente la fereastra principală a aplicaţiei Până în prezent. Pentru realizarea acestor componente simple şi containere se folosesc clasele din pachetele java. O prezentare succintă a clasei JFrame este dată în Indexul de clase. butoane. Exemplul 1 În fişierul AdComp. static AB ab=new AB(). Adăugarea de componente se face prin una din metodele add() ale clasei Container.awt şi javax. adaugă componenta comp la containerul contentPane conţinut în JFrame. static AF af=new AF(). Dacă. import javax.JFrame sau a unei subclase a acesteia.cum se adaugă la fereastra aplicaţiei un buton (o instanţă a clasei JButton). În JFrame există un Container (un obiect dintr-o subclasă a clasei Container) numit contentPane. Acestea pot fi componente simple. în care se testează adăugarea la fereastra principală a unui buton şi se face contorizarea numărului de apăsări pe butonul respectiv. /* clasa imbricata pentru interfata utilizator grafica */ 216 . import java. am arătat că.. Adăugarea de componente nu se face direct la instanţele clasei JFrame. .*. În locul unui buton se putea folosi orice altă componentă.swing.cum se tratează evenimentele de acţiune generate la apasarea butonului. static JButton buton=new JButton(textButon+contorActionari). atunci când folosim JFC/Swing.event. completată cu cea din Tutorialul Java. static IUG iug=new IUG("Un buton de contorizare a apasarilor"). sau pot fi containere. iar cea completă se găseşte în Java API.*. câmpuri de text etc. comp este referinţă la o componentă. care sunt descrise în documentaţia Java API. ca etichete. de exemplu. Pentru a construi o interfaţă utilizator grafică este necesar ca în fereastra principală să introducem diverse componente.alte componente. class AdComp { static String textButon="Numar de actionari: ".swing.awt. import java.

clasa AB. setLocation(200.În constructorul clasei IUG se adaugă la containerul de conţinut al ferestrei principale (contentPane) butonul button. 80). // adaugarea ascult. buton. necesar pentru închiderea aplicaţiei. pe ecran apare o fereastră cu titlul "Un buton de 217 . setSize(300.add(buton). evenimentele de acţiune vor fi generate atunci când se apasă pe buton (se face click de mouse pe suprafaţa butonului). . Obiectele indicate de referinţele buton af şi ab au fost construite înainte de a se construi interfaţa grafică. getContentPane(). // adaugarea ascultatorului de fereastra buton. se adaugă la buton ascultătorul de evenimente de fereastră af şi ascultătorul de evenimente de acţiune ab.addActionListener(ab). care asculta şi tratează evenimentele de acţiune generate de buton. // adaugarea butonului addWindowListener(af). clasa IUG. În acest scop se foloseşte instrucţiunea buton.setText(textButon+contorActionari). } } /* Metoda principala a aplicatiei */ public static void main(String args[]) { } } Remarcăm următoarele: . Întrucat în programul nostru sursa evenimentelor de acţiune (la care a fost inregistrată instanţa ab a clasei AB) este butonul buton. care este interfaţa utilizator grafică. de actiune setVisible(true). clasa AF. } } /* Clasa ascultatoare de fereastra */ static class AF extends WindowAdapter { public void windowClosing(WindowEvent e) { System.setText(text). se foloseşte instrucţiunea getContentPane(). . care indică valoarea contorului. // incheierea executarii aplicatiei } } /* Clasa ascultatoare de actiuni asupra butonului */ static class AB implements ActionListener { public void actionPerformed(ActionEvent e) { contorActionari++. 150). .Metoda actionPerformed(Event e) din clasa imbricată AB este invocată atunci când se produce un "eveniment de acţiune". În acest scop. .În acelaşi constructor.exit(0). care este ascultătorul evenimentelor de fereastră.add(buton). În această metodă se incrementează variabila contorAcţionări şi se pune în buton un nou text.S-au declarat trei clase imbricate: .Programarea orientata pe obiecte în limbajul Java static class IUG extends JFrame { IUG(String titlu) { // constructorul clasei IUG super(titlu). Când punem în execuţie această aplicaţie. din clasa JButton. .

} public int numarApasari() { // se intoarce numarul de apasari return contor. indicand noua valoare a contorului de acţionări. } public void reset() { // se pune contorul la zero contor=0. */ import java. 218 . this. setText(this.java. în interiorul căreia se găseşte un buton pe care apare inscripţia "Număr de acţionări: 0". import javax.*.swing. folosit şi în mai multe aplicaţii. // butonul se asculta pe sine } public void actionPerformed(ActionEvent e) { contor++.Severin Bumbaru contorizare a apăsărilor". Exemplul 2 Folosirea unei clase de buton de contorizare proprie. se foloseşte o instanţă a clasei ButonContor.event.*. import javax. setText(nume+contor). // contorul de apasari private String nume.event. constatăm că s-a modificat textul continut.java se dă o modificare a aplicaţiei din exemplul precedent.nume=nume+" #". în locul unei instanţe a clasei JButton.nume+contor). reprodus aici: /* Buton care contorizeaza numarul de apasari si afiseaza acest numar pe suprafata sa. ca în fişierul ButonContor. De fiecare dată. derivată din clasa JButton Având în vedere ca butonul de contorizare a apăsărilor poate fi. public class ButonContor extends JButton implements ActionListener { private int contor. în principiu. In acest scop. în care.swing.*. când facem click de mouse pe acest buton. import java.awt. addActionListener(this).awt. // numele butonului public ButonContor(String nume) { // constructorul butonului contor=0. setText(nume+contor). putem să îl declarăm ca o clasa publică într-un fişier separat. întrucât butonul din clasa ButonContor se ascultă pe el însuşi. În acest caz nu a mai fost necesar să se creeze o clasă de ascultare a butonului. } } În fişierul AdComp1. butonul isi asculta propriile evenimente de actiune. dupa numele butonului.*.

În mod normal însă. cât şi la modificarea dimensiunilor acestuia. 150).LayoutManager sau subinterfaţa acesteia java. setSize(300. vom studia cele mai larg utilizate clase de gestionare a poziţionării. // adaugarea butonului addWindowListener(af). setLocation(200. într-un comtainer se plasează mai multe componente.contentPane şi FlowLayout pentru clasa Panel. 80). În acest scop.LauoutManager2. static IUG iug=new IUG("Un buton de contorizare a apasarilor"). Orice gestionar de poziţionare implementează interfaţa java. Gestionarul de poziţionare este o clasă care asigură poziţionarea şi redimensionarea automată a componentelor situate într-un container. Modificarea gestionarului de pozitionare se face prin metoda public void setLayout(LayoutManager manager) 219 . // adaugarea ascultatorului de fereastra setVisible(true). Acesta este BorderLayout pentru Frame şi JFrame. Fiecare clasă de container are un gestionar de poziţionare implicit. /* clasa imbricata pentru interfata utilizator grafica */ static class IUG extends JFrame { IUG(String titlu) { // constructorul clasei IUG super(titlu).awt. } } /* Clasa ascultatoare de fereastra */ static class AF extends WindowAdapter { public void windowClosing(WindowEvent e) { System.swing. a fost introdus conceptul de gestionar de poziţionare (în engleză: Layout Manager).awt şi javax. În acest caz. În cele ce urmează.awt. static ButonContor buton=new ButonContor("Contor apasari"). este foarte important să se stabilească modul în care aceste componente sunt poziţionate pe suprafaţa containerului. existente în pachetele java. atât la crearea containerului. // incheierea executarii aplicatiei } } /* Metoda principala a aplicatiei */ public static void main(String args[]) { } } Gestionarea poziţionării componentelor Am arătat în secţiunea precedentă cum se poate plasa într-un container (în particular într-un contentPane) o singură componentă.Programarea orientata pe obiecte în limbajul Java class AdComp1 { static AF af=new AF(). getContentPane().add(buton).exit(0).

awt.event.Container. addWindowListener(af).Severin Bumbaru din clasa java.awt. componenta respectivă este plasată implicit în zona CENTER. ButonContor b1. // ascultatorul de actiuni static IUG iug=new IUG("Adaugare de butoane"). b2=new ButonContor("E"). iar ZONA este una din cele cinci zone menţionate mai sus. // ascultatorul de fereastra static AA aa=new AA(). Dacă se foloseşte metoda add(componenta). NORTH. import java. Exemplu În fişierul Butoane. CENTER şi EAST şi o etichetă (instanţă a clasei javax.add(b1. În acest caz.awt.java este dat un exemplu. BorderLayout.JLabel) în zona SOUTH.addActionListener(aa). Adăugarea de componente la container se face.ZONA). fără a indica zona.java. SOUTH.WEST. În fiecare din aceste zone se poate plasa numai o singură componentă. b3.NORTH). unde componenta este referinţa la componenta adaugată. aşa cum s-a procedat în secţiunea precedenta. import java. deoarece este gestionarul de poziţionare implicit pentru conţinutul instanţelor clasei JFrame. 220 . EAST si CENTER. setLocation(200. respectiv. în care se plasează în fereastra aplicaţiei câte un buton în fiecare din zonele NORTH. se consideră că suprafaţa containerului este imparţită în cinci zone numite. În eticheta de la partea de jos se afişează numărul total de acţionări asupra tuturor butoanelor.addActionListener(aa).add(b2.swing. cp.add(b3. b2. în acest caz. cp. b2. BorderLayout. BorderLayout.EAST).*. Clasa BorderLayout Începem cu această clasă.*. b1. b3=new ButonContor("W"). Container cp=getContentPane().*. b3.150). în exemplul din fişierul AdComp. b4=new ButonContor("C"). b4. class Butoane { static AF af=new AF(). Pe suprafaţa fiecărui buton este afişat numărul de apăsări succesive.addActionListener(aa). cp. b1=new ButonContor("N"). WEST. static class IUG extends JFrame { JLabel lab=new JLabel("Actionati butoanele"). IUG(String titlu) { super(titlu). setSize(400. care poate fi însă ea însăşi un container. folosind metoda add(componenta.WEST). static int totalActionari=0. BorderLayout.swing. import javax.300).

setVisible(true).addActionListener(aa). fiind definită de noi ca o clasa publică în fişierul ButonContor. . EAST si CENTER ale ferestrei principale. cum se modifică automat dimensiunile componentelor atunci când modificăm cu mouse-ul dimensiunile ferestrei. } } static class AF extends WindowAdapter { public void windowClosing(WindowEvent e) { System. cât şi numărul total de acţionari afişat pe eticheta din partea inferioară a ferestrei. putem vedea cum se plasează cele cinci componente pe suprafaţa ferestrei.setText("Total actionari: "+totalActionari).JLabel.exit(0). la fiecare buton se adaugă. 221 . În exemplul nostru se afişează numarul total de acţionări ale butoanelor (valoarea câmpului total al clasei Butoane). .adăugarea la fereastra aplicaţiei a butoanelor şi a etichetei se face în constructorul clasei IUG.lab.CENTER). Dacă facem click de mouse pe oricare din butoane.add(b4.java. . ascultătorul de acţiune ac. Punând în execuţie această aplicaţie.add(lab.eticheta din zona SOUTH face parte din clasa javax.pentru a fi totalizat numărul de apăsări al tuturor butoanelor. de asemenea.SOUTH).swing. instanţă a clasei AC. Instanţele acestei clase au ca principal rol afişarea pe suprafaţa lor a unui text şi/sau a unei pictograme. WEST.clasa ButonContor extinde clasa JButton şi implementează interfaţa ActionListener.Programarea orientata pe obiecte în limbajul Java b4. iug. . În constructorul acestei clase există instrucţiunea addActionListener(this). cp. } } static class AA implements ActionListener { public void actionPerformed(ActionEvent e) { totalActionari++. astfel că fiecare buton îşi ascultă propriile evenimente de acţiune. BorderLayout. cp. BorderLayout. de asemenea. Putem urmări. . } } public static void main(String args[]) { } } Remarcăm următoarele: .în metoda actionPerformed(ActionEvent e) din clasa ButonContor se incrementează contorul intern al butonului respectiv şi se afişează valoarea contorului pe suprafaţa butonului. care incrementează câmpul total al clasei Butoane.în constructorul clasei imbricate IUG se adaugă câte un ButonContor în fiecare din zonele NORTH. se modifică atât contorul afişat pe butonul respectiv.

Este posibil să se specifice modul de aliniere a componentelor: la stânga. Numărul de componente pe o linie depinde de lăţimea componentelor şi de lăţimea containerului în care sunt acestea plasate. In fereastra aplicatiei apar mai multe butoane din clasa ButonContor si un buton de anulare.awt. în ordinea în care acestea sunt adăugate. static class IUG extends JFrame { JLabel lab=new JLabel("Actionati butoanele").*.awt. Când s-a terminat o linie.Severin Bumbaru Clasa FlowLayout Gestionarul de poziţionare java. // ascultatorul de fereastra static Anulare anulare=new Anulare(). // ascultatorul // butonului de anulare static IUG iug. a carui apasare anulaza toate contoarele. 222 . // fereastra aplicatiei static int numarButoane. În fereastra aplicaţiei sunt plasate mai multe butoane din clasa ButonContor şi un buton de anulare a tuturor contoarelor. în care se testează gestionarul de poziţionare FlowLayout. class ButoaneF { static AF af=new AF(). ca parametru în linia de comanda. fie invocând metoda public void setAlignement(int align) în care argumentul align poate fi FlowLayout. Îtrucât la crearea gestionarului de poziţionare nu s-a precizat alinierea componentelor. import java. putem constata cum se modifică în mod corespunzator dimensiunile şi amplasarea butoanelor.CENTER. se trece la linia următoare. IUG(String titlu) { // constructorul ferestrei aplicatiei super(titlu). Exemplul 1 În fişierul ButoaneF. /* Testarea gestionarului de pozitionare FlowLayout. JButton br=new JButton("Reset").RIGHT sau FlowLayout.event. Aceasta se face fie specificând alinierea ca argument al constructorului. modul de aliniere este implicit CENTER.*. Modificând cu mouse-ul dimensiunile ferestrei.java este dat un exemplu de aplicaţie.*.swing. import javax. Numărul de butoane de contorizare este dat la punerea în execuţie a aplicatiei. la dreapta sau la centru.awt. ButonContor bc[]. de la stânga la dreapta şi de sus în jos.LEFT. FlowLayout. La lansarea in executie se da ca parametru in linia de comanda numarul de butoane de contorizare */ import java.FlowLayout plasează componentele pe suprafaţa containerului una după alta.

după adăugarea butoanelor de contorizare. } } static class AF extends WindowAdapter { public void windowClosing(WindowEvent e) { System.java şi se deosebeşte de aceasta prin următoarele: . cât şi butoanele respective. for(int i=0. } } public static void main(String args[]) throws Exception { if(args. . din clasa JButton. i++) iug. // crearea ferestrei aplicatiei } } Remarcăm că aplicaţia ButoaneF este o modificare a aplicaţiei Butoane din fişierul Butoane. Atât acest tablou. System. se creează în constructorul clasei IUG. // setarea gestionarului // de pozitionare bc=new ButonContor[numarButoane].add(br).150). care implementează interfaţa ActionListener.setLayout(new FlowLayout()).reset().în metoda main se preia un argument din linia de comandă.exit(0).pentru ascultarea acţionării butonului de anulare. se adaugă la fereastra aplicaţiei butonul de anulare br. . // crearea butoanelor cp. // adaugarea butoanelor la contentPane } cp. a fost declarată clasa imbricată Anulare. addWindowListener(af).Programarea orientata pe obiecte în limbajul Java Container cp=getContentPane().s-a introdus tabloul bc[] care conţine referinţe la instanţele clasei ButonContor. } numarButoane=Integer. cp.exit(1). // crearea tabloului de // butoane iug=new IUG("FlowLayout cu "+numarButoane+ " butoane de contorizare").println("Utilizare: java ButoaneF <numarButoane>"). care trebuie să fie numărul de butoane de acţionare solicitat de utilizator.addActionListener(anulare).length!=1) { System. // adaugarea butonului de anulare br. // adaugarea ascultatorului setVisible(true).bc[i]. i<numarButoane. setLocation(200. } } static class Anulare implements ActionListener { public void actionPerformed(ActionEvent e) { for(int i=0. i++) { bc[i]=new ButonContor("B"+(i+1)).150).out. setSize(300. i<numarButoane.add(bc[i]). .parseInt(args[0]). după care se construieşte fereastra aplicaţiei. 223 .

java este dată o modificare a aplicaţiei din exemplul precedent. în metoda actionPerformed() a clasei imbricate de ascultare a evenimentelor de acţiune Actiuni s-a invocat metoda getActionCommand()a clasei ActionEvent. La lansarea in executie se da ca parametru in linia de comanda numarul de butoane de contorizare Actionarea unuia din butoanele de aliniere are ca efect modificarea corespunzatoare a alinierii componentelor pe suprafata containerului Actionarea butonului de anulare produce anuloarea tuturor contoarelor. totuşi. în mod obisnuit. /* Testarea alinierii componentelor cand se foloseste gestionarul de pozitionare FlowLayout.*. // ascultatorul de fereastra static Actiuni actiuni=new Actiuni(). // ascultatorul // butoanelor de aliniere si de anulare static IUG iug. care există în toate clasele care generează evenimente de acţiune. static FlowLayout layout=new FlowLayout(). de exemplu în clasa AbstractButton. din care este derivată şi clasa JButton. Este posibil.Modificarea alinierii se face invocând pentru gestionarul de poziţionare metoda setAlignment(int align) a clasei FlowLayout. să se modifice acest şir folosind metoda setActionCommand(String command). */ import java. trei butoane de aliniere si un buton de anulare.awt. . // fereastra aplicatiei static int numarButoane. în care sau introdus trei butoane suplimentare. În acest scop: . import java.*. In fereastra aplicatiei apar mai multe butoane din clasa ButonContor.swing. Dupa ce s-a aplicat această metodă. Această metodă întoarce un String care.*. 224 .event. pentru a se aplica efectiv noua poziţionare.Severin Bumbaru Exemplul 2 În fişierul Aliniere. IUG(String titlu) { // constructorul ferestrei aplicatiei super(titlu). ButonContor bc[]. import javax. JButton bas=new JButton("Stanga"). care au ca efect modificarea alinierii butoanelor pe suprafaţa containerului. este textul de pe butonul respectiv. bad=new JButton("Dreapta"). class Aliniere { static AF af=new AF(). se invocă pentru conţinutul ferestrei (contentPane) metoda doLayout() a clasei Container.awt.Pentru a se afla care buton a fost acţionat. bac=new JButton("Centru"). static class IUG extends JFrame { JLabel lab=new JLabel("Actionati butoanele"). JButton br=new JButton("Anulare").

length!=1) { System. cp. i<numarButoane.reset().addActionListener(actiuni).doLayout().equals("Centru")) layout.Programarea orientata pe obiecte în limbajul Java Container cp=getContentPane(). setLocation(200.addActionListener(actiuni).equals("Dreapta")) layout. // adaugarea butonului de anulare br.equals("Anulare")) for(int i=0.out.setAlignment(FlowLayout. else { if(comanda. } } } public static void main(String args[]) throws Exception { if(args. if(comanda. bac. // adaugarea butoanelor la contentPane } cp.parseInt(args[0]).exit(1).add(bas). // setarea gestionarului de pozitionare bc=new ButonContor[numarButoane].150).println("Utilizare: java Aliniere <numarButoane>"). else if(comanda.equals("Stanga")) layout. bad. } numarButoane=Integer. for(int i=0.bc[i].150). else if(comanda.setAlignment(FlowLayout. // crearea butoanelor cp.addActionListener(actiuni).LEFT).RIGHT). addWindowListener(af). // crearea tabloului de // butoane iug=new IUG("FlowLayout cu "+numarButoane+ " butoane de contorizare"). setVisible(true).exit(0). } } static class Actiuni implements ActionListener { public void actionPerformed(ActionEvent e) { String comanda=e. iug.addActionListener(actiuni).setAlignment(FlowLayout. // adaugare butoane // de aliniere cp.add(bc[i]). i<numarButoane. setSize(300. } } static class AF extends WindowAdapter { public void windowClosing(WindowEvent e) { System. i++) { bc[i]=new ButonContor("B"+(i+1)).add(bad).getActionCommand().add(bac).add(br).CENTER).getContentPane(). // adaugarea ascultatorului bas. // crearea ferestrei aplicatiei } } 225 .setLayout(layout). cp. System. i++) iug. cp.

Severin Bumbaru Clasa GridLayout Gestionarele de poziţionare din clasa java. în realitate numai numărul de linii este respectat.GridLayout plasează componentele în celulele unei grile rectangulare. class Grila { static AF af=new AF(). /* Testarea alinierii componentelor cand se foloseste gestionarul de pozitionare GridLayout. La punerea în execuţie a aplicaţiei. dacă se modifică cu mouse-ul dimensiunile acesteia.awt. dar respectând alinierea verticală şi orizontală impusă de grilă.are în plus ca coloane al grilei. în timp ce numărul de coloane este practic ignorat. În consecinţă.*. int vgap) argumente spaţiul orizontal şi. cât şi cel de coloane ale grilei.are ca argumente numărul de linii şi de . */ import java. la fel ca în cazul gestionarului FlowLayout. Plasarea efectivă a componentelor în celulele grilei astfel creeate se face apoi de la stânga la dreapta şi de sus in jos.java se dă un exemplu de aplicaţie.*. toate componentele de pe aceeaşi coloană sunt aliniate vertical. toate componentele vor fi aşezate vertical.swing. Se poate verifica şi ce se întâmplă dacă numărul de coloane dat ca parametru este mai mic sau mai mare decât cel necesar. numărul de coloane se stabileşte automat. respectiv. Exemplu În fişierul Grila. cu rotunjire în plus.*. import javax. Punerea in executie a aplicatiei se face prin comanda java Grila <numarContoare> <nrLinii> <nrColoane> Actionarea butonului de anulare produce anuloarea tuturor contoarelor.awt. Deşi în constructor se indică atât numărul de linii. int cols. vertical între componente. Dacă numărul de componente este mai mare decât numărul de linii. int cols) . dacă numarul lor total este mai mic sau egal cu cel de linii.awt. în care se testează gestionarul de poziţionare GridLayout. Se poate observa ordinea în care sunt butoanele aşezate pe grilă şi modul în care se schimbă aspectul ferestrei. int hgap. import java. public GridLayout(int rows.event. prin împărţirea numărului de componente la cel de linii. numărul de linii al grilei şi numărul de coloane. La stabilirea amplasării componentelor în container. In fereastra aplicatiei apar mai multe butoane din clasa ButonContor si un buton de anulare. se dau ca parametri în linia de comandă numărul total de butoane de contorizare. una sub alta. // ascultatorul de fereastra 226 . Clasa are doi constructori: public GridLayout(int rows.

setLocation(200. // setarea // gestionarului de pozitionare bc=new ButonContor[numarButoane]. i++) { bc[i]=new ButonContor("B"+(i+1)).parseInt(args[2]).exit(0). Container cp=getContentPane().length!=3) { System. } } static class Actiuni implements ActionListener { public void actionPerformed(ActionEvent e) { String comanda=e. } } static class AF extends WindowAdapter { public void windowClosing(WindowEvent e) { System. ButonContor bc[]. nrLinii. for(int i=0. cp. nrColoane)). i<numarButoane.bc[i].add(br).println( "Utilizare: java <numarButoane> <nrLinii> <nrColoane>"). } } 227 . setSize(400. i<numarButoane. // adaugarea ascultatorului setVisible(true). nrColoane. IUG(String titlu) { // constructorul ferestrei aplicatiei super(titlu).parseInt(args[1]). if(comanda.addActionListener(actiuni).exit(1).add(bc[i]). /* Crearea ferestrei aplicatiei */ iug=new IUG("GridLayout cu "+numarButoane+ " butoane de contorizare"). nrColoane=Integer.equals("Anulare")) for(int i=0.150). // fereastra aplicatiei static int numarButoane. i++) iug. // ascultatorul // butonului de anulare static IUG iug. // adaugarea butonului de anulare br.getActionCommand(). // crearea butoanelor cp.reset(). static class IUG extends JFrame { JLabel lab=new JLabel("Actionati butoanele"). System. JButton br=new JButton("Anulare"). addWindowListener(af). } /* Preluarea argumentelor din linia de comanda */ numarButoane=Integer.parseInt(args[0]).Programarea orientata pe obiecte în limbajul Java static Actiuni actiuni=new Actiuni(). // adaugarea butoanelor la contentPane } cp. } } public static void main(String args[]) throws Exception { /* Verificarea numarului de argumente din linia de comanda */ if(args. nrLinii=Integer.out.setLayout(new GridLayout(nrLinii.250).

Se poate urmări efectul modificării cu mouse-ul a dimensiunilor ferestrei.event. De exemplu. La lansarea aplicaţiei în execuţie. fără a mai fi influenţate de dimensiunile ferestrei. import java.java se dă un exemplu de aplicaţie. class ButoaneBox { static AF af=new AF(). Se observă că dimensiunile componentelor rămân constante. Constructorul clasei este public BoxLayout(Container target. toate plasate unul sub altul */ import java.BoxLayout plasează toate componentele containerului pe o singură direcţie.*.swing. comanda java ButoaneBox 5 Y are ca efecte punerea in executie a aplicatiei cu 5 butoane contor si un buton de anulare. // ascultatorul de fereastra static Anulare anulare=new Anulare().awt. 228 . // ascultatorul // butonului de anulare static IUG iug. se indică numărul de butoane de contorizare şi direcţia după care acestea vor fi plasate (x sau y). a carui apasare anulaza toate contoarele. gestionarul BoxLayout a fost folosit direct în containerul contentPane al ferestrei aplicaţiei. Exemplul 1 În fişierul ButoaneBox. /* Testarea gestionarului de pozitionare BoxLayout. static class IUG extends JFrame { JLabel lab=new JLabel("Actionati butoanele").*. // fereastra aplicatiei static int numarButoane. import javax. în care se testează clasa BoxLayout. static int axa.*. int axis) în care target este o referinţa la containerul ţintă (al cărui gestionar de poziţionare este creat). La lansarea in executie se da ca parametru in linia de comanda numarul de butoane de contorizare si numele axei in lungul careia vor fi plasate componentele (X sau Y). care poate fi orizontală sau verticală.awt. iar axis poate fi BoxLayout. In fereastra aplicatiei apar mai multe butoane din clasa ButonContor si un buton de anulare.Severin Bumbaru Clasa BoxLayout Gestionarul de poziţionare javax.X_AXIS sau BoxLayout.Y_AXIS şi indică direcţia (axa) după care vor fi plasate componentele.swing. În acest caz.

Programarea orientata pe obiecte în limbajul Java

ButonContor bc[]; JButton br=new JButton("Reset"); IUG(String titlu) { // constructorul ferestrei aplicatiei super(titlu); Container cp=getContentPane(); setSize(350,350); setLocation(200,150); addWindowListener(af); cp.setLayout(new BoxLayout(getContentPane(), axa)); bc=new ButonContor[numarButoane]; for(int i=0; i<numarButoane; i++) { bc[i]=new ButonContor("B"+(i+1)); // crearea butoanelor cp.add(bc[i]); // adaugarea butoanelor la contentPane } cp.add(br); // adaugarea butonului de anulare br.addActionListener(anulare); // adaugarea ascultatorului setVisible(true); } } static class AF extends WindowAdapter { public void windowClosing(WindowEvent e) { System.exit(0); } } static class Anulare implements ActionListener { public void actionPerformed(ActionEvent e) { for(int i=0; i<numarButoane; i++) iug.bc[i].reset(); } } public static void main(String args[]) throws Exception { if(args.length!=2 ) { System.out.println( "Utilizare: java ButoaneBox <numarButoane> <axa>"); System.exit(1); } String numeAxa=args[1].toUpperCase(); if(numeAxa.equals("Y")) axa=BoxLayout.Y_AXIS; else if(numeAxa.equals("X")) axa=BoxLayout.X_AXIS; else { System.out.println("Axa nu poate fi decat X sau Y"); System.exit(1); } numarButoane=Integer.parseInt(args[0]); iug=new IUG("BoxLayout cu "+numarButoane+ " butoane de contorizare"); } }

În loc de a folosi gestionarul BoxLayout într-un container oarecare, se preferă să se foloseasca clasa javax.swing.Box, care are acest gestionar implicit.

229

Severin Bumbaru Exemplul 2 În fişierul TestBox.java se dă o variantă a aplicaţiei din exemplul precedent, în care se utilizează drept container pentru butoane o instanţă a clasei Box. În constructorul ferestrei aplicaţiei, după ce se creeaza această instanţă a clasei Box, se adaugă la ea succesiv toate componentele, după care este ea însăşi adaugată la conţinutul ferestrei aplicaţiei (la contentPane). În această situaţie, gestionarul de poziţionare BoxLayout este folosit prin intermediul instanţei clasei Box, în care sunt plasate componentele.
/* Testarea clasei javax.swing.Box In fereastra aplicatiei apar mai multe butoane din clasa ButonContor si un buton de anulare, a carui apasare anulaza toate contoarele. La lansarea in executie se da ca parametru in linia de comanda numarul de butoane de contorizare si numele axei in lungul careia vor fi plasate componentele (X sau Y). De exemplu, comanda java TestBox 5 Y are ca efecte punerea in executie a aplicatiei cu 5 butoane contor si un buton de anulare, toate plasate unul sub altul */

import java.awt.*; import java.awt.event.*; import javax.swing.*; class TestBox { static AF af=new AF(); // ascultatorul de fereastra static Anulare anulare=new Anulare(); // ascultatorul // butonului de anulare static IUG iug; // fereastra aplicatiei static int numarButoane; static int axa; static class IUG extends JFrame { JLabel lab=new JLabel("Actionati butoanele"); ButonContor bc[]; JButton br=new JButton("Reset"); Box box; IUG(String titlu) { // constructorul ferestrei aplicatiei super(titlu); setSize(350,350); setLocation(200,150); addWindowListener(af); box=new Box(axa); // se creeaza o instanta a clasei Box // orientata pe directia axa bc=new ButonContor[numarButoane]; for(int i=0; i<numarButoane; i++) { bc[i]=new ButonContor("B"+(i+1)); // crearea butoanelor box.add(bc[i]); // adaugarea butoanelor la caseta box } box.add(br); // adaugarea butonului de anulare br.addActionListener(anulare); // adaugarea ascultatorului getContentPane().add(box); // adaugarea casetei box la

230

Programarea orientata pe obiecte în limbajul Java

// contentPane setVisible(true); } } static class AF extends WindowAdapter { public void windowClosing(WindowEvent e) { System.exit(0); } } static class Anulare implements ActionListener { public void actionPerformed(ActionEvent e) { for(int i=0; i<numarButoane; i++) iug.bc[i].reset(); } } public static void main(String args[]) throws Exception { if(args.length!=2 ) { System.out.println( "Utilizare: java Box <numarButoane> <axa>"); System.exit(1); } String numeAxa=args[1].toUpperCase(); if(numeAxa.equals("Y")) axa=BoxLayout.Y_AXIS; else if(numeAxa.equals("X")) axa=BoxLayout.X_AXIS; else { System.out.println("Axa nu poate fi decat X sau Y"); System.exit(1); } numarButoane=Integer.parseInt(args[0]); iug=new IUG("Box cu "+numarButoane+ " butoane de contorizare"); } }

Poziţionarea absolută a componentelor în container
În general, este recomandabil ca pentru amplasarea componentelor în containere să se folosească gestionari de poziţionare. În acest fel se asigură modificarea automată a poziţiei şi dimensiunilor componentelor, atunci când se modifică dimensiunile containerului. Există totuşi situaţii, în care se preferă ca poziţiile şi dimensiunile componentelor să fie fixe şi să fie indicate prin program. Din această cauză, în afară de amplasarea flexibilă a componentelor în containere, folosind clasele de gestionare a poziţionării, este posibil să se proiecteze şi interfeţe grafice în care poziţionarea componentelor se face folosind coordonatele şi dimensiunile absolute ale acestora. În acest scop: a/ pentru a se indica faptul că nu se foloseşte un gestionar de poziţionare, se recurge la instrucţiunea: setLayout(null); b/ pentru stabilirea coordonatelor colţului din stânga sus şi dimensiunilor fiecărei componente se foloseşte metoda
public void setBounds(int x, int y, int width, int height);

231

Severin Bumbaru din clasa java.awt.Component. În acest mod, fiecare componentă este plasată în container cu colţul stânga-sus în punctul de coordonate (x,y)şi are dimensiunile date prin lăţimea width şi înălţimea height. În locul metodei setBounds se pot folosi şi metodele
public void setLocation(Point location) public void setSize(int latime, int inaltime)

care există, de asemenea, în clasa Component şi permit setarea separată a poziţiei şi dimensiunilor componentelor. Poziţia şi dimensiunile astfel stabilite ale componentelor rămân neschimbate, chiar dacă se modifică dimensiunile containerului care le conţine.

Exemplu: În fişierul PozAbs.java se dă un exemplu de aplicaţie, în care se recurge la poziţionarea absolută a componentelor pe suprafaţa ferestrei principale a aplicaţiei, care este o instanţă a clasei JFrame. În fereastră (mai exact în containerul contentPane al ferestrei) se plasează următoarele componente: - o etichetă cu textul "Butoane de contorizare"; - patru butoane de contorizare ale clasei ButonContor, creată de noi anterior; - o etichetă cu textul "Anularea tuturor contoarelor >>>"; - un buton din clasa JButton cu inscriptia "Reset", care serveşte aici pentru a comanda punerea la zero a tuturor contoarelor. Pentru a realiza poziţionarea absolută a acestor componente, se seteaza la null gestionarul de poziţionare al containerului contentPane conţinut în fereastra aplicaţiei, iar pentru fiecare componentă se indică poziţia şi dimensiunile, invocând metoda setBounds().

/* Pozitionarea absoluta a componentelor in container */ import java.awt.*; import java.awt.event.*; import javax.swing.*; class PozAbs { static AF af=new AF(); // ascultatorul de fereastra static AA aa=new AA(); // ascultatorul de actiuni static IUG iug=new IUG("Pozitionare absoluta"); static class IUG extends JFrame { JLabel et1=new JLabel("Butoane de contorizare"); JLabel et2=new JLabel("Anularea tuturor contoarelor >>>"); JButton br=new JButton("Reset"); int numarContoare=4; ButonContor bc[]=new ButonContor[numarContoare]; /* Constructorul ferestrei aplicatiei */

232

Programarea orientata pe obiecte în limbajul Java

IUG(String titlu) { super(titlu); Container cp=getContentPane(); setSize(420,220); setLocation(200,150); addWindowListener(af); cp.setLayout(null); // se elimina gestionarul de pozitionare din // contentPane et1.setBounds(150, 5, 160,10); // pozitia si dimensiunile etichetei cp.add(et1); // adaugarea etichetei for(int i=0; i<numarContoare; i++) { bc[i]=new ButonContor("B"+i); // crearea butoanelor-contor bc[i].setBounds(10+100*i, 20, 90,70); // stabilirea pozitiei // si dimensiunilor butoanelor-contor cp.add(bc[i]); // adaugarea butoanelor-contor la contentPane } et2.setBounds(10, 140, 200,10); // locul si dimens. etichetei 2 cp.add(et2); // adaugarea etichetei 2 la contentPane br.setBounds(210, 120, 70, 60); // pozitia si dimensiunile // butonului de anulare br.addActionListener(aa); // ascultarea butonului de anulare cp.add(br); // adaugarea butonului de anulare la contentPane setVisible(true); } } /* Ascultatorul actiunilor butonului de anulare. Cand este apasat acest buton, se pun la zero toate contoarele */ static class AA implements ActionListener { public void actionPerformed(ActionEvent e) { for(int i=0; i<iug.numarContoare; i++) iug.bc[i].reset(); } } /* Ascultarea evenimentelor de fereastra */ static class AF extends WindowAdapter { public void windowClosing(WindowEvent e) { System.exit(0); } } public static void main(String args[]) { } }

Gruparea componentelor
Pentru a poziţiona componentele în structuri mai complicate decât cele oferite de clasele de gestionare a poziţiei existente, se poate recurge la gruparea mai multor componente în containere auxiliare, care se plasează apoi în containerul principal. Drept containere auxiliare, se folosesc cel mai frecvent instanţe ale claselor java.awt.Panel, javax.swing.JPanel şi javax.swing.Box.

233

Severin Bumbaru

Clasele Panel si Jpanel
Clasa java.awt.Panel (panou) reprezinta cel mai simplu container, care este o suprafaţă dreptunghiulară fără bordură. Gestionarul de poziţionare implicit este FlowLayout, dar se poate pune oricare altul. Panourile sunt frecvent folosite pentru a plasa pe ele diferite componente, formând un grup care se plaseaza apoi într-un alt container. Clasa javax.swing.JPanel este varianta de Panel folosită în JFC/Swing, fiind un container genreric. Exemplu În fişierul Panouri.java este dat un exemplu în care fereastra aplicaţiei, cu gestionar de pozitionare GridLayout, conţine în cele patru celule ale reţelei două panouri şi două butoane de anulare. Un panou conţine 5 butoane de contorizare amplasate cu gestionar BorderLayout, iar alt panou conţine trei butoane de contorizare amplasate cu FlowLayout (gestionarul implicit). Fiecare buton de anulare pune la zero contoarele de apăsări dintr-un panou.

import java.awt.*; import java.awt.event.*; import javax.swing.*; class Panouri { static ButonContor bc[]=new ButonContor[8]; static JButton br1=new JButton("Reset 1"), br2=new JButton("Reset 2"); static Anulare anulare=new Anulare(); static IUG iug=new IUG("Gruparea componentelor pe panouri"); static class IUG extends JFrame { JPanel p1=new JPanel(); // p1 are implicit FlowLayout JPanel p2=new JPanel(new BorderLayout()); // p2 primeste BorderLayout IUG(String titlu) { super(titlu); Container cp=getContentPane(); setSize(500,400); addWindowListener(new AF()); cp.setLayout(new GridLayout(2,2)); /* Crearea butoanelor */ for(int i=0; i<8; i++) bc[i]=new ButonContor("B"+i); /* Completarea cu butoane a panoului p2 */ p2.add(bc[0], BorderLayout.NORTH); p2.add(bc[1], BorderLayout.WEST); p2.add(bc[2], BorderLayout.CENTER); p2.add(bc[3], BorderLayout.EAST); p2.add(bc[4], BorderLayout.SOUTH); /* Completarea panoului p1 */ for(int i=5; i<8; i++) p1.add(bc[i]); /* Adaugarea de ascultatori la butoanele de anulare */ br1.addActionListener(anulare); br2.addActionListener(anulare); /* Adaugarea de panouri si butoane la controlPane */ cp.add(p2); cp.add(p1); cp.add(br1);

234

Programarea orientata pe obiecte în limbajul Java

cp.add(br2); setVisible(true); } } static class AF extends WindowAdapter { public void windowClosing(WindowEvent e) { System.exit(0); } } static class Anulare implements ActionListener { public void actionPerformed(ActionEvent e) { String actiune=e.getActionCommand(); if(actiune.equals(br1.getText())) for(int i=0; i<5; i++) bc[i].reset(); else if(actiune.equals(br2.getText())) for(int i=5; i<8; i++) bc[i].reset(); } } public static void main(String args[]) { } }

Clasa Box
Clasa javax.swing.Box are ca instanţe containere speciale, care nu pot folosi decât gestionarul de poziţionare javax.swing.BoxLayout. Orice incercare de a-i pune alt gestionar produce o eroare de execuţie din clasa AWTError. Într-un container din clasa Box, componentele pot fi amplasate numai pe o singură direcţie: orizontală sau verticală.

Clasa dispune de metode statice pentru crearea de "casete" (instanţe ale clasei Box) orizontale sau verticale:
public static Box createHorizontalBox() public static Box createVerticalBox()

Se pot creea, de asemenea "componente invizibile" de dimensiuni fixe sau variabile, care pot fi folosite la distanţarea componentelor vizibile. În acest scop, se folosesc metodele public static Component createRigidArea(Dimension d) - creeaza o "componentă ascunsă" de dimensiune fixă; public static Component createHorizontalStrut(int width) - creeaza o "componentă ascunsă" de lăţime fixă, dar de înălţime variabilă; public static Component createVerticalStrut(int height) - creeaza o "componentă ascunsă" de înalţime fixă, dar de lăţime variabilă; public static Component createGlue() - creaza o "componentă ascunsă" cu ambele dimensiuni variabile;

235

Severin Bumbaru Combinarea adecvată de containere din clasa Box şi folosirea în acestea a diferitelor componente vizibile şi ascunse permite crearea de interfeţe grafice cu aspecte foarte diversificate.

Exemplu În fişierul Casete.java este dată o aplicaţie în care se folosesc trei casete din clasa Box: două verticale şi una orizontală.

/* Exemplu de utilizare a containerelor din clasa javax.swing.Box */ import java.awt.*; import java.awt.event.*; import javax.swing.*; class Casete { static ButonContor bc[]=new ButonContor[5]; static JButton br1=new JButton("Reset 1"), br2=new JButton("Reset 2"); static Anulare anulare=new Anulare(); static IUG iug=new IUG("Gruparea componentelor in casete"); static class IUG extends JFrame { Box c1=Box.createVerticalBox(); Box c2=Box.createVerticalBox(); Box c3=Box.createHorizontalBox(); IUG(String titlu) { super(titlu); setSize(280,160); addWindowListener(new AF()); /* Crearea butoanelor */ for(int i=0; i<5; i++) bc[i]=new ButonContor("B"+i); /* Completarea cu butoane a casetei c1 */ c1.add(Box.createVerticalStrut(18)); // deplasare in jos c1.add(bc[0]); c1.add(bc[1]); c1.add(Box.createVerticalStrut(10)); // deplasare in jos c1.add(br1); /* Completarea casetei c2 */ for(int i=2; i<5; i++) c2.add(bc[i]); c2.add(Box.createVerticalStrut(5)); // deplasare in jos c2.add(br2); /* Adaugarea de ascultatori la butoanele de anulare */ br1.addActionListener(anulare); br2.addActionListener(anulare); /* Adaugarea casetelor c1 si c2 la caseta c3 */ c3.add(Box.createGlue()); // pentru alinierea la centru c3.add(c1); c3.add(Box.createHorizontalStrut(10)); c3.add(c2); /* Adaugarea casetei c3 la contentPane */ getContentPane().add(c3); setVisible(true);

236

Programarea orientata pe obiecte în limbajul Java

} } static class AF extends WindowAdapter { public void windowClosing(WindowEvent e) { System.exit(0); } } static class Anulare implements ActionListener { public void actionPerformed(ActionEvent e) { String actiune=e.getActionCommand(); if(actiune.equals(br1.getText())) for(int i=0; i<2; i++) bc[i].reset(); else if(actiune.equals(br2.getText())) for(int i=2; i<5; i++) bc[i].reset(); } } public static void main(String args[]) { } }

Remarcăm următoarele: - butoanele au fost plasate în cele două casete verticale, c1 şi c2; - întrucât numărul de butoane din cele două casete este diferit, în caseta c1 s-a introdus o componentă ascunsă pentru alinierea la partea inferioară. De asemenea, în ambele casete verticale s-au introdus în faţa ultimului buton componente ascunse pentru distanţare; - cele două casete verticale au fost introduse în cea orizontală; - componenta ascunsă cu dimensiuni variabile, introdusă în faţa primei casete din c3, a fost pusă pentru a se obţine alinierea pe centru a casetelor c1 şi c2. În lipsa acesteia, caseta c1 ar fi fost aliniată la stânga; - caseta c3 a fost introdusă în contentPane. Urmăriţi ce se întâmplă când modificaţi cu mouse-ul dimensiunile ferestrei aplicaţiei.

Întrebări
Nivel 1
1. 2. 3. 4. 5. 6. 7. 8. 9. Ce este interfaţa utilizator? Ce este interfaţa utilizator grafică? Ce sunt obiectele grafice? Ce este AWT? Ce este JFC/Swing? Ce rol are clasa Component şi din ce pachet face parte? Ce deosebire este între componentele atomice şi containere? Care este clasa folosită în JFC/Swing pentru fereastra principală a aplicaţiei? Ce conţin la partea superioară instanţele clasei JFrame?

237

Severin Bumbaru 10. Ce sunt evenimentele în cazul interfeţei utilizator grafice? 11. Ce este programarea orientată pe evenimente? 12. Care este modelul de evenimente folosit pe platforma Java 2? 13. Cum sunt generate evenimentele? 14. Cum sunt utilizate evenimentele? 15. Ce deosebire este între evenimentele de nivel jos şi cele semantice? 16. Care este rădăcina claselor de evenimente generate de obiectele interfeţei grafice? 17. Ce clase de evenimente cunoasteţi? 18. În ce pachete se găsesc clasele de evenimente? 19. Ce sunt interfeţele pentru ascultarea de evenimente şi la ce folosesc? 20. Care este rolul unei clase ascultătoare de evenimente? 21. Ce este un adaptor pentru ascultarea de evenimente? 22. Cum poate fi comandată prin interfaţa utilizator grafică încheierea executării aplicaţiei? 23. Care este componenta instanţei clasei JFrame la care se adaugă componentele interfeţei grafice? 24. Ce este un gestionar de poziţionare? 25. Care sunt interfeţele gestionarilor de poziţionare? 26. Care este gestionarul de poziţionare implicit pentru contentPane? 27. Care este gestionarul de poziţionare implicit pentru Panel şi JPanel? 28. Cum sunt amplasate componentele în cazul gestionarului BorderLayout? 29. Cum sunt amplasate componentele în container în cazul gestionarului FlowLayout? 30. Cum sunt aliniate componentele în cazul gestionarului FlowLayout? 31. Ce fel de evenimente generează un buton? 32. Cum sunt amplasate componentele în cazul gestionarului GridLayout? 33. Cum se stabileste numarul de linii şi de coloane pentru gestionarul GridLayout? 34. Cum sunt plasate componentele într-un BoxLayout?

Nivel 2
1. Ce categorii de interfeţe utilizator cunoasteţi? 2. Ce este un limbaj de comandă şi ce astfel de limbaje cunoasteţi? 3. Care sunt în prezent cele mai larg folosite interfeţe utilizator grafice? 4. Prin ce pachete se realizează AWT pe platformele Java? 5. Prin ce pachete se realizează JFC/Swing pe platforma Java 2? 6. In ce constă deosebirea de abordare între AWT şi JFC/Swing? 7. Ce metode ale clasei Component cunoasteţi? 8. Ce metode ale clasei JFrame cunoasteţi? 9. Cum este ghidat procesul de calcul în programarea procedurală tradiţională? 10. Cine are iniţiativa acţiunilor în programarea orientată pe evenimente? 11. Care sunt obiectele care intervin atunci când se generează un eveniment? 12. Ce sunt evenimentele de mouse şi cum sunt ele generate? 13. Ce sunt evenimentele de tastă şi cum sunt ele generate? 14. Care sunt evenimentele generate de o fereastră şi cum sunt ele ascultate? 15. Care sunt evenimentele de mouse? 16. Cum sunt ascultate evenimentele de mouse? 17. Care sunt evenimentele de tasta? 18. Cum sunt ascultate evenimentele de tasta? 19. În ce stare trebuie sa fie fereastra pentru a genera evenimente de tastă?

238

Ce reprezintă clasa Box? 36. Ce fel de containere auxiliare se folosesc pentru gruparea componentelor? 34. Cum se adaugă un ascultător la o sursă? 22. Care sunt zonele unui BorderLayout şi câte componente pot fi plasate în fiecare zonă? 24. Ce se întâmplă în cazul gestionarului GridLayout. Ce se înţelege prin poziţionarea absolută a componentelor? 31.Programarea orientata pe obiecte în limbajul Java 20. dacă numarul de componente conţinute este mai mare decât numărul de celule ale grilei stabilite la crearea containerului? 28. Cum pot fi create instanţele clasei Box? 37. Ce se întâmplă cu componentele unui container cu gestionar FlowLayout. În ce ordine se plasează componentele adăugate la un container cu gestionar GridLayout? 29. Ce se întâmplă cu componentele unui container cu gestionar BorderLayout dacă se modifică dimensiunile acestuia? 25. Ce legatură există între clasele Box şi BoxLayout? 30. Ce componente ascunse se pot pune într-un container din clasa Box? 239 . Ce este un Panel sau un JPanel? 35. cum se poate afla care din ele a fost acţionat atunci când este receptat un eveniment de acţiune? 26. Dacă într-un container există mai multe butoane. Poate un obiect grafic să-şi asculte propriile evenimente? Cum se programează aceasta? 23. dacă se modifică laţimea acestuia? 27. În ce clasă există metoda getContentPane() şi la ce foloseşte? 21. Ce metode se folosesc pentru poziţionarea absolută a componentelor? 33. Cum se setează gestionarul de poziţionare pentru a realiza poziţionarea absolută? 32.

O prezentare a acestor componente însoţită de ilustraţii sugestive şi de descrierea detaliată a utilizării fiecăreia se găseşte în lecţia Using Swing Components din sectiunea Creating a GUI 240 . 4. 3. Deosebim: 1. selectoare de culori. Componente de control: butoane. este necesar ca la fereastra aplicaţiei (din clasa JFrame) să se adauge diferite obiecte grafice numite componente. rigle ajustabile.Severin Bumbaru Componente grafice din JFC/Swing Componente ale interfeţei utilizator grafice Clasa JComponent Componente de control Butoane Clasa AbstractButton Butoane obişnuite (cu o singură stare stabilă) Butoane cu două stări stabile Casete de validare Butoane radio Liste Liste ascunse Câmpuri de text Rigle cu cursor Meniuri Meniuri cu bară Meniuri volante Componente de afişare Componente de afişare needitabile Componente de afişare editabile Întrebări. tabele editabile. Componente de afişare needitabile: etichete. liste ascunse. 2. casete de validare. etc. arbori. panouri glisante. liste. meniuri. indicatoare. câmpuri de text. butoane radio. etc. selectoare de fişiere. Containere: panouri. 240 241 244 244 244 245 245 246 246 249 250 253 256 258 258 260 262 262 263 265 Componentele din JFC/Swing Pentru a realiza interfaţa utilizator grafică a unei aplicaţii folosind JFC/Swing. Componente de afişare editabile: zone de text.

Specificaţia completă a clasei JComponent este dată in documentaţia Java API.Container.JComponent extinde clasa java. 241 . decât o scurta prezentare a unor componente mai larg folosite şi a modului lor de utilizare. iar o descriere amplă a facilităţilor şi modului de utilizare se găseşte în capitolul The JComponent class din tutorialul Java. câteva facilităţi pe care le ofera orice JComponentă: . iar uneori îşi schimbă şi aspectul.swing. O astfel de inscripţie se ataşează componentei prin metoda public void setToolTipText(String text). Caracteristicile componentelor JFC/Swing Fiecare componentă a interfeţei utilizator grafice se caracterizează prin aspect. Fiecare clasă de componente oferă un aspect tipic al instanţelor sale. Clasa JComponent Clasa abstracta javax. folosind metoda public void setBorder(Border border). Starea se poate modifica fie datorită acţiunilor utilizatorului. ca exemplu. Starea componentei este dată. Comportamentul componentei este modul în care aceasta reacţionează atunci cînd se acţionează asupra ei de către utilizator sau când este invocată o metodă şi constă în modificarea stării şi a aspectului şi în generarea de evenimente.Programarea orientata pe obiecte în limbajul Java with JFC/Swing din Java Tutorial. În JFC/Swing programatorului i se pun însa la dispoziţie metode şi clase prin care poate modifica aspectul componentelor. Aspectul este dat de figura prin care este reprezentată pe ecran componenta respectivă. adică o inscripţie explicativă care apare când punem cursorul de mouse pe componenta respectivă. . O specificaţie mai detaliată a clasei JComponent este dată în indexul de clase.posibilitatea de a-i pune componentei o bordură. stare şi comportament.posibilitatea de a modifica culoarea de fond şi culoarea de primplan ale componentei folosind metodele: public void setBackground(Color color). Majoritatea claselor de componente din JFC/Swing sunt derivate din clasa JComponent. fără să apăsăm butonul. orice componenta Swing are şi caracteristici de container. În general. Noi nu vom face aici. .awt.posibilitatea de a-i ataşa componentei o "inscripţie volanta" (engleză: ToolTip). Mai multe metode sunt indicate în Indexul de clase. fie datorită invocării prin program a unor metode ale acesteia. la modificarea stării componenta generează un eveniment. In consecinţă. ca la orice obiect. public void setForeground(Color color). moştenind caracteristicile acestei clase. din lipsă de timp. de valorile câmpurilor sale. Iată.

cu diferite aspecte: chenar simplu. public static CompoundBorder createCompoundBorder(Border outsideBorder.LOWERED. public static Border createRaisedBevelBorder() . Clasele de borduri şi interfaţa Border se gasesc în pachetul javax. unde: type .java este dat un exemplu de testare a posibilităţii de a stabili aspectul 242 .BorderFactory care oferă metode pentru crearea unor borduri standard.posibilitatea de a adăuga la fiecare componentă a unui text explicativ volant (engleză: Tool Tip). Pentru a ataşa componentei un text volant se foloseşte metoda clasei JComponent public void setToolTipText(String text).creeaza o bordură cu aspect de înălţare a componentei. indicându-se bordura exterioară (outsideBorder) şi cea interioara (insideBorder). int thickness) creează o bordură formată dintr-o linie de grosime (thickness) dată.tipul bordurii. . bordură care dă aspect de supraînălţare. .swing.creeaza o bordură cu titlu. public static Border createLoweredBevelBorder() .creeaza o bordură pentru care se impun tipul şi culorile. chenar cu titlu. Iată unele din metodele clasei BorderFactory: public static Border createLineBorder(Color color) .RAISED sau BevelBorder. public static Border createBevelBorder(int type. sau ambele.posibilitatea de a introduce în componentă un text.posibilitatea de a alege aspectul general al tuturor componentelor interfeţei grafice (engleză: Look and Feel).creeaza o bordură compusă. Border insideBorder) . care conţine indicaţii care apar când se pune cursorul mouse-ului pe componenta respectivă.culoarea marginii care creează aspectul de înălţare sau coborâre. public static TitledBorder createTitledBorder(String title) .culoarea umbrei. Pentru a pune o bordură se foloseşte clasa javax. bordură care dă aspect de scufundare.swing. Exemplu În fişierul TestComp. Color highlight.creeaza o bordura cu aspect de scufundare a componentei. Color shadow) .creează o bordură (un - chenar) dintr-o singură linie.posibilitatea de a pune în jurul componentei una sau mai multe borduri (engleză: Border). o imagine. fără a apăsa butonul de mouse. care poate fi BevelBorder.Severin Bumbaru Componentele din JFC/Swing oferă programatorului unele facilităţi importante privind stabilirea aspectului şi comportamentului acestora. public static Border createLineBorder(Color color. highlight .border. shadow . Iată unele ditre ele: . Adăugarea bordurii la componentă se face prin metoda clasei JComponent public void setBorder(Border border). .

cp.awt.cyan. deocamdată.add(b1).RAISED. javax. Color. 400). b2=new JButton("Un buton cu bordura liniara"). Border bord1.createBevelBorder(BevelBorder.swing.createLineBorder(Color.createLoweredBevelBorder()). b6=new JButton(new ImageIcon("buton_go.createTitledBorder( "Un buton cu titlu.b7. class TestComp { static AF af=new AF().setBorder(BorderFactory. bord1=BorderFactory.swing.*. //b1.gif")). cp.red. bord3=BorderFactory. Color. setSize(300.add(b5). b4.border.b2.createRaisedBevelBorder()). addWindowListener(af).setBorder(BorderFactory.setBorder(BorderFactory. /* clasa imbricata pentru interfata utilizator grafica */ static class IUG extends JFrame { //JLabel lab1.blue). Container cp=getContentPane(). lab3. static IUG iug=new IUG("Butoane cu diferite aspecte"). IUG(String titlu) { // constructorul clasei IUG super(titlu).Programarea orientata pe obiecte în limbajul Java componentelor şi a le ataşa texte volante. Acelaşi mod de lucru poate fi însă folosit pentru orice alte clase care sunt derivate din JComponent.b3.LOWERED. bord2). 243 . Color. b3=new JButton("Un buton cu bordura cu titlu").red). b4=new JButton("Un buton ridicat").add(b6). bord3. cp. cp. cp. b5=new JButton("Un buton coborat").yellow). Color. b1=new JButton("Un buton obisnuit").createTitledBorder("Un titlu")). b2. instanţe ale clasei JButton.b6.setBackground(Color. lab2. java.b4.createCompoundBorder(bord1. cp. b2.setToolTipText("Bordura este rosie cu grosimea 4"). b3. b7=new JButton("Un buton cu bordura compusa").createBevelBorder(BevelBorder. bord2.awt. b5.blue).setBorder(bord3).add(b7). bord2=BorderFactory.b5. javax. care contine o imagine")).green.*. lab4.add(b2).add(b4).setBorder(BorderFactory. setLocation(200. Drept componente s-au folosit.*. // adaugarea ascultatorului de fereastra //panel=new JPanel(). //JPanel panel.*. cp. b7. cp.setBorder(BorderFactory.setBackground(Color. JButton b1.add(b3).1)).setLayout(new GridLayout(7. import import import import java. setVisible(true). 4)).event. 150). //panel. care a mai fost deja utilizată în capitolul precedent. b6.

această imagine trebuie să existe în acelaşi director cu clasa TestComp (deci în directorul curent al dvs). uşor de utilizat. În JFC/Swing există mai multe tipuri de butoane: butonul simplu..border. caseta de validare. Acţionarea butonului se face punând deasupra lui cursorul mouse-ului şi apasând un buton al acestuia. apasaţi butonul din dreapta şi va apare un meniu din care selectaţi opţiunea "Save image as .". riglele ajustabile. listele ascunse. meniurile şi câmpurile de text. Pentru a realiza acest lucru.în penultimul buton (b6) s-a introdus imaginea care se găseşte în fişierul buton_go. a fost necesar să se importe pachetul javax.swing. Iată câteva dintre acestea: 244 . Clasa AbstractButton Clasa javax.gif. Toate acestea sunt subclase ale clasei abstracte javax.Severin Bumbaru } } /* Clasa ascultatoare de fereastra */ static class AF extends WindowAdapter { public void windowClosing(WindowEvent e) { System.AbstractButton defineşte caracteristicile comune ale diferitelor tipuri de butoane din JFC/Swing. Butoane Butoanele sunt obiecte grafice. .java. . cel cu bordura roşie groasă) i s-a ataşat un text explicativ volant. puneţi cursorul mouse-ului pe această imagine.pentru a lucra cu borduri." sau "Save picture as . butonul radio şi articolul de meniu.exit(0). apare textul volant..AbstractButton.. prin intermediul cărora utilizatorul poate introduce anumite comenzi. Dacă doriţi sa testati programul. dacă punem cursorul de mouse deasupra acestui buton fără să apăsăm şi aşteptăm câteva secunde. // incheierea executarii aplicatiei } } /* Metoda principala a aplicatiei */ public static void main(String args[]) { } } Remarcăm următoarele: .swing. Din această categorie fac parte butoanele. al căror aspect este similar celor al butoanelor folosite în aparatura electronică şi electrică.swing. Componente de control Componentele de control sunt dispozitive de intrare virtuale.butonului al doilea (b2.. . apoi salvaţi imaginea în acelaşi director cu fişierul TestComp. listele.s-au folosit bordurile standard din clasa BorderFactory.

În secţiunile următoare vom prezenta modul de utilizare a diferitelor tipuri de butoane. implicit.swing. De fiecare dată când este acţionat. Cât timp se ţine butonul de mouse apăsat deasupra lui. ActionEvent.swing. . care sunt ascultate de un ascultător de acţiune (ActionListener). . realizate prin subclase ale clasei ToggleButton şi prezentate în continuare. .orice buton poate avea o mnemonică.butonul are un nume al acţiunii de comandă pe care o exercită. cel mai frecvent se folosesc caseta de validare şi butonul radio.orice buton poate avea un text.JButton. void addItemListener(ItemListener i). Butonul obişnuit (cu o singură stare stabilă) Butoanele obişnuite se realizează folosind clasa javax. acest nume este identic cu textul butonului. ca orice altă componentă. butonul generează un AcţionEvent şi un ChangeEvent. O specificare mai detaliată a clasei JToggleButton este dată în indexul de clase. cel mai frecvent se folosesc evenimentele de acţiune (ActionEvent). care poate fi pus prin metoda void setText(String text) şi poate fi aflat prin metoda String getText().swing. evenimente de componentă. când butonul este selectat sau deselectat.orice buton poate avea cel puţin o pictogramă. când se acţioneaza asupra lui. folosind clasele corespunzătoare ale pachetului javax.AbstractButton şi reprezintă butoane cu două stări stabile. O prezentare mai amplă a clasei AbstractButton este dată în Indexul de clase. al cărei argument este codul tastei care trebuie acţionată. generează numai un ChangeEvent. . Mnemonica se pune cu metoda void setMnemonic(int mnemonic). Trecerea de la o stare la alta este impusă de utilizator prin click de mouse sau este comandată prin program. derivată din clasa javax. Totuşi. Butonul generează de asemenea. Există metode de adăugare a ascultătoarelor pentru aceste trei tipuri de evenimente: void addActionListener(ActionListener a).Programarea orientata pe obiecte în limbajul Java . void addChangeListener(ChangeListener c). de mouse şi de tastă. . adică i se poate asocia o tastă.butonul generează trei tipuri de evenimente: . 245 . . sub forma unui şir de caractere. Când este eliberat.swing. ChangeEvent. butonul se află în starea "apăsat" ("acţionat").swing. în care ajunge când este eliberat. când îşi modifică starea. În practică. care poate fi pusă prin metoda void setIcon(Icon defaultIcon) şi obţinută prin metoda Icon getIcon(). Butonul cu două stări stabile Clasa javax. în cazul butoanelor obişnuite. a cărei apasare are acelaşi efect cu apăsarea cu mouse-ul a butonului respectiv.AbstractButton. Butonul obişnuit are o singură stare stabilă. ItemEvent. aşa cum am arătat în exemplele date în capitolul precedent. dar el poate fi modificat prin metoda void setActionCommand(String command) şi poate fi aflat prin metoda String getActionCommand().JToggleButton este derivata din javax. Clasele Button şi JButton sunt specificate mai detaliat în Indexul de clase.

În momentul în care este selectat ("apăsat") un buton al grupului. care este ascultat de clase cu interfaţa java.JToggleButton. În starea opusă (deselectat). astfel de comutatoare se comporta identic cu casetele de validare. La fiecare click de mouse pe suprafata casetei de validare.AbstractButton.awt.event.awt. în locul casetei de validare se foloseste un comutator ("switch"). diferenţa fiind numai în aspectul grafic. caseta de validare este reprezentată grafic printr-un patrat. În unele sisteme de interfaţă grafică. 246 .JRadioButton. când caseta se găseşte în starea "selectat". Imaginea casetei este insoţită şi de un text explicativ. aceasta trece dintr-o stare în cealaltă. astfel că la un moment dat numai unul dintre ele poate fi "selectat". cel mai important este java.swing. în care se testează butoanul simplu.*. În JFC/Swing.Severin Bumbaru Caseta de validare Caseta de validare este un obiect de control cu două stări stabile. care este derivată din clasa javax.ButtonGroup. Dintre evenimentele generate de caseta de validare. Butonul radio Butonul radio este un buton cu două stări stabile.swing.event.swing. Exemplu În fişierul TestButoane.JCheckBox. Metoda prin care se captează astfel de evenimente întrun ItemListener este public void itemStateChanged(ItemEvent e) Pentru a afla în ce stare se gaseşte caseta la un moment dat. se foloseşte metoda public boolean isSelected() din superclasa javax. Gruparea butoanelor se face folosind clasa javax. În mod obişnuit.event. import java.java se dă un exemplu de aplicaţie. import java. trecerea de la o stare la alta făcându-se la fiecare click de mouse pe suprafaţa butonului.awt. butoanele radio sunt realizate ca instanţe ale clasei javax.JToggleButton. Din punct de vedere funcţional.*.ItemListener. în care apare un simbol de bifare (de validare). În JFC/Swing casetele de validare se realizează folosind clasa javax. care face parte dintr-un grup de butoane.swing. cum ar fi simbolul V sau X. la care ambele stări ("apăsat" şi "eliberat") sunt stabile. caseta este vidă. Acesta are aspectul unui buton. caseta de validare şi butonul radio. se deselectează automat cel care era selectat anterior.awt.swing.swing.ItemEvent. care este derivată din clasa javax. Astfel de evenimente sunt generate în momentele în care caseta a fost selectată sau deselectată.

static IUG iug=new IUG("Diferite tipuri de butoane").*.add(b1).addActionListener(ascult). box1.add(b2). IUG(String titlu) { // constructorul clasei IUG super(titlu).addActionListener(ascult). JLabel label.createVerticalBox(). /* clasa imbricata pentru interfata utilizator grafica */ static class IUG extends JFrame { JButton b1. rb1. class TestButoane { static AF af=new AF(). box1.VK_F2). cb2. box1=Box. Box box1. cb2. cb1.VK_F6).b2.setMnemonic(KeyEvent. rb3=new JRadioButton("BR 3 (F7)"). care se grupeaza si se pun in box3 */ rb1=new JRadioButton("BR 1 (F5)"). box2. box3=Box. b1.setMnemonic(KeyEvent. box2. cb1. // adaugarea ascultatorului de fereastra /* Se creeaza doua butoane. JRadioButton rb1. b1 si b2. rb3. static Ascultator ascult=new Ascultator().setMnemonic(KeyEvent. b2=new JButton("B2 (F2)"). cb2. b2. 247 .Programarea orientata pe obiecte în limbajul Java import javax. box2.VK_S). care se pun in caseta box1 */ b1=new JButton("B1 (F1)").setMnemonic(KeyEvent. 150). box3.setMnemonic(KeyEvent. box1. rb3. setLocation(200. setSize(300. box2=Box.createVerticalBox().createVerticalBox(). 50). JCheckBox cb1.swing.addActionListener(ascult).VK_F1). box3. ButtonGroup grup.addActionListener(ascult).VK_A).add(cb2). rb2.add(new JLabel("Butoane simple")).VK_F7).addActionListener(ascult).add(new JLabel("Butoane radio")). b1. box4.add(new JLabel("Casete validare")). rb1.setMnemonic(KeyEvent. /* Se creeaza trei butoane radio. rb2.setMnemonic(KeyEvent. cb2=new JCheckBox("Caseta 2 (S)"). b2.addItemListener(ascult). addWindowListener(af). /* Se creeaza doua casete de validare. rb2. care se pun in box2 */ cb1=new JCheckBox("Caseta 1 (A)"). rb3. rb2=new JRadioButton("BR 2 (F6)"). box2.VK_F5). Container cp=getContentPane().add(cb1).addItemListener(ascult).

add(box1). .createHorizontalGlue()).createHorizontalGlue()). iug.add(Box. setVisible(true).exit(0).add(Box. ItemListener { public void actionPerformed(ActionEvent e) { iug. cp. box4. String selectie.două butoane simple din clasa JButton.două casete de validare din clasa JCheckBox. box4. butoanele sunt referite prin b1 şi b2 şi sunt puse în caseta verticală box1. box4. cu textele B1 şi B2. grup.add(rb1). cp.createHorizontalStrut(15)). box4. } } /* Clasa ascultatoare de fereastra */ static class AF extends WindowAdapter { public void windowClosing(WindowEvent e) { System. } } /* Metoda principala a aplicatiei */ public static void main(String args[]) { } } În fereastra principală a aplicaţiei apar: .add(box2).getActionCommand()). referite prin br1.getText()). grup=new ButtonGroup(). .add(rb2).trei butoane radio din clasa JRadioButton. if(cb.createHorizontalBox().setText("A fost apasat butonul "+e. grup.add(box4. cu textele Caseta 1 şi Caseta 2.SOUTH). BorderLayout. box2 si box3 se pun in box4 . BorderLayout. } public void itemStateChanged(ItemEvent e) { JCheckBox cb=(JCheckBox)e. 248 .add(rb3).add(rb3). referite prin cb1 şi cb2 şi puse în caseta verticală box2.add(Box. box4. grup. /* box1.Severin Bumbaru box3.add(Box.add(rb1).add(label.createHorizontalStrut(15)). else selectie="A fost deselectata ". box3. label=new JLabel("Actionati butoanele si urmariti mesajul").add(rb2).add(box3). box4.label.setText(selectie+cb. cu textele BR1. // incheierea executarii aplicatiei } } /* Clasa ascultatoare de actiuni si de selectari */ static class Ascultator implements ActionListener. BR2 şi BR3. box4.CENTER). box3. iar aceasta se pune in controlPane */ box4=Box.label.isSelected()) selectie="A fost selectata ".getItem().

Pentru aprofundarea folosirii diferitelor tipuri de butoane. apoi se apasă tasta 249 . din clasa javax. iar aceasta este pusă în zona CENTER a panoului controlPane.în zona SOUTH a controlPane este pusă o etichetă din clasa JLabel. Articolele din listă pot fi. listele se realizează ca instanţe ale clasei javax. Pentru a constata care caseta de validare care a fost selectată sau deselectată. Check Boxes and Radio Buttons din Java Tutorial.JList. se numeşte listă o componentă care conţine articole selectabile. Ulterior este posibil să se adauge articole la listă. La crearea listei. Ascultarea evenimentelor de acţiune (ActionEvent) şi de selecţie (ItemEvent) se face cu clasa Ascultare. folosită pentru a afişa evenimentele. Dacă se dă comanda Alt-<Tastă mnemonică> se obţine acelaşi efect ca atunci când se face click de mouse pe butonul respectiv. Detectarea butonului care a fost apăsat. tasta corespunzătoare a fost menţionată între paranteze. se face în metoda actionPerformed(ActionEvent action) folosind metoda String getActionCommand() din clasa ActionEvent. . fie că este vorba de un buton simplu sau unul radio.JScrollPane.event. prin click de mouse pe articolul respectiv. În JFC/Swing. sunt plasate în caseta orizontală box4. box2 şi box3.se face click de mouse pe primul articol din zona care trebuie selectată. orice obiecte afişabile. în textul fiecărui buton. folosind metoda Object getItem() din clasa ItemEvent.swing. Lista poate fi cu selecţie simplă sau cu selecţie multiplă. Selectarea lor se face de către utilizator. se apasă simultan tastele Alt şi F2.Programarea orientata pe obiecte în limbajul Java br2 şi br3 si puse în caseta verticală box3. Simbolurile tastelor se găsesc în clasa java. ea poate fi pusă pe un panou glisant.awt. după cum pot fi selectate simultan unul sau mai multe articole. Daca lista este mai lunga decât spaţiul de afişare disponibil. Fiecărui buton (sau casetă de validare) i-a fost ataşată o mnemonică. box1. De exemplu.swing. în loc de a apăsa cu mouse-ul butonul B2. Selectarea simplă a unui articol se face prin click de mouse pe articolul respectiv. recomandăm capitolul How to use Buttons.cele trei casete verticale. în principiu. constructorului i se dă ca argument tabloul obiectelor pe care le va conţine lista. care implementează interfeţele ActionListener şi ItemListener. Pentru comoditatea utilizatorului. după care se aplică metoda boolean isSelected() a acestui obiect. Liste În cazul interfeţelor utilizator grafice.KeyEvent. Selectarea multiplă se face în două moduri: . sau să se elimine. . în metoda itemStateChanged(ItemEvent item) se procedează astfel: se determină mai întâi obiectul selectabil (în cazul nostru caseta de validare) care a generat evenimentul.

Severin Bumbaru Shift şi se face click pe ultimul articol din această zonă. acest nou articol este selectat (rămâne vizibil).awt. este posibil ca acestea sa fie făcute editabile. în care caz ele se comportă ca o combinaţie între listă şi câmpul de text: utilizatorul poate să introducă textul manual. apoi se apasă tasta Shift şi se acţionează tastele cu săgeţi sus/jos până când sunt selectate toate articolele din zona respectivă. Clasa are numeroase alte metode.în timpul utilizării listei. De câte ori se face o selecţie de articole din listă. se generează un eveniment din clasa javax.swing.event.la crearea listei.ItemEvent. care este ascultat cu ajutorul unei clase care implementează interfaţa javax. În mod implicit.primeşte ca argument un tablou de obiecte. se generează.Vector. care este ascultat cu un java. . care sunt articolele din listă public JList(Vector listData).event. aceasta generează un eveniment de articol din clasa java.se face click de mouse pe primul articol din zonă. iar celelalte dispar.JComboBox. pentru realizarea listelor ascunse se foloseşte clasa javax.util. care are ca elemente articolele listei. . Dacă acum facem click de mouse pe un alt articol din lista devenită vizibilă. Într-o listă ascunsă nu este posibilă selecţia multiplă.awt.întoarce tabloul indicilor articolelor selectate public Object[] getSelectedValues() . La fiecare acţionare asupra listei ascunse.ListSelectionEvent. Pentru aprofundare. Totuşi.ListSelectionListener.awt.event.swing. Punerea articolelor în listă se poate face astfel: . recomandăm capitolul How to Use Lists din Java Tutorial. Liste ascunse Lista ascunsă este o listă din care se vede un singur articol (cel care este selectat).ItemListener.primeşte ca argument o instanţă a clasei java. invocându-se una din metodele public void setListData(Object[] listData) public void setListData(Vector listData) Pentru a afla articolele selectate dintr-o listă se pot folosi metodele: public int[] getSelectedIndices() . folosind unul din constructorii public JList(Object[] listData) . instanţele clasei JComboBox nu sunt editabile. folosind unul din constructorii 250 . În acest fel se selectează toate articolele din zona respectivă. Celelalte articole ale listei sunt "ascunse" şi devin vizibile numai dacă se face click pe articolul vizibil. Când este selectat un nou articol din lista ascunsă.ActionEvent. În JFC/Swing. un java. sau poate să aleagă unul din listă. deci ocupa pe ecran spaţiu mult mai putin decât una obişnuită.întoarce tabloul articolelor selectate.la crearea listei ascunse.event. Punerea articolelor în listă poate fi făcută astfel: . de asemenea.swing.

/* clasa imbricata pentru interfata utilizator grafica */ static class IUG extends JFrame { JList lista1. Pentru a afla articolul selectat se foloseşte metoda public Object getSelectedItem() iar pentru a afla indicele articolului selectat se foloşeste metoda public int getSelectedIndex() Pentru ca lista ascunsă sa devină editabilă.*. java. import import import import java. se foloseşte metoda public void setEditable(boolean aFlag).înserează un articol pe poziţia index. Pentru aprofundarea folosirii listelor ascunse recomandăm capitolul How to Use Combo Boxes din Java Tutorial.elimină articolul de pe poziţia anIndex.awt.*. public void removeItemAt(int anIndex) .java este dat un exemplu de aplicaţie în care se folosesc instanţe ale claselor JList şi JComboBox.swing. folosind metodele public void addItem(Object anObject) .adaugă un articol la sfârşitul listei.*.Programarea orientata pe obiecte în limbajul Java public JComboBox(Object[] items) public JComboBox(Vector items) . JLabel label. public void insertItemAt(Object anObject.în timpul utilizării listei. 251 . IUG(String titlu) { // constructorul clasei IUG super(titlu).event.în care parametrul boolean aFlag indică dacă lista va fi sau nu editabilă. int index) . static AAL ascult=new AAL(). javax.*. static IUG iug=new IUG("Diferite tipuri de liste").event. JComboBox combo. lista2. Exemplu În fişierul Liste. class Liste { static AF af=new AF(). Eliminarea unui articol din listă se face cu una din metodele public void removeItem(Object anObject) .elimină articolul anObject.swing. static AEA ascult1=new AEA(). javax.awt.

Severin Bumbaru setSize(350. "Sambata". panel. lista2.createTitledBorder( "Lista ascunsa")). "Aprilie". "Al doilea". "Octombrie". lista1. combo.addListSelectionListener(ascult). BorderLayout. setVisible(true). lista1. // ascultarea listei cp.setSelectionModel(new DefaultListSelectionModel()). lista2=new JList(luni). "Marti". lista1=new JList(zile).add(lista1. lista2. setLocation(200.CENTER).add(label. BorderLayout. "August". Listei i se pune un model de selectie care permite numai selectarea unui singur articol */ String luni[]={"Ianuarie". "Al treilea". "Mai".setBorder(BorderFactory.setBorder(BorderFactory.setSelectionMode(ListSelectionModel.SOUTH). "Al patrulea"}. "Vineri".createTitledBorder( "Lista")). JPanel panel=new JPanel(). lista2.add(panel. 240). Listei nu i se pune un model de selectie. lista2. 50).add(combo). /* Se creeaza o lista cu lunile anului. "Joi". "Decembrie"}. lista2 cp. combo=new JComboBox(ordinea). pusa intr-un panou glisant. "Miercuri". /* Se creeaza o lista ascunsa (din clasa JComboBox) */ String ordinea[]={"Primul ".EAST). Container cp=getContentPane(). "Februarie".createTitledBorder( "Afisarea mesajelor privind articolele selectate")). JScrollPane scroll=new JScrollPane(lista2). BorderLayout.setBorder(BorderFactory. deci se pot face implicit selectii multiple intr-o singura zona continua */ String zile[]={"Luni". combo. "Iulie". "Septembrie". addWindowListener(af). label.add(scroll.addListSelectionListener(ascult). } } /* Clasa ascultatoare de fereastra */ static class AF extends WindowAdapter { public void windowClosing(WindowEvent e) { 252 .WEST). "Noiembrie". BorderLayout. cp.addItemListener(ascult1). // adaugarea ascultatorului de fereastra /* Se creeaza o lista cu zilele saptamanii. cp. // panoul glisant // care contine lista nou creata. /* Se creeaza o "eticheta" pentru afisarea mesajelor */ label=new JLabel("Selectati articolele si urmariti efectul").setBorder(BorderFactory.createTitledBorder( "Lista glisanta")). "Martie".SINGLE_SELECTION). "Duminica"}. "Iunie".

toString()). Dacă în câmpul de text se introduce o valoare numerică.awt. iug. câmpurile de text se realizează ca instanţe ale clasei javax. în care se poate introduce o singură linie de text. Când câmpul de text este activ şi se apasă tasta Enter.setText(buff.setText(e.ActionEvent. i++) buff.append(selectie[i].getItem(). for(int i=0. Textul conţinut în câmpul de text poate fi obţinut în două moduri: .swing.prin metoda public String getText() a clasei JTextField. se afiseaza toate articolele selectate din lista sursa */ static class AAL implements ListSelectionListener { public void valueChanged(ListSelectionEvent e) { JList sursa=(JList)e.label.prin metoda public String getActionCommand() a clasei ActionEvent. La aparitia unui astfel de eveniment.label. // incheierea executarii aplicatiei } } /* Clasa ascultatoare de selectari ale articolelor de lista folosita pentru JList.toString()). StringBuffer buff=new StringBuffer(). El se prezintă sub forma unei ferestre dreptunghiulare editabile.JTextField.getSource(). prin intermediul câmpului de text se introduce o singură valoare numerică sau un şir de caractere. De obicei. ea trebuie verificata sintactic şi 253 .exit(0). i<selectie. În JFC/Swing.toString()+" ").getSelectedValues(). este generat un eveniment de acţiune din clasa java. } } /* Clasa ascultatoare de evenimente de articol folosita pentru JComboBox.Programarea orientata pe obiecte în limbajul Java System. Object selectie[]=sursa. . se afiseaza articolul care l-a produs */ static class AEA implements ItemListener { public void itemStateChanged(ItemEvent e) { iug.length. } } /* Metoda principala a aplicatiei */ public static void main(String args[]) { } } Câmpul de text Câmpul de text este principalul instrument al interfeţei grafice prin care utilizatorul introduce date de la tastatură. La aparitia unui astfel de eveniment.

JTextField tf1. ele trebuie utilizate în secvenţe try . se folosesc metodele de analiză şi conversie din clasele acoperitoare. setLocation(200. pentru a introduce. static Actiuni act=new Actiuni(). IUG(String titlu) { // constructorul clasei IUG super(titlu).swing.lang. în funcţie de tipul valorii pe care acest câmp trebuie să o conţină. recomandăm capitolul How to Use Text Fields din Java Tutorial. panel. tf2. import java.awt. unde str este şirul care trebuie analizat.*.2)). /* Adaugarea la panou a etichetelor si campurilor de text */ panel. 254 . Container cp=getContentPane(). 150)..Double. un şir de caractere. catch. import java. respectiv. // adaugarea ascultatorului de fereastra /* Crearea panoului pentru campurile de text */ panel=new JPanel(). class CampuriText { static AF af=new AF(). există şi clasa javax.awt.event. se poate observa cum se determină care câmp de text a generat evenimentul de acţiune şi cum se preia şi analizează textul din câmpul respectiv. pentru un numar de tip double se va folosi metoda public double parseDouble(String str) din clasa acoperitoare java.*.setLayout(new GridLayout(3. Pentru aprofundarea utilizării câmpurilor de text.Severin Bumbaru convertită din forma externă (de şir de caractere) în forma internă. prin care este realizat ascultătorul de evenimente de acţiune. care se foloseşte pentru introducerea parolelor. import javax. Întrucât aceste metode pot să genereze excepţii de format incorect (NumberFormatException).add(new JLabel("Un sir de caractere: ")). addWindowListener(af). 50).java este dat un exemplu de aplicaţie în care se utilizează trei câmpuri de text. JLabel label. în afara clasei JTextField. setSize(450. Menţionăm că. Exemplu În fişierul CâmpuriText.swing.JPasswordField. tf3. De exemplu. static IUG iug=new IUG("Campuri de text"). În clasa imbricată Actiuni. În acest scop. un număr întreg şi un număr în virgulă mobilă. /* clasa imbricata pentru interfata utilizator grafica */ static class IUG extends JFrame { JPanel panel.*.

label. iug.CENTER). iug. if(sursa==iug.tf1) iug.label. tf3=new JTextField().getActionCommand().tf2) try { int n=Integer. cp.setText(text1+" 2 numarul intreg "+n).add(tf1). text1="Ati introdus in campul ". tf2.parseInt(text). /* Se creeaza o "eticheta" pentru afisarea mesajelor */ label=new JLabel("Introduceti date in campuri si urmariti efectul").addActionListener(act).tf3) try { double d=Double. panel. } catch(Exception e2) { iug. tf2=new JTextField().setBorder(BorderFactory.setText(text1+"3 numarul real "+d). panel.Programarea orientata pe obiecte în limbajul Java tf1=new JTextField(). String text=e. panel. tf1.label. } } } /* Metoda principala a aplicatiei */ 255 . panel.setText("In campul 3 nu este un numar real!").add(new JLabel("Un numar intreg")). BorderLayout.setText(text1+"1 textul: "+text). } else if(sursa==iug.parseDouble(text). } catch(Exception e1) { iug.setText("In campul 2 nu este un numar intreg!").add(panel.add(tf2).label. tf3. label.getSource().add(label.exit(0). BorderLayout.label. } } /* Clasa ascultatoare de fereastra */ static class AF extends WindowAdapter { public void windowClosing(WindowEvent e) { System. // incheierea executarii aplicatiei } } /* Clasa ascultatoare a actiunilor asupra campurilor de text */ static class Actiuni implements ActionListener { public void actionPerformed(ActionEvent e) { JTextField sursa=(JTextField)e.add(new JLabel("Un numar real: ")).add(tf3).createTitledBorder( "Afisarea mesajelor privind campurile de text")).addActionListener(act). panel.addActionListener(act). else if(sursa==iug. setVisible(true). /* Adaugarea la contentPane a panoului cu campuri de text */ cp.SOUTH).

care poate fi JSlider.stabilirea valorii diviziunilor mici setPaintTicks(boolean b) . import java.ChangeEvent. import javax.determină dacă diviziunile vor fi vizibile setPaintLabels(boolean b) .event. Pentru a stabili aspectul riglei se folosesc metodele public public public public void void void void setMajorTickSpacing(int n) . value . care sunt ascultate cu o clasă care implementează interfaţa javax. La deplasarea cursorului.*.event.valorile minimă şi maximă de pe scala riglei.*.orientarea riglei.awt.*.Severin Bumbaru public static void main(String args[]) { } } Rigla cu cursor Clasa javax. Prin deplasarea cursorului cu ajutorul mouse-ului se modifică valoarea indicată de riglă. Exemplu În fişierul TestRigla.java este dat un exemplu de aplicaţie în care se testează o riglă cu cursor realizată ca instanţă a clasei JSlider.max]). dintre care cel mai complet este public JSlider(int orientation. cum este potenţiometrul din aparatura electronică. min. La partea superioară a ferestrei apare o riglă în poziţie orizontală.swing.HORIZONTAL sau JSlider. rigla generează evenimente din clasa javax. Valoarea minimă şi cea maximă de pe scala riglei şi valoarea unei diviziuni se indică prin program.swing. import java.swing.valoarea indicată iniţial de cursorul riglei (trebuie să fie în intervalul [min. 256 . max .VERTICAL.JSlider oferă o componentă care are aspectul unei rigle prevăzute cu cursor. recomandăm consultarea capitolului How to Use Sliders din Java Tutorial. Când se modifică cu mouse-ul poziţia cursorului.event. int value) în care orientation .awt.determină dacă vor fi afişate valorile numerice ale diviziunilor. int max.swing. Pentru aprofundarea utilizării riglelor cu cursor. Crearea riglei se face folosind unul dintre constructorii ei. int min. Rolul riglei poate fi asemănat cu cel al unui dispozitiv de ajustare continuă.ChangeListener.stabilirea valorii diviziunilor mari setMinorTickSpacing(int n) . în eticheta de la partea inferioară a ferestrei aplicaţiei se afişeaza noua valoare indicată de riglă.

exit(0).*.setMinorTickSpacing(1). 150). BorderLayout. } } /* Metoda principala a aplicatiei */ 257 .label. label.add(label. 35). 80.add(rigla.setBorder(BorderFactory. JLabel label. /* clasa imbricata pentru interfata utilizator grafica */ static class IUG extends JFrame { JSlider rigla. } } /* Clasa ascultatoare de fereastra */ static class AF extends WindowAdapter { public void windowClosing(WindowEvent e) { System. rigla.swing. // adaugarea ascultatorului de fereastra /* Se creeaza o "eticheta" pentru afisarea mesajelor */ label=new JLabel("Deplasati cursorul riglei si urmariti efectul"). BorderLayout. static AscultRigla ascult=new AscultRigla(). -20.Programarea orientata pe obiecte în limbajul Java import javax. setSize(450. rigla=new JSlider(JSlider.setMajorTickSpacing(10). addWindowListener(af). cp. setVisible(true).HORIZONTAL. 50). // incheierea executarii aplicatiei } } /* Clasa ascultatoare a evenimentelor de ajustare a riglei */ static class AscultRigla implements ChangeListener { public void stateChanged(ChangeEvent e) { iug.addChangeListener(ascult).setPaintLabels(true). rigla. setLocation(200. cp.CENTER). rigla.getValue()).setPaintTicks(true).event. Container cp=getContentPane(). class TestRigla { static AF af=new AF().setText("Noua valoare: "+iug. rigla. IUG(String titlu) { // constructorul clasei IUG super(titlu). rigla.SOUTH).createTitledBorder( "Ajustarea valorii")). static IUG iug=new IUG("O rigla ajustabila"). rigla.rigla.createTitledBorder( "Afisarea mesajelor privind valoarea ajustata")).setBorder(BorderFactory.

meniurile permit utilizatorului să aleagă una din mai multe opţiuni posibile. În JFC/Swing se disting două categorii de meniuri: . .swing. acesta acţionează ca un buton obişnuit. Barele de meniu nu pot fi adăugate la un container ca nişte componente obişnuite. adică generează un 258 .Severin Bumbaru public static void main(String args[]) { } } Meniuri La fel ca listele sau butoanele radio. care apar în poziţia în care se găseşte cursorul de mouse.swing.JMenuBar.swing.JMenu. Dacă utilizatorul alege cu mouse-ul un aricol de meniu. în care caz noul (sub)meniu se desfăşoară şi căutarea continuă.articolul ales este el însuşi un meniu (un JMenu). Bara de meniu poate sa conţină unul sau mai multe meniuri. daca este necesara. Este însă posibil ca un articol de meniu să fie el însuşi un meniu (din clasa JMenu). Pentru a pune bara de meniu la partea superioară a ferestrei aplicaţiei se foloseşte metoda clasei JFrame public void setJMenuBar(JMenuBar menubar) Adăugarea de meniuri la bara de meniu se face prin metoda clasei JMenuBar public JMenu add(JMenu c) iar adăugarea de articole sau submeniuri la un meniu se face prin metodele clasei JMenu public public public public JMenuItem Component JMenuItem JMenuItem add(JMenuItem menuItem) add(Component c) add(String s) add(Action a) Pentru a introduce în meniu o linie orizontală de separare a două articole se foloseşte metoda public void addSeparator() Atunci când este selectat un articol de meniu simplu (din clasa JMenuItem). Dacă se selectează un articol de meniu sub forma de casetă de validare (din clasa JCheckBoxMenuItem). . care se realizează ca instanţe ale clasei javax. adică generează un eveniment de acţiune (ActionEvent). La rândul său. care pornesc dintr-o bară situată la partea superioară a ferestrei aplicaţiei.acesta este un articol propriu-zis (un JMenuItem). sunt posibile deci două situaţii: . numai la partea superioara a ferstrei aplicatiei si se realizeaza ca o instanta a clasei javax. în care caz opţiunea respectivă este selectată.meniuri cu bară. fiecare meniu poate conţine unul sau mai multe articole. Meniuri cu bară Bara de meniu se poate plasa. acesta se comporta ca o caseta de validare.meniuri derulante (pop-up).JMenuItem sau javax.swing.JCheckBoxMenuItem. care sunt instanţe ale claselor javax.

add(mi2). // bara de menu se adauga la fereastra /* Se creeaza meniurile si se adauga la bara de meniu */ menu1=new JMenu("Un menu").event.add(mi3). menu2=new JMenu("Alt menu"). class Meniuri { static AF af=new AF().add(mi5).swing. mi2. setLocation(200. mi5=new JMenuItem("Beta"). IUG(String titlu) { // constructorul clasei IUG super(titlu). JMenu menu1.awt.*. Container cp=getContentPane(). mi5. Posibilităţile oferite de meniuri sunt mult mai bogate decât s-a arătat aici. static IUG iug=new IUG("O fereastra cu bara de menu"). mi5. import java.addActionListener(aa).addActionListener(aa). mi3=new JMenuItem("C").add(menu1). addWindowListener(af). menuBar.add(menu3). JMenuItem mi1. static AA aa=new AA(). mi3. respectiv ItemListener. mi2=new JMenuItem("B"). mi2. menu2. import java. setSize(350. Pentru aprofundare recomandăm consultarea capitolului How to Use Menus din Java Tutorial. 259 . mi4. 50). Exemplu În fişierul Meniuri. mi3. /* clasa imbricata pentru interfata utilizator grafica */ static class IUG extends JFrame { JMenuBar menuBar. JLabel label.addActionListener(aa). menu2. 150).addActionListener(aa). menu1.addActionListener(aa).awt.add(mi1). mi4.add(menu2). mi4=new JMenuItem("Alpha").java este dat un exemplu de aplicaţie cu bară de meniu. /* Se creaza articole de menu si se adauga la meniuri */ mi1=new JMenuItem("A"). menuBar. import javax.Programarea orientata pe obiecte în limbajul Java eveniment de articol (ItemEvent). Ascultarea acestor evenimente se face cu clase care implementează interfeţele ActionListener. /* La menu2 se aduga un submeniu cu doua articole */ JMenu menu3=new JMenu("Un submeniu").*. menu1. // adaugarea ascultatorului de fereastra menuBar=new JMenuBar().add(mi4). menu3. menu2.*. mi1. // se creeaza bara de menu setJMenuBar(menuBar). menu3.

meniurile volante sunt tratate ca nişte componente obişnuite.în corpul metodei corespunzatoare situaţiei în care trebuie să se afişeze meniul (mousePressed.add(label. mouseReleased sau mouseClicked) se invocă metoda show menţionată mai sus.SOUTH). int x. meniul pop-up se comportă la fel ca un meniu cu bară. // incheierea executarii aplicatiei } } /* Ascultator de actiuni pentru articolele de menu */ static class AA implements ActionListener { public void actionPerformed(ActionEvent e) { iug.label. atunci când este necesar. } } /* Clasa ascultatoare de fereastra */ static class AF extends WindowAdapter { public void windowClosing(WindowEvent e) { System. În rest.getActionCommand()). se creează o clasă ascultătoare de mouse (care implementează interfaţa MouseListener sau extinde clasa MouseAdapter) şi . Se demonstrează acest procedeu în exemplul de mai jos. De obicei. Afişarea meniului pop-up trebuie programată. dacă a fost acţionat butonul de mouse care ne interesează.createTitledBorder( "Afisarea mesajelor privind selectarea articolelor de meniu")). cp.exit(0).JPopupMenu.setBorder(BorderFactory. În JFC/Swing. se doreste ca afişarea meniului pop-up să se facă atunci când se efectuează o anumită acţiune a mouse-lui asupra componentei respective. label. meniurile volante se realizează ca instanţe ale clasei javax. care pot să fie afişate prin program. iar x şi y sunt coordonatele punctului în care acesta va fi afişat. folosindu-se în acest scop metoda din clasa JPopupMenu public void show(Component invoker.Severin Bumbaru /* Se creeaza o "eticheta" pentru afisarea mesajelor */ label=new JLabel("Selectati articole de meniu si urmariti efectul"). 260 . setVisible(true). BorderLayout. int y) în care invoker este referinţa la componenta in spaţiul căreia trebuie să apară meniul.setText("A fost selectata optiunea: "+ e. } } /* Metoda principala a aplicatiei */ public static void main(String args[]) { } } Meniuri volante (pop-up) Spre deosebire de meniurile cu bară.swing. În acest scop.

mi2.event. mi3. popup.add(label. mi3=new JMenuItem("C"). atunci când acesta se găseşte în spaţiul ferestrei. /* Se adauga la eticheta label ascultatorul de mouse pentru afisarea meniului popup 261 .setBorder(BorderFactory.Programarea orientata pe obiecte în limbajul Java Exemplu În fişierul Popup. IUG(String titlu) { // constructorul clasei IUG super(titlu). import java. Container cp=getContentPane(). care este ataşata etichetei label în calitate de ascultător de mouse. Evenimentul care declanşează apariţia meniului este apăsarea pe butonul din dreapta al mouse-ului.java se dă un exemplu de aplicaţie în care se testează utilizarea unui menu pop-up. // adaugarea ascultatorului de fereastra /* Se creeaza meniul pop-up */ popup=new JPopupMenu().add(mi1).add(mi2). setLocation(200. JLabel label. /* clasa imbricata pentru interfata utilizator grafica */ static class IUG extends JFrame { JPopupMenu popup. 150). JMenuItem mi1. static AA aa=new AA(). static AfisPopup afisare=new AfisPopup().addActionListener(aa). popup.*. static IUG iug=new IUG("Exemplu de menu pop-up").swing. label. mi2. import java.*.awt. addWindowListener(af).*. /* Se creaza articole de menu si se adauga la meniuri */ mi1=new JMenuItem("A"). 50). BorderLayout. cp. mi2=new JMenuItem("B"). Acest eveniment este urmărit de instanţa clasei AfisPopup. Drept componentă pe suprafaţa căreia trebuie să apară meniul s-a ales eticheta de la partea inferioară a ferestrei aplicaţiei. /* Se creeaza o "eticheta" pentru afisarea mesajelor */ label=new JLabel(" Apasati pe aceasta eticheta butonul drept al mouse-ului").SOUTH).awt.createTitledBorder( "Afisarea mesajelor privind selectarea articolelor de meniu")).addActionListener(aa). mi1.add(mi3).addActionListener(aa). setSize(350. class Popup { static AF af=new AF(). import javax. popup. mi3.

popup.javax. } } /* Clasa ascultatoare de fereastra */ static class AF extends WindowAdapter { public void windowClosing(WindowEvent e) { System.pentru realizarea unor "bare de progres" adică a unor bare de lungime variabilă.setText("A fost selectata optiunea: "+ e.addMouseListener(afisare).pentru afişarea de "inscripţii volante".getComponent(). .javax.Severin Bumbaru */ label. } } /* Ascultator de actiuni pentru articolele de menu */ static class AA implements ActionListener { public void actionPerformed(ActionEvent e) { iug.getActionCommand()).swing.show(e. . setVisible(true). când se pune cursorul de mouse deasupra unei alte componente. e.swing.exit(0). // incheierea executarii aplicatiei } } /* Clasa ascultatoare de mouse pentru afisarea meniului pop-up */ static class AfisPopup extends MouseAdapter { public void mousePressed(MouseEvent e) { if((e. care arată cum evoluează realizarea unei anumite activităţi (de la 0% la 262 .getX().getModifiers()&InputEvent. } } /* Metoda principala a aplicatiei */ public static void main(String args[]) { } } Componente de afişare Componentele de afişare sunt cele care servesc pentru a afişa anumite texte sau imagini şi pot fi needitabile sau editabile.label.getY()).swing.JLabel . e. Componente de afişare needitabile Componentele de afişare needitabile sunt realizate ca instanţe ale următoarelor clase: .JTooltip .JProgressBar .javax.BUTTON3_MASK)!=0) iug.pentru realizarea unor "etichete" în care pot fi afişate texte sau imagini. fără a putea fi editate de utilizator.

public void setRows(int rows) . care au fost prezentate anterior. În aceeaşi categorie pot fi încadrate şi clasele javax. Pentru aprofundarea acestora şi pentru a studia folosirea barelor de progres recomandăm capitolele How to Use Labels. încât să se realizeze automat trecerea de la un rând la altul. javax. si How to Use Color Choosers din Java Tutorial.JTextArea.swing.JTextArea (arie de text) sunt suprafeţe de afişare a unor texte editabile cu mai multe linii.JFileChooser (pentru realizarea de selectoare de fişiere). Iată unele dintre metodele oferite de clasa JTextArea: public int getRows() .JPasswordField.JTextPane şi javax.swing.JTextField şi javax. How to Use Trees. Componente de afişare editabile Componentele de afişare editabile permit utilizatorului operaţii de editare în timpul executării programului.setează numărul maxim de linii. Componenta are comportamentul unui editor de text simplu: permite să se introducă text de la tastatură. How to Use Tool Tips şi How to Monitor Progress din Java Tutorial.setează numărul maxim de coloane. javax. sau se poate obţine sub forma de String textul existent. să se şteargă textul în întregime sau pe porţiuni.swing. Astfel.JEditorPane. Prin metode speciale se poate seta componenta astfel. public int getColumns() . În JFC/Swing există un număr important de clase pentru astfel de componente.întoarce numărul maxim de coloane din aria de text. Tot în categoria componentelor editabile intră şi clasele javax.întoarce numărul maxim de linii din aria de text. javax. 263 .swing. How to Use File Choosers. public void setColumns(int columns) .JTable (pentru realizarea de tabele editabile).swing.swing.Programarea orientata pe obiecte în limbajul Java 100%). iar pentru celelalte recomandăm folosirea documentaţiei indicate. să se adauge sau să se însereze text. Vom prezenta aici numai clasa JTextArea.swing. How to Use Tables. Utilizarea etichetelor şi a inscripţiilor volante a fost deja prezentată. Pentru aprofundare recomandăm folosirea capitolelor Using Text Components.JColorChooser (pentru realizarea de selectoare de culori). pentru editare de texte există clasele javax.swing. Se oferă metode prin care se poate adăuga text prin program.swing.JTree (pentru realizarea de arbori) şi javax. Clasa JtextArea Instanţele clasei javax.swing.

addWindowListener(af). JLabel label. cp.awt.Severin Bumbaru public void setFont(Font f) .*. Punând în execuţie această aplicaţie. observăm cum se rearanjează automat liniile de text. import java.text. public String getText() .întoarce textul selectat. setând trecerea automată la linie nouă la sfârşit de cuvant (astfel încât un cuvânt să nu se împartă pe două linii).event. public void append(String str) . public int getLineCount() .swing.înserează şirul str începând de la poziţia pos.java se dă un exemplu simplu de creare a unei instanţe a clasei JTextArea.add(ta. 150). int end) . public void setLineWrap(boolean wrap) . Ultimele două metode sunt moştenite de la superclasa javax. // static AA aa=new AA(). int pos) . class ZonaText { static AF af=new AF().întoarce numărul de linii de text conţinute efectiv.*.indică dacă se face trecere automată la linie nouă. 50).CENTER).JTextComponent.setWrapStyleWord(true). setSize(450. BorderLayout.awt. setVisible(true). //static AfisPopup afisare=new AfisPopup(). public String getSelectedText() . Dacă modificăm cu mouse-ul dimensiunile ferestrei.întoarce sub forma de String textul conţinut. } } /* Clasa ascultatoare de fereastra */ 264 . ta. Container cp=getContentPane().adaugă la sfârşit textul str.swing. public void setWrapStyleWord(boolean word) . import javax.*. constatăm cum aria de text se comportă ca un mic editor de text: putem să introducem de la tastatură text nou sau să modificăm textul existent. setLocation(200. public void replaceRange(String str. ta.indică dacă trecerea automată la linie nouă se face la sfârşit de cuvânt. static IUG iug=new IUG("O zona de text"). import java. IUG(String titlu) { // constructorul clasei IUG super(titlu).înlocuieşte prin şirul str caracterele cuprinse între poziţiile start şi end. public void insert(String str. Exemplu În fişierul ZonaText.setează fontul.setLineWrap(true). int start. // adaugarea ascultatorului de fereastra ta=new JTextArea (). /* clasa imbricata pentru interfata utilizator grafica */ static class IUG extends JFrame { JTextArea ta.

Prin ce clasă se realizează câmpul de text şi ce conţine el? 18. Cum se stabileşte aspectul componentelor din JFC/Swing? 5. Ce reprezintă clasa AbstractButton? 11. Ce reprezintă clasa JToggleButton? 12. // incheierea executarii aplicatiei } } /* Metoda principala a aplicatiei */ public static void main(String args[]) { } } Întrebări Nivel 1 1. Ce este un meniu? 23. Ce poate conţine o componentă atomică din JFC/Swing? 9. Care sunt caracteristicile componentelor din JFC/Swing? 4. La ce serveşte clasa ButtonGroup? 15. Prin ce clasă se realizează bara de meniu? 26. Ce este o listă în JFC/Swing şi prin ce clasă se realizează? 16. Ce categorii de componente grafice cunoaşteţi? 2.exit(0). Unde poate fi plasat un meniu cu bara? 25. Ce este o riglă ajustabilă şi prin ce clasă se realizează? 21. Ce conţine bara de meniu? 27. Ce este un buton radio şi prin ce clasă se realizează? 14. Care este deosebirea dintre componentele atomice şi containere? 8. Prin ce clase se realizează articolele de meniu? 30.Programarea orientata pe obiecte în limbajul Java static class AF extends WindowAdapter { public void windowClosing(WindowEvent e) { System. Prin ce se caracterizează starea componentei? 6. Ce conţine un meniu? 29. Care este dispozitivul electronic pe care îl simulează o riglă ajustabilă? 22. Prin ce se caracterizeaza comportamentul componentei? 7. Ce categorii de meniuri există în JFC/Swing? 24. Ce este un meniu derulant şi prin ce clasă se realizează? 265 . Ce evenimente generează un câmp de text şi când le generează? 20. Ce este o casetă de validare şi prin ce clasă se realizează? 13. Care este principala utilizare a câmpului de text? 19. Care este rădăcina ierarhiei claselor de componente? 3. Prin ce clasă se realizează un meniu utilizabil într-o bară de meniu? 28. Ce este o listă ascunsă şi prin ce clasă se realizează? 17. Care sunt componentele de control şi ce rol au? 10.

Ce este o mnemonică? 10.Severin Bumbaru 31. Ce clase de componente pot fi folosite pentru a realiza un selector de fişier? 34. Care este clasa prin care se realizează bordurile? 5. Cum se poate pune un text într-o componentă? 6. Cum se poate afla care buton a fost apăsat? 13. Care este superclasa clasei JComponent şi ce decurge din aceasta? 2. Cum se pot trasa diviziunile riglei ajustabile? 25. Ce deosebire este între selecţia simplă şi selecţia multiplă? 17. Cum se poate pune o imagine într-o componentă? 7. Ce este un text volant şi cum este el ataşat unei componente? 3. Sunt oare editabile instanţele clasei JComboBox? 21. Cum poate fi determinat momentul selectării unui articol din listă? 19. Ce clase pot fi folosite la realizarea de componente cu text editabil? 266 . Cum se adaugă bordura unei componente? 4. Cum se poate converti textul preluat din câmpul de text într-o valoare numerică? 23. Ce sunt componentele de afişare editabile? 34. Cum se programează afişarea pe ecran a unui meniu pop-up? 31. Cum se stabileşte intervalul de valori al riglei ajustabile? 26. Cum se face selectarea unui articol dintr-o listă? 16. Care sunt caracteristicile unui AbstractButton? 9. Ce evenimente generează un articol de meniu? 30. Ce componente de afişare editabile cunoaşteţi? 35. Ce componente de afişare needitabile cunoaşteţi? 33. Cum se poate afla în ce stare se găseşte la un moment dat o casetă de validare? 15. Cum se poate afla textul conţinut într-un câmp de text? 22. Cum se adaugă un articol la un meniu? 29. Cum pot fi selectate mai multe articole ale listei? 18. Cum se poate obţine valoarea indicată de riglă? 27. Care este clasa de componente folosite la alegerea culorii? 33. Ce sunt componentele de afişare needitabile? 32. Prin ce metodă se pune bara de meniu în fereastra aplicaţiei şi cărei clase îi aparţine această metodă? 28. Cum se poate determina momentul schimbării stării unei casete de validare? 14. Cum se poate determina ce articole de listă sunt selectate la un moment dat? 20. Ce reprezintă instanţele clasei JTable? 32. Ce metode ale clasei JTextArea cunoasteţi? 35. Cum se adaugă componentă la container? 8. Cum se poate detecta momentul apăsării unui buton? 12. Ce sunt instanţele clasei JTextArea şi cum se comportă ele? Nivel 2 1. Ce evenimente generează un AbstractButton? 11. Ce orientare poate avea o riglă ajustabilă? 24.

În fine. 267 270 272 278 280 280 283 289 Utilizarea ferestrelor de dialog Ferestrele de dialog sunt ferestre care se afişează pe ecran numai temporar.swing. pentru a elimina fereastra de dialog. Când fereastra de dialog este deschisă.JDialog. Aceste trei metode sunt moştenite de JDialog de la superclasa java. Principalul avantaj al folosirii ferestrelor de dialog este că apar pe ecran numai atunci când sunt necesare şi nu încarcă fereastra principală a aplicaţiei cu elemente care nu sunt necesare în permanenţă. Se permite ca. Instanţele acestei clase se comportă asemanator cu cele ale clasei JFrame. Utilizarea ferestrelor de dialog Alegerea culorii Clasa Color Alegerea culorii folosind clasa JColorChooser Elemente de grafică Contextul grafic Metodele paint şi repaint Întrebări. aceste componente nu se adaugă direct la fereastră.Dialog. ci la panoul contentPane conţinut în aceasta şi obţinut prin metoda public Container getContentPane(). 267 .JDialog. eliberând toate resursele pe care le foloseşte. iar pentru ascunderea ei se invocă metoda public void hide(). Ferestrele de dialog pot fi modale sau nemodale. javax.Programarea orientata pe obiecte în limbajul Java Utilizarea ferestrelor de dialog. în care caz se atribuie un proprietar implicit. În JFC/Swing. până când se încheie lucrul cu fereastra de dialog modală respectivă.swing. în loc de proprietar.awt. La fel ca la JFrame. permiţând adăugarea oricăror componente.JFrame. ea trece în prim plan sau în plan secund împreună cu proprietarul ei. Desenarea In aceasta sectiune vom studia utilizarea ferestrelor de dialog si a unor clase necesare pentru reprezentari grafice.swing. Proprietarul se transmite ca argument al constructorului ferestrei de dialog. pentru a transmite anumite mesaje sau a permite introducerea unor date.awt. ferestrele de dialog se realizează folosind clasa javax. se invocă metoda public void dispose(). să se pună argumentul null. Fereastra de dialog poate avea ca "proprietar" (owner) o instanţă a claselor java. Când este afişată pe ecran o fereastră modală.Frame. java.Dialog sau javax.awt. toate celelalte ferestre existente pe ecran sunt blocate (nu se poate acţiona asupra lor). Pentru afişarea pe ecran a ferestrei de dialog se invocă metoda public void show().

swing. un câmp de text şi două butoane: OK şi Cancel. fereastra de dialog dispare fără să se facă adăugarea textului. Clasa JOptionPane oferă metode statice pentru a creea patru tipuri de ferestre de dialog: .fereastra conţine un mesaj.java este dat un exemplu de aplicaţie. preconfigurate. Dacă se apasă butonul Cancel. Exemplu În fişierul Dialog1. .Severin Bumbaru Clasele Dialog şi JDialog sunt prezentate ceva mai detaliat în indexul de clase.pentru dialog de opţiune (showOptionDialog). programul prin care se realizează dialogul a fost plasat în metoda actionPerformed a clasei IntroducereText care ascultă evenimentele de acţiune generate de butonul menţionat. Când este acţionat butonul. ceeace uşurează programarea. în care se testează diferitele tipuri de ferestre de dialog create cu metodele statice ale clasei javax. Dacă se răspunde prin acţionarea butonului Yes.în fereastra se afişează un mesaj (o întrebare) şi trei butoane de confirmare: Yes/No/Cancel. la apăsarea unuia dintre ele.swing. prin acţionarea butonului "Introducere text". Fereastra principală a aplicaţiei conţine un buton cu inscripţia "Introducere text" şi o arie de text (JTextArea). metoda întoarce valoarea corespunzatoare şi fereastra de dialog dispare. iar metoda întoarce null. fereastra de dialog dispare. Pentru detalii trimitem la documentaţia Java API. Utilizatorul introduce în câmpul de text o valoare (un şir de caractere sau un număr) şi apasa tasta <Enter> sau actioneaza cu mouse-ul butonul OK. În acest scop. se face adăugarea. care întruneşte caracteristicile celor trei tipuri de mai sus. . apare o noua fereastră de dialog. în cazul de faţă. În ambele cazuri fereastra de dialog dispare. Pentru fiecare din aceste patru tipuri de ferestre de dialog există mai multe metode cu numele corespunzător. /* Alegerea culorilor folosind obiectele de culoare predefinite din clasa Color 268 . Întrucât întregul dialog este declanşat. care diferă între ele prin lista de argumente. cu mesajul "Introduceţi un text". Clasa JDialog este folosită pentru realizarea unor ferestre de dialog configurate de programator după dorinţa sa. care conţine mesajul de avertisment "Nu se permite un şir vid". în JFC/Swing a fost creată clasa javax.pentru dialog de confirmare (showConfirmDialog) .JOptionPane.JOptionPane care este prezentată în indexul de clase. . este însă suficient să se folosească ferestre de dialog standard.pentru dialog de mesaj (showMessageDialog) . apare o fereastră de dialog de intrare. apare o nouă fereastră de dialog. iar metoda întoarce şirul introdus în câmpul de text.fereastra conţine o informaţie şi un buton OK care se apasă pentru a închide fereastra. Dacă se acţioneaza butonul OK fără să fi introdus nimic în câmpul de text. care cere confirmarea că acest text trebuie introdus în aria de text. În multe situaţii.pentru dialog de intrare (showInputDialog) . Dacă se introduce un şir în câmpul de text şi se acţioneaza butonul OK sau tasta Enter. iar dacă se răspunde prin apăsarea butonului No sau Cancel.

"Doriti adaugarea textului: "+sirIntrodus+"?"). import javax.append(sirIntrodus+"\n"). arieText=new JTextArea(). boolean terminat=false.add(arieText.swing.YES_OPTION) iug.awt. 269 . setLocation(100. // adaugarea ascultatorului de fereastra JButton buton1=new JButton("Introducere text"). BorderLayout.arieText.awt.event. //import javax. buton1.*.event. addWindowListener(af).equals("")) JOptionPane. arieText.showConfirmDialog(iug.add(buton1.showInputDialog("Introduceti un text"). BorderLayout. setVisible(true).swing. static IntroducereText it=new IntroducereText().exit(0). IUG(String titlu) { // constructorul clasei IUG super(titlu). class Dialog1 { static AF af=new AF(). if(raspuns==JOptionPane. setSize(250.*. 200).addActionListener(it). cp. JOptionPane.CENTER). arieText. "Nu se permite un sir vid!".NORTH). while(!terminat) { sirIntrodus=JOptionPane.*.*.setWrapStyleWord(true).WARNING_MESSAGE). /* clasa imbricata pentru interfata utilizator grafica */ static class IUG extends JFrame { JTextArea arieText. if(sirIntrodus!=null) { if(sirIntrodus. cp. else { int raspuns=JOptionPane. import java. static IUG iug=new IUG("Utilizarea unei ferestre de dialog").setLineWrap(true). 50). Container cp=getContentPane().showMessageDialog(iug.trim(). "Avertisment". // incheierea executarii aplicatiei } } /* Clasa pentru introducerea textului prin fereastra de dialog */ static class IntroducereText implements ActionListener { public void actionPerformed(ActionEvent e) { String sirIntrodus. } } /* Clasa ascultatoare de fereastra */ static class AF extends WindowAdapter { public void windowClosing(WindowEvent e) { System.Programarea orientata pe obiecte în limbajul Java */ import java.

"Doriti adaugarea textului: "+sirIntrodus+"?").showMessageDialog(null.pentru culoarea de prim-plan (a textului). } } else terminat=true. metoda întoarce null."Avertisment". "Nu se permite un sir vid!".awt. Alegerea culorii În multe aplicaţii. } } } /* Metoda principala a aplicatiei */ public static void main(String args[]) { } } Cu privire la metoda actionPerformed din clasa IntroducereText remarcăm următoarele: 1) Instrucţiunea sirIntrodus=JOptionPane.showInputDialog("Introduceti un text"). care întoarce o valoare de tip int. care poate fi egală cu una din cosnstantele YES_OPTION. Cea mai simplă utilizare a acestei clase este utilizarea culorilor predefinite.Color. 2) Instrucţiunea JOptionPane.pentru culoarea de fond.blue. are ca efect afişarea pe ecran a unei ferestre de dialog de intrare. JOptionPane. NO_OPTION sau CANCEL_OPTION care sunt definite în clasa JOptionPane. În consecinţă.yellow. dacă dorim să punem componentei comp culoarea 270 . Pentru aprofundarea utilizării ferestrelor de dialog.WARNING_MESSAGE). De exemplu. recomandăm consultarea capitolului How to Make Dialogs din Java Tutorial. culoarea albastru este reprezentată prin câmpul static Color. Pentru reprezentarea şi manipularea informaţiei despre culoare se foloseşte clasa java. pe care le conţine sub forma de câmpuri statice. În rest. iar culoarea galben prin Color. are ca efect afişarea unei ferestre de dialog de confirmare. public void setForeground(Color color) . la proiectarea interfeţei utilizator grafice este necesar să se impună culorile de fond şi de primplan ale diferitelor componente.Severin Bumbaru terminat=true. are ca efect afişarea unei ferestre de dialog care conţine un mesaj de avertisment. 3) Instrucţiunea int raspuns=JOptionPane. Dacă s-a acţionat butonul Cancel. considerăm că procedura de dialog rezultă clar din textul metodei. Şirul introdus în câmpul de text al acestei ferestre este intors şi atribuit variabilei sirIntrodus.showConfirmDialog(iug. folosind metodele clasei Component public void setBackground(Color color) .

awt.Programarea orientata pe obiecte în limbajul Java de fond albastru şi culoarea de primplan galben.cyan.swing.lightGray. dar am preferat ca cititorii să se familiarizeze cu cele existente în clasa Color).orange. Pentru ascultarea lui s-a creeat clasa AscultaLista.*.event.event. Color. "magenta"}. Fereastra aplicaţiei conţine o listă cu denumirile culorilor predefinite din clasa Color şi un panou pe care se afişează culorile respective. Culorile predefinite sunt folosite şi în exemplul care urmează.este un tablou de instanţe ale clasei Color. // panoul pe care se prezinta culoarea String[] numeCulori={"black". Color. javax. Când se selectează un articol din listă. Color[] tablouCulori={Color.*. Color.awt. "orange". "yellow". În acest scop. Când se selectează o culoare din listă.green.awt. Lista de culori listaCulori din clasa JList este construită pe baza tabloului numeCulori şi deci conţine ca articole numele culorilor (denumirile puteau fi date în limba română. 271 . se determină indicele articolului care a fost selectat şi se setează drept culoare de fond a panoului culoarea cu acelaşi indice din tablouCulori. Color.yellow.*.yellow). În metoda valueChanged a acestei clase.darkGray. Exemplu În fişierul Culori. "lightGray". se observa imediat modificarea corespunzătoare a culorii panoului. Color. vom folosi instrucţiunile: comp. "blue". /* clasa imbricata pentru interfata utilizator grafica */ static class IUG extends JFrame { JPanel panouCuloare.pink. Color. care conţine toate culorile predefinite din aceasta clasă. javax. Color. în care se demonstrează utilizarea culorilor predefinite din clasa java. prin setarea corespunzătoare a culorii de fond a panoului.black.java se dă un exemplu de aplicaţie. în program au fost folosite două tablouri: numeCulori . Color. tablouCulori . "white".blue. Color.magenta}. static IUG iug=new IUG("Alegerea culorii din lista").white.*. class Culori { static AF af=new AF().setBackground(Color.este un tablou de şiruri (String[]) care conţin numele culorilor. Color.gray. "red".swing.blue). java. comp. se generează un ListSelectionEvent. "gray". "darkGray". "pink".red. Color.setForeground(Color. "cyan".Color. /* Alegerea culorilor folosind obiectele de culoare predefinite din clasa Color */ import import import import java. "green". Color. Pentru a afla toate culorile predefinite şi celelalte specificaţii privind clasa Color trimitem cititorii la documentaţia Java API.

// incheierea executarii aplicatiei } } /* Clasa ascultatoare a listei de culori */ static class AscultLista implements ListSelectionListener { public void valueChanged(ListSelectionEvent e) { int indiceCuloare=iug.white}. green.add(panouCuloare. 50). setVisible(true).Severin Bumbaru JList listaCulori. } } /* Metoda principala a aplicatiei */ public static void main(String args[]) { } } Clasa Color Clasa Color încapsulează informaţiile despre culoare. Color. BorderLayout. Container cp=getContentPane(). // crearea panoului pentru culoare cp.setBackground(iug.WEST). culoarea este dată prin trei numere cuprinse în intervalul [0.add(panouCulori. Color[] tablouCulori={Color.black.getSelectedIndex().darkGray. blue) în care fiecare culoare este considerată ca fiind compusă din trei culori fundamentale: roşu.tablouCulori[indiceCuloare]). listaCulori. 200). setLocation(100. Color. addWindowListener(af).listaCulori. // adaugarea ascultatorului de fereastra panouCuloare=new JPanel().panouCuloare. În consecinţă. JScrollPane panouCulori=new JScrollPane(listaCulori). verde şi albastru. cp. IUG(String titlu) { // constructorul clasei IUG super(titlu). În Java AWT se foloseşte modelul de culori RGB (engleză: red. 272 . listaCulori=new JList(numeCulori). setSize(250. BorderLayout. reprezentând ponderile celor trei culori fundamentale. În figura de mai jos este reprezentată schema de combinare a acestor trei culori fundamentale.SINGLE_SELECTION). listaCulori. } } /* Clasa ascultatoare de fereastra */ static class AF extends WindowAdapter { public void windowClosing(WindowEvent e) { System.addListSelectionListener(new AscultLista()).CENTER).setSelectionMode(ListSelectionModel.exit(0). iug. 255].

Saturaţie (engleză: Saturation) este puritatea culorii. Valoarea 0 înseamnă negru (iluminare 0%). se obţin diferite nuanţe de gri. Daca alpha=255.255] şi exprima opacitatea culorii respective.1. nuanţa (Hue) nu are semnificatie. ci şi printr-un număr întreg (de tip int). 60 este galben. Culoarea în sistemul RGB poate fi exprimată nu numai printr-o instanţă a clasei Color. Dacă ponderile celor trei culori sunt egale.7.. g.b=0] la alb [r=255.0. Alte culori: orange: [r=255. destinată monitoarelor cu tub catodic.. culoarea este complet transparentă. constructori şi metode care suportă sistemele de culori sRBG şi HSB.360]. Strălucire (engleză: Brightness) este exprimată de asemenea în procente. r în biţii 16. Dacă alpha=0. toate culorile posibile. g.g=255.g=0.. b exprimate în intervalul [0. culoarea este complet opaca.g=0. în intervalul [0. Sistemul de culori HSB (engleză: Hue. de asemenea. în care cei patru octeţi au.31.g=255.b=0].100].b=0].15 şi b în biţii 0.b=255]. în intervalul [0. r.23. pink (roz): [r=255. deci parametrii Hue şi Saturation nu au 273 . Clasa Color conţine şi un al patrulea câmp. cuprinse intre 0 si 255.. Clasa Color conţine..b=255]. în principiu..b=255] iar culoarea magenta are ponderile [r=255. iar la valoarea 100 culoarea este pură. b şi alpha se exprimă prin numere reale în intervalul [0. Culoarea galbenă are ponderile [r=255.100]. 120 este verde etc. Între aceste valori extreme putem avea diferite opacităţi intermediare.. unde 0 este rosu. În acest sistem.. culoarea cyan (azuriu) are ponderile [r=0. respectiv. de asemenea. de la negru [r=0. Aceasta înseamnă că. g în biţii 8.g=255. Componentele sunt plasate astfel: alpha în biţii 24. parametrii r. dacă o figură cu această culoare se suprapune peste alta. în intervalul [0. care poate avea. exprimată în procente. Standardul sRGB defineşte o variantă standardizată a sistemului RGB. numit alpha.b=175].Programarea orientata pe obiecte în limbajul Java Prin modificarea ponderilor celor trei culori se pot obţine.0]. o maschează complet. deci practic invizibilă. valori întregi în intervalul [0. Saturation and Brightness) ofera o descriere a culorilor independentă de sistemul de afişare. La valoarea 0. valorile componentelor alpha..255].g=175.g=200... folosind următorii trei parametri: Nuanţa (engleză: Hue) care se exprimă în grade.

se ia în consideraţie numai partea fracţionara: de exemplu valoarea 2. dacă se consideră saturaţia şi strălucirea egale cu 1. alb şi galben. mov. darkGray.3333 (1200).0].0 .. Toate aceste culori sunt opace. cyan: h=0. orange. rosu. valorile parametrului Hue (nuanţă) pentru principalele culori sunt: red: h=0. 1. 274 . magenta. lightGray. Diagrama de mai jos dă o reprezentare a culorilor exprimate în sistemul HSB. red. gri. pink. blue: h=0. parametrii Hue.73. deci au componenta alpha cu valoarea 255. culorile negru.6666 (600).73 se consideră echivalentă cu 0. roz.0.5 (1800).8333 (3000) Culoarea neagra (black) se obtine punând strălucirea Brightness=0. Valoarea 100 reprezintă strălucirea maximă. green: h=0.0 (100%). Variabile: Clasa Color conţine variabile statice finale (constante) care sunt instanţieri ale clasei pentru diferite culori tipice: black. respectiv. green. iar culoarea albă (white) se obţine punand saturaţia Saturation=0 şi strălucirea Brightness=1. magenta: h=0. verde. În clasa Color. white yellow. blue. gray.green.6666 (2400). albastru. azuriu.Severin Bumbaru sens. Dacă valorile sunt în afara acestui interval. gri deschis. Acestea sunt. yellow: h=0. culoarea verde va fi reprezentata prin Color. cyan. De exemplu. Dacă se menţine saturaţia la valoarea 0 şi se dau strălucirii diferite valori între 0 şi 1 se obţin nuanţele de gri. Saturation şi Brightness se exprimă prin numere reale (tipul float) în intervalul [0. gri inchis. În aceste condiţii.

31 ai argumentului) este luat în consideraţie. O prezentare mai completă a câmpurilor.creează o culoare opacă cu parametrii r. int b. În dreptul fiecărei rigle există un câmp de text în care se afişează valoarea indicată.. parametrul alpha (bitii 24. public Color(float r.g.1. int g.b împacetaţi în cei patru octeţi ai argumentului rgba. albastru).b sunt numere întregi în intervalul [0. constructorilor şi metodelor clasei Color este dată în Indexul de clase. 1. int getGreen() .255]..Programarea orientata pe obiecte în limbajul Java Constructori: Clasa Color are mai mulţi constructori.întoarce ponderea culorii blue(albastru).b.b daţi ultimii trei octeţi ai argumentului rgb. Exemplul 1: În fişierul TestRGB. în intervalul [0.0]. În partea stângă a ferestrei sunt trei rigle de ajustare (JSlider) pentru cele trei culori fundamentale (roşu. Color darker() .creează o instanţă a clasei Color (deci în sistemul RGB) pornind de la parametrii h.0.întoarce ponderea culorii green(verde).întoarce ponderea culorii red (rosu).java este dat un exemplu de aplicaţie. iar componenta alpha are implicit valoarea 255.în care argumentele r. în care cei patru octeţi sunt parametrii r.. int alpha) . public Color(float r. int getBlue() .. float g. static Color getHSBColor(float h.. float alpha) .g.creează o versiune mai întunecată a acestei culori.similar cu cel precedent. Color brighter() . float s. green. în care r. 255].creează o culoare opacă în sistemul sRGB. boolean hasalpha) .creează o versiune mai luminoasă a acestei culori. s şi b ai culorii respective.0 . float b.r. dintre care menţionăm aici pe cei mai frecvent folosiţi: public Color(int r. blue. verde.. float b) . În partea dreaptă a ferestrei există un panou (JPanel) a cărui culoare de fond corespunde combinaţiei de culori date de cele trei rigle. în întervalul [0.0] într-un număr întreg (int). float b) .b sunt ponderile culorilor fundamentale în intervalul [0. int getAlpha() . reprezentând ponderile culorilor red.g.0 .creează o culoare în sistemul sRGB.transformă parametrii h. indicându-se în plus gradul de opacitate alpha.întoarce componenta alpha(opacitatea culorii).b ai culorii exprimate în sistemul HSB prin numere reale în intervalul [0. Daca al doilea argument este true. float s.0. float b) . public static int HSBtoRGB(float h.g. iar alpha are valoarea implicită 1. int b) . 275 .255].. public Color(int r. exprimaţi is sistemul HSB..0]. 1. în care se testează compunerea diferitelor culori în sistemul RGB. fiind daţi toti cei patru parametri. public Color(int rgb) . de asemenea în intervalul [0. Metode: Menţionăm aici metodele cel mai frecvent utilizate. float g. int g.alpha ai aceleeaşi culori exprimate în sistemul RGB.g.. public public public public public public public int getRed() . public Color(int rgba.s.creează o culoare pornind de la parametrii alpha.

add(hue). panouCuloare=new JPanel(). // culoarea panoului panouCuloare JLabel culoriRGB. 1. setLocation(100.add(panouCuloare.event.0. /* Alegerea culorilor in sistemul HSB (Hue. // panoul pe care se prezinta culoarea Color culoare. BorderLayout. // caseta riglelor de ajustare JPanel panouCuloare. cp. 200).awt.Severin Bumbaru Puteţi ajusta culorile şi urmări efectul produs. Container cp=getContentPane(). Brightness)"). BorderLayout.CENTER). culoriRGB=new JLabel().SOUTH). bright. Fereastra se aseamană cu cea din exemplul precedent. static IUG iug=new IUG("Alegerea culorii in sistemul HSB"+ " (Hue. // pentru afisarea culorilor in sistem RGB IUG(String titlu) { // constructorul clasei IUG super(titlu). La partea inferioară a ferestrei sunt afişate componentele culorii în sistemul RGB.WEST). // ajustarea saturatiei box1. box1. javax. // rigle de ajustare a culorilor Box box1. // crearea panoului pentru culoare cp. Saturation.swing. /* clasa imbricata pentru interfata utilizator grafica */ static class IUG extends JFrame { AjustCuloare hue.ajustare. satur=new AjustCuloare("Saturatie "). Valorile corespunzătoare sunt indicate în câmpurile de text alăturate. // crearea etichetei cu valori RGB cp. saturaţie şi strălucire. puneCuloarea().*.add(box1. class TestHSB { static AF af=new AF(). hue=new AjustCuloare("Nuanta "). BorderLayout. javax.setPaintLabels(true).add(bright).event.java este dat un exemplu de aplicaţie în care se testează alegerea culorilor în sistemul HSB. setSize(500. dar cele trei rigle servesc pentru ajustarea componentelor HSB: nuanţa. satur. ca numere reale în intervalul [0.add(satur).swing.0].*.add(culoriRGB. Brightness) */ import import import import java. // adaugarea ascultatorului de fereastra /* Se creeaza caseta cu dispozitive de ajustare */ box1=Box. // ajustarea nuantei box1.*. } 276 . 50). java. // ajustarea stralucirii bright.awt.*. addWindowListener(af). bright=new AjustCuloare("Stralucire "). // se pune culoarea initiala setVisible(true).createVerticalBox(). Exemplul 2: În fişierul TestHSB. Saturation.

00".substring(0.getMinimumSize()). // incheierea executarii aplicatiei } } /* Metoda principala a aplicatiei */ public static void main(String args[]) { 277 .0f.getGreen()+ " albastru: "+culoare.createHorizontalStrut(5)). // rigla de ajustare a valorii float fval=1. bright.white).createHorizontalGlue()). ajustare.setPaintTicks(true).. } } /* Un "dispozitiv" de ajustare a valorii unei culori */ static class AjustCuloare extends Box implements ChangeListener { JTextField valoare.puneCuloarea().fval.HORIZONTAL. valoare. // modificarea culorii panoului } } /* Clasa ascultatoare de fereastra */ static class AF extends WindowAdapter { public void windowClosing(WindowEvent e) { System. add(new JLabel(culoare)). valoare.createHorizontalStrut(5)). // determinarea valorii reale // in intwervalul 0. add(ajustare).fval)). // valoarea HSB (in intervalul 0.setMajorTickSpacing(20).getValue()/100. 0. 100. valoare=new JTextField("1.setBackground(culoare).Programarea orientata pe obiecte în limbajul Java /* Metoda de determinare a culorii RGB */ void puneCuloarea() { culoare=new Color(Color. add(Box. valoare.setEditable(false).HSBtoRGB(hue. ajustare..4).fval.100).setText((fval+" ")..setMaximumSize(valoare. ajustare=new JSlider(JSlider.1).exit(0).setBackground(Color. satur. culoriRGB.getBlue()). ajustare.X_AXIS).setText("Culori RGB -> rosu: "+ culoare. AjustCuloare(String culoare) { super(BoxLayout.getRed()+" verde: "+culoare. add(valoare). add(Box.1 valoare. valoare.0f. ajustare. } /* metoda de ascultare a deplasarii cursorului riglei */ public void stateChanged(ChangeEvent e) { fval=ajustare.setMinorTickSpacing(10).4)). // camp pentru afisarea valorii HSB JSlider ajustare.. // afisarea valorii iug.RIGHT).addChangeListener(this).. // conversie din HSB in RGB panouCuloare.setHorizontalAlignment(JTextField. add(Box.

pentru alegerea culorii unui panou. alegerea culorii se poate face în trei moduri: . boolean modal. B.0. Exemplu În fişierul SelectCulori. în JFC/Swing este prevazută clasa javax. .title este titlul ferestrei de dialog create. culoarea obţinută este mai deschisă. selectând culoarea prin alegerea cu mouse-ul a punctului de pe panou care are culoarea potrivita (trei butoane alăturate. .awt. indiferent de valorile celorlalte două componente. notate H.Dacă saturaţia şi strălucirea au valori diferite de 0.în sistemul RGB. /* Alegerea culorilor folosind un JColorChooser */ import java. .argumentul boolean modal indică dacă fereastra este modală. .folosind un tablou de culori.event.java se dă un exemplu de aplicaţie în care. respectiv Cancel al selectorului de culoare.JColorChooser. ActionListener okListener.okListener si cancelListener sunt ascultătoarele de acţiune care reacţioneaza la apăsarea butonului OK. constatăm următoarele: . Instanţele acestei clase sunt panouri de selectare a culorii. S. Folosind un JColorChooser.în sistemul HSB.*.c este componenta beneficiară (owner) a ferestrei de dialog create. arată care din cele trei componente se menţine constantă.0. care pot fi folosite atât prin încorporarea lor într-o fereastră obişnuită. JColorChooser chooserPane.*.0.chooserPane este instanţa clasei JColorChooser care se întroduce în fereastra de dialog.0 la 1. Cu cât valoarea strălucirii este mai mare. modificând strălucirea de la 0.Dacă strălucirea este 0. cât şi sub forma unei ferestre de dialog. culoarea se poate ajusta prin modificarea nuanţei. .Severin Bumbaru } } Ajustând valorile prin intermediul riglelor. culoarea este mai deschisă. Cu cât saturaţia este mai mare. de la negru la alb. nuanţa respectivă este mai pronunţată. Alegerea culorii folosind clasa JColorChooser Pentru a alege culoarea în mod interactiv. celelalte două fiind date de coordonatele punctului ales pe panou).String title. valoarea nuanţei nu are efect: în acest caz. . import java. care conţine în ea un JColorChooser şi întoarce culoarea selectată. Pentru a creea o fereastră de dialog. în care fiecare celulă este colorată în altă culoare. ActionListener cancelListener) în care: . .0 se obţin diferite nuanţe de gri. se foloseşte o fereastră de dialog. . iar cu cât strălucirea este mai mare. culoarea obţinută este negru. 278 .swing. folosind trei rigle de ajustare a culorilor fundamentale.awt. în clasa JColorChooser există metoda public static JDialog createDialog(Component c.Dacă saturaţia este 0. în care se găseşte un JColorChooser.

BorderLayout. JDialog dialogCuloare. setVisible(true). cp.getActionCommand().swing. static AscultDialog ascultDialog=new AscultDialog(). setSize(350. butonCuloare.show().CENTER).selectorCuloare. } } /* Metoda principala a aplicatiei */ 279 .exit(0). JButton butonCuloare=new JButton("Schimbarea culorii"). // incheierea executarii aplicatiei } } /* Ascultator actiuni fereastra dialog */ static class AscultDialog implements ActionListener { public void actionPerformed(ActionEvent e) { if(e. selectorCuloare. } } /* Ascultarea butonului de comanda */ static class AscultButon implements ActionListener { public void actionPerformed(ActionEvent e) { iug.setBackground( iug. } } /* Clasa ascultatoare de fereastra */ static class AF extends WindowAdapter { public void windowClosing(WindowEvent e) { System. static AscultButon ascultButon=new AscultButon().add(butonCuloare.getColor()). butonCuloare. class SelectCulori { static AF af=new AF().add(panouCuloare.setToolTipText("Selectarea culorii panoului"). ascultDialog). Container cp=getContentPane(). static IUG iug=new IUG("Alegerea culorii folosind JColorChooser"). IUG(String titlu) { // constructorul clasei IUG super(titlu). true. ascultDialog. setLocation(100. // crearea panoului pentru culoare cp.addActionListener(ascultButon). 200).*.panouCuloare.createDialog(butonCuloare. selectorCuloare=new JColorChooser(). BorderLayout. 50). dialogCuloare=JColorChooser. addWindowListener(af). /* clasa imbricata pentru interfata utilizator grafica */ static class IUG extends JFrame { JPanel panouCuloare.SOUTH). "Alegerea culorii".dialogCuloare. // panoul pe care se prezinta culoarea JColorChooser selectorCuloare. // adaugarea ascultatorului de fereastra panouCuloare=new JPanel().Programarea orientata pe obiecte în limbajul Java import javax.equals("OK")) iug.

culoarea curentă.awt. desenarea se poate face pe orice componentă grafică. text stilizat şi alte construcţii grafice. care permit trasarea de desene pe suprafaţa componentelor grafice realizate pe diverse dispozitive fizice. axa Ox este orientată catre dreapta. . Aceasta este clasa de bază a tuturor contextelor grafice. Pe fiecare platformă. 280 . Ne vom rezuma aici numai la câteva noţiuni elementare. Pentru a se asigura independenţa de platformă. In principiu.awt. Pentru desenare se mai folosesc frecvent şi clasele JPanel şi JLabel. toate coordonatele din desen sunt raportate la această origine. având ca unitate de măsură pixelul (punctul de pe ecran). în Java API a fost introdusă clasa abstractă java. în mediul de execuţie Java.Canvas.Graphics.Severin Bumbaru public static void main(String args[]) { } } Elemente de grafică Java API ofera programatorilor posibilităţi ample privind realizarea de desene. Există însă clasa java. Contextul grafic Modul de realizare a imaginilor şi desenelor este strâns dependent atât de echipament (hardware) cât şi de sistemul de operare. care conţine toate câmpurile şi metodele acestei clase. Studiul poate fi apoi continuat cu secţiunea 2D Graphics a aceluiaşi tutorial.decupajul curent (dreptunghiul în interiorul căruia se trasează desenul). Coordonatele se exprimă în numere întregi (int). . trebuie să existe o implementare a contextului grafic. . ale cărei instanţe sunt simple panouri destinate desenării (în engleză Canvas este pânza pictorului). Un obiect din clasa Graphics încapsulează informaţia de stare a contextului grafic la care se referă şi anume: . dar este specifică platformei respective.referinţa la obiectul din clasa Component (sau dintr-o subclasa a acesteia) pe care se desenează. Pentru aprofundare recomandăm lectia Working with Graphics din Java Tutorial. iar axa Oy este orientată în jos.fontul curent. utile în realizarea unor aplicaţii grafice simple. . .operaţia logică pe pixeli curentă (XOR sau paint).alternarea curentă de culori pentru operaţia pe pixeli XOR.o translaţie a originii sistemului de coordonate. . Sistemul de coordonate folosit pentru grafică are originea în colţul din stânga sus al componentei. adică o extindere a clasei Graphics.

int width.setează operaţiile pe pixeli la modul XOR. Principalele metode ale clasei Graphics sunt următoarele: public abstract Graphics create() . int dx. deci modul efectiv în care se realizează funcţiile respective.creează şi întoarce un nou obiect din clasa Graphics. int y. int x2.y) al sistemului de coordonate curent.. adică desenarea se face peste fondul existent. public abstract void setPaintMode() . clasa abstractă Graphics conţine acele metode. y+dy).întoarce dreptunghiul de decupare curent.setează culoarea de desenare curentă. int height) setează dreptunghiul de decupare curent. iar axa 0y . public abstract Font getFont() . Practic. public abstract Rectangle getClipBounds() . dacă un pixel nou plasat are aceeaşi culoare curentă cu cea existentă anterior în acelaşi loc. int width. public abstract void setXORMode(color c1) . ea va fi înlocuită cu culoarea curentă. public abstract Graphics create(int x. Pe programatorul de aplicaţii sau miniaplicaţii în Java nu îl interesează însă acest lucru.setează fontul curent. având lăţimea width şi 281 . public abstract Color getColor() . aceasta înseamnă că. Axa 0x este îndreptată spre dreapta.întoarce culoarea de desenare curentă. int width. int dy) . invers. fără să se preocupe de modul în care acestea vor fi executate. Conţinutul concret al acestor metode. deoarece el foloseşte în programele sale metodele clasei abstracte Graphics.întoarce fontul curent.translatează originea sistemului de coordonate în punctul (x.0) se găseşte în colţul din stânga-sus al dreptunghiului de desenare. având originea (x+dx. public abstract void drawRect(int x. int y2) .y1) până în punctul (x2. int y. int height. public abstract void setFontMetrics(FontMetrics fm) . int y. int y) . folosinduse culoarea de desenare curentă. care este o copie a obiectului pentru care se aplică această metodă.setează metrica fontului curent. public abstract void translate(int x. public abstract FontMetrics getFontMetrics() . int y1.întoarce metrica fontului curent. însă cu o noua translaţie a originii (x. public abstract void copyArea(int x.se traseaza o linie dreaptă din punctul de coordonate (x1.in jos. dacă pixelul existent anterior avea culoarea c1. fără a lua în consideraţie culoarea fondului.y). int height) creează şi întoarce o copie a obiectului din clasa Graphics căruia i se aplică. int y. care trebuie să existe în orice context grafic.se trasează un dreptunghi cu colţul din stânga sus în punctul (x. int width. public abstract void drawLine(int x1. lăţimea width şi înălţimea height într-o noua zonă de aceleaşi dimensiuni. public abstract void setColor(Color c) .setează operaţia logică pe pixeli curentă la modul paint.copiaza suprafaţa dreptunghiulara cu originea (x.Programarea orientata pe obiecte în limbajul Java Originea sistemului de axe (punctul de coordonate 0. int height) .y) şi cu valori noi valori ale lăţimii şi înălţimii dreptungiului de desenare (suprafeţei de decupare). deci de dispozitivul fizic pe care se face desenarea şi de sistemul de operare folosit. depinde de contextul grafic real. public abstract void setClip(int x.y). adică se alternează pixelii de culoare curentă cu cei din culoarea c1. public abstract void setFont(Font f) . ea va fi înlocuita cu c1.y2).

int height) şterge conţinutul dreptunghiului de coordonate şi dimensiuni specificate. int width. public abstract void drawPoligon(Poligon p) . int arcHeight) .trasează un poligon cu nPoints vârfuri. int width.desenează un dreptunghi astfel luminat. luând în consideraţie şi iluminarea. int height) dreptunghiul specificat.Severin Bumbaru înălţimea height. Unghiul 0 este corespunzator poziţiei de la ora 3 a acului de ceasornic. int width. int y. int[] yPoints. . unde arcWidth si arcHeight sunt respectiv diametrul orizontal şi diametrul vertical al arcelor de rotunjire.y) sunt date în tabelele xPoints şi yPoints. public abstract void fillRect(int x. int height.trasează poligonul specificat ca argument. int nPoints) . int y.umple cu culoarea curentă interiorul unui dreptunghi tridimensional. încât el apare că iese din suprafaţa de baza. height). int y. int y. public abstract void drawArc(int x. care se înscrie în public abstract void fillOval(int x. int arcAngle) . int height.y) sunt date în tabelele xPoints şi yPoints. int y. height). int width. situate în punctele ale căror coordonate (x. int width. int y. umplându-l cu culoarea de fond. public abstract void drawPolyline(int[] xPoints. se trasează efectiv numai arcul care începe de la unghiul startAngle şi se extinde pe un unghi egal cu arcAngle. public abstract void draw3DRect(int x. int arcHeight) . int y. Unghiurile sunt măsurate în grade.se desenează ovalul înscris în dreptunghiul cu colţul din stânga sus în punctul (x. height). int[] yPoints. int width. public abstract void fill3dRect(int x. int nPoints) . sau este scufundat în aceasta suprafaţă.umple cu culoarea curenta un poligon cu nPoints vârfuri.umple cu culoarea curentă poligonul specificat ca argument. int width. int x. int arcWidth. int startAngle. public abstract void fillPoligon(int[] xPoints. public abstract void fillArc(int x. public abstract void fillPoligon(Poligon p) . boolean raised) . public abstract void drawRoundRect(int x.y) sunt date în tabelele xPoints şi yPoints. int height) umple cu culoarea curentă interiorul dreptunghiului cu colţul din dreapta sus în punctul (x. int y.y) şi cu dimensiunile (width. dacă raised=true. int arcAngle) .trasează un dreptunghi cu colţurile rotunjite.umple cu culoarea curentă interiorul unui dreptunghi cu colţurile rotunjite.trasează şirul 282 . care trece prin punctele ale căror coordonate (x. boolean raised) .se umple cu culoarea curentă conţinutul ovalului înscris în dreptunghiul cu colţul stânga sus în punctul (x. public abstract void clearRect(int x. int startAngle. situate în punctele ale căror coordonate (x. int width. numărul de puncte este nPoints.umple cu culoarea curentă sectorul mărginit de arcul specificat prin parametri şi de razele de la capete. int nPoints) . int height) .y) şi de dimensiuni (width.y) şi cu dimensiunile (width. int y. int height. public abstract void drawPoligon(int[] xPoints. int y. public abstract void drawString(String str. int[] yPoints.se desenează un arc circular sau eliptic. dacă raised=false. int width. int height. int y) . int height. iar sensul pozitiv al unghiurilor este cel contra acelor de ceasornic. int height. int arcWidth. public abstract void fillRoundRect(int x. public abstract void drawOval(int x. Putem să ne imaginăm că din elipsa înscrisă în acest dreptunghi şi având centrul în centrul dreptunghiului. int width.trasează o linie frântă.

începând cu caracterul cu indicele offset. int y) . de asemenea. programatorul doreşte să solicite explicit desenarea. s-a creat clasa PanouDesen ca o extensie a clasei Canvas.Component. folosind în acest scop contextul grafic g primit ca argument. astfel încât să se traseze diferite desene: un dreptunghi gol. în clasa java. Metoda paint nu este invocată explicit în program. metoda paint() este redefinita. metoda paint trebuie redefinită în program pentru orice componentă pe care dorim să se traseze un desen. care este derivata din clasa Canvas In clasa PanouDesen. /* Testarea clasei Graphics In fereastra aplicatiei iug se introduce suprafata de desenare panouDesen din clasa PanouDesen. În fereastra aplicaţiei s-a introdus o instanţă a clasei PanouDesen. int y) . foloseşte metoda public void repaint() Aceasta metodă care există. În acest scop. Sau testat în acest fel metodele clasei Graphics.y).trasează un şir de caractere conţinute în obiectul iterator. astfel incat sa traseze mai multe desene. În schimb. baza primului caracter al şirului este în punctul de coordonate (x. public abstract void drawString(AttributedCharacterIterator iterator. int offset.awt. singurul ei rol fiind de a apela metoda paint. baza primului caracter se găseşte în punctul de coordonate (x. Contextul grafic nu este instanţiat de către programator. a fost redefinită metoda paint(). folosind fontul şi culoarea curente.y).trasează length caractere din tabloul data.awt. nu trebuie redefinită. care specifică nu numai caracterele propriuzise ci şi fontul fiecărui caracter.y).Component (rădăcina ierarhiei de clase a componentelor) există metoda public void paint(Graphics g) Această metodă traseaza efectiv desenul. În această clasă. int length. fontul şi culoarea sunt cele curente. un dreptunghi plin cu colţurile rotunjite.java este dat un exemplu de aplicaţie simplă. un dreptunghi plin. Dacă. un oval gol. Ea este invocată implicit (de către maşina virtuală Java) atunci când componenta respectivă este afişată pe ecran sau îşi modifică dimensiunile şi/sau poziţia. testandu-se metodele clasei Graphics */ 283 . Exemplul 1: În fişierul Desen. un oval plin. int x. în clasa java. un dreptunghi gol cu colţurile rotunjite. int x.Programarea orientata pe obiecte în limbajul Java de caractere str. În aceast scop se folosesc în metoda paint metodele de desenare ale clasei Graphics. baza primului caracter este în punctul de coordonate (x. ci este transmis acestei metode de către maşina virtuală Java. o linie frântă şi un poligon. Metodele paint si repaint Pentru desenarea pe suprafaţa unei componente. în care se testează diferite metode ale clasei Graphics. totuşi. public abstract void drawChars( char[] data.

drawArc(150. import javax.40.25. import java.*.setColor(Color.setColor(Color.red). g. panouDesen=new PanouDesen(). g. g.40. g.40. yp={100.Severin Bumbaru import java. IUG(String titlu) { super(titlu).add(panouDesen).5.150).fillOval(50.40.40.setColor(Color. static class IUG extends JFrame { PanouDesen panouDesen.fillArc(150. getContentPane(). addWindowListener(sfarsit).95.drawRoundRect(150.black).exit(0).*.40.10).55}.10. setSize(220.120.70.fillRoundRect(150. g.green). static IUG iug=new IUG("Exemplu de desenare").setColor(Color.drawOval(5.150}.130).55.drawArc(100.-5.40.40.25).25. ylf={100.5.white).ylf.125}.80}.40.100. g.90. g.*.black).75.30. 284 . g.25).drawRoundRect(100. g. } } static class Sfarsit extends WindowAdapter { public void windowClosing(WindowEvent e) { System.blue).40. class Desen { static Sfarsit sfarsit=new Sfarsit(). g.black).40. g. } } static class PanouDesen extends Canvas { public void paint(Graphics g) { setBackground(Color. g.drawOval(50. g. int[] xlf={5.10.75.5.awt.5.130). g.65.yp. g. setVisible(true).85. int[] xp={15.awt.25.drawPolygon(xp.5).6).green).5.10.40.setColor(Color.75.50.setColor(Color.40.-5.40.25).drawRect(5.5.10). g.event.drawPolyline(xlf. setLocation(200.10). g. g.setColor(Color. g.130).25.fillRect(50.25.drawRect(50.25). g. g.swing.40.40.-5.25.40.80.setColor(Color. g.40.25).magenta).200).25).

yp. Trasarea functiei se face fie cand se selecteaza o noua functie. în care se introduc de la tastatură marginile inferioară şi superioară a intervalului în care se trasează funcţia (sub forma de numere reale) şi numărul de subintervale în care se împarte acesta.int y[]. Folosind aceste date se calculează scările pe x şi y. Se selecteaza functia de trasat si se introduc valorile marginilor intervalului de reprezentare.fillPolygon(xp. Pentru suprafaţa de afişare s-a creat clasa Grafic. pe care se trasează graficul. În acest scop. Scările de reprezentare pe cele două axe se aleg automat. Se determină apoi ymax şi ymin. } } public static void main(String args[]) { } } Exemplul 2: În fişierul GraficeFunctii. derivată din clasa Canvas. în care vectorii x şi y conţin coordonatele punctelor prin care trece curba.panoul fct. fie cand este selectat unul din campurile de text si se apasa tasta <Enter>. /* Aplicatie de trasare a graficelor unor functii. derivată din clasa JPanel şi s-a folosit gestionarul de poziţionare GridLayout. care conţine o listă de selectie a funcţiei de reprezentat şi trei câmpuri de text. se calculează mai întâi valorile reale ale funcţiei de reprezentat. în care se afişează eventualele mesaje de eroare. completându-se cu ele vectorul real valy. În acest scop.java este dat un exemplu de aplicaţie pentru trasarea graficelor unor funcţii. Daca se introduc date gresite. astfel încât graficul să ocupe întreaga suprafaţă de desenare. ci apare un mesaj de eroare */ 285 . ea este derivată din clasa WindowAdapter şi implementează interfeţele ActionListener şi ItemListener.5). Clasa Actiuni interceptează evenimentele generate de fereastra principală.eticheta mesaj. folosind metoda drawPoliline(int x[]. În fereastra aplicaţiei s-au pus: . iar xmin şi xmax sunt date. după care se calculează coordonatele pe desen ale punctelor.setColor(Color.suprafaţa de afişare gr. Aceste calcule se fac în metoda calcul() din clasa Actiuni. Trasarea graficului se face sub forma unei linii frânte.Programarea orientata pe obiecte în limbajul Java g. nu se traseaza functia. . completându-se astfel vectorii x şi y. g.int nrPuncte).yellow). iar dimensiunile suprafeţei de desenare se determină prin metodele getWidth() şi getHeight(). câmpurile de text şi lista de selecţie a funcţiilor. Pentru panoul fct a fost creată clasa Functii. . iar trasarea graficului se face în metoda paint() din clasa Grafic.

} // Introducerea datelor si calcularea coordonatelor static class Functii extends JPanel { // Componenta de selectare a functiei JLabel lab=new JLabel("Alegeti functia de reprezentat"). public static void main(String args[]) { JFrame fp=new JFrame("Grafice de functii").*.add("x^2"). static Label mesaj=new Label().500). cp. static boolean trasare=false.setSize(500. yabsc.2)). xord. // Constructorul clasei Functii Functii() { // Adaugarea de functii la lista de optiuni f. // Adaugarea componentelor 286 .event. f.green). Choice f=new Choice(). import java. f.add(mesaj.swing.add("cos(x)").cyan). // inaltimea si latimea suprafetei de desenare si pozitiile axelor static int inaltime.add("cos(x)/sqrt(1+x*x)").setBackground(Color. static Functii fct=new Functii(). // indicele functiei care se reprezinta grafic // Tabele de coordonate ale punctelor graficului functiei static int x[]=new int[nrNoduri].awt. // Campurile de text pentru introducerea marginilor intervalului // si numarului de subintervale JTextField inf=new JTextField("-6."South"). static Grafic gr=new Grafic(). // numarul de subintervale static int nrNoduri=nrPasi+1. JTextField pasi=new JTextField("200"). f. f.setBackground(Color. y[]=new int[nrNoduri].*. cp. static int nrPasi=200. gr. // numarul de puncte ale graficului static int indFunc."North").28").28"). JTextField sup=new JTextField("6.add(fct. fp. cp."Center").add(gr. latime.awt.addWindowListener(act). import javax.1*x))*cos(x)"). f.add("sin(x)").Severin Bumbaru import java. fp. f. fp. // Setarea gestionarului de pozitionare setLayout(new GridLayout(4.getContentPane(). class GraficeFunctii { static Actiuni act=new Actiuni().add("exp(-abs(0.setVisible(true).add("x^3").*. mesaj. Container cp=fp.add("log(1+x^2)-1").

cos(x).0+x*x).//Se calculeaza coordonatele punctelor graficului gr. add(new Label("Marginea inferioara a intervalului: ")).addActionListener(act). add(new Label("Marginea superioara a intervalului: ")).addActionListener(act).addItemListener(act). } } // Captarea si tratarea evenimentelor static class Actiuni extends WindowAdapter implements ActionListener.log(1+x*x)-1. case 1: return x*x*x.sin(x).exit(0). } public void actionPerformed(ActionEvent e) { reprezinta().sqrt(1. sup. add(inf). } } // Calcularea coordonatelor tuturor punctelor graficului void calcul() throws Exception { double xmin.setText("").//Se traseaza graficul functiei } catch(Exception e) { mesaj.1*x))*Math. ItemListener { public void windowClosing(WindowEvent e) { System.exp(-Math.Programarea orientata pe obiecte în limbajul Java add(new Label("Alegeti functia de reprezentat: ")).cos(x).setText("eroare: "+e). } public void reprezinta() { try { calcul().pas.cos(x)/Math. } // Calcularea valorii functiei in punctul de abscisa x double func(double x) { switch(indFunc) { case 0: return x*x. } public void itemStateChanged(ItemEvent e) { reprezinta().abs(0.repaint().addActionListener(act). } return 0. case 4: return Math. // Initializari mesaj.scarax. case 3: return Math. case 5: return Math. add(f). // Adaugarea la componente a interceptorului de evenimente inf. add(sup).xmax.0.ymax. add(pasi). 287 .ymin. add(new Label("Numarul de subintervale pentru trasare: ")).scaray. pasi. case 6: return Math. case 2: return Math. f.

drawLine(0. i++) { if(valy[i]>ymax) ymax=valy[i]. // Trasarea axelor de coordonate g. } // Determinarea pozitiilor pe desen ale axelor de coordonate yabsc=inaltime+(int)Math. trasare=true. g.yabsc.y. for (int i=1. x=new int[nrNoduri].latime. } // Determinarea scarilor de reprezentare pe cele doua directii scarax=latime/(xmax-xmin). // Determinarea valorilor minima si maxima ale lui y ymin=valy[0]. i<nrNoduri.setColor(Color.getText()). } 288 . } } // Componenta pe care se traseaza desenul static class Grafic extends Canvas { // Metoda de trasare a graficului public void paint(Graphics g) { if(!trasare) return.sup.getText()).inf.Severin Bumbaru trasare=false.// tabloul ordonatelor // Preluarea indicelui functiei selectate indFunc=fct. xord=(int)Math.drawPolyline(x.inaltime). x[i]=(int)Math.yabsc).getWidth().pasi.f. // se afla indicele functiei // Determinarea dimensiunilor suprafetei de desenare inaltime=gr.parseInt(fct.round(ymin*scaray).getHeight().func(xmin+i*pas). if(nrP != nrPasi) { nrPasi=nrP.nrNoduri). i<nrNoduri. i++) valy[i]=fct.round((valy[i]-ymin)*scaray).getText()). i++) { y[i]=inaltime-(int)Math. // Lungimea subintervalului double valy[]=new double[nrNoduri]. // Trasarea curbei (sub forma de linie franta) g. // marginea din stanga xmax=Double. if(valy[i]<ymin) ymin=valy[i]. if(xord>=0 && xord<=latime) g.setColor(Color. } xmin=Double.drawLine(xord.round(-xmin*scarax). // inaltimea suprafetei de desenare latime=gr.repaint(). scaray=inaltime/(ymax-ymin). // Preluarea datelor introduse in campurile de text int nrP=Integer.0. nrNoduri=nrPasi+1.parseDouble(fct. // latimea suprafetei de desenare // Calcularea ordonatelor punctelor graficului for (int i=0. if(nrP<1) throw new Exception("Numar de intervale incorect"). // marginea din dreapta if(xmin==xmax) throw new Exception("xmin==xmax").round(i*pas*scarax). // Calcularea coordonatelor de pe desen ale punctelor graficului for(int i=0. if(yabsc>=0 && yabsc<=inaltime) g.xord. ymax=valy[0]. pas=(xmax-xmin)/nrPasi. y=new int[nrNoduri].getSelectedIndex().blue).red). i<nrNoduri. gr.parseDouble(fct.

Se redefineste în program metoda repaint? Nivel 2 1. Ce conţine o fereastră de dialog de intrare şi cum este ea utilizată? 9. Ce conţine o fereastră de dialog de confirmare? 8. 9. 8. Care tipuri de ferestre pot fi create folosind metodele clasei JOptionPane? 6. 2. Ce conţine o fereastră de dialog de mesaj? 7. Cum este invocată metoda paint? 20. Prin ce tip de date se exprimă componentele modelului HSB şi în ce interval de valori? 289 . Care este culoarea pentru care toate cele trei culori fundamentale au valoarea 255? 12. Care este culoarea pentru care cele trei culori fundamentale RGB au valoarea 0? 11. Prin ce metodă se afişează pe ecran o fereastră de dialog? 4. Pe ce fel de componente se poate face desenarea? 14. 6. În ce scop este redefinită metoda paint? 21. La ce foloseşte clasa JColorChooser? 13. Ce este contextul grafic? 17. Ce trebuie să conţină corpul metodei paint pentru a se trasa un desen? 22. La ce foloseşte metoda repaint? 23. Care este sistemul de coordonate pentru reprezentări grafice? 15. 5. 7.Programarea orientata pe obiecte în limbajul Java } } Întrebări Nivel 1 1. Ce este modelul HSB? 10. Ce sunt ferestrele de dialog? Ce deosebire există între ferestrele de dialog modale şi cele nemodale? Ce sunt ferestrele de dialog standard? Cum se creeaza ferestrele de dialog standard? Cum se stabileşte culoarea de fond a unei componente? Ce este culoarea de prim plan a unei componente şi prin ce metodă se modifică? Ce sunt instanţele clasei Color? Care este principalul model de culori folosit în Java? Prin ce tip de date se exprimă culorile în sistemul RGB şi care este intervalul în care acestea iau valori? 10. Prin ce metode se închide o fereastră de dialog? 5. 3. Prin ce clasă abstractă este reprezentat contextul grafic în Java API? 18. Prin ce clasă se realizează ferestrele de dialog în JFC/Swing? 2. Care este unitatea de măsură folosită pe axele de coordonate pentru reprezentări grafice? 16. 4. Ce relaţie există între fereastra de dialog şi proprietarul ei? 3. În ce clasă este declarată metoda paint şi ce rol are ea? 19.

0? 12. Ce modele de culori se folosesc în JColorChooser? 15. Cum se creează o instanţă a clasei JColorChooser? 13. Pentru ce fel de culori HSB saturaţia are valoarea 0. Ce câmpuri conţine un obiect al clasei Graphics? 16. Unde se plasează în program redefinirea metodei paint? 290 . Ce fel de metode conţine clasa Graphics? 17.Severin Bumbaru 11. Cum poate fi afişat un JColorChooser sub formă de fereastră de dialog? 14.

numite şi noduri sau pagini. 291 Introducere în HTML Deşi prezentarea limbajului HTML nu constituie un obiectiv al acestui manual. vom da aici unele noţiuni introductive asupra acestui limbaj. unite între ele prin legăturica în Figura 1. 291 . Ce este un hipertext Hipertextul (engleză: hypertext) este o colecţie de documente. fiind utile pentru o mai bună înţelegere a utilizării appleturilor. Crearea şi utilizarea appleturilor Introducere în HTML Ce este un hipertext Ce este WWW Ce este HTML Ctructura documentului HTML Carcaje de formatare a textului folosite frecvent Legaturi catre alte pagini Marcajul APPLET Utilizarea marcajelor HTML în textele introduse în componentele JFC/Swing Applet-uri Clasa Applet întrebări.Programarea orientata pe obiecte în limbajul Java Introducere în HTML.

Severin Bumbaru . În estenţă. Prin aceste marcaje se indică legăturile către alte documente şi către 292 . ci cu un program special numit navigator sau browser. În limba engleză. "pânză de păianjen". Netscape Navigator şi Internet Explorer. iar pentru marcarea paginilor de WWW. cu scopul de a însera în ele legăturile necesare. să se adopte o convenţie privind modul în care se însereaza în pagina de hipertext legăturile către alte pagini. ale cărui noduri sunt raspândite în întreaga lume. pagina curentă se schimbă cu pagina către care indică legătura respectivă. Utilizatorul poate naviga pe această reţea. sub forma unui cuvânt sau unui grup de cuvinte puse în evidenţă prin subliniere. Ce este HTML HyperText Markup Language (HTML) este un limbaj de marcare a hipertextelor. colorare sau prin ambele procedee. Dacă se face click cu mouse-ul pe o astfel de "legătura". Paginile (nodurile) hipertextului sunt stocate sub forma de fişiere. de regulă. Documentele sunt stocate sub formă de fişiere pe diferite calculatoare. în prezent. situate pe un singur calculator. Putem deci considera că WWW este perceput de utilizator ca un hipertext. "reţea". care acţioneaza ca servere de web. desigur. Pentru utilizatorul care vede pe ecran pagina respectivă. numite marcaje sau taguri. care conţine nişte simboluri speciale. folosind un program numit browser de web (navigator). Transmiterea prin Internet a paginilor WWW se face folosind un protocol special. se foloseşte un limbaj numit HTML. ceeace sugerează legaturile existente între noduri într-un hipertext. o pagină HTML este un fişier de text ASCII. Citirea unui asemenea hipertext nu se face cu un editor de texte obişnuit. Asadar. această legătură apare. Ce este WWW World-Wide Web (WWW) este un sistem de regăsire a informaţiei distribuite pe Internet. WWW este o astfel de "pânză de păianjen" care acopera întreaga lume şi ale cărei noduri sunt documente.Figura 1 Este necesar. sau pe mai multe calculatoare legate în reţea. Cele mai răspândite browsere de web sunt. web înseamnă "plasa". numit HTTP (Hypertext Transfer Protocol).

.Figura 2 Pentru crearea de documente HTML se poate folosi un editor de text simplu.Programarea orientata pe obiecte în limbajul Java appleturi. astfel: <HTML><HEAD>Antetul documentului </HEAD><BODY>Corpul documentului </BODY></HTML> Antetul documentului conţine. dar nu este permis ca domeniile lor să se intersecteze. Acelaşi document poate fi pus în pagina. În limbajul HTML nu se face distincţie în marcaje între literele mari şi cele mici. ca în Figura 2. </HTML> este echivalent cu tagul <html> . deoarece întreaga informaţie despre structură şi formatare este conţinuta în marcaje (taguri).. Mult mai comoda este folosirea unor editoare speciale de pagini Web. titlul acestuia şi informaţii despre autor. opţional. iar pe ecran se vede documentul sub forma în care acesta apare şi in browser. dar .. de asemenea. tipul de document etc. . Fiecare marcaj (tag) este de forma <tag> .. care prezintă interfaţă utilizator grafică.. cum sunt Netscape Composer sau Front Page. ca în Figura 2. deci tagul <HTML> .a. informaţii privind formatarea documentului şi altele. care are forma: 293 .. </html>. Aceste marcaje pot fi cuprinse unul în altul.b. </tag>. deci începe printr-un nume de marcaj (tag) cuprins între paranteze unghiulare şi se termină prin acelaşi marcaj. Structura documentului HTML Un document HTML are urmatoarea structură: <HTML> <HEAD> Antetul documentului </HEAD> <BODY> Corpul documentului </BODY> </HTML> Modul de punere în pagină nu are importanţă. de exemplu. imagini sau secvenţe audio incluse în document.în acest caz . O componentă importantă a antetului este titlul documentului. în mod ASCII. fiecare document HTML începe cu marcajul <html> şi se termină cu </html>.cel care creează documentul trebuie să cunoască bine sintaxa HTML şi toate tagurile acestuia. dându-se. Astfel. având în faţa numelui simbolul / (slash).

m este mai lat decat i). gray (gri). white (alb). când se ajunge la marginea din dreapta a paginii.. teal (verde inchis). Se poate. blue (albastru). Culoarea fondului se indică prin parametrul bgcolor=culoare. Parametrii din marcajul <font > sunt face=formă. Deosebirea între Serif şi SansSerif este prezentă. fiecare paragraf începe de la capăt de linie. În acest scop. Primele două au caractere de lăţime variabilă (de exemplu. se pot folosi diferite forme de caractere. iar ultimul are toate caracterele de aceeasi lăţime (exemplu: în cuvantul lăţime. olive (oliv). care se afişează pe ecran. green (verde). unde numele culorilor sunt aceleaşi ca pentru caractere. navy (bleu marin).Severin Bumbaru <TITLE>Titlul documentului</TITLE> Titlul este un text. trei forme care sunt disponibile pe orice platformă: Serif. cum se poate observa comparând caracterele din cuvintele de mai jos: Serif SansSerif Indicarea fontului Se numeşte font tipul de literă folosit într-un text. Acestea sunt liniuţele mici care delimitează unele linii ale literelor. Există. aqua (albastru deschis). S-a menţionat mai sus cum pot fi indicate forma şi culoarea caracterelor dintr-un paragraf ca parametri în marcajul <P>. culoarea caracterelor şi forma caracterelor din paragraful respectiv. silver (argintiu).awt. sansSerif si Monospace. purple (purpuriu). respectiv absenţa serifurilor. În funcţie de platformă. totuşi. m şi i au aceeaşi lăţime). yellow (galben). lime (verde deschis). unde culoare poate fi: black (negru). </P>. trecerea la linie nouă se face automat.Color. folosirea marcajului de sfârşit de paragraf </P> nu este obligatorie. Forma şi culoarea se indică în acelaşi mod ca în marcajul <P>. scris cu astfel de caractere. totuşi. Corpul documentului este documentul propriu-zis. forţa trecerea la linie nouă prin marcajul <br> (prescurtare de la break). În marcajul <P> se pot introduce şi indicaţii privind culoarea de fond. Exista însă şi situaţii în care un anumit font se foloseşte numai într-o porţiune de paragraf. Forma caracterelor cu care este scris paragraful este indicată prin parametrul face=forma. Aceste indicaţii se dau prin parametri de forma nume=valoare. Totusi. care apare în bara de titlu a browserului care vizualizează documentul respectiv. sau se extinde pe mai multe paragrafe. inclusiv legăturile conţinute în documentul respectiv. Atunci când documentul este vizualizat în browser. În interiorul paragrafului. se foloseşte marcajul <font parametri> text</font>. fuchsia (roz). red (rosu). maroon (maron). Termenul este preluat din tipografie şi se referă la reprezentarea formei şi mărimii unui caracter. Marcaje de formatare a textului folosite frecvent Marcarea paragrafelor Fiecare paragraf este cuprins între marcajele <P> . Remarcăm că sunt alte nume de culori decât cele din clasa java. Culoarea caracterelor se indică prin parametrul color=culoare. Mărimea este un număr întreg cu sau 294 . color=culoare şi size=mărime.

textul HTML <H1>Primul titlu></H1><H2>Al doilea titlu</H2><H3>Al treilea titlu</H3> apare pe ecran sub forma Primul titlu Al doilea titlu Al treilea titlu Se poate astfel continua până la marcajul <H6>.. </I> pentru text cursiv (engleză: italic). <strike> .. Exemplu Textul HTML următor: <font face=serif color=purple size=+1> proba de text </font> va apare scris pe ecran sub forma proba de text Nu este obligatoriu să se indice toţi cei trei parametri. de exemplu. De exemplu... subliniat etc. Indicarea stilului În afară de forma.. textul se caracterizează şi prin stil: păstrând forma fontului. stilul textului se indică prin marcaje speciale: <B> . </U> pentru text subliniat (engleză: underline). cursiv. Se folosesc numai cei prin care noul font diferă de cel anterior. Pentru marcarea titlurilor se foloseşte marcajul <Hn>titlu</Hn> în care n este un număr întreg cuprins în intervalul [1. <U> . textul poate să apară îngroşat. +3] arată mărimea relativă. Mărimea indicată ca numar intreg cu semn în intervalul [-3.. îngrosat (engleză: bold). </sup> text scris mai mic şi mai sus decât cel de bază (engleză: superscript). De exemplu. <sub> . cât şi prin cel de dedesubt.. Aceste stiluri pot fi şi combinate. În HTML. titlul respectiv se afişează scris cu caractere mai mici. parametrii size=3 si size=+3 indică fonturi de mărimi diferite. acesta indică mărimea absolută a fontului. </sub> text scris mai mic şi mai jos decât textul de bază (engleză: subscript). Cu cât cifra n este mai mare. </strike> pentru text tăiat cu o linie (engleză: strikethrough). marimea şi culoarea fontului. Aşa dar. Dacă se foloseşte un număr întreg fără semn.. cursiv şi subliniat</U></I></B> apare pe ecran sub forma: text aldin.. cursiv şi subliniat Marcarea titlurilor şi subtitlurilor Titlurile diferitelor secţiuni ale textului (capitole. <sup> . 6].. </B> pentru text aldin.. <I> . subcapitole etc) se pun în evidenţă prin faptul că apar scrise cu caractere diferite de restul textului (de regulă mai mari) şi sunt distanţate prin câte o linie atât de textul de deasupra. 295 . textul HTML <B><I><U>text aldin. faţă de cea pentru care este setat browserul utilizat.Programarea orientata pe obiecte în limbajul Java fără semn..

Dacă documentul ţintă se găseşte pe acelaşi disc cu documentul în care apare această referinţă. Acest marcaj este <PRE> text preformatat </PRE>. urmând calea d1/d2/d3/ unde d1. textul <PRE> un exemplu de text preformatat scris pe trei linii </PRE> va apare pe ecran sub forma un exemplu de text preformatat scris pe trei linii Legături către alte pagini Legăturile cu alte documente sunt marcate prin ancore. este vizibil textul de legătură. În acest caz.html" dar având grijă să înceapă cu "/". sub forma unui text subliniat şi având o culoare diferită de a restului documentului. pentru separarea directoarelor se foloseşte bara (slash.html" este o referinţă la documentul docum. /).html. ne deplasăm două directoare "înapoi" către rădacină. până la directorul în care se găseşte fişierul care conţine documentul. se modifica şi aşezarea în pagină a textului. simbolul . a/ Documentul ţintă se găseşte pe acelasi calculator.. (doua puncte succesive) înseamnă deplasare cu un director înapoi./d2/d3/docum. după care parcurgem "înainte" calea d2/d3 şi ajungem la documentul docum. care sunt taguri de forma: <A HREF="referinţă la document">text de legătură</A> Parametrul HREF (Hypertext Reference) reprezintă indicarea locului în care poate fi găsit documentul către care se face trimiterea (referinţa la document).Severin Bumbaru Text preformatat S-a arătat mai sus că aşezarea textului în pagină se face de către browser. d2 si d3 sunt directoare. respectând marcajele de formatare din textul HTML. În schimb. cum sunt caracterul de trecere la linie nouă sau de întoarcere a carului sunt ignorate de browser şi nu au efect la afişarea pe ecran.html. Există.html" are semnificaţia următoare: pornind de la directorul în care se găseşte documentul sursă. iar / înseamna deplasare cu un director înainte.La indicarea căii. Această referinţă nu este vizibilă în fereastra de browser în care este afişat documentul. Referinţa la document depinde de locul în care acesta se găseşte. Spaţiile şi caracterele speciale din textul HTML. referinţa la document este 296 ./. În acest caz. b/ Documentul ţintă se găseşte pe un alt calculator. în care calea se trasează pornind de la directorul în care se găseşte documentul sursă. de forma: cale/document unde cale (engleza: path) este succesiunea de directoare parcurse de la rădăcina arborelui de directoare. În consecinţă. dacă se modifică dimensiunile ferestrei. referinţa: ". conform convenţiei din sistemul de operare Unix. care se găseşte pe discul C. De exemplu. ceeace înseamnă că se porneşte de la rădăcină. De exemplu: "C:/d1/d2/d3/docum. discul poate fi omis. a2/ Referinţa relativă.. punând referinţa sub forma "/d1/d2/d3/docum. referinţa poate fi: a1/ Referinţa absolută.. deci este o referinţă absolută. totuşi un marcaj care impune ca textul sa fie aşezat pe ecran aşa cum este el în pagina HTML. De exemplu.

Universitatea din Galati.html" Prima parte a URL-ului (în cazul de faţă http:) reprezintă protocolul de transmisie folosit. care pot fi domenii naţionale (de exemplu: ro .baza appletului se aliniază cu linia de bază a textului. Marcajul APPLET Pentru a introduce într-un document HTML o referinţă la un applet. De exemplu.aliniere cu elementul cel mai înalt din linie (fie el text.html" "http://java. texttop . dacă browserul folosit pentru vizualizarea documentului HTML nu este capabil sa utilizeze appleturi. dacă fişierul bytecode al appletului se găseşte în acelaşi director cu fişierul HTML în care acesta este invocat. poate fi una din următoarele: left | right | top | texttop | middle | absmiddle | baseline | bottom | absbottom unde left şi right indică aliniere la stânga sau la dreapta. de exemplu java.Franta.com). Modul de adresare pe Internet este. Subdomeniile pot fi împărţite în subsubdomenii s. org . de . de exemplu: CODE=TestFlowAp. care este modul de adresare caracteristic pentru WWW. absbottom .m. în care se află bytecode-ul appletului (indicarea extensiei nu este obligatorie).ro/~sbumbaru/CursJava/Sapt01/poo. absmiddle .un text care va apare în locul appletului.adresa pe Internet a unui calculator. cu observaţia că nu se mai termină prin numele documentului ţintă. iar în domeniul com există subdomeniul sun .organizaţii.aliniere cu cel mai înalt element de text din linia respectivă.referinţa la directorul în care se găseşte bytecode-ul appletului. locaţia atlas.mijlocul appletului se aliniază cu mijlocul elementului cel mai mare din linie. fr .com/docs/books/jls/html/index. top . lăţime si înălţime .Programarea orientata pe obiecte în limbajul Java un URL (engleză: Uniform Resource Locator). Fiecare domeniu este imparţit în subdomenii (de ex. în principiu.d până se ajunge la calculatoare individuale. relativă sau sub forma de URL.fişierul cu extensia . parametrul CODEBASE lipseşte.baza appletului va fi elementul cel mai de jos din linie. aliniere . Iată exemple de URL-uri: "http://www.sun.: în domeniul ro există subdomeniul ugal .ugal. imagine sau alt applet).cs.ro înseamnă calculatorul atlas din subreţeaua stud.educaţional.Marea Britanie. middle . baseline sau bottom . această referinţă poate fi absolută.comercial. Urmeaza calea absolută parcursă pe calculatorul respectiv (de exemplu /docs/books/jls/html/) şi numele documentului (index. se foloseşte marcajul (tagul) APPLET.w3. care are forma următoare: <APPLET CODE=fişier_class [CODEBASE=localizare] WIDTH=lăţime HIGHT=înălţime[ALIGN=aliniere]> [<PARAM NAME=nume VALUE=valoare>]* [text_de_înlocuire] </APPLET> în care: fişier_class . Cele două bare (//) indică modul de acces (în cazul de faţă .Germania etc) sau domenii profesionale (com .html).class sau CODE=TestFlowAp localizare .ugal. reprezentând lăţimea şi înălţimea appletului.org/default.mijlocul appletului se aliniază cu mijlocul liniei de bază a textului.firma Sun Microsystems).sun. acesta fiind cel din parametrul CODE.a. la fel ca în cazul legăturilor către alte documente. din subdomeniul ugal al domeniului ro. net .numere întregi. edu . text_de_înlocuire. următorul: Internetul este împărţit în domenii.Romania.class.retele). uk . 297 .stud.alinierea appletului în pagina de browser.html" "http://lib.

care se vor transmite appletului la lansarea acestuia. dar în CODEBASE s-a folosit forma absolută a căii. fără să mai 298 .. pentru fiecare din ei indicându-se un nume şi o valoare. dar în CODEBASE se foloseşte un URL la care poate fi găsit appletul respectiv. folosind în acest scop sub-marcajul [<PARAM NAME=nume VALUE=valoare>]* Atât numele.Severin Bumbaru Dacă este necesar. În CODEBASE s-a folosit forma relativa a căii. Exemplul 1: marcajul <APPLET CODE="CBGroupAp" WIDTH=180 HEIGHT=80> Testarea clasei CheckboxGroup </APPLET> se foloseşte pentru a include în documentul HTML a unui applet./Sapt01/surse WIDTH=200 HEIGHT=100>Primul applet</APPLET> se foloseşte pentru a include în documentul HTML appletul al cărui fişier bytecode este PrimApplet.class şi care se găseşte în alt director decât fişierul HTML. Dacă browserul folosit nu suportă appleturi java. în locul rezervat appletului va apare textul de înlocuire "Testarea clasei CheckboxGroup". marcajul APPLET poate să conţină unul sau mai mulţi parametri. Exemplul 3: marcajul <APPLET CODE=PrimApplet CODEBASE=/CursJava/Sapt11/surse WIDTH=200 HEIGHT=100> Primul applet </APPLET> are aceeaşi semnificaţie ca cel din exemplul anterior. al cărui fişier de bytecode este CBGroupAp.ro/~sbumbaru/CursJava/Sapt11/surse WIDTH=200 HEIGHT=100> Primul applet </APPLET> are aceeaşi semnificaţie ca cel din exemplul anterior.class şi se găseşte în acelasi director cu documentul HTML în care există acest tag. Folosirea de parametri în appleturi În marcajul APPLET pot fi introduşi şi unul sau mai mulţi parametri.ugal. Exemplul 2: marcajul <APPLET CODE=PrimApplet CODEBASE=. Appletul va avea lăţimea 180 şi înălţimea 80. cât şi valoarea sunt şiruri. Aceşti parametri apar în subtagul PARAM.cs. Preluarea în applet a fiecăruia din aceşti parametri se face invocând metoda public String getParameter(String name) care primeşte ca argument numele parametrului şi întoarce valoarea acestuia sub forma de şir. Avantajul este că valorile parametrilor pot fi modificate direct în fişierul HTML. dar pe acelaşi disc. Exemplul 4: marcajul <APPLET CODE=PrimApplet CODEBASE=http://lib.

să aibă diferite fonturi.java este dat un exemplu de aplicaţie. cu inscripţia Reset. conform cu marcajele HTML utilizate. care se afişează alternativ într-o etichetă.2) în textele introduse în componentele JFC/Swing (cum ar fi cele din clasele JButton. Utilizarea marcajelor HTML în textele pentru componentele JFC/Swing În mod obişnuit. Exemplu: În fişierul DouaTexte. Dacă. în care se afişează un text iniţial. . însă. JLabel. sintaxa HTML nu este respectată. culori şi stiluri. . . textul introdus în componentele AWT sau JFC/Swing prin metoda void setText(String text) apare pe ecran pe suprafaţa componentei respective sub forma unui text scris pe o singura linie. metoda generează o excepţie. folosind fontul SansSherif. Acest applet este inclus în pagina HTML din fişierul DouaTexte. Dacă textul introdus prin metoda setText() începe cu marcajul <HTML>.o arie de text (JTextArea).) pot fi folosite marcaje HTML. culoarea neagra şi o mărime implicită. Exemplu În fişierul TextHTML.o etichetă (JLabel) pe suprafaţa căreia se afişează textul existent în aria de text din partea stângă. el este interpretat ca un text HTML şi tratat în mod corespunzător.Programarea orientata pe obiecte în limbajul Java fie necesar să se modifice şi să se recompileze programul appletului. fără a se face modificări în programul appletului. a cărui acţionare are ca efect revenirea la textul 299 .java este dat un exemplu de applet în care sunt preluaţi doi parametri.un buton cu inscripţia Vizualizare text. Începând cu platforma Java 2 (SDK 1.un al doilea buton. Schimbarea textului se face la apăsarea pe buton. care poate fi apoi modificat de utilizator. în care se experimentează folosirea textelor HTML în componentele interfeţei grafice.html prin următorul marcaj: <APPLET CODE=DouaTexte WIDTH=250 HEIGHT=100 ALIGN=middle> <PARAM NAME=textul1 VALUE="Acesta este primul text"> <PARAM NAME=textul2 VALUE="Acesta este al doilea text"> </APPLET> Pentru a se afişa alte texte. a cărui acţionare are ca efect afişarea pe suprafaţa etichetei a textului din aria de text. cu numele textul1 si textul2. JPanel etc. este suficient să se modifice în mod corespunzător valorile parametrilor din acest marcaj. În fereastra aplicaţiei sunt plasate următoarele componente: . Aceasta înseamnă că textul poate să apară pe suprafaţa componentei respective pe mai multe linii. Aceşti parametri sunt şiruri de caractere.

Acest text poate fi însă modificat în fereastra din stânga şi vizualizat în eticheta din dreapta. 300 . apăsând pe acelaşi buton.setBorder(BorderFactory.add(ta). import javax. astfel. ta. se apasă butonul Reset.*. // butonul de revenire la textul initial reset.addActionListener(new Reset()).setLineWrap(true). // aria in care se introduce textul HTML ta. ta. Se pot experimenta. hb. În aria de text este introdus iniţial un text HTML. /* Textul introdus initial in aria de text */ String textInitial="<html>\n<h2>Proba HTML</h2>Text normal<br>\n"+ "<i>Text italic <b>Text italic aldin</b></i><br>\n"+ " <font face=serif color=blue size=4>\n"+ " Text albastru cu font serif\n </font>\n<p bgcolor=aqua>"+ "Revenire la text normal<br>cu fond aqua\n</html>". Înscripţiile de pe cele două butoane au fost formatate folosind marcaje HTML. vb. sfarsit=new Sfarsit(). class TextHTML extends JFrame { JTextArea ta.10).createRaisedBevelBorder()).createTitledBorder( "Introduceti aici un text HTML")). /* Constructorul clasei TextHTML construieste interfata grafica */ TextHTML() { super("Incercare de texte HTML").addActionListener(new Vizualizare()).setBorder(BorderFactory. ta. // butonul de comanda a // vizualizarii textului buton.createHorizontalBox(). reset. Container cp=getContentPane().setWrapStyleWord(true).swing. care poate fi vizualizat apăsând pe butonul Vizualizare text. hb. Sfarsit sfarsit. Box vb=Box.event.*.createRaisedBevelBorder()). JLabel label. Box hb=Box. String textButon="<html><font color=red size=4>"+ "<b><i>Vizualizare text</i></b></font>". revenirea la textul iniţial.add(hb).append(textInitial). JButton buton=new JButton(textButon).awt.*.Severin Bumbaru afişat iniţial în aria de text. // incheierea executarii aplicatiei addWindowListener(sfarsit). import java.add(reset). buton.awt.add(buton).createVerticalBox(). /* Experimentarea folosirii marcajelor HTML in textele pentru componente JFC/Swing */ import java. ta=new JTextArea(15. apoi.setBorder(BorderFactory. Dacă se doreşte. diferite modificări ale textului iniţial sau se poate introduce oricând un text obişnuit sau un hipertext nou. JButton reset=new JButton("<html><font color=blue size=4>"+ "<b>Reset</b></font>"). vb.

în metoda main() s-a creat o instanţă a acestei clase.setText("Eroare de sintaxa HTML").add(vb.createTitledBorder( "Vizualizarea textului HTML")).setOpaque(true).add(label.300). } /* Clasa de ascultare a inchiderii ferestrei principale*/ class Sfarsit extends WindowAdapter { public void windowClosing(WindowEvent e) { System. În consecinţă.BorderLayout. label=new JLabel(). cp. // instantierea aplicatiei } } Remarcăm că. în această aplicaţie.CENTER). label. s-au introdus următoarele abordări noi faţă de aplicaţiile anterioare: .setBorder(BorderFactory. setVisible(true). label.white).getText()).clasele interioare şi câmpurile clasei TextHTML nu au mai fost declarate statice. .setText(ta. 301 . în schimb. fiind doar o ilustrare a unui alt mod de lucru posibil în Java. } } /* clasa de ascultare a butonului de vizualizare a textului */ class Vizualizare implements ActionListener { public void actionPerformed(ActionEvent e) { try { /* afisarea pe componenta label a textului extras din aria de text ta */ label. setLocation(50.setText(textInitial).BorderLayout. // eticheta pe care se vizualizeaza textul HTML label. adăugarea componentelor la fereastra principală se face în constructorul clasei TextHTML.setText("").s-a considerat că interfaţa grafică este însăşi clasa principala TextHTML.50).exit(0). } } } /* Clasa de ascultare a butonului de Reset */ class Reset implements ActionListener { public void actionPerformed(ActionEvent e) { ta.WEST). } } public static void main(String args[]) { TextHTML text=new TextHTML(). label. Desigur că acest mod de construire a aplicaţiei nu are legătura cu tema acesteia. setSize(450.Programarea orientata pe obiecte în limbajul Java cp. } catch(Exception ex) { // s-a constatat o eroare in textul HTML label. derivata din clasa JFrame.setBackground(Color.

Internet Explorer sau HotJava.applet şi este o subclasă a clasei Panel din pachetul java. astfel încât să execute anumite acţiuni specifice momentelor în care sunt invocate. cum sunt Netscape Navigator. În mod normal. Clasa Applet este superclasa tuturor miniaplicaţiilor care sunt încorporate în pagini Web sau pot fi vizualizate cu un Java Applet Viewer. Dintre acestea. Întrucât utilizarea clasei JApplet este mai complicată. Aşa cum sunt ele oferite de clasa Applet. ne vom rezuma aici la descrierea şi exemplificarea utilizării clasei Applet. înregistrarea ascultătorilor de evenimente etc. Pentru executarea unui applet trebuie să existe deci două entităţi: applet-ul propriu-zis şi contextul în care acesta se execută (engleză: applet context). Container şi Panel. numită context de applet. respectiv în momentul încărcării acestuia în memorie. metoda destroy() se foloseşte în special pentru a distruge firele de execuţie paralele care au fost create de către applet. Pentru testare. un caz special de container.swing. aceste metode nu fac nimic. public void init() . sau derivată din clasa JApplet. cele mai importante sunt : init(). ci este înglobat într-o altă aplicaţie. Ea este redefinită în marea majoritate a applet-urilor. folosind drept context un program de vizualizare special.metoda este invocată de către browser sau appletviewer atunci 302 . existent in SDK. Clasa Applet moşteneşte metodele superclaselor sale Component. Ele pot fi însă redefinite de programatori în subclasele clasei Applet. applet-ul este. Metodele start() şi stop() se folosesc numai pentru lansarea şi oprirea proceselor dinamice (de exemplu animaţie şi/sau sunete) care nu trebuie să continuie când appletul nu este vizibil pe ecran.applet. existentă în pachetul java. appletul poate fi executat. Metoda init() este utilizată pentru a crea partea "statică" a applet-ului: adăugarea de componente la applet. În consecinţă. care nu poate rula în mod independent. care extinde clasa Applet şi există în pachetul javax.Severin Bumbaru Applet-uri Miniaplicaţia (engleză: applet) este un mic program cu interfaţă utilizator grafică. start(). stop() şi destroy(). numit appletviewer. de fapt. de asemenea. Principalele metode ale clasei Applet: Vom prezenta aici metodele mai frecvent utilizate. în momentul începerii sau întreruperii execuţiei şi înainte ca appletul să fie distrus. derivată din clasa Applet. Orice applet este realizat ca o clasă. Pentru celelalte recomandăm consultarea documentaţiei originale. Aceste metode sunt apelate de către browser în momentele importante ale ciclului de viaţă al unui applet. contextul de executare a unui applet este un navigator de Web (engleză: web browser). În fine. sau a elibera anumite resurse ocupate de acesta. oferind şi metode specifice.awt. Clasa Applet Clasa Applet se găseşte în pachetul java.

applet şi java. public void start() . s-au utilizat numai componente din pachetele java. setarea culorilor şi înregistrarea interceptorului de evenimente. conţinut în tagul APPLET al documentului HTML.adăugarea componentelor la applet. iar fişierul HTML în care este folosit acest applet este PrimApplet.întoarce valoarea parametrului cu numele dat ca argument. înaintea invocării metodei destroy().întoarce URL-ul la care se găseşte documentul care conţine appletul. public URL getCodeBase() . drepturi de autor etc. acest rol fiind îndeplinit chiar de către applet.metoda este invocată de către browser înainte de distrugerea appletului.java este dat un applet de testare a unui grup de casete de validare (butoane radio) din fişierul TestCheckboxGroup. Exemplul 2: În fişierul CBGroupAp.html. gestionarul de poziţionare implicit este 303 . folosindu-se numai o invocare de metodă prin care se scrie un text pe suprafaţa appletului. este înlocuită de alta.Programarea orientata pe obiecte în limbajul Java când appletul este încărcat în memorie. . . Pentru compatibilitate. public AppletContext getAppletContext() . acesta poate sa îşi înceteze temporar execuţia. în care se găseşte appletul. deci înainte de prima invocare a metodei start().nu mai există o fereastră principală sub formă de cadru (Frame sau JFrame) ca în cazul aplicaţiei.java. Remarcăm următoarele deosebiri faţă de o aplicaţie similară: .java. public String getParameter(String name) . împreună cu fişierele HTML în care se afişeaza acestea. Întrucât appletul nu mai este vizibil pe ecran. Dăm în continuare trei exemple de applet-uri.întoarce URL-ul (locaţia pe Internet) la care se găseşte bytecode-ul appletului. în care nu se redefineşte nici o metodă a clasei Applet.având în vedere că. adică atunci când este vizitată sau revizitată pagina Web în care acesta este inclus. metoda este invocată. nu mai este necesară o clasă care sa intercepteze evenimentele generate de fereastra principală. public void stop() . acum se fac în metoda init().în consecinţă.dacă este redefinită în subclase. public void destroy() .metoda este invocată de către browser atunci când pagina de Web. Exemplul 1: În introducere a fost deja dat un exemplu de applet simplu. public boolean isActive() .determină dacă appletul este activ.întoarce o referinţă către contextul appletului. .metoda este invocată de către browser atunci când appletul trebuie să îşi înceapă execuţia. public URL getDocumentBase() . de asemenea.awt. versiunea. În clasa Applet metoda întoarce null. pentru clasa Applet. metoda poate intoarce informaţii despre applet: autorul. care în cazul aplicaţiei se fac în metoda main() sau în constructorul interfeţei utilizator grafice. fără a fi însă eliminată din memorie. public String getAppletInfo() . Programul acestui applet se găseşte în fişierul PrimApplet.

pentru a vizualiza applet-ul TestFlowAp. Care este marcajul cu care începe şi se termină un document HTML? 9. Ce este un browser de Web? 5. Exemplul 3: În fişierul TestFlowAp. Întrebări Nivel 1 1. Cum sunt folosite marcajele HTML în componentele JFC/Swing? 15.Severin Bumbaru FlowLayout.html. Oricare din aceste applet-uri poate fi vizionat şi într-un appletviewer. Când sunt invocate metodele start() şi stop() ale unui applet? 23. pentru a utiliza gestionarul BorderLayout acesta a trebuit adăugat în mod explicit. Ce este HTTP? 6. Care sunt principalele metode ale unui applet şi de către ce program sunt invocate ele? 21. Ce este un applet? 16. Cum se specifică titlul unui document HTML? 12. Ce formă au marcajele HTML? 8. Ce sunt nodurile hipertextului? 3. Care este structura unui document HTML? 10. La ce serveşte marcajul APPLET şi ce conţine el? 14. prin care se selectează modul de aliniere a etichetelor pe suprafaţa containerului ("Stânga". Acţionand aceste butoane se poate testa modul de aranjare al etichetelor pentru diferite tipuri de aliniere.html unde TestFlow. dacă (din fereastra Xwindow sau MS-DOS) se dă comanda: appletviewer fisierHTML De exemplu. Ce este HTML? 7. într-un document HTML. "Centru". Pentru vizualizarea appletului se foloseste fişierul CBGroupAp.java se prezintă un applet de testare a gestionarului de poziţionare FlowLayout. În ce scop se foloseşte metoda destroy() a unui applet? 304 . Ce contexte de applet cunoaşteţi? 19. În ce zonă a documentului HTML se specifică titlul acestuia? 11. Ce este un context de applet? 18. Vizualizarea din browser a acestui applet se face folosind fişierul TestFlow.html este fişierul HTML în care este invocat acest applet. legăturile către alte pagini ale hipertextului? 13. Din ce clasă este derivată clasa Applet? dar clasa JApplet? 20. La ce serveşte metoda init() în cazul unui applet? 22. se dă comanda appletviewer TestFlow. Ce este un hipertext? 2. "Dreapta").html. Pe suprafaţa appletului apar două butoane de comandă ("Pune" şi "Elimina") pentru adaugarea sau eliminarea de etichete şi trei butoane radio. Ce clase se folosesc pentru realizarea applet-urilor? 17. Ce este WWW? 4. Prin ce se marchează.

Cum se reprezintă. Cum se reprezintă. Cum se marchează paragrafele într-un document HTML? 2. Cum se marcheaza titlurile şi subtitlurile de capitole într-un document HTML? 12. stop() şi destroy()? 305 . există o eroare de sintaxa HTML? 20. o referinţă la o pagină situată pe alt calculator de pe Internet? 16. Ce componente ale interfeţei grafice permit folosirea textelor HTML? 18. Ce conţine marcajul <font> şi ce semnificaţie are? 9. o referinţă relativă la altă pagina de pe acelaşi calculator? 15.Programarea orientata pe obiecte în limbajul Java 24. Cum pot fi introduşi parametri în marcajul APPLET şi la ce folosesc? 17. Ce se întamplă dacă. culoarea fondului unui paragraf? 5. Care sunt principalele tipuri (forme) de caractere folosite în documentele HTML? 8. Este absolut necesar ca un paragraf să se încheie cu marcajul </P>? 3. să fie redefinite toate cele patru metode principale init(). Cum se specifică culoarea caracterelor într-un document HTML? 6. într-un text care se pune într-o componentă JFC/Swing. Cum se marchează stilul textului într-un document HTML? 11. într-o legatură HTML. Ce efect au metodele init(). într-o legatură HTML. start() şi stop() ale unui applet. Cum se specifică forma caracterelor într-un document HTML? 7. Cum se reprezinta. o referinţă absoluta la altă pagină de pe acelaşi calculator? 14. Ce este un text preformatat şi cum se marchează el într-un document HTML? 13. Cum se specifică. start(). într-o legatură HTML. într-un document HTML. aşa cum sunt ele conţinute în clasa Applet? 21. la crearea unei noi clase de applet. Prin ce metodă se introduce un text HTML într-o componentă JFC/Swing? 19. Ce este stilul textului? 10. Cum este utilizat un appletviewer? Nivel 2 1. Cum se marchează într-un document HTML trecerea forţată la linie nouă? 4. Este obligatoriu ca.

fluxul (engleză: stream) este o cale de comunicaţie între o sursă de date şi o destinaţie (Figura 1).Severin Bumbaru Fluxuri de intrare/ieşire şi fişiere Fluxuri de intrare/ieşire Introducere Pachetul java. reţeaua de calculatoare etc. ecranul.io Clasele de bază ale ierarhiilor de fluxuri de intrare/ieşire Clasa Reader Clasa Writer Clasa InputStream Clasa OutputStream Consideraţii generale privind utilizarea fluxurilor Clasele PrintStream şi PrintWriter Fişiere Clasa File Citirea fişierelor Citirea fişierelor de octeţi: clasa FileIntputStream Citirea fişierelor de caractere: clasa FileReader Scrierea în fişiere Scrierea în fişiere de octeţi: clasa FileOutputStream Scrierea în fişiere de caractere: clasa FileWriter Fişiere cu acces direct Fluxuri de prelucrare Fluxuri de date Fluxuri de obiecte Întrebări. În limbajul Java. tastatura. de asemenea. să se transmită date între două aplicaţii sau între două fire de execuţie ale aceleeaşi aplicaţii. este necesar să se transmită date între diferite componente cum sunt: memoria internă. 306 . 306 306 307 310 310 311 312 312 313 313 315 316 319 319 310 322 322 323 324 327 327 329 331 Fluxuri de intrare/ieşire şi fişiere Introducere În majoritatea aplicaţiilor. Poate fi necesar. fişierele de pe disc.

cât timp (există date de citit) citire din flux -Închiderea fluxului Programatorului procesului sursă îi revine obligaţia de a pregăti.clase abstracte (culoare albastră). Aceste ierarhii de clase sunt reprezentate în figurile 2.Figura 1 Fluxul este un concept situat pe un nivel înalt de abstractizare. dar în limbajul Java ea este totuşi uşurată de existenţa unui număr destul de mare de clase cu această destinaţie. Desigur că este necesar ca interpretarea datelor din flux la destinaţie să corespundă cu cea de la sursă.io. Pachetul java. deci întreaga responsabilitate îi revine celui care programează acest proces.cât timp (există date de transmis) scriere în flux -Închiderea fluxului La destinaţie (flux de intrare) -Deschiderea fluxului . nici modul în care trebuie interpretată secvenţa de octeti sau de caractere respectivă. rădăcinile acestor ierarhii sunt clasele abstracte InputStream şi OutputStream. toate fluxurile transmise de acesta către exterior se numesc fluxuri de ieşire. Principalele operaţii care au loc asupra unui flux sunt: La sursă (flux de ieşire) . care sunt reprezentate în aceste figuri prin culori diferite: . pentru fiecare din cele două categorii de fluxuri există câte o ierarhie de clase de fluxuri de intrare şi o ierarhie de clase de fluxuri de iesire.clase care efectuează operaţiile de intrare sau de ieşire propriu-zise (culoare verde) şi modelează sursele sau destinaţiile fluxurilor (engleză: Data Sink Streams). un grup de 32 de octeţi transmişi între sursă şi destinaţie poate să reprezinte 32 de caractere ASCII sau 16 caractere Unicode sau 8 numere de tip int sau 4 numere de tip double etc. 4 şi 5. 307 . acelaşi flux este de ieşire în raport cu sursa şi de intrare în raport cu destinaţia. datele care urmează a fi transmise pe fluxul de ieşire. Nu prezintă importanţă nici natura sursei sau a destinaţiei. de la sursă la destinaţie se transmite o succesiune de caractere Unicode (de câte 16 biţi). În mod corespunzător. iar în al doilea caz . . În afară de cele patru ierarhii menţionate. grupate în pachetul java. În consecinţă. Pentru un proces dat. iar cele primite din exterior se numesc fluxuri de intrare. Distingem trei tipuri de clase. În primul caz. 3.Deschiderea fluxului .io există şi clase auxiliare şi interfete.Programarea orientata pe obiecte în limbajul Java .io În Java 2 SDK se consideră că fluxurile pot fi de caractere saude octeţi. fiind privit ca o simplă succesiune de octeţi sau de caractere care se transmite între sursă şi destinaţie. rădăcinile ierarhiilor de clase sunt clasele abstracte Reader şi Writer. Se disting doua feluri de fluxuri: de ieşire şi de intrare. Pentru fluxurile de caractere. în pachetul java. Programarea operaţiilor de intrare/ieşire poate fi destul de complicată. Interpretarea şi tratarea datelor conţinute în flux se face de către procesul de destinaţie. sub forma unei succesiuni de caractere sau de octeţi. De exemplu.Pentru fluxurile de octeţi. Această abstractizare permite să se trateze în mod unitar toate tipurile de transmisii de date.o succesiune de octeţi (de 8 biţi).

.Ierarhia claselor pentru fluxuri de ieşire de caractere 308 .Figura 2 .Figura 3 .Ierarhia claselor pentru fluxuri de intrare de caractere .Severin Bumbaru .clase care efectuează unele operaţii de transformare a datelor de pe flux (culoare violet) şi reprezinta "fluxuri de prelucrare" (engleză: Processing Streams).

De exemplu. În JDK 1. Pentru transmiterea datelor codificate binar sau a textelor în care caracterele sunt codificate pe un octet (de exemplu în codul ASCII) este preferabilă folosirea fluxurilor de octeţi.Ierarhia claselor pentru fluxuri de intrare de octeţi . Aceasta reflectă "simetria" operaţiilor de intrare şi de ieşire.Ierarhia claselor pentru fluxuri de ieşire de octeti Se observă corespondenţa între clasele de fluxuri de intrare şi de ieşire în cadrul aceleeaşi categorii de fluxuri. Există totuşi şi clase de intrare fără corespondent la ieşire (de exemplu StringBufferInputStream sau PushbackInputStream) sau clase de ieşire fără corespondent la intrare (de exemplu PrintStream).1.Figura 5 .Figura 4 . unui BufferedReader îi corespunde un BufferedWriter.Programarea orientata pe obiecte în limbajul Java . unui FileInputStream îi corespunde un FileOutputStream.0 existau numai clasele de fluxuri de octeţi. în cazul fluxurilor de octeţi. în cazul fluxurilor de caractere. Fluxurile de caractere au fost introduse începand cu JDK 1. Pentru transmiterea textelor sau a datelor reprezentate în format extern şi codificate în Unicode este preferabil. În mod similar. să se folosească fluxuri de caractere. unui CharArrayReader îi corespunde un CharArrayWriter etc. În prezent se folosesc ambele categorii de fluxuri. 309 . evident. unui PipedInputStream îi corespunde un PipedOutputStream etc.

16383) sau -1 dacă s-a ajuns la sfârşit de fişier. metoda produce blocarea procesului până când apar caractere în fluxul de intrare.Reader este rădăcina ierarhiei de clase de fluxuri de intrare de caractere. pe care îl transmite la un OutputStream (de exemplu la un PrintStream sau la un FileOutputStream).Figura 6.. . public int read(char[] cbuf) throws IOException . de la simplu la complex.citeşte din flux o secvenţă de caractere şi le depune într-o zonă tampon (buffer) constituită din tabloul de caractere cbuf. astfel încât ieşirea unui flux poate fi intrare a altui flux. Metode: citeşte din fluxul de intrare un singur caracter. sau se ajunge la sfârşit de fişier. Clasele de bază ale ierarhiilor de fluxuri de intrare/ieşire Clasa Reader Clasa abstractă java.io.Severin Bumbaru Fluxurile pot fi înlănţuite. public int read() throws IOException - 310 . metoda produce blocarea procesului în care este invocată. care o converteşte în fluxul de caracrtere flux2. iar acesta face conversia într-un flux de octeţi.Înlănţuire de fluxuri de intrare În Figura 7 este reprezentată o înlănţuire similară de fluxuri de ieşire: ieşirea fluxului de caractere BufferedWriter este aplicată la intrarea fluxului OutputStreamWriter. în Figura 6 este dată schema unei înlănţuiri de fluxuri de intrare: ieşirea fluxului InputStream (sub forma de fluxului de octeţi flux1) este dată la intrarea fluxului InputStreamReader.Figura 7 .este preluat fe fluxul de intrare de caractere cu zonă tampon BufferedReader. Vom începe însă cu prezentarea comparativă a claselor abstracte care constituie rădăcinile celor patru ierarhii de clase de fluxuri. până când apare un caracter în fluxul de intrare. în cele ce urmează vom căuta să facem o prezentare graduală. Astfel. iar acesta . întoarce caracterul citit (în domeniul 0 .la rândul lui . întoarce numărul de caractere citite sau -1 dacă s-a atins sfârşitul de fişier. Aceasta ne va permite să ne formăm o vedere de ansamblu asupra principalelor metode folosite în lucrul cu fluxuri. .Înlănţuire de fluxuri de ieşire Având în vedere complexitatea programării operaţiilor de intrare/ieşire.

int off. int off.întoarce true dacă fluxul de intrare este gata pentru a putea fi citit. dacă fluxul nu a fost marcat sau nu suportă resetarea. procesul apelant este blocat pană când apare cel puţin un caracter în fluxul de intrare. aceste caractere sunt scrise efectiv în fluxul de destinaţie. invocarea metodelor read().închide fluxul.Programarea orientata pe obiecte în limbajul Java public abstract int read(char[] cbuf. pentru a se putea reveni la ea ulterior.se închide fluxul de ieşire. public abstract void(char[] cbuf. se generează o excepţie de intrare/ieşire. excepţia de intrare/ieşire apare dacă fluxul nu suportă marcarea sau dacă se produce altă eroare de intrare/ieşire. public boolean ready() . se generează o excepţie de intrare/ieşire. dacă această destinaţie este tot un flux. public void write(char[] cbuf) throws IOException - caracterele conţinute în tabloul cbuf. astfel că se "descarcă" întregul lanţ de fluxuri.scrie în flux caracterele existente în şirul str. întoarce numărul de caractere sărite efectiv."descarcă" fluxul de ieşire.io.indică dacă fluxul suportă marcarea. public void reset() throws IOException . public void mark(int readAheadLimit) throws IOException . invocarea ulterioară a metodelor write() sau flush() pentru acest flux va produce o excepţie de intrare/ieşire. ready(). public long skip(long n) throws IOException . int off. începând de la poziţia off (offset).Writer este rădăcina ierarhiei de clase pentru fluxuri de ieşire de caractere.se sare peste n caractere din fluxul de intrare. dacă fluxul a salvat într-o zonă tampon anumite caractere scrise cu metodele write(). public void write(String str) throws IOException .fără ca acest marcaj să se piardă. public abstract void close() throws IOException . iar numărul maxim de caractere citite este len. dar depunerea caracterelor citite în zona tampon de destinaţie se face începând de la poziţia off (offset). 311 . public abstract void close() throws IOException . int len) throws IOException - scrie în flux len caractere din şirul str. public abstract void flush() throws IOException . argumentul readAheadLimit indică numărul de caractere care vor putea fi ulterior citite din flux. public boolean markSupported() . începând de la poziţia off (offset). Metode: public void write(int c) throws IOException - scrie în fluxul de ieşire scrie în fluxul de ieşire caracterul c. este readus la poziţia corespunzătoare ultimului marcaj. public void write(String str. invocă şi metoda flush() a acestuia. Clasa Writer Clasa abstractă java. mark() sau reset pentru acest flux va genera o excepţie de intrare/ieşire. care nu vor fi citite. int len) throws IOException .marchează poziţia curentă în fluxul de intrare.dacă fluxul a fost marcat. din acest moment.acţionează asemănător cu metoda precedentă. dacă se întâlneşte sfârşitul de fişier. int len) throws IOException scrie în fluxul de ieşire len caractere din tabloul cbuf.

io. dacă se întâlneşte sfârşitul de fişier se generează o eroare de intrare/ieşire.OutputStream este rădăcina ierarhiei de clase pentru fluxuri de iesire de octeţi.indică dacă fluxul suportă marcarea."descarcă" fluxul de 312 . din acest moment. int len) throws IOException - scrie în fluxul de ieşire len octeţi din tabloul buf. iar numărul maxim de octeţi citiţi este len. public int read(byte[] buf) throws IOException . dacă fluxul nu a fost marcat sau nu suporta resetarea. public abstract void flush() throws IOException . ready(). public int read() throws IOException public abstract int read(byte[] buf.închide fluxul. întoarce numărul de octeţi săriţi efectiv. excepţia de intrare/ieşire apare dacă fluxul nu suportă marcarea sau dacă se produce altă eroare de intrare/ieşire. sau se ajunge la sfârşit de fişier. întoarce octetul citit (in domeniul 0 . Clasa OutputStream Clasa java. int off.. public int available() throws IOException . int off. public boolean markSupported() . 255) sau -1 dacă s-a ajuns la sfârşit de fişier. int len) throws IOException . până când apare un octet în fluxul de intrare.întoarce numărul de octeţi disponibili pentru citire în fluxul de intrare. Metode: public void write(int c) throws IOException - scrie în fluxul de ieşire ultimul scrie în fluxul de ieşire octet al numărului c.dacă fluxul a fost marcat. este readus la poziţia corespunzătoare ultimului marcaj. argumentul readAheadLimit indică numărul de octeţi care vor putea fi ulterior citiţi din flux.se sare peste n octeţi din fluxul de intrare. metoda produce blocarea procesului până când apar octeţi în fluxul de intrare.io. procesul apelant este blocat până când apare cel puţin un octet în fluxul de intrare. invocarea metodelor read(). metoda produce blocarea procesului în care este invocată. public void reset() throws IOException .marchează poziţia curenta în fluxul de intrare. fără ca acest marcaj să se piardă. mark() sau reset() pentru acest flux va genera o excepţie de intrare/ieşire. începând de la poziţia off (offset). public long skip(long n) throws IOException . public void write(byte[] buf) throws IOException - octeţii conţinuti în tabloul buf. public abstract void(byte[] buf.Severin Bumbaru Clasa InputStream Clasa java.acţionează asemănător cu metoda precedentă. public abstract void close() throws IOException . dar depunerea octeţilor citiţi în tabloul de destinaţie byte[] se face începând de la poziţia off (offset). pentru a se putea reveni la ea ulterior. Metode: citeşte din fluxul de intrare un singur octet. care nu vor fi citiţi.InputStream este rădăcina ierarhiei de clase pentru fluxuri de intrare organizate pe octeţi.citeşte din flux o secvenţă de octeţi şi îi depune într-o zonă tampon (buffer) constituită din tabloul de octeţi buf. public void mark(int readAheadLimit) throws IOException . întoarce numărul de octeţi citiţi sau -1 dacă s-a atins sfârşitul de fişier. se generează o excepţie de intrare/ieşire.

respectiv de octeţi. Metodele read() pentru citirea de secvenţe de caractere. în timp ce cele cu numele print() sau println() formatează datele. aceşti octeţi sunt scrişi efectiv în fluxul de destinaţie. dacă se 313 . introduse începând cu JDK 1. De exemplu. În consecinţă. de asemenea. însă în clasa Writer metoda write() scrie în fluxul de ieşire un caracter. Metodele claselor Writer şi OutputStream sunt. Metodele read(). cât şi cele de fluxuri de octeţi. iar în clasa OutputStream scrie un octet. precedate eventual de semn. nu înlocuiesc pe cele anterioare. de caractere Unicode.1. În cazul că în metodele write() se scrie în flux conţinutul unui tablou. Aceste clase nu se folosesc în mod independent. la sfârşitul şirului de octeţi generat. generând reprezentările datelor respective sub forma de şiruri de octeţi (caractere în codul ASCII) sau.Programarea orientata pe obiecte în limbajul Java ieşire. Se vor putea deci folosi. Deosebirea este ca în clasa Reader metoda read() citeşte din fluxul de intrare un caracter.io. având ca rădăcini clasele InputStream şi OutputStream. Remarcăm că ierarhiile de clase Reader şi Writer. respectând convenţia de codificare (pe octeti sau pe caractere) specifică platformei pe care ruleaza aplicaţia respectivă. Metodele write(). markSupported(). Se ştie că forma internă a datelor diferă de forma externă. dacă fluxul a salvat într-o zonă tampon anumiţi octeţi scrişi cu metodele write(). Metodele claselor PrintStream şi PrintWriter fac această conversie din forma internă în cea externă a diferitelor tipuri de date. Clasele PrintStream şi PrintWriter Clasele java. se recomandă ca pentru a obţine fluxuri de caractere să se folosească clasa PrintWriter.PrintWriter se folosesc pentru a transmite către un flux se ieşire date formatate pentru tipărire (afişare). în timp ce pe ecranul calculatorului sau la imprimantă apar sub forma unor şiruri de cifre zecimale. după necesităţi. reset() şi close() există în ambele clase. de caractere) capacitatea de formatare a datelor în vederea tipăririi. ci le completează. iar în clasa InputStream se folosesc tablouri de octeţi. skip(). în clasa Writer acesta este un tablou de caractere. cât şi ca funcţionalitate. public abstract void close() throws IOException . Consideraţii privind utilizarea fluxurilor Se remarcă cu uşurinţă faptul că metodele claselor Reader şi InputStream sunt similare atât ca seigatură (şi deci ca mod de invocare). Deosebirea dintre print() şi println() este că metodele cu numele println() adaugă.io. invocă şi metoda flush() a acestuia. Totuşi. astfel că se "descarcă" întregul lanţ de fluxuri. Clasa PrintStream Clasa PrintStream conţine doua feluri de metode de scriere a datelor: metodele cu numele write() scriu întotdeauna octeţi (fără formatare). similare ca signatură şi funcţionalitate. respectiv. flush() şi close() există în ambele clase. respectiv. ci adaugă altui flux de ieşire (de octeţi sau. iar in clasa OutputStream este un tablou de octeţi. iar în clasa InputStream citeşte un octet. mark().PrintStream şi java. numerele întregi sunt reprezentate intern sub formă binară.se închide fluxul de ieşire. atât clasele de fluxuri de caractere. se deosebesc numai prin aceea ca în clasa Reader se folosesc ca destinaţie tablouri de caractere. un caracter de sfârşit de linie ('\n'). dacă această destinaţie este tot un flux. invocarea ulterioară a metodelor write() sau flush() pentru acest flux va produce o excepţie de intrare/ieşire.

se afişează şirul de caractere s. se scriu în fluxul de ieşire len octeţi din tabloul de octeti buf (buffer).se afişează obiectul obj convertit în şir de caractere prin aplicarea metodei String. descărcarea acestuia (flush). după afişare se trece la linie nouă. respectiv cuvântul true sau false. public void println(double d) . public void println(boolean b) .introduce în fluxul de ieşire codul caracterului '\n' (linie nouă). respectiv cuvântul true sau false.se afişează şirul de caractere s.se afişează numărul real în simplă precizie f. public void print(boolean b) . public void println(char c) . transmiţând de ieşire un singur octet (ultimul octet al conţinutul lor la ieşire). depinzând de platformă). public void println(Object obj) . în timp ce dacă se foloseşte metoda println(). public void print() . la rândul ei.se afişează numărul întreg i.se afişează conţinutul tabloului de caractere s. public void println(float f) . public void print(char c) . public void close() . public void write(int b) .Severin Bumbaru foloseşte metoda print(). int off. al doilea argument indică dacă fluxul se descarcă automat atunci când se întâlneste în flux caracterul '\n' (linie nouă) sau se execută metoda println() sau se tipăreşte un tablou de octeţi.se afişează numărul întreg i. public void println(char[] s) . public void print(String s) . conectat la fluxul de ieşire out. boolean autoFlush) .valueOf(obj).creează un nou flux de formatare pentru tipărire. public void print(Object obj) . depinzând de platformă).închide fluxul. public void print(float f) .valueOf(obj) care. începând de la poziţia off (offset).transmite în fluxul de ieşire forma externă a valorii variabilei booleene b. public void write(byte[] buf. public void println(long l) . public void print(double d) . public void print(char[] s) .se afişează conţinutul tabloului de caractere s.toString() din clasa căreia îi aparţine obiectul. public PrintStream(OutputStream out. conectat la fluxul de ieşire out.se afişează numărul real în dublă precizie d. acest flux nu se descarcă automat.se afişează numărul real în simplă precizie f. metoda println() provoacă. public void println(int i) .se afişează numărul real în dublă precizie d.se afişează caracterul c (pe unul sau doi octeţi. public void print(long l) . Dacă fluxul este cu descărcare automată. afişarea se face fără a se trece la o linie nouă.creeaza un nou flux de formatare a datelor pentru tipărire.se afişează numărul întreg lung l.scrie în fluxul argumentului). Metode: public void flush() - descarcă fluxul (goleşte zonele tampon. int len) - 314 . public void println(String s) .se afişeaza obiectul obj convertit în şir de caractere prin aplicarea metodei String. Constructori: public PrintStream(OutputStream out) . apeleaza metoda obj.se afişează caracterul c (pe unul sau doi octeţi.se afişează numărul întreg lung l. de asemenea. public void print(int i) .transmit în fluxul de ieşire forma externă a valorii variabilei booleene b.

de regulă. Liniile textului pot avea lungimi diferite. dependent de platformă. pentru fişierele de text se foloseşte cel mai frecvent codul ASCII. care au codurile ASCII 0x0D şi respectiv 0x0A. a lungimii fiecărui câmp. boolean autoFlush) . datele se păstrează sub forma de fişiere.creează un nou flux de formatare pe caractere. Prin formatul înregistrării se înţelege descrierea structurii acesteia. marcajul de sfârşit de linie este constituit numai din caracterul '\n' (New Line. cu excepţia celor care scriu octeţi bruti (write()). fiecare înregistrare este o linie de text. care face conversia caracterelor pe unul sau doi octeţi. 0x0A). Acest marcaj depinde de platformă. Datele din câmpuri pot fi reprezentate fie sub forma lor externă. '\n'). adică un şir de caractere care se termină cu un marcaj de trecere la linie nouă.la fel ca şi constructorul precedent. Fiecare înregistrare (engleză: Record) este o grupare de informaţii sau de date care poate fi tratată în mod unitar. în fişierele MS-DOS marcajul de sfârşit de linie este format din secvenţa de caractere "\r\n". dar al doilea argument specifică dacă are loc descărcarea automată a fluxului. pe un suport extern şi identificată printr-un nume. public PrintWriter(Writer out) Metode: Această clasa implementează aceleaşi metode ca şi clasa PrintStream. adică din caracterul de întoarcere la cap de linie (Carriage Return. 315 . '\r' ) şi caracterul de linie nouă (New Line.creează un nou flux de formatare pentru afişare. conectându-l la fluxul de ieşire pe octeţi out. dar al doilea argument indică dacă se face descărcare automată a fluxului. boolean autoFlush) . În prezent.la fel ca şi constructorul precedent. de regulă. lungime predefinită. iar fiecare înregistrare este constituită din mai multe câmpuri de date. care constă din specificarea câmpurilor de date pe care le conţine. conectându-l la fluxul de ieşire pe caractere out. public PrintWriter(OutputStream out. distingem fişiere de text şi fişiere de date. fie sub formă binară. dar pot exista şi platforme pe care se foloseşte Unicode sau o altă convenţie de codificare. În principiu. de asemenea. În fişierele de date. fără descărcare automată. public PrintWriter(OutputStream out) . de platformă. fără descărcare automată. Pe platforme Unix. De exemplu. După formatul înregistrărilor. a tipului de date conţinut în fiecare câmp şi a modului de reprezentare a datelor. Fişierul (engleză: File) este o colecţie de înregistrări situată. În fişierele de text. Fişiere În memoria externă a calculatorului. el creează şi un OutputStreamWriter intermediar. Fişierele pot fi clasificate după diferite criterii. iar formatul înregistrărilor diferă de la un fişier la altul. Codificarea caracterelor în fişier depinde. toate înregistrările unui fişier de date au acelaşi format. înregistrările au.Programarea orientata pe obiecte în limbajul Java Clasa PrintWriter Constructori: . public PrintWriter(Writer out.

se poate şterge un fişier existent etc. În limbajul Java.Severin Bumbaru După modul de exploatare. 3/ se închide fişierul. locul în care se găseşte (de exemplu unitatea de disc şi calea către directorul care îl conţine) şi modul în care va fi utilizat (pentru citire. Clasa File oferă. numite şi fişiere cu acces aleator (engleză: random access file) ordinea de parcurgere a înregistrărilor din fişier este arbitrară. se poate crea un fişier nou. se consideră că. Fişierele de intrare/ieşire permit ca. În cazul fişierelor cu acces direct. Operaţiile cu fişierul se fac în ordinea următoare: 1/ se deschide fişierul. În principiu.File conţin informaţii privind numele fişierului şi calea pe care se găseste acesta (engleza: Path). fişierul este privit ca sursa sau destinaţia unui flux. Desigur însă că. în care scop trebuie să se comunice sistemului de operare numele fişierului. Totuşi. Acelaşi fişier poate fi citit de mai multe ori. 316 . din momentul deschiderii fişierului şi până în momentul închiderii acestuia se pot efectua numai operaţii de citire. de regula. În cazul fişierelor de date. de asemenea. datele se transmit de la memoria internă la fişier sub forma unui flux de ieşire. după ce au fost deschise. Întreaga responsabilitate privind interpretareaacestor fluxuri revine programelor care le prelucrează. fişierele pot fi de intrare. Clasa File Instanţele clasei java. fară să se ia în consideraţie informaţia pe care o conţin aceste fluxuri. În cazul citirii din fişier. 2/ se exploatează fişierul. în operaţiile de intrare/ieşire. datele se transmit de la acesta către memoria internă sub forma unui flux de intrare. legatura dintre memoria internă şi fişierul de date se face. comunicarea între memoria internă şi un fişier de text se face sub forma unui flux de caractere. de ieşire sau de intrare/ieşire (de manevră). prin fluxuri de octeţi. pentru scriere sau în ambele moduri). pe platformele pe care reprezentarea caracterelor se face pe un octet (de exemplu în cod ASCII). în sensul că la fiecare operaţie de intrare/ieşire făcută asupra fisierului respectiv se poate indica adresa sau numărul de ordine al înregistrării care va fi citită sau scrisă. În limbajul Java. efectuând o succesiune de operaţii de citire/scriere. cât şi de citire. comunicarea dintre memoria internă şi fişier se poate face prin fluxuri de caractere numai dacă datele din fişier sunt reprezentate exclusiv în format extern (deci sub forma de şiruri de caractere). Fişierele cu acces secvenţial se caracterizează prin faptul că înregistrările lor pot fi parcurse într-un singur sens. el poate fi deschis ca fişier de intrare. în ordinea în care acestea sunt plasate în fişier. acesta poate fi tratat şi ca un flux de octeţi. între momentele de deschidere şi de închidere a fişierului respectiv se pot face numai operaţii de scrieire. În cazul operaţiei de scriere. După modul de acces fişierele pot fi cu acces secvenţial sau cu acces direct. Dacă însă există şi câmpuri de date în format binar. În cazul fişierelor de ieşire. În cazul fişierelor de intrare. dacă el poate fi citit sau scris. între fişier şi memorie se transmit numai fluxuri de caractere sau de octeţi. metode prin care se pot face unele operaţii legate de prezenţa fişierului respectiv: se poate afla dacă fişierul există. să se efectueze atât operaţii de scriere. după ce s-a încheiat scrierea într-un anumit fişier de ieşire şi acesta a fost închis.io.

pornind de la directorul curent. care în limbajele C şi Java se reprezintă sub forma '\\'. reprezentarea căii se face sub o formă independentă de platformă. Remarcăm că separarea directoarelor se face prin caracterul '/' (slash). Calea absolută constă în indicarea unităţii de disc şi a succesiunii de directoare prin care se ajunge de la rădacină la fişierul care ne interesează. ca separator se foloseşte caracterul '\' (backslash). În clasa File.txt" indică faptul că. după care se merge înainte (către frunzele arborelui director) trecând la subdirectorul alpha şi de aici la subdirectorul beta. Remarcăm că numele clasei File poate să ne inducă în eroare. Se ştie că.\\. Separatorul se păstrează într-un câmp separat şi este setat automat în funcţie de sistemul de operare al calculatorului pe care se execută programul. întrucât nu trebuie modificate căile fişierelor folosite în program atunci când se trece de pe o platformă pe alta.txt". se face o deplasare către rădăcină cu doua directoare. calea se păstrează sub forma unui tablou de şiruri de caractere. calea relativa ". calea se reprezintă în moduri diferite.\\alpha\\beta\\fisier1. în care se memoreaza numele fiecărui director conţinut în cale. De exemplu. ATENŢIE: pentru asigurarea portabilităţii programelor sursă. în sistemul Unix... în care se găseşte fişierul căutat cu numele fişier1.txt. În consecinţă. este recomandabil ca./alpha/beta/fisier1. 317 . În realitate. Calea relativă. pe diferite platforme. instanţele ei conţin căile şi numele fişierelor. în căile date ca argumente ale metodelor clasei File. aceeaşi cale relativă se va scrie pe o astfel de platforma sub forma ".. În acest scop. Pe platformele firmei Microsoft (MS-DOS. arată cum se poate ajunge de la directorul curent la fişierul căutat. Calea poate fi absolută sau relativă. Windows).Programarea orientata pe obiecte în limbajul Java Calea indică modul în care poate fi localizat fişierul de pe disc. lăsându-ne să credem că instanţele acestei clase sunt fişiere. să se folosească numai varianta Unix de separatori./. în instanţele clasei File. În acest fel.. Compilatorul javac de pe platformele Microsoft înlocuieşte automat separatorul '/' prin ' \\' in timp ce pe platformele Unix (Linux) nu se face înlocuirea inversă. portabilitatea programului creşte.

calea va conţine separatorii impliciţi de pe platforma curentă. public File(File parent. întoarce un şir vid. public static final char separatorChar - Constructori: public File(String pathname) - creează o instanţă a clasei File.' (punct şi virgulă) pe platforme Microsoft.intoarce true dacă această cale este absolută (dacă este prefixată cu '/' pe platformele Unix sau cu '\\' pe platformele Microsoft). fiind ':' (două puncte) sub Unix şi '. public String getPath() .conţine caracterul de separare a căilor. public boolean exists() . NOTĂ: aceste câmpuri se completează automat. acest caracter este dependent de platformă.întoarce un URL (Uniform Resource Locator) corespunzător căii din această instanţă. public static final String separator .testează dacă aplicaţia poate citi fişierul indicat de această instanţă a clasei File.întoarce calea părinte. public static final String pathSeparator . public boolean isAbsolute() .conţine caracterul de separare (separatorChar) sub forma de String.întoarce calea conţinută în această instanţă.întoarce numele fişierului (ultimul nume din cale). în care calea este compusă dintr-o cale "părinte" (formată numai din directoare) şi o cale "copil" (care poate fi director sau fişier).Severin Bumbaru Clasa File prezentată în detaliu Câmpuri: conţine caracterul prin care se separă directoarele dintr-o cale.testează dacă fişierul indicat există. public String getAbsolutePath() .întoarce calea părinte sub forma de instanţă a clasei File.testează dacă aplicaţia poate scrie în fişierul indicat. public boolean canRead() . Metode: Specificăm aici principalele metode ale clasei File.întoarce calea absolută corespunzătoare căii conţinute în această instanţă.se deosebeşte de constructorul precedent numai prin faptul că "părintele" este o instanţă a clasei File. în funcţie de platforma pe care rulează programul. public URL toURL() .testează dacă ultimul nume din această cale este al unui director.întoarce o instanţă a clasei File care conţine calea absolută corespunzatoare celei din instanţa curentă.creează o instanţă a clasei File. public String getName() . public File(String parent. public File getParentFile() . dacă această cale este vidă. public static final char pathSeparatorChar . acest carecter este dependent de platforma. public boolean isDirectory() . public boolean canWrite() . public String getParent() . fiind '/' (slash) pe platforme Unix şi '\' (backslash) pe platforme Microsoft. public File getAbsoluteFile() . 318 . forma acestui URL este dependentă de sistem (Nota: URL-ul se foloseşte pentru a localiza un fişier cu ajutorul unui browser de Web).caracterul de separare a căilor (pathSeparatorChar) sub formă de String. String child) . String child) . care conţine calea dată ca argument.

dacă fişierul indicat în această cale nu există. care conţine numele de directoare şi de fişier din această cale.cere ca fişierul să fie şters când se încheie funcţionarea maşinii virtuale Java (are efect numai dacă funcţionarea se încheie normal).Programarea orientata pe obiecte în limbajul Java public boolean isFile() - testează dacă ultimul nume din această cale este al unui fişier. public boolean delete() . care are ca sursă un fişier. întoarce null.şterge fişierul. altfel întoarce un tablou de instanţe ale clasei File. public void deleteOnExit() . Metodele se aplică pentru un fişier situat în directorul curent. sau nu poate fi deschis pentru citire.întoarce Exemplu: În fişierul TestFile. 319 . public File[] listFile() . Orice instanţă a acestei clase este un flux de intrare.întoarce lungimea fişierului indicat de această instanţă (în octeţi).FileInputStream permite citirea datelor din fişiere sub forma de fluxuri de octeţi. Citirea fişierelor Citirea fluxurilor de octeţi: clasa FileInputStream Clasa java.întoarce un tablou de şiruri. public boolean createNewFile() throws IOException . câte una pentru fiecare nume de fişier din directorul indicat de această cale. creează un fişier nou vid.io.dacă această cale nu se încheie cu un nume de director. în care se testează utilizarea metodelor clasei File. public long lastModified() .java este dat un exemplu de aplicaţie. Dacă fişierul nu există. întoarce truedacă ştergerea a avut loc. La crearea acestei instanţe se caută şi se deschide fişierul indicat ca argument al constructorului. public String[] list() . timpul la care s-a făcut ultima modificare în fişierul indicat de această cale (exprimat în milisecunde de la 1 ianuarie 1970 ora 00:00:00 GMT). public long length() . se generează o excepţie. pentru un director şi pentru un fişier situat în alt director.

deoarece au acelaşi descriptor.in. sau zero dacă s-a intâlnit sfârşitul de fisier fără să se citească nici un octet. programul intră în aşteptare.întoarce numărul de octeţi disponibili pentru citire din fluxul de intrare. dacă acesta nu se află în directorul curent. care se pun în tabloul b începând de la poziţia off (offset). public int available() throws IOException .citeşte din fişier un singur octet.io.se citesc din fluxul de intrare cel mult len octeţi. care se pun în tabloul b. int len) throws IOException . public FileInputStream(FileDescriptor fdObj) . public void close() throws IOException . deoarece la creare s- 320 . dacă în fluxul de intrare nu mai sunt octeţi de citit. f2. dacă octetul nu este înca disponibil în fluxul de intrare. Clasa FileDescriptor conţine. care sunt descriptori ai fluxurilor de intrare/ieşire standard. de asemenea. întoarce numărul de octeţi citit efectiv. Exemplu: În fişierul TestFileInput. int off. dacă s-a întâlnit sfârşitul de fişier fără să se citească nici un octet.length octeţi. după care octeţii respectivi se afişează.întoarce un descriptor al acestui fişier. În consecinţă. se întoarce numărul de octeţi săriţi efectiv. se creează un nou flux (cu referinţa f1). În final. în continuare fluxurile f1 şi f2 citesc date din acelaşi fişier. al cărui nume se dă ca parametru în linia de comandă. fără a le da nici o interpretare. Constructori: public FileInputStream(String name) throws FileNotFoundException . se creaza un flux care citeşte datele de la tastatura.închide fişierul. în care se testeaza metodele clasei FileInputStream. programul intră în aşteptare. public final FileDescriptor getFD() throws IOException . public int read(byte[] b) throws IOException . intoarce -1. Întrucât se ştie că f1 este un fişier de text.se creează un nou flux de intrare de octeţi. out şi err. În aplicaţie se deschide fişierul f1. care este conectat la fluxul de intrare fdObj deja existent. atunci şirul name conţine şi calea). public long skip(long n) throws IOException . (name este numele fişierului.se sare peste n octeţi din fişierul de intrare. În consecinţă. prin care se citesc octeţi dintr-un fişier de text.se creează un flux de intrare de octeţi având ca sursă fişierul name.java este un exemplu de aplicaţie. Metode: public int read() throws IOException .FileDescriptor şi pot fi folosiţi ca argument al constructorului pentru a crea un nou flux conectat la un fişier deja deschis. care citeşte datele de la tastatura. dacă nu s-a întâlnit sfârşitul de fişier şi nu sunt octeţi disponibili pentru citire în fluxul de intrare. public FileInputStream(File file) throws FileNotFoundException . Se deschide apoi un al doilea flux.se citesc din fişier cel mult b. care este echivalent cu f1. programul intră în aşteptare. NOTA: descriptorii de fişiere sunt obiecte care aparţin clasei java. public int read(byte[] b.se creează un flux de intrare de octeţi având ca sursă fişierul indicat de instanţa file a clasei File. dacă se foloseşte ca argument al constructorului clasei FileInputStream obiectul FileDescriptor. întoarce numărul de octeţi citit efectiv. dar nu s-a întâlnit sfârşitul de fişier.Severin Bumbaru Constructorii şi metodele clasei FileInputStream Metodele acestei clase permit să se citească din fişierul de intrare octeţi sau secvenţe de octeţi. câmpurile statice in. octeţii sunt afişati convertiţi în caractere.

io. dar moşteneşte următoarele metode ale clasei InputStreamReader: public int read() throws IOException - citeşte din fluxul de intrare un singur caracter şi-l întoarce convertit în int. public String getEncoding() . Metode: Clasa FileReader nu are metode proprii. folosind diverse metode.throws FileNotFoundException .FileReader este derivată din clasa java.Programarea orientata pe obiecte în limbajul Java a folosit descriptorul FileDescriptor.deschide ca flux de intrare de caractere fişierul cu calea file.InputStreamReader şi foloseşte metodele acesteia.verifică dacă fluxul de intrare este gata pentru citire (dacă conţine caractere care pot fi citite). public int read(char[] buf. Chiar dacă fişierul nu este codificat în Unicode.in.FileDescriptor şi este o referinţă la fluxul de intrare standard. pe care le pune în tabloul buf începând de la poziţia off (offset). Clasa java. ci şi o instanţă a clasei FileReader. Citirea din fişiere de caractere: Clasa FileReader Citirea unui fişier de text se poate face nu numai folosind o instanţă a clasei FileInputStream. public FileReader(FileDescriptor fd) . ci în alt cod de caractere (de cele mai multe ori ASCII). Acesta este câmpul in din clasa java. citirea fişierului se face de trei ori.java este dat un exemplu de aplicaţie în care se testează metodele clasei FileReader. Exemplu: În fişierul TestFileReader. public void close() throws IOException . Fişierul care se citeşte poate fi acelaşi ca şi în cazul citirii cu un flux de octeţi (din clasa FileInputStream). al cărui descriptor este fd.închide fluxul de intrare. Constructori: public FileReader(String fileName) throws FileNotFoundException - deschide ca flux de caractere de intrare fişierul cu numele fileName (eventual acest şir cuprinde şi calea).deschide un nou flux de intrare de caractere şi îl conectează la fluxul deja existent. int off. deci tratează fluxul de la tastatură ca pe un fişier folosit pentru citire. int len) throws IOException - citeşte din fluxul de intrare cel mult len caractere. 321 . În această aplicaţie. public FileReader(File file) . Deosebirea este că această ultimă clasă creează un flux de caractere. public boolean ready() throws IOException .io.io. se face automat conversia în Unicode. în loc de un flux de octeţi.întoarce numele canonic al codului folosit pentru caractere.

dacă fişierul nu există. se creează unul nou). se va crea pe disc un fişier nou.creeaza un nou flux de octeţi de ieşire.java se dă un exemplu de aplicaţie. public FileOutputStream(File file) throws IOException . calea) name şi creează un flux de octeţi către acest fişier. Exemplu: În fişierul TestFileOutput. Se închide şi se redeschide iarăşi. Se scriu cuvintele "Text adăugat". dacă fişierul nu există. public void write(byte[] b) throws IOException - conţinuti în tabloul b. eventual. în care se sriu octeţii primiţi din flux.se deschide pentru scriere fişierul indicat de calea file şi se creează un flux de octeţi către acesta. scrierea se va face în coada fişierului deja existent (scrierea începe după ultima înregistrare deja existentă). public void write(byte[] b. se redeschide pentru citire şi se afişează. În acest scop. Metode: public void write(int b) throws IOException - scrie în fişier un singur octet. boolean append) throws FileNotFoundException . În fişier se scrie textul dat în linia de comandă. după care se închide. cu numele dat ca argument. apoi este redeschis pentru citire şi conţinutul este afişat pe ecran. Constructorii şi metodele clasei FileOutputStream Constructori: public FileOutputStream(String name) throws FileNotFoundException - Deschide pentru scriere fişierul cu numele (şi. scrierea se face de la începutul fişierului.txt" (dacă nu există. excepţia se generează dacă fişierul nu există şi nici nu poate fi creat. fişierul este închis. dar dacă al doilea parametru este true. public FileOutputStream(String name. în care se testează metodele clasei FileOutputStream.întoarce un descriptor al acestui fişier. scrie în fişier toti octeţii scrie conţinut în argumentul b.Severin Bumbaru Scrierea în fişiere Clasa FileOutputStream Fiecare instanţă a clasei java. scrierea în fişier se va face de la începutul acestuia ("peste" ceeace.închide fişierul. eventual. exista deja scris). se creează unul nou. int off. Metoda de scriere în fişier folosită de fiecare dată este cea în care 322 . Fluxul se poate conecta şi la un flux de octeti de ieşire deja existent. public final FileDescriptor getFD() throws IOException .io.acţionează la fel ca în cazul constructorului precedent. lansarea în execuţie se face sub forma java TestFileOutput text_de_scris_în_fişier După ce s-a scris textul. dar de data aceasta pentru scriere "în coada" conţinutului existent. care se conectează la fluxul deja existent cu descriptorul fd. public void close() throws IOException . public FileOutputStream(FileDescriptor fd) . Se deschide un fişier cu numele "ProbaScriere.FileOutputStream este un flux de octeţi de ieşire conectat la un fişier. int len) throws IOException - în fişier len octeţi din tabloul b începând de la poziţia off (offset).

goleşte conţinutul zonei tampon. respectiv.ioFileDescriptor. - Metode: Metodele clasei FileWriter sunt moştenite de la clasa OutputStreamWriter. int off. Clasa FileWriter este derivată din java. Exemplu: În fişierul TestFileWriter.out. public FileWriter(File file) throws IOException . Clasa FileWriter Scrierea într-un fişier de text se poate face. scrierea în fişier se va face în coada celui deja existent.deschide pentru scriere fişierul indicat prin calea file şi creează un flux de caractere de ieşire conectat la acest fişier. int off. public void write(String str. Pentru afişare pe ecran. public void close() throws IOException . public String getEncoding() . descărcându-l în fişierul de ieşire. a doua oară s-a folosit tot un flux creat ca instanţă a clasei FileOutputStream. folosind clasa FileWriter. dacă al doilea parametru este true. int len) throws IOException - scrie în fişierul de ieşire len caractere din tabloul de caractere cbuf. dar. cu descriptorul fd.OutputStreamWriter şi foloseşte metodele acesteia.java este dat un exemplu similar cu cel din fişierul TestFileOutput.io.închide fişierul de ieşire. începând de la poziţia off (offset). public FileWriter(String fileName. îl creează.java. public void write(int c) throws IOException - scrie în fişier un singur caracter. dacă fişierul nu există. Constructori: public FileWriter(String fileName) throws IOException . public void write(char[] cbuf. int len) throws IOException - scrie în fişier len caractere din şirul str începând de la poziţia off. fiind astfel tratat acest flux ca un fişier.întoarce numele canonic al codului de caractere utilizat de acest flux. Instanţele acestei clase sunt fluxuri de ieşire de caractere. public FileWriter(FileDescriptor fd) . în care în locul claselor FileInputStream şi FileOutputStream s-au folosit clasele FileReader şi. public void flush() throws IOException .Programarea orientata pe obiecte în limbajul Java se scrie un tablou de octeţi. boolean append) throws IOException la fel ca în cazul constructorului precedent. dar care a fost conectat la fluxul standard de iesire java. de asemenea. FileWriter.creează un flux de caractere de ieşire şi îl conectează la fluxul deja existent. 323 .deschide fişierul fileName pentru scriere şi creează un flux de caractere de ieşire conectat la acest fişier. prin care se face scrierea într-un fişier.

Fişierul cu acces direct poate fi deschis în modul read (numai pentru citire). cât şi în mod binar. În ultimul caz. String mode) throws FileNotFoundException . fişierul cu acces direct trebuie să fie stocat pe un suport adresabil. dacă este "rw" 324 . cum ar fi discul magnetic. la fel ca în cazul claselor DataOutputStream şi DataInputStream. De regulă. Clasa RandomAccessFile Clasa java. Valoarea acestui indice (poziţia cursorului de fişier relativ la începutul acestuia) poate fi "citită" cu metoda getFilePointer() şi poate fi modificată cu metoda seek(). la citirea din fişier. La sfârşitul operaţiei. astfel de fişiere pot fi utilizate atât pentru citire. Fişierul cu acces direct este privit aici ca un tablou de octeţi memorat într-un sistem de fişiere (de regulă în memoria externă).: Random Access File). cât şi scrieri. În JDK. se generează o excepţie de sfârşit de fişier din clasa EOFException (End of File Exception). cât şi pentru scriere.io. care se comportă ca un indice al acestui tablou. din pachetul java. sunt fişiere la care programatorul poate indica prin program locul (adresa) din fişier de la care începe operaţia de citire sau de scriere. memoria RAM sau ROM. deci nu face parte din niciuna din cele patru ierarhii de fluxuri de intrare/ieşire prezentate anterior. În consecinţă. ca şi acestea.Severin Bumbaru Fişiere cu acces direct Fişierele cu acces direct. care este derivată din IOException. În toate celelalte cazuri când nu se poate efectua o operaţie de citire sau de scriere se genereaza o IOException (Input-Output Exception). în care scrierea s-a făcut folosind un DataOutputStream. Modul poate fi "r" (numai citire) sau "rw" (citire si scriere). cursorul se deplasează pe o distanţă corespunzatoare cu numarul de octeţi care au fost citiţi sau scrişi efectiv. discul optic. trebuie să se respecte modul în care acesta a fost scris. cât şi metode de scriere şi de citire pentru toate tipurile de date primitive şi pentru şiruri de caractere.deschide fişierul cu acces direct cu numele file în modul de exploatare mode.RandomAccessFile este derivată direct din clasa Object. fişierele cu acces direct sunt instanţe ale clasei RandomAccessFile. Dacă la citire se întâlneşte sfârşitul de fişier. clasa RandomAccessFile oferă atât metode de scriere şi de citire de octeţi. Constructori public RandomAccessFile(String file. Scrierea în fişierele cu acces direct se poate face atât în mod text (succesiunea de octeţi fiind privită ca o succesiune de caractere). numite şi fisiere cu acces aleator (engl. Este evident că. write (numai pentru scriere) sau read/write. deşi face parte.io. Există un cursor al fişierului (numit în engleză File Pointer). la fel ca în fişierele de date. Orice citire sau scriere se face începând de la poziţia pe care se găseşte acest cursor. Pentru ca înregistrările sale să poată fi parcurse într-o ordine arbitrară. este posibil să se efectueze atât citiri .

citeşte un întreg scurt (pe doi octeţi). public final int readUnsignedByte() throws IOException - 325 . public void write(int n) throws IOException . Metode public final FileDescriptor getFD() throws IOException .încearca să sară peste n octeţi.Programarea orientata pe obiecte în limbajul Java şi fişierul nu există.length octeţi. int length) throws IOException . pe care îi pune în tabloul b. se creează un fişier nou. dacă în fluxul de intrare nu este disponibil nici un octet.întoarce poziţia cursorului de fişier. public RandomAccessFile(File file.citeşte doi octeţi. întoarce numărul de octeţi cititi efectiv sau -1. pe care îi interpretează ca un numar întreg scurt fără semn.întoarce descriptorul de fişier. 255). citeşte din fişier un singur octet (sau întoarce -1 dacă s-a atins sfârşitul fişierului). public int read(byte[] b) throws IOException . int offset. pe care îi interpretează ca un caracter Unicode.. public final byte readByte() throws IOException - citeşte o valoare primitivă de tip byte. public void close() throws IOException .scrie în fişier un singur octet. public final int readUnsignedShort() throws IOException . int length)throws IOException - citeşte cel mult length octeţi pe care îi pune în tabloul b începând de la poziţia offset. public final char readChar() throws IOException .scrie în fişier conţinutul tabloului b. se blochează dacă nu are sufucienţi octeţi. citeşte un singur octet. public void write(byte[] b) throws IOException . întoarce numărul de octeţi săriţi efectiv.citeşte maximum b. public final void readFully(byte[] b. iar la întâlnirea sfârşitului de fişier generează o EOFException. întoarce numărul de octeţi citit efectiv. int offset. se intră în aşteptare. String mode) throws IOException - acţionează asemănător cu constructorul precedent. public void seek(long pos) throws IOException - deplasează cursorul de fişier pe poziţia pos. public final short readShort() throws IOException . public long length() throws IOException .citeşte exact length octeţi. public void write(byte[] b.întoarce lungimea fişierului (exprimată în octeti).length octeţi pe care îi pune în tabloul b. public final void readFully(byte[] b) throws IOException . int offset. public int skipBytes(int n) . dar calea şi numele fişierului care se deschide sunt date de instanţa file a clasei File.citeşte exact b. public long getFilePointer() throws IOException . pe care îl interpretează ca număr întreg fără semn (în intervalul 0 .citeşte doi octeţi.throws IOException . int length)throws IOException - scrie length octeţi din tabloul b începând cu cel de pe poziţia offset. public void setLength(long newLength) throws IOException - setează noua lungime a fişierului. pe care îi depune în tabloul b începând de la poziţia offset. public int read() throws IOException public int read(byte[] b.închide fişierul. public final boolean readBoolean() throws IOException - citeşte o valoare booleană (un octet).

public final void writeBoolean(boolean b) throws IOException .Severin Bumbaru public final int readInt() throws IOException - citeşte un int (pe patru citeşte un long (pe opt citeşte un float (pe citeşte un double (pe octeţi).citeşte un şir de caractere în format UTF-8. public final String readUTF() throws IOException . public final void writeFloat(float v) throws IOException . care apoi sunt citite şi afişate. public final String readLine() throws IOException - Exemplu În fişierul AccesDirect. public final void writeInt(int v) throws IOException . public final float readFloat() throws IOException - patru octeţi). 326 .scrie un float (pe patru octeţi).scrie un long (pe opt octeţi).java este dat un exemplu de aplicaţie. Înainte de fiecare citire a unei serii de date se poziţionează cursorul de fişier la începutul seriei respective.scrie o valoare booleană (pe un octet). în care se creează şi se utilizează un fişier cu acces direct.scrie un şir de caractere Unicode. care este citită şi afişată. public final void writeShort(short v) throws IOException .fad". citeşte din fişier o linie de text. public final void writeUTF(String s) throws IOException .scrie un short (pe doi octeţi). public final void writeDouble(double v) throws IOException .scrie un caracter Unicode (pe doi octeţi). public final void writeChar(char v) throws IOException .scrie un int (pe patru octeţi). Se fac două serii de scrieri de date. adică un şir de caractere încheiat prin marcajul de sfârşit de linie ('\n' pe platforme Unix sau '\r' '\n' pe platforme Microsoft). după care se poziţionează cursorul la începutul celei de a doua serii de date. public final void writeLong(long v) throws IOException .scrie un şir de caractere în format UTF-8. iar datele se citesc respectând modul în care acestea au fost scrise. Fişierul este apoi închis şi redeschis în mod "r" ("read"). public final void writeByte(byte v) throws IOException . public final void writeChars(String s) throws IOException .scrie un şir de caractere convertit în secvenţă de octeţi (fiecare caracter este reprezentat pe un octet. public final long readLong() throws IOException - octeţi).scrie un double (pe opt octeţi).scrie o valoare de tip byte. cu numele "Proba. eliminându-se octetul superior al codului caracterului). public final void writeBytes(String s) throws IOException . Prima dată fişierul este deschis în mod "rw" (read/write). public final double readDouble()throws IOException - opt octeţi).

char.io.scrie o valoare booleană.io. Constructor: .io. int. În acest scop. byte.scrie o valoare de .io. la care se adaugă următoarele metode specifice.DataOutputStream este derivată din clasa java.Se pot citi cu un DataInputStream numai date care au fost scrise cu un DataOutputStream.io. Astfel. Se poate conecta.DataOutputStream şi java. cu condiţia ca aceste date să fie citite ulterior printr-un DataInputStream. la rândul lui. În mod similar. de asemenea la intrarea unui BufferedOutputStream care. intrarea unui DataInputStream poate fi conectată la ieşirea unui FileInputStream. ByteArrayOutputStream sau PipedOutputStream.DataInputStream. float sau double) şi şiruri de caractere. public DataOutputStream(OutputStream out) Metode: Aceasta clasă conţine metodele clasei java. public final void writeByte(byte v) throws IOException tip byte pe un octet. în format Unicode. ieşirea unui DataOutputStream se poate conecta la intrarea unui FileOutputStream.scrie o valoare de .io. În această secţiune ne vom ocupa de două categorii de fluxuri de prelucrare: fluxurile de date şi fluxurile de obiecte. Clasele de fluxuri de prelucrare din Java API au fost prezentate pe scurt la descrierea pachetului java. Ea permite să se transmită date primitive către un flux de ieşire într-o formă portabilă (independentă de platformă).FilterOutputStream şi implementează interfaţa java. long. În consecinţă. ByteArrayInputStream sau PipedInputStream. este conectat la oricare din cele trei menţionate anterior. ci fluxuri de prelucrare.Programarea orientata pe obiecte în limbajul Java Fluxuri de prelucrare Fluxurile de prelucrare se conectează la alte fluxuri de intrare/ieşire pentru a face anumite transformări asupra datelor din fluxul respectiv. conectat la ieşire la un OutputStream (adică la o instanţă a unei clase derivate din clasa OutputStream). public final void writeInt(int v) throws IOException . short.scrie o valoare tip char. ci la alte fluxuri.scrie o valoare de tip 327 . pot fi folosite clasele java. Clasa DataOutputStream Clasa java.DataOutput.creează un nou flux de ieşire de date.io. Fluxuri de date În unele aplicaţii se doreşte să se transmită într-un flux de ieşire sau să se recepţioneze dintrun flux de intrare date primitive reprezentate binar (de tip boolean. public final void writeShort(short v) throws IOException de tip short pe doi octeţi. destinate scrierii în fluxul de ieşire a datelor primitive sau a unor şiruri de caractere: public final void writeBoolean(boolean v) throws IOException .OutputStream. ele nu se conectează direct la sursă sau la destinaţie. Instanţele acestor clase nu sunt fluxuri de intrare/ieşire propriu-zise. public final void writeChar(char v) throws IOException .

int off.sare peste n octeţi din fluxul de intrare. dar se citesc len octeţi. public final void writeDouble(double v) throws IOException valoare de tip double pe opt octeţi. Se pot citi cu DataInputStream numai date care au fost scrise cu DataOutputStream.InputStream. flux de date de intrare. public final void writeLong(long v) throws IOException .DataInput.io. public final void readFully(byte[] b) throws IOException public final void readFully(byte[] b. public final int size() . public final boolean readBoolean() throws IOException .io.citeşte din fluxul de intrare un număr de octeţi egal cu lungimea tabloului b. convertit într-un şir de octeţi prin suprimarea octetului superior al fiecărui caracter. public final void writeFloat(float v) throws IOException de tip float pe 4 octeţi. Clasa java. primit ca argument. la care se adaugă următoarele metode specifice. primit ca argument. şi îi pune în acest tablou.întoarce numărul de octeţi scrişi în acest flux de ieşire.acţionează similar cu metoda precedentă.DataInput: . Clasa DataInputStream Un DataInputStream este un flux de intrare de octeţi care este conectat la intrare la un alt InputStream şi citeste din acesta date primitive într-o formă independentă de platformă.End of File). dar nu s-a atins sfârşitul de fişier. apoi fiecare caracter din şir pe câte un singur octet). public final void writeUTF(String v) throws IOException . public final byte readByte() throws IOException . public final void skipBytes(int n) throws IOException . se generează o EOFException.citeşte din fluxul de intrare 328 .DataInputStream este derivată din clasa java. întoarce numărul de octeţi săriţi efectiv (este posibil să nu reuşească să sară n octeti.FilterInputStream şi implementează interfaţa java.scrie un şir de caractere codificat în formatul UTF-8 într-o formă independentă de maşină (se scrie mai întâi lungimea şirului pe doi octeţi. public final void writeChars(String v) throws IOException .creează un citeşte date din fluxul de intrare in. care sunt depuşi în tabloul b.Severin Bumbaru int pe 4 octeţi. care Metode: Aceasta clasă conţine toate metodele clasei java.io. prin care se implementează interfaţa java. Dacă se întâlneşte sfârşitul de fişier (EOF .scrie în flux un şir de caractere (în Unicode). începand de la poziţia off.io. de exemplu dacă a întalnit sfârşitul fluxului). int len) throws IOException .io.scrie un şir de caractere.scrie o valoare de . Constructor: public DataInputStream(InputStream in) . Dacă în fluxul de intrare nu sunt înca suficienţi octeţi.scrie o valoare .citeşte un octet din fluxul de intrare şi îl converteşte în valoare booleană.scrie o tip long pe 8 octeţi. procesul este pus în aşteptare până apar noi octeţi. public final void writeBytes(String v) throws IOException .

Aceasta inseamnă că trebuie îndeplinite următoarele condiţii: 329 .ObjectOutputStream şi java. În acest scop. 255] şi îl întoarce sub formă de int.ObjectInputStream.citeşte un şir de caractere în format UTF (care a fost scris cu writeUTF(String str)).citeşte din fluxul de intrare un char (doi octeţi.java se dă un exemplu de aplicaţie. 127]. public final int readUnsignedByte() throws IOException . public final float readFloat() throws IOException . Astfel de obiecte se numesc serializabile. După ce au fost scrise datele.citeşte opt octeţi si îi interpretează ca un număr de tip double. Obiectele transmise de aceste fluxuri trebuie sa implementeze interfaţa java. înainte de a fi transmise. după care se citesc datele în aceeaşi ordine în care au fost scrise. Pe platforma Java 2.io.Serializable. public final int readUnsignedShort() throws IOException .io.citeşte patru octeţi si îi interpretează ca un număr de tip int scris cu writeInt(int v). se închide fişierul pentru scriere şi se redeschide pentru citire. public final long readLong() throws IOException . public final String readUTF() throws IOException . scris anterior cu writeShort(short v). Fluxuri de obiecte Fluxurile de obiecte sunt fluxuri de prelucrare care permit să se transmită obiecte. public final int readInt() throws IOException . pentru comparaţie. Exemplu În fişierul FisierDate.Serializable.citeste opt octeţi si îi interpretează ca un număr de tip long. adică să fie puse sub forma unei serii de octeti. scris cu writeFloat(float v). pe care îl tratează ca un număr întreg cu semn în intervalul [-128. format Unicode).citeşte patru octeţi si îi interpretează ca un număr de tip float.citeşte doi octeţi din fluxul de intrare şi îi interpretează ca un număr de tip short. Datele scrise în fişier şi cele citite sunt afişate pe ecran pe perechi. pe care îl tratează ca număr întreg fără semn în intervalul [0. public final char readChar() throws IOException .citeşte din fluxul de intrare doi octeţi. fluxurile de obiecte se realizează prin clasele java.citeşte din fluxul de intrare un singur octet.io.io. se consideră că a fost scris cu writeByte(byte v). în care se creează un fişier de date şi se scriu date în acest fişier folosind un DataOutputStream legat la un FileOutpusStream. scris cu writeLong(long v). public final short readShort() throws IOException . public final double readDouble() throws IOException . obiectele transmise trebuie să fie serializate.Programarea orientata pe obiecte în limbajul Java un singur octet. pe care îi interpretează ca număr întreg fără semn şi-l întoarce sub formă de int. scris cu writeDouble(double v). Interfaţa Serializable Orice obiect care se transmite pe un flux trebuie să aparţină unei clase care implementează interfaţa java. într-un format care să permită la destinaţie reconstituirea în memorie a obiectului respectiv.

ObjectInputStream serveşte pentru citirea (deserializarea) fluxurilor de obiecte care au fost scrise folosind clasa java. cea mai frecvent folosită fiind următoarea: public final void writeObject(Object obj)throws IOException . Clasele care necesită o manipulare specială la serializare sau deserializare trebuie să conţina metode cu signaturile următoare: private void writeObject(java.toate câmpurile obiectului trebuie să fie serializabile. O prezentare mai amplă a acestei interfeţe se găseşte în documentaţia Java API. Dacă. fie unor clase care implementează interfaţa Serializable.io. care există şi în clasele DataOutputStream şi RandomAccessFile. Intrarea unui ObjectInputStream este conectată la ieşirea unui alt flux de intrare. În plus. primitive.io.ObjectOutputStream este clasa fluxurilor de prelucrare pentru obiecte. de preferinţă FileInputStream. la transmiterea obiectelor pe flux.Severin Bumbaru . Clasa ObjectInputStream Clasa java. iar utilizarea lor este asemănătoare cu cea a fluxurilor de date (DataOutputStream). Informaţii mult mai ample despre această clasă pot fi găsite în documentaţia Java API.clasa trebuie să conţină un constructor fără argumente.ObjectInputStream in) throws IOException. Într-un flux de obiecte se pot scrie atât obiecte serializate. . adică fie să aparţina unor tipuri de date. Interfaţa Serializable nu conţine câmpuri sau metode.io. ea conţine metode necesare pentru citirea 330 . ea conţine metode necesare pentru scrierea în flux a obiectelor. se pune clauza implements Serializable. Fluxurile de obiecte se conectează la ieşire la un alt flux. ByteArrayOutputStream sau PipedOutputStream. având rolul de a serializa obiectele care urmează să fie puse într-un flux de ieşire. se generează excepţia NotSerializableException. cât şi date primitive sau şiruri. ByteArrayInputStream sau PipedInputStream. Clasa ObjectOutputStream conţine toate metodele de scriere a datelor primitive şi a şirurilor. În plus.scrie în fluxul de ieşire obiectul obj sub formă serializată. Clauza implements Serializable constituie doar o indicaţie pentru compilatorul Java să o pună sub forma serializabilă. Clasa ObjectOutputStream Clasa java. de preferinţă la un FileOutputStream. Clasa ObjectInputStream conţine toate metodele de citire a datelor primitive şi a şirurilor existente în clasa DataInputStream.la declararea clasei respective.ObjectOutputStream out) throws IOException private void readObject(java.ObjectOutputStream. ClassNotFoundException.io. se constată că unul din acestea nu este serializabil.io. .

IOException Informaţii mai ample despre această clasă se găsesc în documentaţia Java API. iar pentru datele primitive şi pentru şiruri se folosesc metodele specifice pentru scrierea tipurilor respective. În partea a doua a metodei main() se deschide fişierul Proba1. putându-se astfel verifica faptul că serializarea şi deserializarea s-au făcut corect. au fost scrise în fişier (prin metoda writeObject) şi tablouri unidimensionale şi bidimensionale. în care se testează clasele ObjectOutputStream şi ObjectInputStream. Care sunt rădăcinile ierarhiilor de clase pentru fluxuri de octeţi? 9. se creează un fişier (Proba1.java este dat un exemplu de aplicaţie. Care sunt etapele de utilizare a unui flux de iesire? 4. În ultima parte a metodei main() se afişează pe ecran datele citite. Cum se închide un fişier? 15. Ce este un fişier? 11.dat. se închide fişierul Proba1. în ordinea în care au fost scrise. Din acest exemplu se poate constata că clasele ObjectOutputStream şi ObjectInputStream constituie un instrument foarte puternic de salvare şi restaurare a datelor din memorie la nivelul obiectelor (al structurilor de date). Ce sunt fluxurile de prelucrare? 10. Care sunt rădăcinile ierarhiilor de clase pentru fluxuri de caractere? 8.io? 6. în afară de date primitive şi obiecte. Remarcăm că. Exemplu În fişierul FisierObiecte. Pentru scrierea obiectelor şi a tablourilor se foloseşte metoda void writeObject(Object obj). Ce deosebire este între fluxurile de ieşire şi cele de intrare? 3. Ce clase se folosesc pentru a scrie date într-un fişier de octeţi şi pentru a citi date 331 .dat) în care se scriu atât obiecte (din clasele Persoana şi Student). Ce deosebire este între fluxurile de caractere şi cele de octeţi? 7. dintre care cea mai frecvent folosită este public final Object readObject() throws OptionalDataException.dat pentru citire şi se citesc din el toate datele scrise anterior. În prima parte a metodei main(). care au fost apoi citite corect (prin metoda readObject). Care sunt clasele folosite pentru scrierea fişierelor? 13. După ce s-a încheiat scrierea datelor. Ce conţine pachetul java. Care sunt clasele folosite pentru citirea fişierelor? 12. Întrucât metoda Object readObject() întoarce un Object. Întrebări Nivel 1 1. şiruri şi tablouri. Care sunt etapele de utilizare a unui flux de intrare? 5. Ce este un stream? 2. acesta este convertit prin cast într-un obiect din clasa căruia îi aparţine în realitate. care îl scutesc pe programator de munca laborioasă şi dificilă se a programa aceste operaţii la nivelul inferior al fluxurilor de octeţi sau la nivelul fluxurilor de date primitive.Programarea orientata pe obiecte în limbajul Java obiectelor serializate. Cum se deschide un fişier? 14. cât şi date primitive. ClassNotFoundException.

Severin Bumbaru dintr-un astfel de fişier? 16. Ce sunt fişierele cu acces direct? 17. Cărei clase îi aparţin fişierele cu acces direct? 18. Ce fel de operaţii se pot face asupra unui fişier cu acces direct? 19. Ce este cursorul (pointerul) fişierului cu acces direct? 20. Care sunt modurile în care poate fi deschis un fişier cu acces direct? 21. Ce sunt fluxurile de prelucrare? 22. Ce sunt fluxurile de date? 23. Prin ce clase se realizează fluxurile de date? 24. Ce este un flux de obiecte? 25. Prin ce clase se realizează fluxurile de obiecte? 26. Ce proprietate trebuie sa aibă obiectele pentru a putea fi transmise într-un flux de obiecte? 27. Ce reprezintă interfaţa Serializable? 28. Cum este folosită interfaţa Serializable? 29. Ce condiţii trebuie să îndeplinească o clasă pentru a fi serializabilă? 30. Ce metode conţine interfaţa Serializable?

Nivel 2
1. Dece fluxul este un obiect abstract? 2. Clasele Reader şi Writer sunt abstracte sau instanţiabile? 3. Ce se înţelege prin marcarea unui flux şi prin ce metodă se realizează? 4. Cum se poate reveni într-un flux la marcajul făcut anterior? 5. Clasele InputStream şi OutputStream sunt sau nu instanţiabile? 6. În ce situaţii este obligatorie folosirea fluxurilor de octeţi? 7. Ce clasă se foloseşte pentru a scrie date într-un fişier de caractere? 8. Ce clasă se foloseşte pentru a citi date dintr-un fişier de caractere? 9. Prin ce metode se scriu datele primitive într-un fişier cu acces direct? 10. Prin ce metode se citesc datele primitive dintr-un fişier cu acces direct? 11. Prin ce metode se scriu şirurile de caractere într-un fişier cu acces direct? 12. Ce este UTF? 13. Pot fi fluxurile de date conectate direct la un fişier? 14. La ce fluxuri se conectează fluxurile de date? 15. Ce se întamplă dacă se încearcă introducerea într-un flux de obiecte a unui obiect neserializabil? Când se constată anomalia: la compilare sau la execuţie? 16. Un flux de obiecte poate conţine şi date primitive? dece? 17. Pot fi puse tablourile într-un flux de obiecte?

332

Programarea orientata pe obiecte în limbajul Java

Fire de execuţie
Conceptul de proces. Procese paralele şi concurente Fire de execuţie Clasa Thread Interfaţa Runnable Sincronizarea firelor de execuţie Întrebări. 333 335 335 346 348 354

Conceptul de proces. Procese paralele şi concurente
În general, se numeşte proces o succesiune de transformări sau de operaţii care conduce la realizarea unui anumit rezultat. Esenţial pentru un proces este caracterul său temporal: fiecare transformare elementară necesită un anumit timp, iar procesul în ansamblu este o succesiune de astfel de transformări elementare. Termenul este folosit în domenii diferite: procese fizice, procese chimice, procese tehnologice, procese biologice, procese economice, procese sociale, procese juridice etc. În informatică, procesul este un program în execuţie. În consecinţă, fiecărui proces i se asociază un program, şi un ansamblu de resurse necesare executării acestui program: o anumită zonă din memoria internă în care se păstrează datele programului, acces la procesorul sistemului, acces la anumite dispozitive de intrare/ieşire etc. Procesul constă tocmai în efectuarea în timp a succesiunii de operaţii prevăzută în program, folosind în acest scop resursele alocate. În mod tradiţional, programul este executat de către un singur procesor (dispozitiv de prelucrare), care poate efectua, la un moment de timp dat, numai o singură operaţie. În consecinţă, operaţiile prevăzute în program trebuie executate secvenţial, astfel încât operaţia următoare nu poate începe decât după încheierea celei precedente. Toate programele prezentate de noi în capitolele precedente se încadrează în această categorie.

Este posibil ca mai multe procese să se desfăşoare simultan, adică intervalele de timp corespunzătoare acestor procese să se suprapună total sau parţial. Astfel de procese pot fi paralele sau concurente.

333

Severin Bumbaru

Dacă procesele de calcul care au loc simultan folosesc resurse diferite (sunt executate de procesoare diferite, folosesc zone de memorie internă şi externă diferite etc.), ele se numesc procese paralele. Dacă procesele care se desfăşoară în acelaşi interval de timp folosesc anumite resurse comune, ele se numesc procese concurente. Cel mai frecvent se întâlneşte situaţia, în care mai multe procese folosesc în comun acelaşi procesor. Întrucât, la un moment dat, procesorul nu poate efectua decât o singură operaţie, înseamnă că este necesar să se adopte o anumită strategie, conform căreia timpul de funcţionare al procesorului este partajat între diferitele procese concurente. În principiu, aceste strategii se împart în două categorii: 1. Se acordă fiecăruia dintre procesele concurente un anumit nivel de prioritate. Dacă mai multe procese solicită simultan aceeaşi resursă, ea este alocată procesului cu prioritate superioară.

Conform acestei strategii, dacă, în timpul derularii unui proces A, procesorul este solicitat de un alt proces B de prioritate superioară, procesul A este întrerupt, trecându-se la executarea procesului B. După încheierea executării procesului prioritar B, se revine la procesul A, care este continuat din starea în care a fost întrerupt. Este însa posibil ca, în timp ce se deruleaza procesul B, procesorul sa fie solicitat de un alt proces C, de prioritate şi mai înalta. În acest caz, şi procesul B va fi întrerupt, trecându-se la executarea procesului C şi aşa mai departe. 2. Timpul total de funcţionare a procesorului este porţionatsau divizat (împărţit în intervale de durate egale sau diferite), acordându-se succesiv câte un astfel de înterval de timp fiecăruia dintre procesele concurente. La expirarea intervalului de timp alocat, numit şi felie sau tranşă de timp (engleză: time slice), procesul în curs este întrerupt şi se trece la executarea procesului următor, prin rotaţie. O astfel de utilizare a procesorului se numeşte "partajare a timpului" (engleză: time sharing sau time slicing). Cele două strategii menţionate aici pot fi aplicate în diferite variante şi pot fi combinate în diferite moduri. Cel mai frecvent, partajarea timpului este aplicată numai pentru procesele cu acelaşi nivel de prioritate. Majoritatea sistemelor de operare ale calculatoarelor moderne permit executarea în acelaşi timp a mai multor programe, deci permit concurenţa proceselor la nivel de program (de aplicaţie). De exemplu, în timp ce edităm un text, putem tipări alt text la imprimantă, putem aştepta sosirea de pe reţea a unei pagini de Web etc. Studierea acestui mod de funcţionare a calculatorului, cunoscut sub numele de multitasking, se face la cursul de "Sisteme de operare". Pentru a pune în evidenţă distincţia între program şi proces, putem menţiona că acelaşi program poate da naştere la procese diferite: dacă programul conţine ramificaţii şi/sau cicluri, parcurgerea efectivă a acestora (ce ramuri vor fi executate efectiv şi de câte ori se vor parcurge ciclurile) depinde de datele de intrare. În cadrul multitaskingului, este chiar posibil ca doi utilizatori să utilizeze simultan acelaşi program folosind date diferite, astfel încât se generează procese diferite.

334

Programarea orientata pe obiecte în limbajul Java

Fire de execuţie
Firul de execuţie (în engleză: Thread) este, în esenţă, un subproces strict secvenţial. Menţinând definiţia procesului ca un program în curs de execuţie, putem considera acum că procesul este format din mai multe fire de execuţie care se derulează în paralel, concurând la utilizarea resurselor alocate procesului respectiv. În limbajul Java, există posibilitatea de a se crea programe care conţin mai multe fire de execuţie. Aceasta înseamnă că, la executarea lor, se vor crea mai multe subprocese care se vor desfăşura simultan, folosind acelaşi procesor şi aceeaşi zonă de memorie. Acest mod de funcţionare se numeşte în engleză multithreading.

Chiar şi în cazul programelor Java în care nu sunt prevăzute explicit mai multe fire de execuţie, în timpul executării lor coexistă cel puţin două astfel de fire: cel al aplicaţiei propriu-zise şi cel al colectorului de reziduuri (garbage collector). Colectorul de reziduuri este un fir de execuţie cu nivel de prioritate coborât, care funcţionează atunci când apar întreruperi în desfăşurarea aplicaţiei propriu-zise (de exemplu, când se aşteaptă efectuarea unor operaţii de intrare/ieşire). În consecinţă, maşina virtuală Java are intrinsec o funcţionare de tip multithreading. Există două moduri de a programa un fir de execuţie: - prin extinderea clasei Thread; - prin implementarea interfeţei Runnable.

Clasa Thread
Clasa java.lang.Thread realizează un fir de execuţie. Acesta poate fi un fir de execuţie obişnuit, sau un demon. Demonul (engleză: daemon thread) este un fir de execuţie de prioritate coborâtă, care nu este invocat în mod explicit. El stă "adormit" şi intră automat în execuţie atunci când sunt îndeplinite anumite condiţii. Un exemplu tipic de demon este colectorul de reziduuri. După cum ştim deja, acesta este un fir de execuţie de prioritate coborâtă, care intră în funcţiune atunci când în memorie apar obiecte către care nu mai există referinţe. Crearea unui fir de execuţie se face invocând unul dintre constructorii clasei Thread. Dintre aceştia, îi menţionâm aici pe următorii:

- creează un nou fir de execuţie cu numele implicit Thread-n, unde n este un număr de ordine; public Thread(String name) - creează un nou fir de execuţie cu numele name; public Thread(Runnable target) - creează un nou fir de execuţie, care conţine obiectul target cu interfaţa Runnable, iar numele firului este cel implicit;
public Thread()

335

Severin Bumbaru
public Thread(Runnable target, String name) - creează un conţine obiectul target cu interfaţa Runnable şi are numele name.

nou fir de execuţie,

care

Cele mai frecvent utilizate metode ale clasei Thread sunt run(), start() şi sleep(). Iată o listă a principalelor metode ale acestei clase:

public void run() - conţine programul care trebuie executat de firul respectiv; Aşa cum este ea în clasa Thread, metoda nu face nimic (are corpul vid). Această metodă trebuie redefinită fie prin crearea unei subclase a clasei Thread, fie prin crearea unei obiect cu interfaţa Runnable, care să fie înglobat în acest Thread (folosind constructorul Thread(Runnable target)); public void start() - pune firul nou creat în starea "gata pentru execuţie"; public static void sleep(long millis) throws InterruptedException opreşte temporar execuţia acestui fir, pentru o durata de millis milisecunde; public static void yield() - opreşte temporar execuţia acestui fir, permiţând monitorului să dea controlul altui fir de aceeaşi prioritate; public static Thread currentThread() - întoarce o referinţă la firul care este executat în momentul curent; public final void setPriority(int newPriority) - seteaza prioritatea firului de execuţie; prioritatea trebuie sa fie cuprinsă în intervalul [Thread.MIN_PRIORITY, Thread.MAX_PRIORITY] (valorile lor fiind, respectiv, 1 şi 10). Nerespectarea acestui interval genereaza o IllegalArgumentException. Daca nu este stabilită explicit, prioritatea este Thread.NORM_PRIORITY (are valoarea 5). public final int getPriority() - întoarce prioritatea curentă a firului de execuţie. public final void setName(String name) - pune firului de execuţie un nou nume; public final String getName() - întoarce numele firului de execuţie; public final void setDaemon(boolean on) - dă firului de execuţie calitatea de demon (dacă argumentul este true) sau de fir obişnuit (dacă argumentul este false); Metoda poate fi invocată numai dacă firul nu este activ, altfel se generează o IllegalThreadStateException. public final boolean isDaemon() - testează dacă firul de execuţie este demon.

La programarea unui fir de execuţie, principala atenţie se acordă metodei run(), deoarece ea conţine programul propriu-zis, care trebuie executat de acest fir. Totuşi, metoda run()nu este invocată explicit. Ea este invocată de maşina virtuală Java, atunci când firul respectiv este pus în mod efectiv în execuţie. Pentru redefinirea metodei Run este necesar sa creem o subclasă a clasei Thread sau sa creem o clasă cu interfaţa Runnable, şi să dăm o instanţă a acestei clase ca argument constructorului clasei Thread. După ce firul de execuţie a fost creat (de exemplu prin expresia new Thread()), el există în memorie, dar înca nu poate fi executat. Se găseşte, deci, în starea "nou creat" (engleza: born). Pentru a-l face gata de execuţie, pentru firul respectiv este invocată metoda start().

După invocarea metodei start(), firul este executabil, dar aceasta nu înseamnă că el este

336

Programarea orientata pe obiecte în limbajul Java pus în execuţie imediat: noul fir devine concurent cu cele deja existente (în primul rând cu cel care l-a creat), şi va fi pus în execuţie în mod efectiv (i se va acorda acces la procesor) atunci când îi vine rândul, conform cu strategia de alocare a resurselor adoptată. Un fir în curs de execuţie poate fi oprit temporar ("adormit") invocând metoda statică sleep(long millis). Argumentul acestei metode este intervalul de timp cât procesul se va găsi în stare de "somn", exprimat în milisecunde.

Referitor la utilizarea acestei metode, remarcăm două aspecte: - întrucât ea poate "arunca" o InterruptedException, este necesar să fie prinsă într-un bloc try..catch; - întrucat metoda este statică şi nu are ca argument un fir de execuţie, ea nu poate fi invocată decât în metodele firului de execuţie căruia i se aplică. Fiecărui fir de execuţie i se asociază o anumită prioritate. Aceasta este un numar întreg, cuprins între valorile Thread.MIN_PRIORITY şi Thread.MAX_PRIORITY (având valorile 1 şi respectiv 10). Dacă metoda setPriority(int newPriority) nu este invocată explicit, firului i se dă prioritatea implicita Thread.NORM_PRIORITY, respectiv 5. Daca firul de execuţie solicită o operaţie de intrare/ieşire, el rămîne blocat pe întreaga durată a executării operaţiei respective. În timpul în care firul de execuţie "doarme" (ca urmare a invocării metodei sleep()) sau este blocat (deoarece asteapta terminarea unei operatii de intrare/iesire), se pot executa alte fire, de prioritate egală sau inferioară. În schimb, firele de prioritate superioară pot întrerupe în orice moment executarea celor de prioritate inferioară. Un proces poate fi pus, de asemenea, în aşteptare prin invocarea metodei wait(). În acest caz, firul aşteaptă confirmarea efectuării unei anumite acţiuni, prin invocarea metodei notify() sau notifyAll(). Aceste trei metode există în clasa Object şi servesc la sincronizarea firelor de execuţie.

Având în vedere cele de mai sus, punem în evidenţă urmatoarele stări în care se poate găsi un fir de execuţie pe durata ciclului său de viaţă: - nou creat (engleză: born) - este starea în care se găseşte imediat ce a fost creat prin operatorul new; în această stare, firul nu poate fi executat; - gata de execuţie (engleză: ready) - este starea în care firul poate fi pus în execuţie; punerea efectivă în execuţie se face de către maşina virtuala Java atunci când procesorul este liber şi nu sunt gata de execuţie fire de prioritate superioară; - în execuţie (engleză: running) - este starea în care procesul se execută efectiv (ocupă procesorul); - adormit (engleză: sleeping) - este starea de oprire temporară, ca urmare a invocării metodei sleep(); - blocat (engleză: blocked) - este starea în care aşteaptă incheierea unei operaţii de intrare/ieşire; - în aşteptare (engleză: waiting) - este starea în care firul se găseşte din momentul în care

337

Severin Bumbaru se invocă metoda wait(), până când primeşte o confirmare dată prin invocarea metodei notify(); - mort (engleză: dead) - este starea în care intră firul de execuţie dupa ce s-a încheiat executarea metodei run(). Relaţiile dintre aceste stări sunt reprezentate grafic în figura de mai jos.

Denumirile stărilor firului de execuţie au fost date în limba engleză, pentru a putea fi urmarită mai uşor documentaţia originală din Java API. Trecerea de la starea Born la starea Ready (gata) se face prin invocarea metodei start(). Trecerea de la starea Ready la starea Running (în execuţie) se face de către maşina virtuală Java (de către dispecerul firelor) atunci când sunt create condiţiile necesare: procesorul este liber şi nici un fir de execuţie de prioritate superioară nu se găseşte în starea Ready. Trecerea de la starea Running la starea Ready se face la executarea metodei yield(), sau atunci când a expirat tranşa de timp alocată procesului (în cazul sistemelor cu diviziune a timpului). Trecerea de la starea Running la starea Sleeping se face la executarea metodei sleep(). Trecerea de la starea Sleeping la starea Ready se face când a expirat intervalul de timp de

338

Programarea orientata pe obiecte în limbajul Java "adormire" (intervalul dat ca argument în metoda sleep(long millis)). Trecerea de la starea Running la starea Blocked are loc atunci când firul de execuţie respectiv solicită efectuarea unei operaţii de intrare ieşire. Trecerea de la starea Blocked la starea Ready are loc când s-a încheiat operaţia de intrare/ieşire solicitată de acest fir. Trecerea de la starea Running la starea Waiting se face la invocarea metodei wait(). Trecerea de la starea Waiting la starea Ready se face când se primeşte o confirmare prin invocarea metodei notify() sau notifyAll(). Trecerea de la starea Running la starea Dead are loc atunci când se încheie executarea metodei run() a firului de execuţie respectiv. Se observă că orice fir de execuţie îşi începe ciclul de viaţă în starea Born şi îl încheie în starea Dead. Punerea firului în execuţie efectivă (trecerea de la Ready la Running) se face numai de către dispecerul firelor. În toate cazurile în care se încheie o stare de oprire temporară a execuţiei (Sleeping, Waiting sau Blocked), firul de execuţie respectiv trece în starea Ready, aşteptând ca dispecerul să-l pună efectiv în execuţie (să-l treacă în starea Running). În timpul cât firul de execuţie se găseşte în orice altă stare decât Running, procesorul calculatorului este liber, putând fi utilizat de alte fire de execuţie sau de alte procese.

Exemplul 1 Fişierul DouaFireA.java conţine un exemplu de aplicaţie, în care se creează fire de execuţie folosind o clasă care extinde clasa Thread.
/* Crearea si utilizarea unei clase de fire de executie care extinde clasa Thread dar nu foloseste metodele sleep sau yield. Se creeaza doua fire de aceeasi prioritate (Thread.NORM_PRIORITY). */ class DouaFireA { /* Clasa firelor de executie */ static class Fir extends Thread { Fir(String numeFir) { super(numeFir); System.out.println("S-a creat firul "+getName()); } /* Redefinirea metodei run() din clasa Thread */ public void run() { System.out.println("Incepe executarea firului "+getName()); for(int i=0; i<6; i++) {

339

Severin Bumbaru

System.out.println("Firul "+getName()+" ciclul i="+i); } } } /* incheierea clasei Fir */ public static void main(String args[]) throws Exception { Fir fir1, fir2; System.out.println("Se creeaza firul Alpha"); fir1=new Fir("Alpha"); System.out.println("Se creeaza firul Beta"); fir2=new Fir("Beta"); System.out.println("Se pune in executie firul Alpha"); fir1.start(); System.out.println("Se pune in executie firul Beta"); fir2.start(); System.out.println("Sfarsitul metodei main()"); } /* Sfarsitul metodei main() */ }

Clasa Fir din această aplicaţie extinde clasa Thread, deci instanţele ei sunt fire de execuţie. În clasa Fir s-a redefinit metoda run(), astfel încât să conţină programul firului respectiv. În cazul nostru, firul execută un ciclu, în care afişează la terminal un mesaj, conţinând numele firului şi indicele ciclului executat. În metoda main() a aplicaţiei se creează două instanţe ale clasei Fir, dându-le, respectiv, numele Alpha şi Beta, apoi se lansează în execuţie aceste fire. Iată un exemplu de rezultat al executării acestei aplicaţii:

Se creeaza firul Alpha S-a creat firul Alpha Se creeaza firul Beta S-a creat firul Beta Sfarsitul metodei main() Incepe executarea firului Alpha Firul Alpha ciclul i=0 Firul Alpha ciclul i=1 Firul Alpha ciclul i=2 Firul Alpha ciclul i=3 Firul Alpha ciclul i=4 Firul Alpha ciclul i=5 Incepe executarea firului Beta Firul Beta ciclul i=0 Firul Beta ciclul i=1 Firul Beta ciclul i=2 Firul Beta ciclul i=3 Firul Beta ciclul i=4 Firul Beta ciclul i=5

Remarcăm cele ce urmează. - În realitate, în afară de firele de execuţie Alpha şi Beta create explicit de către noi, mai exista incă două fire de execuţie: cel al aplicaţiei propriu-zise (executarea metodei main()) şi cel al colectorului de reziduuri. Întrucât nu s-au setat explicit priorităţile, firele Alpha, Beta şi main() au toate prioritatea Thread.NORM_PRIORITY.

340

Programarea orientata pe obiecte în limbajul Java - Întrucât toate firele au aceeaşi prioritate, durata executării fiecărui fir este mică şi nu s-au folosit metode de suspendare a execuţiei (yield(), sleep(), wait()), în momentul în care începe executarea unui fir acesta se execută până la capăt, după care procesorul sistemului este preluat de firul următor. În consecinţă s-a executat mai întâi metoda main() până la incheierea ei (confirmată prin mesajul "Sfârşitul metodei main()"), după care se execută complet firul Alpha şi apoi firul Beta (în ordinea lansării). - Aplicaţia se încheie în momentul în care s-a încheiat ultimul fir de execuţie.

Exemplul 2 În fişierul DouaFireA1.java se reia aplicaţia din exemplul precedent, dar la sfârşitul fiecărui ciclu de indice i se invocă metoda yield() care suspendă firul în curs şi permite astfel să se transmită controlul următorului fir de aceeaşi prioritate.
/* Crearea si utilizarea unei clase de fire de executie care extinde clasa Thread. Se foloseste metoda yield() pentru a ceda controlul altui fir de aceeasi prioritate. Se creeaza doua fire de aceeasi prioritate (Thread.NORM_PRIORITY). */ class DouaFireA1 { /* Clasa firelor de executie */ static class Fir extends Thread { Fir(String numeFir) { super(numeFir); System.out.println("S-a creat firul "+getName()); } /* Redefinirea metodei run() din clasa Thread */ public void run() { System.out.println("Incepe executarea firului "+getName()); for(int i=0; i<6; i++) { System.out.println("Firul "+getName()+" ciclul i="+i); yield(); // cedarea controlului procesorului } } } /* incheierea clasei Fir */ public static void main(String args[]) throws Exception { Fir fir1, fir2; System.out.println("Se creeaza firul Alpha"); fir1=new Fir("Alpha"); System.out.println("Se creeaza firul Beta"); fir2=new Fir("Beta"); System.out.println("Se pune in executie firul Alpha"); fir1.start(); System.out.println("Se pune in executie firul Beta"); fir2.start(); System.out.println("Sfarsitul metodei main()");

341

dar se parcurge un ciclu de contorizare (pe j) de 100000000 ori pentru a mari durata de executie a ciclului exterior (pe indicele i). cedându-se procesorul sistemului în favoarea celuilalt fir.în ciclul cu contorul i din metoda run() a clasei Fir s-a mai introdus un ciclu interior (cu contorul j) care se parcurge de 100000000 ori.cele două cicluri (pe i şi pe j) au fost introduse şi în metoda main(). are loc intercalat. dacă cele doua fire ar fi avut priorităţi diferite. se invocă metoda yield() . deoarece.java s-a reluat aplicaţia din Exemplul 1.Severin Bumbaru } /* Sfarsitul metodei main() */ } Rezultatul executarii acestei aplicatii este urmatorul: Se creeaza firul Alpha S-a creat firul Alpha Se creeaza firul Beta S-a creat firul Beta Sfarsitul metodei main() Incepe executarea firului Alpha Firul Alpha ciclul i=0 Incepe executarea firului Beta Firul Beta ciclul i=0 Firul Alpha ciclul i=1 Firul Beta ciclul i=1 Firul Alpha ciclul i=2 Firul Beta ciclul i=2 Firul Alpha ciclul i=3 Firul Beta ciclul i=3 Firul Alpha ciclul i=4 Firul Beta ciclul i=4 Firul Alpha ciclul i=5 Firul Beta ciclul i=5 Se observă cu uşurinţă că. în locul acestuia se putea pune. Aceasta nu s-ar fi întâmplat. Exemplul 3 În fişierul DouaFireB. orice alta secvenţa de instrucţiuni cu durata de execuţie comparabilă. după fiecare parcurgere a unui ciclu într-un fir. evident.NORM_PRIORITY). pentru a putea urmări executarea acesteia după lansarea firelor Alpha şi Beta. aducându-i-se următoarele modificări: . Se creeaza doua fire de aceeasi prioritate (Thread. în acest caz. /* Crearea si utilizarea unei clase de fire de executie. . */ 342 . Alpha şi Beta. In metoda run a firului nu se folosesc metodele sleep() sau yield(). Fragmentele de program nou adăugate sunt puse în evidenţă în textul de mai jos cu caractere aldine (îngroşate). executarea celor două fire. pentru a mări în mod artificial durata de execuţie.

Programarea orientata pe obiecte în limbajul Java class DouaFireB { /* Clasa firelor de executie */ static class Fir extends Thread { Fir(String numeFir) { super(numeFir). System. System. i++) { for(int j=0. for (int i=0. fir2.println("Incepe executarea firului "+getName()).println("Sfarsitul metodei main()").out. System. j<100000000.println("Se pun in executie cele doua fire").println("S-a creat firul "+getName()).out.start().println("Se creeaza firele Alpha si Beta").out.out. System. } /* Sfarsitul metodei main() */ } Iată un exemplu de rezultat obţinut prin executarea acestei aplicaţii: Se creeaza firele Alpha si Beta S-a creat firul Alpha S-a creat firul Beta Incepe executarea firului Alpha Incepe executarea firului Beta Firul Alpha ciclul i=0 Firul Beta ciclul i=0 main() ciclul i=0 main() ciclul i=1 Firul Alpha ciclul i=1 Firul Beta ciclul i=1 main() ciclul i=2 Firul Alpha ciclul i=2 Firul Beta ciclul i=2 main() ciclul i=3 Firul Alpha ciclul i=3 Firul Beta ciclul i=3 343 .start().out. i<5.out. } /* Redefinirea metodei run() din clasa Thread */ public void run() { System. fir3.out. j<100000000. fir2. System. } System. j++). fir1. i++) { for(int j=0. for(int i=0.println("Firul "+getName()+" ciclul i="+i). fir1=new Fir("Alpha").println("main() ciclul i="+i). fir2=new Fir("Beta"). j++). } } } /* incheierea clasei Fir */ public static void main(String args[]) throws Exception { Fir fir1. i<5.

sleep(1000). i++) { System. Exemplul 4 În fişierul DouaFireC. Această metodă aruncă excepţia InterruptedException care trebuie captată. simultan în timp. se aplică o strategie de partajare a timpului.NORM_PRIORITY).println("S-a creat firul "+getName()). Beta si main()) au aceeaşi prioritate (Thread. În mod similar s-a procedat şi în ciclul din metoda main. dar s-a renunţat la ciclurile interioare (cu contorul j). întrucat durata de execuţie a fiecărui fir a devenit mult mai mare decât în exemplul precedent şi toate cele trei fire (Alpha. astfel încât timpul de funcţionare al procesorului este alocat sub forma de tranşe succesive fiecăruia dintre procese. Similar se procedeaza in metoda main() */ class DouaFireC { /* Clasa firelor de executie */ static class Fir extends Thread { Fir(String numeFir) { super(numeFir). În metoda run a firului se foloseste metoda sleep(1000) pentru a pune firul in asteptare pe o durata de 1000 milisecunde. în schimb după parcurgerea fiecărui ciclu de indice i se pune firul respectiv in aşteptare timp de 1000 milisecunde prin invocarea metodei sleep.out. for(int i=0. deci invocarea s-a făcut sub forma Thread. try { sleep(1000).out. } catch(InterruptedException e) {} 344 . /* Crearea şi utilizarea unei clase de fire de execuţie. la invocarea metodei statice sleep a fost necesar să se indice clasa căreia îi aparţine. System.Severin Bumbaru main() ciclul i=4 Sfarsitul metodei main() Firul Alpha ciclul i=4 Firul Beta ciclul i=4 Constatăm că. } /* Redefinirea metodei run() din clasa Thread */ public void run() { System.println("Firul "+getName()+" ciclul i="+i).println("Incepe executarea firului "+getName()).out. În consecinţă. i<5. se creeaza impresia că cele trei procese se desfăşoară în paralel. Având însă în vedere că metoda main() nu se găseşte într-o clasa derivata din Thread.java se reia aplicaţia din exemplul precedent.

fir1=new Fir("Alpha"). se pot executa alte fire. for (int i=0. fir2.out. fir1.println("main() ciclul i="+i). } /* Sfarsitul metodei main() */ } Iată rezultatul executării acestei aplicaţii: Se creeaza firele Alpha si Beta S-a creat firul Alpha S-a creat firul Beta Se pun in executie cele doua fire main() ciclul i=0 Incepe executarea firului Alpha Firul Alpha ciclul i=0 Incepe executarea firului Beta Firul Beta ciclul i=0 main() ciclul i=1 Firul Alpha ciclul i=1 Firul Beta ciclul i=1 main() ciclul i=2 Firul Alpha ciclul i=2 Firul Beta ciclul i=2 main() ciclul i=3 Firul Alpha ciclul i=3 Firul Beta ciclul i=3 main() ciclul i=4 Firul Alpha ciclul i=4 Firul Beta ciclul i=4 Sfarsitul metodei main() În timp ce un fir "doarme". i<5.println("Se creeaza firele Alpha si Beta").println("Se pun in executie cele doua fire").sleep(1000). } catch(InterruptedException e) {} } System. fir2=new Fir("Beta"). chiar dacă ele sunt de prioritate inferioară! 345 .println("Sfarsitul metodei main()").start(). System. fir2.out. try { Thread.out.Programarea orientata pe obiecte în limbajul Java } } } /* incheierea clasei Fir */ public static void main(String args[]) throws Exception { Fir fir1. i++) { System. fir3.out. System.start().

println("Firul "+ 346 . /* Crearea si utilizarea unei clase cu interfata Runnable. deci clasa B nu poate avea ca superclase atât clasa A. i<6. Utilizarea instanţelor claselor cu interfaţa Runnable se face. cât şi clasa Thread. dar ale cărei instanţe trebuie tratate ca nişte fire de execuţie. Singura metodă a acestei interfeţe este public void run() care are acelaşi rol cu cea din clasa Thread. utilizand ca argument al constructorului instante ale clasei Fir cu interfata Runnable.lang. Fragmentele de program modificate sunt puse în evidenţa în textul sursă de mai jos prin caractere aldine (ingroşate).java. Motivul ar putea fi. de exemplu. Se foloseste metoda yield() pentru a ceda controlul altui fir de aceeasi prioritate. for(int i=0.out. cu deosebirea că clasa Fir nu extinde clasa Thread. care nu este descendentă a clasei Thread Se ştie că în Java nu există moştenire multiplă.Severin Bumbaru Interfaţa Runnable Interfaţa java.getName()). B. cel că clasa nou creată. String name) instanţă a clasei Thread creată cu un astfel de constructor. public Thread(Runnable target) public Thread(Runnable target.println("Incepe executarea firului "+ Thread.java se dă un exemplu de aplicaţie similară cu cea din fişierul DouaFireA1.currentThread(). ci implementează interfaţa Runnable. */ class DouaFireAR { /* Clasa cu interfata Runnable */ static class Fir implements Runnable { /* Definirea metodei run() din interfata Runnable */ public void run() { System.NORM_PRIORITY). Exemplul 1 În fişierul DouaFireAR.out. Se creeaza doua fire de aceeasi prioritate (Thread. În acest caz. i++) { System.lang. punându-le ca argumente ale următorilor constructori ai clasei Thread: O se comportă ca şi cum ar fi instanţa unei extensii a clasei Thread care ar conţine metoda run() a obiectului target cu interfaţa Runnable.Thread. Necesitatea implementării interfeţei Runnable apare atunci când dorim să creem o clasa de fire de execuţie care nu extinde clasa Thread. care conţine metoda run(). A.Runnable trebuie implementată de orice clasă care nu este descendentă a clasei java. vom crea o clasă B care extinde clasa A şi implementeaza interfaţa Runnable. trebuie sa extindă o alta clasă.

Programarea orientata pe obiecte în limbajul Java

Thread.currentThread().getName()+" ciclul i="+i); Thread.yield(); // cedarea controlului procesorului } } } /* incheierea clasei Fir */ public static void main(String args[]) throws Exception { Thread fir1, fir2; System.out.println("Se creeaza firul Alpha"); fir1=new Thread(new Fir(), "Alpha"); System.out.println("Se creeaza firul Beta"); fir2=new Thread(new Fir(), "Beta"); System.out.println("Se pune in executie firul Alpha"); fir1.start(); System.out.println("Se pune in executie firul Beta"); fir2.start(); System.out.println("Sfarsitul metodei main()"); } /* Sfarsitul metodei main() */ }

Comparând cu Exemplul 2 din sectiunea Clasa Thread, constatăm cele ce urmează. - Clasa Fir nu mai extinde clasa Thread, ci implementeaza interfaţa Runnable. - În metoda run() a clasei Fir s-a avut în vedere că aceasta nu extinde clasa Thread şi deci nu moşteneşte metodele ecesteia. În consecinţă: . metoda statică yield() a clasei Thread a fost invocată sub forma Thread.yield(); . pentru a obţine o referinţă la instanţa curentă a clasei Thread, necesară invocării metodei getName(), s-a folosit metoda statică Thread.getCurrentThread(). - Crearea celor două fire de execuţie în metoda main() s-a făcut folosind un constructor al clasei Thread, căruia i s-au dat ca parametri o instanţă a clasei Fir şi numele firului respectiv, de exemplu:
fir1=new Thread(new Fir(), "Alpha");

Dacă se compilează şi se execută această aplicaţie, se obţin exact aceleaţi rezultate ca în cazul când s-a recurs la extinderea clasei Thread.

Exemplul 2 În fişierul Bondari.java este dat un exemplu de aplicaţie, în care se pot crea mai multe fire de execuţie, fiecare având propria sa interfaţă grafică. Fiecare fir de execuţie este o instanţa a clasei Bondar, care extinde clasa JFrame şi implementează interfaţa Runnable. Aplicaţia propriu-zisă (care conţine metoda main()) este clasa Bondari, care extinde şi ea clasa JFrame. Fereastra principală a aplicaţiei (interfaţa clasei Bondari) conţine numai un buton cu inscripţia "Creare nou bondar". De câte ori se apasă acest buton, se creeaza o noua instanţă a clasei Bondar. Clasa Bondar are propria ei interfaţă grafică, în care există două rigle pentru ajustarea perioadei şi amplitudinii şi o fereastră în care evoluează "bondarul". Acesta este un mic

347

Severin Bumbaru dreptunghi roşu, a cărui mişcare o simuleaza pe cea a unei insecte în zbor. Amplitudinea, cât şi perioada deplasărilor "bondaruliui" sunt ajustate cu cele două rigle. Dacă se acţioneaza butonul de închidere a ferestrei "bondarului" (cel marcat cu X din colţul dreapta-sus), se încheie ciclul de viaţă al firului de execuţie respectiv. Aceasta are loc, întrucat ciclul din metoda run() a firului continuă cât timp variabila booleana esteViu are valoarea true. Când se acţioneaza butonul de închidere a ferestrei "bondarului", evenimentul este captat de metoda windowClosing() a clasei SfarsitBondar, care pune variabila esteViu a "bondarului" respectiv la valoarea false. Dacă se acţionează butonul de închidere a ferestrei principale (cea care conţine butonul "Creare nou bondar"), evenimentul este captat de metoda windowClosing() a clasei Iesire, astfel că se execută metoda exit(0). Efectul este încheierea execuţiei tuturor firelor şi oprirea maşinii virtuale Java.

Sincronizarea firelor de execuţie
Pană în prezent, am considerat că fiecare fir (Thread) se execută independent, fără legătura cu celelalte fire ale aceleeaşi aplicaţii. Există însă situaţii, în care este necesar să se stabilească anumite interdependenţe între fire. Aceasta se întâmplă, în special, atunci când un fir trebuie să folosească datele produse de alt fir: este evident că nu le poate folosi înainte ca ele să fie produse. În limbajul Java, sincronizarea firelor de execuţie se face prin intermediul monitoarelor. Se numeşte monitor instanţa unei clase care conţine cel puţin o metodă sincronizată, sau o metodă care conţine un bloc sincronizat. Se numeşte metodă sincronizată orice metodă care conţine în antetul său modificatorul synchronized, deci este declarată sub forma
[modif]synchronized tip nume_metoda(declaratii_argumente) {corpul_metodei}

unde modif reprezinta alţi eventuali modificatori (public, static etc.). Când un fir începe executarea uni metode sincronizate a unui monitor, el devine "proprietarul" monitorului căruia îi aparţine această metodă (engleză: owner) şi deţine această calitate până la încheierea executării metodei sincronizate respective, sau până când se autosuspendă invocând metoda wait(), aşa cum vom explica ulterior. Pe toata durata cât un fir de execuţie este proprietarul unui monitor, nici un alt fir nu poate invoca o metodă sincronizată a monitorului respectiv. Aşa dar, orice fir care, în acest interval de timp, ar încerca să invoce o metodă sincronizată a unui monitor al cărui proprietar este alt fir, trebuie să aştepte până când monitorul respectiv este eliberat de proprietarul existent. În acest fel, se evită situaţiile în care un fir de execuţie ar interveni să facă modificări asupra unui obiect, în timp ce acesta se găseşte deja în curs de prelucrare de către un alt fir. De exemplu, dacă un fir de execuţie efectuează ordonarea datelor dintr-un tablou, nu este corect ca un alt fir, în acest timp, să modifice datele din acest tablou.

348

Programarea orientata pe obiecte în limbajul Java

Relaţia producător/consumator şi utilizarea metodelor wait(), notify() şi notifyAll()
În aplicaţiile limbajului Java, pentru sincronizarea firelor se foloseşte frecvent modelul producător/consumator. Considerăm că un fir de execuţie "produce" anumite date, pe care le "consumă" alt fir. Pentru efectuarea acestor operaţii folosim un monitor, care conţine atât datele transmise, cât şi o variabilă booleană, numită variabila de condiţie a monitorului, care indică dacă sunt disponibile date noi, puse de producator şi neutilizate de consumator. Atât punerea de date noi, cât şi preluarea acestora se fac numai folosind metode sincronizate ale monitorului. În corpul acestor metode sincronizate, se pot folosi metodele wait(), notify() şi notifyAll() ale clasei Object. Metoda
public final void wait() throws InterruptedException

şi variantele ei
public final void wait(long timeout) throws InterruptedException public final void wait(long timeout, int nanos) throws InterruptedException

au ca efect trecerea firului de execuţie activ din starea Running în starea Waiting (vezi schema). Metoda wait() fără argumente face această trecere pentru un timp nedefinit, în timp ce celelalte două metode primesc ca argument intervalul de timp maxim pentru care se face suspendarea execuţiei firului. Metodele
public final void notify() public final void notifyAll()

au ca efect trecerea firului de execuţie din starea Waiting în starea Ready, astfel încât el poate fi activat de către dispecer în momentul în care procesorul sistemului devine disponibil. Deosebirea dintre ele este ca metoda notify() trece în starea Readyun singur fir de execuţie dintre cele care se gasesc în momentul respectiv în starea Waiting provocată de acest monitor (care din ele depinde de implementare), în timp ce notifyAll() le trece în starea Ready pe toate. Clasa monitor concepută pentru asigurarea relaţiei producător/consumator are următoarea formă:
class NumeClasaMonitor { // declaraţii câmpuri de date ale monitorului boolean variabilaConditie=false; [public] synchronized void puneDate(declaraţii_argumente) { if(variabila_condiţie) { try { wait(); // se asteapta folosirea datelor puse anterior } catch(InterruptedException e) { /* instrucţiuni de executat dacă a apărut o excepţie de întrerupere */ } } /* punerea de date noi în câmpurile de date ale monitorului */ variabilaConditie=true; // s-au pus date noi

349

Severin Bumbaru
notify(); // se notifica punerea de noi date } // sfarsit puneDate [public] synchronized tip preiaDate(declaratii_argumente) { if(!variabilaConditie) { try { wait(); // se aşteaptă să se pună date noi } catch(InterruptedException e) { /* Instrucţiuni de executat dacă a apărut o excepţie de întrerupere */ } } /* instrucţiuni prin care se folosesc datele din monitor şi se formează valoarea_întoarsă */ variabilaConditie=false; // datele sunt deja folosite notify(); // se notifică folosirea datelor return valoarea_intoarsa; } // sfarsit preiaDate /* Alte metode ale monitorului (sincronizate sau nesincronizate) */ } // sfarsit clasa monitor

Iniţial, variabila variabilaConditie a monitorului are valoarea false, întrucat deocamdată - nu există date noi. Dacă firul de execuţie producător a ajuns în starea, în care trebuie să pună în monitor date noi, el invocă metoda sincronizată puneDate, devenind astfel proprietar (owner) al monitorului. În această metodă, se verifică, în primul rând, valoarea variabilei variabilaConditie. Dacă această variabilă are valoarea true, înseamnă că în monitor există deja date noi, înca nefolosite de consumator. În consecinţă, se invocă metoda wait() şi firul de execuţie monitor este suspendat, trecând în starea Waiting, astfel că el încetează să mai fie proprietar (owner) al monitorului. Dacă un alt fir (în cazul de faţă consumatorul) invocă o metodă sincronizată a aceluiaşi monitor care, la rândul ei, invocă metoda notify() sau notifyAll(), firul pus în aşteptare anterior trece din starea Waiting în starea Ready şi, deci, poate fi reactivat de către dispecer. Dacă variabila variabilaConditie are valoarea false, firul producător nu mai intră în aşteptare, ci execută instrucţiunile prin care modifică datele monitorului, după care pune variabilaConditie la valoarea true şi se invocă metoda notify() pentru a notifica consumatorul că exista date noi, după care se încheie executarea metodei puneDate. Funcţionarea firului de execuţie consumator este asemănătoare, dar acesta invocă metoda preiaDate. Executând această metodă, se verifică mai întâi dacă variabilaConditie are valoarea false, ceeace înseamnă că nu există date noi. În această situaţie, firul consumator intră în aşteptare, până va primi notificarea că s-au pus date noi. Dacă, însă, variabilaConditie are valoarea true, se folosesc datele monitorului, după care se pune variabilaConditie la valoarea false, pentru a permite producătorului să modifice datele şi se invocă metoda notify() pentru a scoate producătorul din starea de aşteptare. Este foarte important să avem în vedere că metoda puneDate este concepută pentru a fi invocată de firul producător, în timp ce metoda preiaDate este concepută pentru a fi invocată de către firul consumator. Numele folosite aici atât pentru clasa monitor, cât şi pentru metodele acesteia şi variabila de condiţie sunt convenţionale şi se aleg de către

350

Programarea orientata pe obiecte în limbajul Java programator, din care cauză au fost scrise în cele de mai sus cu roşu cursiv.

Exemplul 1 În fişierul Sincro.java se dă un exemplu de aplicaţie în care se sincronizeaza două fire de execuţie folosind modelul producător/consumator. Pentru a uşura citirea programului, clasele au fost denumite chiar Producator, Consumator şi Monitor, dar se puteau alege, evident, orice alte nume. Firul de execuţie prod, care este instanţa clasei Producator, parcurge un număr de cicluri impus (nrCicluri), iar la fiecare parcurgere genereaza un tablou de numere aleatoare, pe care îl depune în monitor. Firul de execuţie cons, care este instanţă a clasei Consumator, parcurge acelaşi număr de cicluri, în care foloseşte tablourile generate de firul prod. Transmiterea datelor se face prin intermediul monitorului monit, care este instanţă a clasei Monitor. Această clasă conţine tabloul de numere întregi tab şi variabila de condiţie valoriNoi, care are iniţial valoarea false, dar primeşte valoarea true atunci când producătorul a pus în monitor date noi şi primeşte valoarea false, atunci când aceste date au fost folosite de consumator. Pentru punerea de date noi în monitor, producătorul invocă metoda sincronizată puneTablou. Pentru a folosi datele din monitor, consumatorul invocă metoda sincronizată preiaTablou. Fiecare din aceste metode testează valoarea variabilei de condiţie valoriNoi şi pune firul de execuţie curent în aşteptare, dacă valoarea acestei variabile nu este corespunzătoare. După ce s-a efectuat operaţia de punere/utilizare a datelor, metoda sincronizată prin care s-a făcut această operaţie invocă metoda notify(). Dacă ar fi putut exista mai multe fire în starea Waiting, era preferabil sa se invoce metoda notifyAll().
class Sincro { Producator prod; Consumator cons; Monitor monit; int nrCicluri; /* Clasa Producator. Producatorul genereaza un tablou de date si il pune in monitor pentru a fi transmis consumatorului */ class Producator extends Thread { public void run() { System.out.println("Incepe executarea firului producator"); for (int i=0; i<nrCicluri; i++) { int n=((int)(5*Math.random()))+2; int tab[]=new int[n]; for(int j=0; j<n; j++) tab[j]=(int)(1000*Math.random()); monit.puneTablou(tab); System.out.print("Ciclul i="+i+" S-a pus tabloul: "); for(int j=0; j<n; j++) System.out.print(tab[j]+" "); System.out.println(); } System.out.println("Sfarsitul executiei firului Producator"); } } /* Sfarsitul clasei Producator */ /* Clasa Consumator. Consumatorul foloseste (in cazul de fata doar afiseaza) datele preluate din monitor

351

Severin Bumbaru

*/ class Consumator extends Thread { public void run() { System.out.println("Incepe executarea firului Consumator"); int tab[]; for(int i=0; i<nrCicluri; i++) { tab=monit.preiaTablou(); System.out.print("Ciclul i="+i+ " s-a preluat tabloul "); for(int j=0; j<tab.length; j++) System.out.print(tab[j]+" "); System.out.println(); } System.out.println("Sfarsitul executiei firului Consumator"); } } /* Sfarsitul clasei Consumator */ /* Clasa Monitor. Monitorul contine date si metode folosite in comun de Producator si Consumator. In acest scop, producatorul si consumatorul folosesc metodele sincronizate ale monitorului */ class Monitor { int tab[]; // tabloul de date care se transmit boolean valoriNoi=false; // variabila de conditie a monitorului /* Metoda prin care producatorul pune date in monitor */ public synchronized void puneTablou(int tab[]) { if(valoriNoi) { try { wait(); // se asteapta sa fie folosite datele puse anterior } catch(InterruptedException e) {} } this.tab=tab; // se modifica tabloul tab din monitor valoriNoi=true; // monitorul contine date noi notify(); // se notifica consumatorul ca s-au pus date noi } /* Metoda prin care consumatorul preia datele din monitor */ public synchronized int[] preiaTablou() { if(!valoriNoi) { try { wait(); // se asteapta sa se puna date noi } catch(InterruptedException e) {} } valoriNoi=false; // datele puse anterior au fost folosite notify(); // se notifica producatorul ca datele au fost preluate return tab; } } /* Sfarsitul clasei Monitor */ public Sincro(int numarCicluri) { nrCicluri=numarCicluri; prod=new Producator(); cons=new Consumator(); monit=new Monitor(); prod.start(); cons.start();

352

Programarea orientata pe obiecte în limbajul Java

} public static void main(String args[]) { int numarCicluri=8; System.out.println("Incepe executarea metodei main()"); Sincro sinc=new Sincro(numarCicluri); System.out.println("Sfarsitul metodei main()"); } }

Referitor la acest program, remarcăm urmatoarele: - instrucţiunile care constituie subiectul acestei lecţii au fost puse în evidenţă prin îngrosare; - metodele run() din clasele Producător şi Consumator sunt scrise ca şi când ele s-ar executa în mod independent, însă sincronizarea firelor se face prin invocarea metodelor sincronizate puneTablou şi preiaTablou ale clasei Monitor; în aceste metode, sincronizarea se face folosind variabila de condiţie booleană dateNoi şi invocând în mod corespunzător metodele wait() şi notify(). Iată un exemplu de executare a acestei aplicaţii:

Incepe executarea metodei main() Sfarsitul metodei main() Incepe executarea firului producator Ciclul i=0 S-a pus tabloul: 827 789 Incepe executarea firului Consumator Ciclul i=1 S-a pus tabloul: 464 312 Ciclul i=0 s-a preluat tabloul 827 789 Ciclul i=2 S-a pus tabloul: 455 995 271 40 583 Ciclul i=1 s-a preluat tabloul 464 312 Ciclul i=3 S-a pus tabloul: 581 193 9 635 Ciclul i=2 s-a preluat tabloul 455 995 271 40 583 Ciclul i=4 S-a pus tabloul: 621 164 215 Ciclul i=3 s-a preluat tabloul 581 193 9 635 Ciclul i=5 S-a pus tabloul: 554 626 791 444 Ciclul i=4 s-a preluat tabloul 621 164 215 Ciclul i=6 S-a pus tabloul: 204 961 Ciclul i=5 s-a preluat tabloul 554 626 791 444 Ciclul i=7 S-a pus tabloul: 476 692 Sfarsitul executiei firului producator Ciclul i=6 s-a preluat tabloul 204 961 Ciclul i=7 s-a preluat tabloul 476 692 Sfarsitul executiei firului Consumator

Se observă că, deşi cele două fire se derulează în mod autonom, exista între ele o sincronizare corectă, în sensul că datele puse de producător la un ciclu cu un anumit indice, sunt preluate de consumator la ciclul cu acelaşi indice (de exemplu datele puse de producator în ciclul 3 sunt luate de consumator tot în ciclul 3). Aşa dar, nu există date pierdute sau preluate de două ori.

353

Severin Bumbaru Exemplul 2 În fişierul Bondari1.java se dă un exemplu de aplicaţie cu interfaţă grafică, în care există trei fire de execuţie (în afară de cel al metodei main()): două fire din clasa Bondar, care calculeaza fiecare mişcările unui "bondar", şi un fir de executie din clasa Fereastră, care reprezintă grafic mişcările celor doi bondari. În acest caz, ambii "bondari" se mişca în aceeaşi fereastră. Pentru că fiecare din acestea extinde câte o clasa de interfaţă grafică (respectiv clasele JPanel şi Canvas), pentru realizarea firelor de execuţie s-a folosit interfaţa Runnable. Cele două fire "bondar" (respectiv fir1 şi fir2) au rolul de producător, iar firul care conţine fereastra de afişare (respectiv fir3) are rolul de consumator. Rolul monitorului este îndeplinit de instanţa clasei CutiePoştală, care nu conţine decât variabila de condiţie a monitorului valoareNoua şi două metode sincronizate amPus şi amLuat. Având în vedere că există posibilitatea ca, la un moment dat, să existe în starea Waiting mai multe fire de aşteptare care trebuie reactivate, în aceste metode s-a folosit invocarea notifyAll() în loc de notify(). Dacă se execută această aplicaţie se poate vedea cum cei doi "bondari" evoluează în mod independent în aceeaşi fereastră, putându-se ajusta în mod independent perioada şi amplitudinea fiecăruia.

Întrebări
Nivel 1
1. Ce este un proces (în general)? 2. Cum se defineşte procesul în informatică? 3. Ce se înţelege prin multitasking? 4. Ce sunt firele de execuţie? 5. Ce se înţelege prin multithreading? 6. În ce moduri se poate programa o clasă de fire de execuţie? 7. Ce este clasa Thread? 8. Care sunt principalele metode ale clasei Thread? 9. La ce serveşte metoda run() a clasei Thread? 10. În ce mod este invocată metoda run() a clasei Thread? 11. Ce este interfaţa Runnable şi la ce foloseşte? 12. În ce stare se găseşte firul de execuţie imediat după ce el a fost creat? 13. În ce clasă există metodele wait(), notify() şi notifyAll() şi la ce folosesc ele? 14. Ce metode conţine interfaţa Runnable? 15. Cum se creeaza un fir de execuţie folosind un obiect cu interfaţa Runnable?

Nivel 2
1. Ce sunt procesele paralele? 2. Ce sunt procesele concurente? 3. În ce situaţii şi cum se iau în consideraţie priorităţile proceselor?

354

Programarea orientata pe obiecte în limbajul Java 4. Ce se înţelege prin partajarea timpului? 5. Ce fire de execuţie există obligatoriu în timpul funcţionării maşinii virtuale Java? 6. Ce este un demon? 7. În ce stare trece firul de execuţie după invocarea metodei start()? 8. La ce serveşte metoda sleep() şi în ce stare trece firul de execuţie la invocarea ei? 9. Prin ce metodă se modifică prioritatea unui fir de execuţie? 10. Care este prioritatea implicită a unui fir de execuţie? 11. În ce stare trece firul de execuţie în timpul executării unei operaţii de intrare/ieşire? 12. În ce stare trece firul de execuţie după ce a invocat metoda wait()? 13. În ce stare trece firul de execuţie după ce a expirat intervalul de "somn" dat prin metoda sleep()? 14. În ce stare trece un fir de execuţie blocat după ce s-a încheiat operaţia de intrare/ieşire solicitată? 15. Când se încheie executarea unui fir de execuţie şi în ce stare trece el în acest caz? 16. Dece este necesară sincronizarea firelor de execuţie? 17. Cum se sincronizează firele de execuţie în Java? 18. Ce este un monitor? 19. Ce este o metodă sincronizată şi la ce foloseşte? 20. În ce situaţie firul de execuţie devine proprietarul unui monitor? 21. Ce se întamplă în timpul cât un fir de execuţie este proprietarul unui monitor? 22. Cum se realizează sincronizarea între un fir de execuţie producător şi unul consumator? 23. La ce serveşte variabila de condiţie a monitorului? 24. În ce fel de metode se pot invoca metodele wait(), notify() şi notifyAll()? 25. Care este efectul invocării metodei notify()? 26. Care este efectul invocării metodei notifyAll()?

355

Severin Bumbaru

Index de clase şi de interfeţe
În acest index sunt cuprinse rezumate ale descrierilor de clase şi interfete din Java API care sunt folosite în acest curs practic. În Java API există mult mai multe pachete, clase şi interfeţe decât se prezintă aici. Descrierile complete ale tuturor claselor şi interfetelor pot fi găsite în documentaţia Java API la următoarele adrese: java.sun.com/j2se/1.4/docs/api/ - la firma Sun Microsystems; http://lib.cs.ugal.ro/java/jdk140/api/index.html - pe intranetul Catedrei de Calculatoare si Informatica Aplicata al Universităţii "Dunărea de Jos" din Galaţi

Pachetul java.lang
Clase
Byte - clasă acoperitoare pentru tipul byte - v.cap.4 Boolean - clasă acoperitoare pentru tipul boolean – v. cap.4 Character - clasă acoperitoare pentru tipul char – v.cap.4 Class - clasa claselor – v.cap.4 Double - clasă acoperitoare pentru tipul double – v.cap.4 Float - clasă acoperitoare pentru tipul float – v. cap.4 Integer - clasă acoperitoare pentru tipul int – v. cap.4 Long - clasă acoperitoare pentru tipul long – v. cap.4 Math - clasă care oferă metode pentru calcularea funcţiilor matematice uzuale – v.cap.4 şi completarea din acest index, pag. 361 Number - clasă abstractă, rădăcina claselor acoperitoare numerice – v. cap.4 Object - rădăcina ierarhiei de clase Java (un obiect oarecare) – v.cap.4 şi completarea din acest index pag. 363 Short - clasa acoperitoare pentru tipul short – v.cap.4 String - clasa şirurilor de caractere nemodificabile - v.cap.4 şi completarea din acest index pag. 364 StringBuffer - clasa şirurilor de caractere modificabile (instanţa este o zonă tampon care conţine un şir modificabil) – v. cap.4 şi completarea din acest index pag. 369 System - clasa sistemului de execuţie – v. cap.4 Thread - clasa firelor de execuţie – v.cap.12 Void - clasă acoperitoare pentru tipul void – v.cap.4

Interfeţe
Cloneable - implementată de clasele pentru care se poate folosi metoda clone() din clasa Object. Nu contine metode. Comparable - implementată de clasele ale căror instanţe sunt comparabile între ele (formează o mulţime ordonată). – v. specificatia de la pag. 372 Runnable - implementată de clasele, ale căror instanţe pot fi rulate ca fire de execuţie. – v.cap.12.

Pachetul java.io
Conţine clase şi interfeţe necesare pentru operaţiile de intrare/ieşire (input/output - io).

356

clasa fluxurilor de ieşire de caractere – v. BufferedWriter .clasa fluxurilor de ieşire de caractere. – v. 374.clasa fluxurilor de caractere de scriere în fişiere – v. cap. FileReader .cap.v.377 FileInputStream . cap.clasă ale cărei instanţe conţin informaţii despre fişiere – v.11 şi pag. cap.11 şi pag. cap.clasa fluxurilor care citesc dintr-un tablou de caractere situat în memoria internă – v. cap. cu zonă tampon – v.11 şi completarea de la pag.11 Interfeţe Serializable .clasa fişierelor cu acces direct (acces aleator). cap.clasa fluxurilor de octeţi de ieşire în fişiere (clasa fişierelor deschise pentru ieşire) – v.11 Reader .clasa fluxurilor care citesc dintr-un tablou de octeţi situat în memoria internă + v. cap.11 PrintStream .11. cap. FilterWriter .clasa fluxurilor care scriu într-un tablou de octeţi situat în memoria internă + v.11 şi pag.cap. cap.11 şi completarea de la pag.clasa fluxurilor de intrare de obiecte – v.clasa fluxurilor de intrare de caractere – v. 377. 374.interfaţă pe care trebuie să o aibă obiectele serializabile (care pot fi scrise cu ObjectOutputStream şi citite cu ObjectInputStream) – v. ByteArrayOutputStream . CharArrayReader . 374. FilterOutputStream .11 FileWriter .11 ObjectOutputStream . cap.373 BufferedOutputStream .clasa fluxurilor de imprimare de caractere – v. cap.clasa fluxurilor de imprimare de octeţi – v.clasa fluxurilor de octeţi de intrare din fişiere (clasa fişierelor deschise pentru intrare) – v.11 şi pag.11 FileOutputStream .11. 378.11 DataOutputStream . cap. cu zonă tampon – v.11 şi completarea de la pag. cap. cu zonă tampon – v.cap. 374.11 FileDescriptor . CharArrayWriter .cap.clasa fluxurilor de octeţi de intrare pentru date .11 si completarea de la pag.11 PrintWriter .376 DataInputStream . InputStream . cap.clasa fluxurilor de ieşire de octeţi cu filtru – v.clasa fluxurilor de ieşire de obiecte – v.clasa fluxurilor de caractere de citire din fişiere – v.11 RandomAccessFile . BufferedReader .Programarea orientata pe obiecte în limbajul Java Clase (ierarhiile de clase de intrare/ieşire sunt prezentate în cap.clasa fluxurilor de intrare de octeţi.11 şi pag. cap.11 şi completarea de la pag.clasa fluxurilor de intrare de octeţi cu filtru – v. FilterReader .clasa fluxurilor de ieşire de octeţi – v.clasa fluxurilor de intrare de caractere. ByteArrayInputStream . cap. cap.clasa fluxurilor care scriu într-un tablou de caractere situat în memoria internă – v.11 OutputStream .11 File .clasa flucurilor de ieşire de caractere cu filtru – v.11 FilterInputStream .11 Writer .cap.clasa descriptorilor de fişiere – v. cap.clasa fluxurilor de intrare de octeţi – v.cap.io din acest manual) BufferedInputStream . cap. 378. 373.11 ObjectInputStream . 376. cap.11 şi pag.clasa fluxurilor de ieşire de octeţi.clasa flucurilor de intrare de caractere cu filtru – v.11 357 . secţiunea pachetul java.11 şi completarea de la pag.378. cap. cu zonă tampon – v.11 şi pag. cap. cap.clasa fluxurilor de octeţi de ieşire de date – v. cap.

interfaţă generică pentru ascultătoarele de evenimente. BorderLayout . Event .9 şi pag. Graphics .9 şi pag. 7 şi pag. Font . 403.7 şi pag. 404. – v.7 şi pag. 396. 394. 379 Pachetul java. cap. cap. 387 Container .7 şi pag. 407.util Clase EventObject . 405. Frame .clasa dreptunghiurilor – v.v. cap. 380.gestionar de poziţionare – v.clasa obiectelor care conţin informaţii despre evenimente – v. cap. cap. Rectangle . Point .7 şi pag.9 şi pag. 401. Button .clasa culorilor – v. 397. + v. cap.interfaţă pentru clasele de gestionare a poziţionării cu restricţii – v.7 şi pag. cap.7 şi pag. cap. 396. Dialog .clasa ferestrelor principale ale aplicaţiilor. cap.interfaţă pentru clsasele de gestionare a poziţionării – v.9 şi pag. cap.clasa ferestrelor.clasa butoanelor simple – v. cap. 398. cap.Severin Bumbaru Pachetul java.clasa containerelor (componente care conţin alte componente) – v.awt Clase AWTEvent . cap. Panel . cap. 406 LayoutManager2 .clasă specială de componente pe care se trasează desene . pag.clasa contextelor grafice 2D – v. cap. cap. 401.gestionar de poziţionare – v.gestionar de poziţionare – v. Canvas . – v.clasa ferestrelor de dialog + v. 393.superclasa ascultătoarelor de evenimente generate de componentele interfeţei grafice – v. Dimension . cap.7 şi pag. 401.7 şi pag. 383 Color .9 şi pag. 379 Interfeţe EventListener . pag. GridLayout . 7 şi pag.8 şi pag. 358 .gestionar de poziţionare – v. 402. cap. Interfeţe LayoutManager . cap. cap. GridBagLayout .dimensiunile unei componente – v.9 şi pag.clasa punctelor – v. 381. cap. Insets .clasa evenimentelor din JDK1. 384 Component .clasa fonturilor – v. pag. cap.7 şi pag.clasa panourilor – v.7 şi pag. 399.superclasa tuturor claselor de componente ale interfeţei grafice.clasa inserţiilor (marginilor libere ale containerelor) + v. 383 CardLayout .gestionar de poziţionare – v. 382. Window . cap.0 (înlocuită acum prin clasa AWTEvent) – v.7 şi pag.7 şi pag.clasa contextelor grafice simple – v. FlowLayout . cap. 402.7 şi pag.7 şi pag. – v.9 Graphics2D .

interfaţă pentru ascultătoarele de evenimente de componentă – v..eveniment de tastă – v.cap.8 şi pag.container sub formă de casetă – v.7 şi pag.421. MouseMotionAdapter .adaptor pentru ascultarea evenimentelor de mişcare a mouse-ului – v.adaptor pentru ascultarea evenimentelor de fereastră – v.cap.7 şi pag. KeyListener . KeyAdapter .cap.8 şi pag.interfaţă pentru ascultătoare de evenimente de mouse v.Programarea orientata pe obiecte în limbajul Java Pachetul java.8 şi pag.416.interfaţă pentru ascultătoare de evenimente de tastă – v. KeyEvent .7 şi pag.adaptor pentru ascultătoarele de evenimente de componentă.cap.cap.interfaţă penteru ascultătoare de evenimente de mişcare a mouseului – v.8 şi pag. WindowEvent .cap.awt.420.416. Interfeţe ActionListener .cap.cap.v.eveniment de mouse – v.eveniment de acţiune – v.422.cap.410.8 şi pag. cap.7 şi pag.adaptor pentru ascultarea evenimentelor de tastă – v. cap.cap. folosite pentru distanţare în instanţele clasei Box + v.8 şi pag. ComponentAdapter .cap.eveniment de componentă – v.clasa componentelor invizibile. cap. BorderFactory .8 şi pag. ComponentListener .adaptor pentru ascultarea evenimentelor de mouse – v.cap.8. cap.423 Pachetul javax.interfaţă pentru ascultătoarele de evenimente de acţiune – v.cap.8 şi pag.interfaţă pentru ascultătoare de evenimente de text – v.swing Clase AbstractButton .cap. Superclasa claselor de butoane – v.420.interfaţă pentru ascultătoarele de evenimente de articol – v.417. TextListener . MouseMotionListener .eveniment de articol (selectare sau deselectare) – v. TextEvent . 423.cap.7 şi pag.cap.v.417. AdjustementEvent .cap.clasă abstractă.7 şi pag.eveniment de fereastră .8 şi pag.interfaţă pentru ascultătoare de evenimente de fereastră – v.cap.7 şi pag.7 şi pag.411. Rădăcina ierarhiei claselor de evenimente de intrare – v.422. ItemEvent .clasă abstractă. Box. cap.7 şi pag.8 şi pag. ComponentEvent .8 şi pag.interfaţă pentru ascultătoarele de evenimente de ajustare – v. cap.event Clase ActionEvent .412.7 şi pag. MouseListener .eveniment de text .7 şi pag. 408.7 şi pag.418. WindowAdapter .Filler . 409.eveniment de ajustare – v.425.cap. InputEvent . MouseEvent .v. 409. MouseAdapter . ItemListener . WindowListener . Box .411.gestionar de poziţionare în casetă – v. 408.421.clasă care permite producerea de borduri pentru componentele Swing – v. 359 .8 şi pag. BoxLayout .7.cap. cap.418.cap.421.8.419 AdjustmentListener .8 şi pag.

clasă pentru editoare de text formatat – v.8.7 şi pag.8.clasa meniurilor volante (meniuri pop-up) – v. JScrollBar . cap. cap. cap.8 şi pag. JRadioButton .426.cap.8 şi pag.7 şi pag. JScrollPane .439.8 şi pag. ListSelectionEvent .8.8 şi pag. JPopupMenu .7 şi pag.clasa grupurilor de butoane – v.clasa articolelor de meniu cu buton radio – v.7 şi pag.437. JPasswordField .451 JWindow .427.clasa listelor ascunse – v.clasă pentru editoare de text stilizat – v.v. JProgressBar . cap.cap. JComponent .clasa articolelor de meniu – v. cap.427. 444. cap.clasa barelor de menu – v.clasa evenimentelor de selectare a articolelor de listă v. cap. 426.8.432. JMenuBar . JDialog . cap.clasa casetelor de validare – v.448. cap. JTextField . cap. JColorChooser . JEditorPane . 450. cap.clasa ariilor de text – v. JSplitPane . JRadioButtonMenuItem . ListDataEvent . cap.8 şi pag.10 şi pag.8 şi pag.clasa evenimentelor de meniu – v.cap. JComboBox .443.8 şi pag. JSlider .445.428. cap.7 şi pag.447.8 şi pag.clasa barelor de defilare – v.adaptor pentru ascultătoarele de evenimente de mouse – v.clasa applet-urilor din Swing – v. MouseInputAdapter . JTextArea .swing.eveniment de modificare a datelor dintr-o listă – v. cap.clasa câmpurilor de text – v.452.rădăcina ierarhiei de clase de componente Swing – v.453.cap.cap.eveniment de schimbare a stării sursei – v.441. cap.9.8.clasa selectoarelor de fişiere – v.Severin Bumbaru ButtonGroup .clasa panourilor care pot fi scindate . cap.436.clasă cu metode pentru realizarea unor ferestre de dialog standard – v. cap.cap. JMenuItem .clasa ferestrelor – v.clasa panourilor (containere simple) – v.8 şi pag. JSeparator .superclasa butoanelor cu două stări stabile – v.433.cap. cap.8 şi pag.clasa tabelelor – v. JMenu .8 şi pag.9 şi pag. JOptionPane .clasa listelor afişabile în interfaţa grafică – v. cap.clasa butoanelor – cap. JTextPane . JTabbedPane .clasa etichetelor (componente de afişare needitabile) + v.8 şi pag. JFrame . JCheckBox .clasa articolelor de meniu cu casetă de validare – v.441. 451. JCheckBoxMenuItem .8.442.clasa panourilor cu bare de defilare – v. cap.8. JToggleButton . cap.clasa separatoarelor de meniu v. cap.clasa butoanelor radio – v.clasa panourilor tabulate – v.453 MenuEvent .450. cap.8 şi pag.8 şi pag. cap.8 şi pag. JLabel . cap.435.clasa riglelor cu cursor – v.clasa ferestrelor de dialog – v.clasa selectorului de culori + v. JButton . JFileChooser .432. Pachetul javax.8.7 şi 360 . cap.8 şi pag.446.430.8 şi pag. JTable .cap. cap.clasă folosită în special pentru ferestrele principale ale aplicaţiilor – v. cap.event Clase ChangeEvent .8 şi pag.438.7 şi pag.8 şi pag.cap. JList .clasa câmpurilor pentru introducerea parolei – v.cap.452.9 şi pag. JPanel .clasa barelor de progres – v.cap.8 şi pag. JApplet .clasa meniurilor – v.8 şi pag.8 şi pag.cap.

cap.v. cap.456.455.454. cap. cap.455. PopupMenuListener .7 şi pag. cap. MouseInputListener .8 şi pag. Interfeţe ChangeListener .ascultător de evenimente de modificare a conţinutului unei liste – v.8 şi pag.8 şi pag.454.454. PopupMenuEvent .ascultător de mouse .8 şi pag.Programarea orientata pe obiecte în limbajul Java pag.456.cap.7 şi pag. ListSelectionListener .cap.ascultător al evenimentelor de meniu – v.455.ascultător al evenimentelor de meniu pop-up v. MenuListener .ascultător de evenimente de modificare a articolelor selectate dintr-o listă – v. ListDataListener . 361 .ascultător de evenimente de schimbare a stării – v.clasa evenimentelor generate de meniuri pop-up – v.8 şi pag.

double f2).calculeaza functia exponentiala ea.numarul e (baza logaritmilor naturali). . pi]. public static double IEEEremainder(double f1. a in intervalul [-pi/2.numarul pi (raportul dintre circumferinta cercului si diametru). cum sunt functiile trigonometrice. public static double cos(double a). radacina patrata si altele. unde unghiul a este in radiani. Daca argumentul este negativ sau NaN. public static double toDegrees(double angrad).intoarce arctg a in intervalul [-pi/2.calculeaza radacina patrata a argumentului a. argumentul angDeg din public static double toRadians(double angdeg). Metode: public static double sin(double a).converteste argumentul angrad din radiani in grade. public static double exp(double a).converteste grade in radiani.intoarce tangenta trigonometrica tg a.calculeaza logaritmul public static double sqrt(double a).intoarce arcsin public static double acos(double a).calculeaza restul impartirii f1/f2 conform prescriptiilor standardului IEEE 754. Restul este egal matematic cu 362 . public static double log(double a). rezultatul este NaN. a in intervalul [0.0. pi/2]. Campuri: public static final double E public static final double PI . unde unghiul a este in radiani.intoarce arccos public static double atan(double a). public static double tan(double a).Severin Bumbaru Completări la descrierea claselor şi interfeţelor Clasa Math public final class Math extends Object Clasa Math contine metode statice pentru calcularea unor functii matematice uzuale. pi/2].intoarce sinusul trigonometric sin a. public static double asin(double a). unde unghiul a este in radiani.intoarce cosinusul trigonometric cos a. natural ln a.

public static long abs(long a). unde n este numarul intreg cel mai apropiat de valoarea exacta a raportului f1/f2.se intoarce numarul b si b<=0) intreg cel mai apropiat de argument. public static double floor(double a). a) in coordonate polare (r.calculeaza arctg(a/b) in intervalul [-pi.intoarce cel public static long max(long a. long b). argumentului a (valoarea absoluta). public static int abs(int a). public static int max(int a.intoarce modulul argumentului a (valoarea absoluta). public static long round(double a). double b). cel mai mare din cele doua argumente.intoarce. public static double atan2(double a. 1.intoarce cel mai mare din cele doua argumente. public static double abs(double a). double b). Daca acest intreg este mai mare decat marginea superioara pentru tipul int.intoarce modului argumentului a (valoarea absoluta). cel mai mare numar intreg care nu este mai mare decat argumentul (rotunjire prin micsorare). Daca (a==0 sau daca (a<=0 si b nu este un numar intreg) se genereaza o exceptie aritmetica.MAX_VALUE. Daca restul este zero. rezultatul este Integer. public static double rint(double a). Daca acest intreg este mai mic decat marginea inferioara pentru tipul int. numarul intreg cel mai apropiat de argument. float b). sub forma de valoare double.MIN_VALUE. theta)). 363 .Programarea orientata pe obiecte în limbajul Java valoarea expresiei f1-f2*n. se obtine rezultatul Integer.intoarce.intoarce modului public static float abs(float a). cel mai mic numar intreg care nu este mai mic decat argumentul (rotunjire prin adaos).0.intoarce un numar pseudoaleator in intervalul [0. sub forma de valoare double. sub forma de valoare double.intoarce modulul argumentului a (valoarea absoluta). avand o lege de repartitie (aproximativ) uniforma in acest interval. public static double ceil(double a). public static double random(). public static double pow(double a. pi] tinand seama de semnele argumentelor a si b (se considera ca se calculeaza argumentul theta la conversia din coordonate carteziene (b.calculeaza a .intoarce mai mare din cele doua argumente.intoarce numarul intreg cel mai apropiat de argument (cu aceleasi observatii ca la metoda precedenta). int b). el are semnul primului argument.intoarce. public static int round(float a). public static float max(float a.0].

public static double min(double a.intoarce cel mai mic din cele doua argumente. protected void finalize() Este apelata de colectorul de reziduuri atunci cand acesta constata ca nu mai exista referinte la obiectul respectiv. int b).Object -------------------------------------------------------------------------------public class Object Clasa Object este radacina ierarhiei de clase Java.intoarce cel mai mare din cele doua argumente. inclusiv tablourile. Class Object java. public int hashCode() Intoarce codul de dispersie al obiectului public void notify() Notifica un singur fir de executie dintre cele care asteapta acest obiect. public static int min(int a. 364 . public boolean equals(Object obj) Indica daca acest obiect este sau nu "egal cu" obiectul obj primit ca argument. double b). float b)intoarce cel argumente. public Class getClass() Intoarce clasa caruia ii apartine obiectul. mai mic din cele doua public static float min(float a. Toate celelalte clase.lang. Orice alta clasa ore clasa Object ca superclasa. implementeaza metodele acestei clase ------------------------------------------------------------------------------Constructor: public Object() Metode: protected Object clone() Creaza si intoarce o copie a acestui obiect. double b)intoarce cel mai mic din cele doua argumente.Severin Bumbaru public static double max(double a.

Orice literal sir in limbajul Java. Daca referinta la tablou este nula se genereaza o NullPointerException. Clasa String public final class String extends Object implements Serializable. public void wait(long timeout. Pentru a obtine siruri modificabile se va folosi clasa StringBuffer. exprimat in nanosecunde. unde nanos este un intreg in intervalul 0. Campuri: public static Comparator CASE_INSENSITIVE_ORDER Campul contine un Comparator care ordoneaza obiectele-sir cand ele sunt comparate cu metoda comparetoIgnoreCase(). Se considera ca in acest tablou caracterele sunt reprezentate pe 8 biti. public String(byte[] bytes) Creeaza un obiect al clasei String care contine caracterele din tabloul de octeti primit ca argument. public void wait() Pune firul de executie curent in asteptare.999999. sau pana cand alt fir de asteptare il intrerupe pe cel curent. este in acest caz 1000000*timeout+nanos. pana cand alt fir de executie invoca metoda notify sau notifyAll() pentru acest obiect. public void wait(long timeout) Pune firul de executie curent in asteptare. pana cand alt fir de executie invoca metoda notify sau notifyAll() pentru acest obiect. Nota: amintim ca in limbajul Java reprezentarea interna a caracterelor se face pe 16 biti.Programarea orientata pe obiecte în limbajul Java public void notifyAll() Notifica toate firele de executie care asteapta acest obiect public String toString() Intoarce reprezentarea sub forma de String a acestui obiect. Timpul de asteptare. in Unicode. deci continutul lor nu poate fi modificat. de exemplu "abc". Constructori: public String() Creeaza un sir vid. in codul local valabil pe calculatorul pe care se executa programul. int nanos) Pune firul de executie curent in asteptare. 365 . sau pana cand exprira intervalul de timp dat timeout dat ca argument. Comparable Instantele clasei String sunt siruri de caractere. sau pana cand exprira intervalul de timp dat timeout dat ca argument. Sirurile sunt constante. este un astfel de obiect. Timpul este exprimat in milisecunde.. pana cand alt fir de executie invoca metoda notify sau notifyAll() pentru acest obiect.

Se genereaza NullPointerException daca referinta la tablou este nula. public String(byte[] bytes. sau o IndexOutOfBoundsException daca indicii sunt gresiti. atunci compararea se face la fel ca in metoda urmatoare. String enc) Construieste un sir care contine caracterele din tabloul de octeti bytes. public String(char[] value) Construieste un sir care contine caracterele din tabloul de caractere value. sau UnsupportedEncodingException daca argumentul enc este gresit. intoarce 0 (zero). Metode: public char charAt(int index) Intoarce caracterul situat in sir pe pozitia index. Pot fi generate NullPointerException daca referinta la tablou este nula. Daca acest sir il precede pe o intoarce o valoare negativa. int length. care contine aceleasi caractere ca cele din argumentul buffer. public String(byte[] bytes. dar preia din tabloul value numai count caractere. in care il copiaza pe cel dat ca argument. public String(String value) Creeaza un nou sir. Pot fi generate NullPointerException daca referinta la tablou este nula. Se genereaza IndexOutOfBoundsException daca indicele este gresit. Se considera ca in acest tablou caracterele sunt reprezentate in codul enc. int offset. care apartine clasei StringBuffer (deci este o zona-tampon pentru siruri). int offset. public int compareTo(Object o) Compara acest sir cu obiectul o primit ca argument.Severin Bumbaru public String(byte[] bytes. iar 366 . Se genereaza NullPointerException daca referinta la tablou este nula. Pot fi generate NullPointerException daca referinta la tablou este nula. sau o IndexOutOfBoundsException daca indicii sunt gresiti. public String(char[] value. Daca cele doua siruri sunt identice.Pot fi generate NullPointerException daca referinta la tablou este nula.sau UnsupportedEncodingException daca argumentul enc este gresit. public String(StringBuffer buffer) Creeaza un nou sir. int offset. int length) Actioneaza similar cu constructorul precedent. sau o IndexOutOfBoundsException daca indicii sunt gresiti. sau o IndexOutOfBoundsException daca indicii sunt gresiti. public int compareTo(String anotherString) Compara acest sir cu sirul anotherString primit ca argument. int count) Actioneaza similar cu constructorul precedent. Daca acest obiect nu este un sir. String enc) Actioneaza similar cu constructorul precedent. dar la conversia din octet in Unicode se foloseste sistemul de codificare a caracterelor enc. se genereaza o exceptie de incompatibilitate de clase (ClassCastException). Daca o este un sir.. cu observatia ca se preiau din tabloul bytes numai length octetii de pe pozitiile care incep de la indicele offset. incepand cu cel de pe pozitia offset.

. ignorand deosebirea dintre literele majuscule si cele minuscule. dar conversia se face folosind codificarea enc. char[] dst. public boolean equalsIgnoreCase(String anotherString) Testeaza daca acest sir contine aceleasi caractere ca argumentul anotherString. Se poate genera NullPointerException daca referinta la tablou este nula sau IndexOutOfBoundsException daca indicii sunt gresiti. int dstBegin) Copiaza caracterele din acest sir in tabloul de caractere de destinatie char[]. public static String copyValueOf(char[] data) Intoarce un sir care contine aceleasi caractere cu cele din tabloul data. Plasarea in tabloul de destinatie incepe cu pozitia dstBegin. Copierea incepe de la caracterul de pe pozitia srcBegin si se termina la caracterul de pe pozitia srcEnd-1.Programarea orientata pe obiecte în limbajul Java daca ii succede lui o intoarce o valoare pozitiva. Se poate genera NullPointerException daca referinta la tablou este nula public boolean endsWith(String suffix) Testeaza daca acest sir se termina cu subsirul suffix. luind in consideratie codificarea locala de pe calculatorul pe care ruleaza programul. public byte[] getBytes() Converteste acest sir intr-un tablou de octeti. 367 . public int compareToIgnoreCase(String str) Compara lexicografic acest sir cu sirul str primit ca argument. public String concat(String str) Concateneaza acest sir cu sirul str primit ca argument. Daca acest caracter nu exista in sir. intoarce -1. dar se preiau din tabloul data numai count caractere incepand cu pozitia offset. public int indexOf(int ch) Intoarce indicele la care se gaseste in sir prima aparitie a caracterului ch. int count) Similar cu metoda precedenta. public int hashCode() Intoarce codul de dispersie pentru acest sir. Compararea sirurilor se face in ordine lexicografica (in ordinea in care ar fi plasate intr-un dictionar). public static String copyValueOf(char[] data. public boolean equals(Object anObject) Testeaza daca acest sir este "egal" cu obiectul anObject. ignorand deosebirea dintre literele mici si cele mari. Se genereaza UnsupportedEncodingException daca argumentul enc este gresit. Se poate genera NullPointerException daca referinta la tablou este nula. public byte[] getBytes(String enc) Similara cu metoda precedenta. public void getChars(int srcBegin. int srcEnd. int offset.

public int lastIndexOf(String str) Intoarce indicele ultimei aparitii in acest sir a subsirului str. int ooffset. 368 . public String intern() Intoarce o reprezentare canonica a acestui obiect-sir. int fromIndex) Similar cu metoda precedenta. Argumentul len este lungimea celor doua zone comparate. Argumentele tooffset si ooffset reprezinta indicii pozitiilor de la care incep regiunile comparate in acest sir si. int fromIndex) Similar cu metoda precedenta. publicint length() Intoarce lungimea acestui sir (numarul de caractere continute). dar cautarea inapoi se face de la pozitia fromIndex. dar cautarea in sir incepe de la pozitia fromIndex. public int lastIndexOf(int ch. int len) Similar cu metoda precedenta. in sirul-argument other. char newChar) Intoarce un nou sir. public String replace(char oldChar. dar cautarea in acest sir incepe de la pozitia fromIndex. dar in care toate aparitiile caracterului oldChar sunt inlocuite prin caracterul newChar. int fromIndex) Intoarce indicele ultimei pozitii pe care se gaseste caracterul ch daca se face cautarea inapoi incepand de la pozitia fromIndex. comparatia se face ignorand deosebirea dintre caracterele mari si cele mici. public int lastIndexOf(String str. public boolean regionMatches(boolean ignoreCase. public int lastIndexOf(int ch) Intoarce indicele ultimei pozitii pe care apare caracterul ch in acest sir. dar se ia in consideratie deosebirea intre literele mici si cele mari. Daca primul argument (ignoreCase) are valoarea true. int len) Testeaza daca o regiune din acest sir este egala cu o regiune din sirul other primit ca argument.Severin Bumbaru public int indexOf(int ch. public boolean startsWith(String prefix. public boolean startsWith(String prefix) Testeaza daca acest sir incepe cu subsirul prefix. int toffset. String other. care are acelasi continut cu acest sir. public int indexOf(String str. public boolean regionMatches(int toffset. public int indexOf(String str) Intoarce indicele pozitiei de pe care in acest sir apare prima data subsirul str. int toffset) Testeaza daca subsirul prefix incepe in acest sir de pe pozitia index. int fromIndex) Similar cu metoda precedenta. respectiv. String other. int ooffset.

public String toLowerCase() Intoarce un nou sir. public static String valueOf(char[] data. public static String valueOf(char c) Intoarce un sir care contine numai caracterul c. int count) Intoarce reprezentarea sub forma de sir a subtabloului de lungime count cuprins tabloul data incepand de la indicele offset. public String toUpperCase() Intoarce un nou sir. public char[] toCharArray() Converteste acest sir intr-un tablou de caractere. provenit din acest sir. int endIndex) Intoarce subsirul situat intre pozitiile beginIndex si endIndex-1. public String toUpperCase(Locale locale) Similar cu metoda precedenta. public String trim() Intoarce un nou sir. public static String valueOf(double d) Intoarce reprezentarea sub forma de sir a unui argument de tip double. public static String valueOf(float f) Intoarce reprezentarea ca sir a unui argument de tip float. int offset. in care literele mari ale acestui sir sunt inlocuite cu litere mici. Se genereaza NullPointerException daca referinta la tablou este nula. care contine caracterele acestui sir incepand de la pozitia beginIndex. public String toLowerCase(Locale locale) Similar cu metoda precedenta. Se genereaza NullPointerException daca in referinta la tablou este nula. dar conversia se face respectand conventia locale.Programarea orientata pe obiecte în limbajul Java public String substring(int beginIndex) Intoarce un nou sir. pana la sfarsit. obtinut din acest sir prin eliminarea spatiilor de la inceput si de la sfarsit. public static String valueOf(boolean b) Intoarce reprezentarea sub forma de sir a unui argument de tip boolean. 369 . in care toate literele mici au fost inlocuite cu litere mari. public String toString() Intoarce chiar acest sir. public static String valueOf(char[] data) Intoarce reprezentarea sub forma de sir a tabloului de caractere data. public String substring(int beginIndex. dar inlocuirea literelor mari cu cele mici se face respectand conventia locale.

lungimea depaseste capacitatea. un StringBuffer care contine sirul str. 370 . lungime length. se genereaza o NegativeArraySizeException. Lungimea este numarul efectiv de caractere continute. atunci capacitatea se mareste in mod automat. pe care apoi il adauga la sirul din StringBuffer sau il insereaza in acesta pe o pozitie data. public StringBuffer(String str).intoarce capacitatea curenta a zonei tampon. notifyAll. public int capacity().Severin Bumbaru public static String valueOf(int i) Intoarce reprezentarea ca sir a unui argument de tip int. Operatiile principale asupra unui StringBuffer sunt metodele append si insert. printr-o noua adaugare de caractere. Fiecare StringBuffer are o capacitate si o lungime. Metode mostenite de la clasa java. public static String valueOf(long l) Intoarce reprezentarea ca sir a unui argument de tip long.construieste iar capacitatea este lungimea lui str plus 16. finalize. wait Clasa StringBuffer public final class StringBuffer extends Object implements Serializable Un StringBuffer implementeaza un sir de caractere care poate fi modificat. in care se ppoate plasa un sir de caractere. Daca. Fiecare din ele converteste o data intr-un String.construieste un StringBuffer vid cu capacitatea 16 caractere.lang. notify. public StringBuffer(int length). getClass.Object: clone. El reprezinta o zona tampon din memorie. Constructori: public StringBuffer() . Metode: public int length()- intoarce lungimea sirului continut in StringBuffer (numarul de caractere). public static String valueOf(Object obj) Intoarce reprezentarea ca sir a obiectului obj. iar capacitatea este numarul maxim de caractere care incap in zona tampon rezervata in memorie.construieste un StringBuffer vid de Daca length este negativ.

public StringBuffer append(char[] str). Daca newLength este mai mare decat cea curenta. int srcEnd. Daca dst este null se genereaza o NullPointerException. pe pozitia index. se adauga un numar suficient de caractere nule (\0000) pentru a se obtine noua lungime. Daca noua lungime newLength este mai mica decat cea existenta. Daca srcBegin. public void setCharAt(int index.se adauga obiectul obj public StringBuffer append(String str).se adauga caracterul c. int len).se pune caracterul ch Daca index este incorect.se adauga numarul public StringBuffer append(double d). real f convertit in sir. continute in public StringBuffer append(char[] str. public StringBuffer append(boolean b).se adauga valoarea booleana b convertita in sir. se genereaza o IndexOutOfBondsException. se genereaza o IndexOutOfBoundsException. incepand de la pozitia offset din acest tablou. sirul este trunchiat. convertit in sir. public void setLength(int newLength). public char charAt(int index).se adauga numarul 371 . public void getChars(int srcBegin. Daca capacitatea curenta este mai mica decat minimumCapacity. intreg llung l convertit in sir. srcEnd sau dstBegin nu sunt corecte. int dstBegin) Caracterele situate in StringBuffer intre pozitiile srcBegin si srcEnd-1 sunt copiate in tabloul de caractere dst incepand de la pozitia dstBegin.se adauga sirul str. Capacitatea noului StringBuffer este cea mai mare dintre valoarea argumentului minimumCapacity si dublul vechii capacitati. public StringBuffer append(char c). Daca indicele nu se incadreaza in lungimea sirului curent.se adauga toate caracterele tabloul str. Daca argumentul newLength este negativ se genereaza o exceptie IndexOutOfBoundsException.asigura capacitatea minima a zonei tampon. se genereaza o IndexOutOfBoundsException. convertit in sir. char[] dst. char ch). real d convertit in sir.intoarce caracterul de pe pozitia de indice index.se adauga la acest StringBuffer len caractere din tabloul str. public StringBuffer append(Object obj).se adauga numarul public StringBuffer append(float f).Programarea orientata pe obiecte în limbajul Java public void ensureCapacity(int minimumCapacity). se aloca in memorie o noua zona tampon si se transfera in ea sirul curent. int offset. public StringBuffer append(int i).se adauga intregul i public StringBuffer append(long l).seteaza noua lungime a acestui StringBuffer.

caracterele situate in StringBuffer pe pozitiile de la start la end-1 se inlocuiesc prin subsirul str. public StringBuffer insert(int offset.pe pozitia offset caracterul c sau se genereaza o StringIndexOutOfBoundsException. mai mare ca lungimea sau mai mare ca end se genereaza o StringIndexOutOfBoundsException.se elimina caracterul index sau se genereaza o StringIndexOutOfBoundsException.incepand insereaza numarul intreg i convertit in sir sau se genereaza o StringIndexOutOfBoundsException. char c). public String substring(int start). int len) de la pozitia start la Incepand de la pozitia index insereaza in StringBuffer len caractere situate in tabloul str de la pozitia offset sau se genereaza o StringIndexOutOfBoundsException. sau se genereaza o StringIndexOutOfBoundsException.insereaza incepand de la pozitia offset obiectul obj reprezentat ca sir. public StringBuffer insert(int index.intoarce subsirul pozitia end-1 sau genereaza o StringIndexOutOfBoundsException. int i).Severin Bumbaru public StringBuffer delete(int start. Daca offset nu este corect se genereaza o StringingIndexOutOfBoundsException. Daca indicii start sau end nu sunt corecti se genereaza o StringIndexOutOfBoundsException. String str). de pe pozitia public StringBuffer replace(int start. boolean b). Daca start este negativ. Object obj). public StringBuffer insert(int offset. int end). sau se genereaza o StringIndexOutOfBoundsException.se elimina caracterele de pe pozitiile de la indicele start pana la end-1. public StringBuffer deleteCharAt(int index). int offset.incepand de la pozitia offset se insereaza caracterele din tabloul str. char[] str). char[] str. public StringBuffer insert(int offset. 372 . Daca offset este incorect se genereaza o StringIndexOutOfBoundsException. long l). public StringBuffer insert(int offset. de la se insereaza de la pozitia offset se public StringBuffer insert(int offset. de la public StringBuffer insert(int offset.incepand de la pozitia offset se insereaza numarul intreg lung l convertit in sir.intoarce subsirul sau genereaza o StringIndexOutOfBoundsException. String str).se insereaza incepand pozitia offset valoarea booleana b convertita in sir. public StringBuffer insert(int offset.se insereaza incepand pozitia offset sirul str. int end). care incepe de la pozitia start public String substring(int start. Daca offset este incorect se genereaza o StringIndexOutOfBoundsException. int end.

a.dacă cele două obiecte sunt egale. valoare negativă. a. În acest caz: a. notify. public String toString(). deci fac parte dintr-o mulţime ordonată.Comparable Interfaţa este implementată de clasele ale căror instanţe pot fi comparate între ele. dacă obiectul propriu este succesor al lui obj.incepand de la pozitia offset se insereaza numarul real f convertit in sir sau se genereaza o StringIndexOutOfBoundsException.se pun caracterele din StringBuffer in ordine inversa celei actuale. public int compareTo(Object obj) Fie a şi b două obiecte. float f).compareTo(b)==0 dacă a==b. getClass.incepand de la pozitia offset se insereaza numarul real f convertit in sir sau se genereaza o StringIndexOutOfBoundsException. Când zona tampon se goleşte.intoarce un String StringBuffer. aparţinând unei clase cu interfaţa Comparable.lang. care are acelasi continut cu acest -------------------------------------------------------------------------------Metode mostenite de la clasa Object: clone.Programarea orientata pe obiecte în limbajul Java public StringBuffer insert(int offset.compareTo(b)<0 dacă a<b (a precede lui b). Clasa BufferedInputStream Face parte din pachetul java. Interfaţa conţine o singură metodă: . notifyAll. public StringBuffer insert(int offset. care conţin o zonă tampon (buffer).IO şi extinde clasa FilterInputStream. hashCode. valoare pozitivă.compară obiectul de care aparţine cu obiectul obj primit ca argument. public StringBuffer reverse(). Instanţele acestei clase sunt fluxuri de intrare de octeţi. ea se 373 . dacă obiectul propriu îl precede pe obj. Valoarea întoarsă este: 0 (zero) . finalize. equals. Octeţii sunt citiţi unul câte unul din această zonă tampon. double d).compareTo(b)>0 dacă a>b (a succede lui b). wait Interfaţa Comparable java.

io şi extinde clasa Reader. Metode Aceleaşi ca în clasa InputStream.se creează un BufferedInputStream public BufferedInputStream(InputStream in. Constructori public BufferedInputStream(InputStream in) ataşat fluxului de intrare in.creează un flux de intrare de caractere. în mod automat. Clasa BufferedReader Face parte din pachetul java. int size) . Metode Aceleaşi ca în clasa OutputStream. .se creează un BufferedInputStream ataşat fluxului de intrare in.creează o instanţa a clasei BufferedOutputStream conectată la ieşire la fluxul out şi conţinând o zonă tampon cu lungimea implicită de 512 octeţi. public BufferedReader(Reader in) 374 .creează o instanţa a clasei BufferedOutputStream conectată la ieşire la fluxul out şi conţinând o zonă tampon cu lungimea de size octeţi. lungimea zonei tampon fiind de size octeţi. prin citirea din fluxul de intrare căruia acest BufferedInputStream îi este ataşat. Clasa BufferedOutputStream Face parte din pachetul java. public BufferedOutputStream(OutputStream out.Severin Bumbaru umple din nou. Constructori .io şi extinde clasa FilterOutputStream Constructori public BufferedOutputStream(OutputStream out) . int size) . cu zonă tampon de lungime implicită. conectat la ieşirea fluxului de intrare de caractere in.

public BufferedWriter(Writer out) public BufferedWriter(Writer out.creează un flux de ieşire de caractere. int sz) . situată în memoria internă. la ieşirea fluxului de intrare de caractere in. Clasa ByteArrayInputStream Face parte din pachetul java. cu zonă tampon de lungime implicită. situat în memoria internă.creează un citeşte din tabloul buf[] situat în memoria internă. cu zonă tampon de lungime sz.indicele următorului octet care va fi citit din tabloul de octeţi de intrare buf[]. cu Metode Aceleaşi ca în clasa Writer. conectat . care 375 . protected int mark . flux de intrare de octeţi.poziţia marcată din flux (este iniţializată implicit la zero şi poate fi modificată prin metoda mark()). Clasa BufferedWriter Face parte din pachetul java.tabloul de octeţi din care se face citirea. conectat la ieşire la fluxul de caractere out.creează un flux de ieşire de caractere. sau când se execută metoda flush(). int sz) Metode Aceleaşi ca în clasa Reader.io şi extinde clasa InputStream.Programarea orientata pe obiecte în limbajul Java public BufferedReader(Reader in. zonă tampon de lungime sz. protected int pos . Câmpuri protected byte[] buf . Acest flux conţine o zonă tampon (buffer) din care se citesc datele. Constructori . protected int count .io şi extinde clasa Writer.creează un flux de intrare de caractere.numărul de octeţi existenţi efectiv în tabloul buf (este cel puţin 0 şi cel mult egal cu lungimea tabloului) Constructori public ByteArrayInputStream(byte[] buf) . Caracterele primite sunt acumulate într-o zonă tampon şi sunt transmise la ieşire numai când această zonă tampon s-a umplut. conectat la ieşire la fluxul de caractere out.

public byte[] toByteArray() .Severin Bumbaru public ByteArrayInputStream(byte[] buf.numărul de octeţi valizi existenţi în tabloul buf[]. public ByteArrayOutputStream() . Clasa ByteArrayOutputStream Face parte din pachetul java. care scrie într-un tablou de octeţi situat în memoria internă. Constructori . Referinţa la zona tampon pentru scriere se obţine prin metoda toByteArray(). Câmpuri protected byte[] buf . Metode Aceleaşi ca la clasa InputStream.io şi extinde clasa OutputStream. int length) . Zona tampon (tabloul) în care se scrie are capacitate variabilă: capacitatea lui se mareşte automat dacă prin o nouă scriere se depăşeşte capacitatea existentă. care citeşte dintr-o zonă a tabloului de octeţi buf[] care începe de la poziţia de indice offset a acestui tablou şi are lungimea length.tabloul de octeţi în care se face scrierea. ca şi când s-ar fi fi făcut invocarea de metodă out. 0. public ByteArrayOutputStream(int size) Metode Metodele sunt cele din clasa OutputStream. dacă este necesar.creează un flux de ieşire de octeţi care scrie într-o zonă tampon (tablou) care are iniţial capacitatea de 32 octeţi. dar capacitatea creşte automat. în care este copiat public int size() . de nou tablou de octeţi.creează un flux de ieşire de octeţi care scrie într-o zonă tampon (tablou) care are iniţial capacitatea de size octeţi.întoarce dimensiunea curentă a zonei tampon (valoarea câmpului count).write(buf. situat în memoria protected int count . Clasa CharArrayReader 376 .scrie în fluxul ieşire out întregul conţinut al tabloului (yonei tampon) buf. cont). dacă este necesar. internă. dar capacitatea creşte automat. la care se adaugă: public void writeTo(OutputStream out) throws IOException . int offset.creează un flux de intrare de octeţi. Flux de ieşire de octeţi.întoarce un conţinutul valid al yonei tampon buf.

io şi extinde clasa Writer. . a cărei lungime este dată implicit.întoarce un şir. având acelaşi conţinut cu zona tampon de ieşire. Datele din zona tampon de ieşire pot fi obţinute prin metodele toCharArray() şi toString(). public CharArrayWriter(int initialSize) Metode Aceleaşi ca în clasa Writer. Citirea începe de la poziţia de indice offset. public String toString() Clasa FileDescriptor 377 . situat ]n memoria internă. care scrie într-o zonă tampon situată în memoria internă. care are acelaşi conţinut cu zona tampon. care citeşte din tabloul de caractere buf[]. int offset.creează un flux intrare de caractere. care de public CharArrayReader(char[] buf. situat ]n memoria internă.Programarea orientata pe obiecte în limbajul Java Face parte din pachetul java.creează un flux de intrare de caractere. situat în memoria internă. care scrie într-o zonă tampon situată în memoria internă. int length) . citeşte din tabloul de caractere buf[]. care scriu într-o zonă tampon sub formă de tablou de caractere extensibil. a cărei lungime este initialSize. public CharArrayWriter() .scrie datele din zona tampon public char[] toCharArray() . Instanţele acestei clase sunt fluxuri de intrare de carractere.creează un flux de ieşire de caractere.creează un flux de ieşire de caractere.întoarce un tablou de caractere. Constructori .io şi extinde clasa Reader. la care se adaugă: public void writeTo(Writer out) throws IOException în fluxul de ieşire de caractere out. Instanţele sunt fluxuri de ieşire de caractere. public int size() . Constructori public CharArrayReader(char[] buf) .întoarce lungimea curentă a zonei tampon. . Clasa CharArrayWriter Face parte din pachetul java. iar yona de citire are lungimea length. Metode Aceleaşi ca în clasa Reader. care citesc dintr-un tablou de caractere situat in memoria internă.

Câmpuri public static final FileDescriptor in sistemului. public void sync() throws SyncFailedException tampon ale sistemului pentru dispozitivul corespunzător. System.descriptorul fişierului de intrare standard a . Principala utilizare este la crearea unor fluxuri din clasele FileInputStream sau FileOutputStream. Clasa FilterInputStream Face parte din pachetul java. De fapt.io.err Constructori public FileDescriptor() . System. care preia fluxul de intrare in. În pachetul java. conectate la fişiere deja deschise. Aceste metode pot fi însă redefinite în subclase. .in. . BufferedInputStream şi PushbackInputStream.io. Putem crea şi propriile noastre subclase. Metode public boolean valid() .descriptorul fişierului de ieşire pentru erori public static final FileDescriptor out sistemului. Această metodă întoarce descriptorul fişierului respectiv.io există subclasele DataInputStream. metodele acestei clase sunt cele moştenite de la superclasa InputStream.Severin Bumbaru Face parte din pachetul java. 378 . deci nu fac nici o prelucrare. System.forţează sincroniăarea zonelor fişier sau soclu deschis).creează o instanţă a clasei Filedescriptor.indică dacă acest descriptor de fişier este valid (se referă la un .out public static final FileDescriptor err a sistemului.existentă în clasele FileInputStream şi FileOutputStream. Instanţele clasei FileDescriptor servesc ca manipulatori ai unor fişiere sau socluri deja deschise.creează un flux de intrare de octeţi cu Metode Aceleaşi ca în clasa InputStream. pentru a realiza astfel de prelucrări.descriptorul fişierului de ieşire standard a . Este superclasa claselor de fluxuri de intrare de octeţi. Constructor protected FilterInputStream(InputStream in) filtru. care realizează anumite operaţii de filtrare (prelucrare) a datelor de intrare. care nu este validă (nu indică nici un fişier) Observaţie: pentru a obţine un descriptor de fişier valid se foloseşte metoda public final FileDescriptor getFD()throws IOException .

io există subclasele DataOutputStream. metodele acestei clase sunt cele moştenite de la superclasa OutputStream.io. De fapt. care realizează anumite operaţii de filtrare (prelucrare) a datelor de intrare. Constructor . Putem crea şi propriile noastre subclase. De fapt. 379 . Aceste metode pot fi însă redefinite în subclase. De fapt.io există subclasa PushbackReader. Aceste metode pot fi însă redefinite în subclase. Este superclasa claselor de fluxuri de ieşire de caractere. PrintStream şi altele. Putem crea şi propriile noastre subclase. care realizează anumite operaţii de filtrare (prelucrare) a datelor de ieşire. Clasa FilterReader Face parte din pachetul java. BufferedOutputStream.Programarea orientata pe obiecte în limbajul Java Clasa FilterOutputStream Face parte din pachetul java.creează un flux de ieşire de octeţi cu filtru. Este superclasa claselor de fluxuri de ieşire de octeţi. care realizează anumite operaţii de filtrare (prelucrare) a datelor de ieşire. deci nu fac nici o prelucrare. Clasa FilterWriter Face parte din pachetul java. deci nu fac nici o prelucrare. deci nu fac nici o prelucrare.io. metodele acestei clase sunt cele moştenite de la superclasa Reader.creează un flux de intrare de caractere cu filtru. metodele acestei clase sunt cele moştenite de la superclasa Writer. pentru a realiza astfel de prelucrări. pentru a realiza astfel de prelucrări. pentru a realiza astfel de prelucrări. Aceste metode pot fi însă redefinite în subclase. În pachetul java. În pachetul java. public FilterOutputStream(OutputStream out) Metode Metodele sunt aceleaşi ca în clasa OutputStream. Este superclasa claselor de fluxuri de intrare de caractere.io. . Constructor protected FilterReader(Reader in) care preia fluxul de intrare in. Metode metodele sunt la fel cele din superclasa Reader. care transmite datele la fluxul de ieşire de octeţi out.

creează un flux de ieşire de caractere cu filtru.se generează un eveniment. Metode public Object getSource() public String toString() . Clasa AWTEvent public abstract class AWTEvent extends EventObject Face parte din pachetul java. .util.Severin Bumbaru Constructor protected FilterWriter(Writer out) . indicându-se sursa.orice interfaţă de ascultătoare de evenimente.întoarce reprezentarea sub formă de String a evenimentului. Clasa EventObject public class EventObject extends Object implements Serializable Face parte din pachetul java. Metode Aceleaşi ca în superclasa Writer. Interfaţa EventListener public interface EventListener Face parte din pachetul java. Este o interfaţă generică. Interfaţa nu conţine nici o metodă. Este rădăcina ierarhiei de clase de evenimente. Este superclasa tuturor claselor de evenimente AWT.util. Constructor public EventObject(Object source) . care transmite datele la fluxul de ieşire de caractere out.întoarce sursa evenimentului. Clasa conţine câmpuri 380 . Fiecare eveniment este generat de o sursă (source). Orice eveniment AWT are un identificator.awt. reprezentat prin câmpul id. Fiecare instanţă a clasei EventObject conţine o referinţă la această sursă şi o metodă prin care ea este obţinută. pe care trebuie să o extindă direct sau indirect .

care au ca valori măşti pentru selectarea după id a diferitelor tipuri de evenimente. .masca pentru selectarea evenimentelor de articol. AncestorEvent. public static final long CONTAINER_EVENT_MASK . public static final long WINDOW_EVENT_MASK .identificatorul tipului de eveniment. public static final long INPUT_METHOD_EVENT_MASK .masca pentru selectarea evenimentelor de mouse. ComponentEvent.masca pentru selectarea evenimentelor de focalizare public static final long KEY_EVENT_MASK .awt.event. Clasele de evenimente create în afara pachetelor din Java API trebuie să aibă valoarea câmpului id superioară valorii maxime din câmpul RESERVED_ID_MAX. public static final long ADJUSTMENT_EVENT_MASK . TextEvent.masca pentru selectarea evenimentelor de ajustare. public static final long MOUSE_MOTION_EVENT_MASK .masca pentru selectarea evenimentelor de acţiune. InputMethodEvent. Clasa AWTEvent înlocuieşte clasa Event din JDK 1.masca pentru selectarea evenimentelor de metodă de intrare.swing. public static final long MOUSE_EVENT_MASK . 381 . public static final long ITEM_EVENT_MASK . Câmpuri protected int id . cu excepţia clasei InternalFrameEvent.event.masca pentru selectarea evenimentelor de fereastră.0. InvocationEvent. HierarchyEvent. InternalFrameEvent.masca pentru selectarea evenimentelor de container. care a fost menţinută în pachet numai pentru compatibilitate. Subclasele directe ale clasei AWTEvent sunt: ActionEvent. ItemEvent.masca pentru selectarea evenimentelor de mişcare a mouse-ului. public static final long ACTION_EVENT_MASK .masca pentru selectarea evenimentelor de tastă. AdjustmentEvent. Ele se găsesc în pachetul java.Programarea orientata pe obiecte în limbajul Java statice. care se găseşte în pachetul javax. public static final long TEXT_EVENT_MASK . public static final long FOCUS_EVENT_MASK .masca pentru selectarea public static final long COMPONENT_EVENT_MASK evenimentelor de componentă.masca pentru selectarea evenimentelor de text.

masca pentru selectarea evenimentelor de invocare. WEST. public static final long INVOCATION_EVENT_MASK .masca pentru selectarea evenimentelor de desenare. Se foloseşte în special la depanarea programului.masca pentru selectarea evenimentelor de ierarhie. În prima instrucţiune. public String toString() .valoarea maximă rezervată pentru id.construieşte o nouă instanţă a clasei AWTEvent. În a doua instrucţiune. folosind paramerii unei instanţe a clasei Event.Severin Bumbaru public static final long PAINT_EVENT_MASK . se pune butonul cu inscripţia "OK" în zona SOUTH a aceluiaşi container.SOUTH). SOUTH. p. la care se adaugă: public int getID() .întoarce reprezentarea sub formă de String a evenimentului. public AWTEvent(Object source. specificându-se sursa şi tipul de eveniment. public String paramString() Clasa BorderLayout public class BorderLayout extends Object implements LayoutManager2.masca pentru selectarea evenimentelor de margini ale ierarhiei. public static final long HIERARCHY_EVENT_MASK . public static final long HIERARCHY_BOUNDS_EVENT_MASK . pentru containerul p se setează gestionarul de poziţionare BorderLayout. Serializable Suprafaţa containerului prevăzut cu acest gestionar de poziţionare se împarte în cinci zone: NORTH.construieşte un obiect din clasa AWTEvent. int id) Metode principale Metodele clasei EventObject. Dacă se omite zona.add(new Button("OK"). Constructori . BorderLayout. EAST şi CENTER. 382 .setLayout(new BorderLayout()). public static final int RESERVED_ID_MAX . .întoarce un şir care conţine parametrii evenimentului. Dăm aici un exemplu de utilizare a unui gestionar de poziţionare din clasa BorderLayout: p. se consideră implicit că adăugarea componentei se face în zona CENTER. În fiecare din aceste zone poate fi pusă câte o singură componentă. public AWTEvent(Event event) .întoarce tipul de eveniment.

se creează un gestionar de poziţionare BorderLayout.setează numele acţiunii de comandă generată de buton. . . .întoarce eticheta butonului. fără distanţare între componente.întoarce numele acţiunii de comandă generată de buton.setează distanţarea pe verticală între componente.construieşte un buton care nu conţine text. public BorderLayout() . public void setHgap(int hgap) . Constructori public Button() . având distanţări între componente hgap pe orizontală şi vgap pe verticală.setează distanţarea pe orizontală între componente. public void setActionCommand(String command) public String getActionCommand() .se creează un gestionar de poziţionare BorderLayout.întoarce distanţarea pe orizontală între componente.întoarce distanţarea pe verticală între componente. int vgap) Metode Metodele din interfeţele LayoutManager şi LayoutManager2. la care se adaugă următoarele: public int getHgap() . care poate fi ascultat cu un ActionListener. public void setVgap(int vgap) Clasa Button public class Button extends Component implements Accessible Instanţele acestei clase sunt butoane care conţin un text numit "etichetă" (engl: label). public BorderLayout(int hgap.Programarea orientata pe obiecte în limbajul Java Constructori . Dacă nu se foloseşte această comandă. public void setLabel(String label) . implicit acest nume este identic cu eticheta butonului.setează eticheta butonului. public int getVgap() . 383 . public Button(String label) Metode Metodele sunt cele ale clasei Component la care se adaugă următoarele: public String getLabel() . butonul generează un eveniment de acţiune. Când este apăsat.construieşte un buton care conţine eticheta specificată.

public void removeActionListener(ActionListener l) evenimente de acţiune specificat. folosind configuraţia grafică config. pe care se pot trasa desene (în engleză.La un moment dat este vizibilă numai componenta de deasupra. canvas este pânza pe care se pictează). cardLayout care are pe public CardLayout(int hgap. Clasa CardLayout public class CardLayout extends Object implements LayoutManager2. Constructori public Canvas() .construieşte un margini spaţiile libere hgap pe orizontală şi vgap pe verticală.construieşte un CardLayout fără spaţiu liber în jurul componentelor. Constructori public CardLayout() .elimină ascultătorul de evenimente de acţiune.creează o nouă instanţă a clasei Canvas. int vgap) . dintre care cea mai utilizată este metoda: public void paint(Graphics g) folosind contextul grafic g.creează o nouă instanţă a clasei public Canvas(GraphicsConfiguration config) Canvas. Pentru a realiza un desen. care plasează componentele în container una peste alta.Severin Bumbaru public void addActionListener(ActionListener l) . însă componentele îşi pot schimba locurile între ele prin rotaţie.desenează pe suprafaţa acestei componente (Canvas).adaugă la buton un ascultător de . pentru care se redefineşte metoda paint. . ca într-un pachet de cărţi de vizită. Serializable Instanţele acestei clase sunt gestionari de poziţionare. se creează o subclasă a clasei Canvas. . Clasa Canvas public class Canvas extends Component implements Accessible Instanţele acestei clase sunt suprafeţe rectangulare albe. 384 . Medtode Metodele clasei Component.

green (verde) şi blue (albastru). green: biţii 8 .componenta cu numele name din containerul specificat.pune deasupra ultima componentă din containerul specificat. Explicaţii suplimentare sunt date şi în secţiunea "Clasa Color" din acest manual. Valoarea alpha=0 înseamnă opacitate nulă (culoare total transparentă).Programarea orientata pe obiecte în limbajul Java Metode Metodele interfeţelor LayoutManager şi LayoutManager2. Aceste valori reprezintă intensitatea culorii fundamentale respective în culoarea dată.întoarce spaţiul liber pe orizontală. 1. Acestea pot fi date prin numere întregi în intervalul 0 . 1. în afară de componentele de culoare fundamentale. public void previous(Container parent) public void show(Container parent. 255) astfel: blue . Valorile componentelor fundamentale ale culorii pot fi date şi împachetate într-un singur număr de tip int. Clasa Color conţine şi câmpuri finale pentru culorile tipice.pune deasupra componenta precedentă a containerului specificat. cu intensităţi diferite. 15. public void next(Container parent) .pune deasupra prima componentă din public void setVgap(int vgap) public void first(Container parent) containerul părinte specificat.pune deasupra următoarea componentă a containerului specificat.. 255.. sau culori dintrun spqaţiu de culori arbitrar..0 sau valori întregi în intervalul 0 . care semnifică opacitatea şi are valori reale în intervalul 0. ..întoarce spaţiul liber pe verticală.. la care se adaugă următoarele: public int getHgap() .0 . şi o componentă numită alpha.. Culorile fundamentale din sistemul sRGB (standard RGB) sunt următoarele: red (roşu).0. Orice culoare se obţine prin combinarea acestor trei componente fundamentale.0 . în care fiecare octet conţine una din componente (în intervalul 0 . 255 sau prin numere reale în intervalul 0. 385 . 23. iar valoarea maximă a lui alpha înseamnă opacitate maximă (culoare total netransparentă). String name) .. alpha: biţii 24 . 31.. .pune deasupra public void last(Container parent) . identificat prin ColorSpace. red: biţii 16 . . .7. Fiecare culoare conţine.setează spaţiul liber pe orizontală.. Clasa Color Clasa Color încapsulează culorile din spaţiul de culori implicit sRGB. public void setHgap(int hgap) public int getVgap() ..setează spaţiul liber pe verticală.biţii 0 . În mod implicit se admite opacitatea maximă.

.creează o instanţă a clasei Color pentru cu culoarea cu componentele RGB şi componenta a (alpha) specificate prin numere reale cuprinse între 0.creează o instanţă a clasei Color pentru cu culoarea cu componentele RGB şi componenta a (alpha) specificate prin numere întregi cuprinse între 0 şi 255.culoarea gri.Severin Bumbaru Câmpuri public static final Color white . public Color(int rgb) public Color(int rgba. .creează o instanţă a clasei Color. int g. int b. float b) . int a) .culoarea roşie. care în primii trei octeţi conţine cele trei componente fundamentale. dându-i ca argument un număr de tip int (pe 4 octeţi).creează o instanţă a clasei Color pentru cu culoarea cu componentele RGB specificate prin numere reale cuprinse între 0. int b. float g.culoarea gri deschis. public Color(int r.culoarea gri închis.0 şi 1. . public static final Color lightGray public static final Color gray . iar în ultimul octet componenta alpha. . .public Color(int r. 386 .0. public static final Color magenta public static final Color cyan public static final Color blue .culoarea portocalie (orange).culoarea verde. Al doilea argument indică dacă există sau nu componenta alpha.culoarea neagră. int g.culoarea albastră.creează o instanţă a clasei Color pentru cu culoarea cu componentele RGB specificate prin numere întregi cuprinse între 0 şi 255.culoarea galbenă. public Color(float r.culoarea azuriu (albastru deschis) .creează o instanţă a clasei Color.culoarea roz.culoarea violet. float a) . Constructori . .0. . public Color(float r. float b. public static final Color pink public static final Color orange public static final Color yellow public static final Color green . dându-i ca argument un număr de tip int (pe 4 octeţi). float g. int g.0 şi 1. public static final Color darkGray public static final Color black public static final Color red .culoarea albă. int b) . boolean hasalpha) . care în primii trei octeţi conţine cele trei componente fundamentale. int a) . public Color(int r.

reprezentată sub forma unui număr de tip int. . float[] hsbvals) . float alpha) . float[] components. public static float[] RGBtoHSB(int r. dar culoarea implicită este dată printr-un număr întreg. int v) . dându-se spaţiul de culori cspace (instanţă a clasei ColorSpace). g. alpha). int g.întoarce componenta alpha. Întoarce un tablou.întoarce o variantă mai închisă a acestei culori. public static int HSBtoRGB(float hue. .întoarce o variantă mai deschisă a acestei culori. Ultimul argument poate fi null. public static Color decode(String nm) throws NumberFormatException converteşte un şir de caractere. b.întoarce componenta albastră. float brightness) converteşte culoarea din sistemul HSB (dată prin parametrii hue: nuanţă. saturation: saturaţie şi brightness: strălucire) într-o culoare din sistemul RGB. corespunzătoare componentelor de culoare RGB date ca parametri. public int getAlpha() public int getRGB() .Programarea orientata pe obiecte în limbajul Java public Color(ColorSpace cspace.similar cu metoda precedentă. public Color brighter() public Color darker() . care reprezintă culoarea codificată în octal sau hexazecimal. public static Color getColor(String nm. public int getGreen() public int getBlue() . public static Color getColor(String nm) . . sau poate conţine un tablou în care se vor întoarce componwentele HSB rezultate. 387 . care conţine cele trei componente fundamentale HSB. float saturation. int b. care conţine sub formă împachetată cele patru componente (r.similar cu metoda precedentă. şi întoarce instanţa corespunzătoare a clasei Color. tabloul de componente components şi opacitatea alpha.creează o instanţă a clasei Color.întoarce un int.face conversia culorii din RGB în HSB. generând instanţa corespunzătoare a clasei Color.întoarce componenta verde. Color v) public static Color getColor(String nm. Metode public int getRed() . .caută o culoare în proprietăţile sistemului: caută proprietatea cu numele nm şi decodifică valoarea acestei proprietăţi (care este interpretat ca un şir care conţine număr întreg).întoarce componenta roşie. dar se indică şi culoarea implicită v care va fi folosită dacă proprietatea de sistem cu numele nm.

Este rădăcina ierarhiei tuturor claselor de componente ale interfeţelor grafice AWT şi JFC/Swing. public int getTransparency() . Metode public String getName() .întoarce transparenţa acestei culori (necesară pentru implementarea interfeţei Paint).întoarce o instanţă a clasei Color. Componenta va putea fi ţinta unei operaţii de "drag and drop" (tragere şi lăsare cu mausul).setează numele componentei. atunci când este activă. RenderingHints hints) . public PaintContext createContext(ColorModel cm. public static Color getHSBColor(float h.întoarce obiectul DropTarget asociat acestei componente. Clasa Component public abstract class Component extends Object implements ImageObserver. Parametrul compArray poate fi null. care conţine culoarea pentru care s-au dat ca argumente valorile componentelor sale în sistemul HSB. AffineTransform xform. 388 . float s. public ColorSpace getColorSpace() .întoarce spaţiul culorilor pentru această culoare (o instanţă a clasei ColorSpace). float b) public float[] getRGBComponents(float[] compArray) . public void setName(String name) public Container getParent() .întoarce o referinţă către containerul care conţine această componentă. . care conţine numai cele trei componente RGB (fără componenta alpha). în care se vor pune valorile întoarse.awt. sau este un tablou cu cel puţin 4 componente de tip float.întoarce un tablou de tip float care conţine cele trei componente RGB şi componenta alpha pentru această culoare. .setează un obiect DropTarget pentru această componentă. MenuContainer. dar întoarce un tablou cu trei componente.întoarce numele componentei.Severin Bumbaru . care este necesar ca argument în metodele claselor cu interfaţa Paint. Rectangle r. public void setDropTarget(DropTarget dt) public DropTarget getDropTarget() . Rectangle2D r2d.întoarce un context de desenare.similar cu metoda precedentă. public float[] getRGBColorComponents(float[] compArray) . Serializable Face parte din pachetul java.

public void setEnabled(boolean b) public void setVisible(boolean b) public Color getForeground() . cum sunt cele din clasele Frame şi JFrame. după cum valoarea argumentului este true sau false. sau null.întoarce obiectul de închidere al arborelui de componente AWT şi de gestionare a poziţionării (obiectul proprietar al monitorului de sincronizare a firului de execuţie).întoarce culoarea de prim-plan a componentei (culoarea .întoarce modelul de culori al componentei.Programarea orientata pe obiecte în limbajul Java .setează fontul componentei. public void setForeground(Color c) public Color getBackground() . public Toolkit getToolkit() public boolean isValid() .indică dacă această componentă este afişabilă (este conectată la o resursă de ecran de afişare nativă). public GraphicsConfiguration getGraphicsConfiguration() public final Object getTreeLock() .indică dacă această componentă apare efectiv pe ecran.indică dacă această componentă este validă (este corect dimensionată şi poziţionată în containerul său părinte).arată dacă această componentă este activă (poate răspunde la intrările date de utilizator şi să genereze evenimente). public void setFont(Font f) public ColorModel getColorModel() public Point getLocation() . public void setBackground(Color c) public Font getFont() . . în sistemul de coordonate al containerului părinte.face ca această componentă să fie activă sau inactivă.setează proprietatea de vizibilitate a componentei.întoarce culoarea de fond a componentei. .întoarce Toolkit-ul pentru această componentă.întoarce locaţia componentei (coordonatele colţului din stânga sus) în sistemul de coordonate al ecranului. cu excepţia celor de cel mai înalt nivel. .setează culoarea de fond a componentei. .setează culoarea de prim-plan a componentei. public boolean isDisplayable() . . textului). . . .întoarce locaţia componentei (coordonatele colţului din stânga sus). public Point getLocationOnScreen() 389 .indică dacă această componentă este vizibilă.întoarce fontul componentei. . public boolean isVisible() public boolean isShowing() public boolean isEnabled() . Toate componentele sunt iniţial vizibile.întoarce configuraţia grafică a acestei componente sau a containerului în care se găseşte.

public void setBounds(int x. . int height) public void setSize(Dimension d) public Rectangle getBounds() .întoarce dimensiunile maxime ale componentei. . public void validate() valid. public void setLocation(int x.setează locaţia componentei (coordonatele colţului din stânga sus) în sistemul de coordonate al containerului părinte. . public void setSize(int width.întoarce dimensiunile preferabile ale componentei.întoarce dimensiunile componentei. int y) .setează coordonatele colţului din stânga sus.întoarce coordonata y a colţului din stânga-sus (în sistemul de coordonate al containerului părinte).întoarce dimensiunile minime ale componentei. Toate componentele Swing şi unele din componentele AWT sunt "Lightweight".transmite gestionarului de poziţionare indicaţia de a poziţiona . int width. public void setLocation(Point p) public Dimension getSize() .întoarce o instanţă a clasei Rectangle (dreptunghi) care conţine lăţimea.setează locaţia şi dimensiunile componentei.întoarce coordonata x a colţului din stânga-sus (în sistemul de coordonate al containerului părinte).setează locaţia componentei (coordonatele colţului din stânga sus) în sistemul de coordonate al containerului părinte. public int getY() public int getWidth() .întoarce true dacă această componentă nu are un suport nativ. lăţimea şi înălţimea componentei. . . int y.Severin Bumbaru .setează dimensiunile componentei.întoarce lăţimea componentei. toate public int getHeight() public boolean isOpaque() componentele sunt opace). înălţimea şi locaţia componentei. . . public boolean isLightweight() public Dimension getPreferredSize() . 390 .întoarce înălţimea componentei. public Dimension getMinimumSize() public Dimension getMaximumSize() public void doLayout() . int height) . . .indică dacă această componentă este opacă (implicit. public void setBounds(Rectangle r) public int getX() . adică sunt desenate în Java şi deci nu folosesc componentele grafice de pe platforma locală.asigură că această componentă are un gestionar de poziţionare componenta.setează dimensiunile componentei.

int y.creează un context grafic pentru această componentă. public Graphics getGraphics() public void setCursor(Cursor cursor) public Cursor getCursor() .Programarea orientata pe obiecte în limbajul Java . int width. . Aceasta înseamnă că: (1) se şterge vechiul conţinut.redesenează componentă (face ca metoda update pentru această componentă să fie invocată cât mai rapid posibil). (3) se apelează metoda paint pentru a desena complet componenta. Această metodă este apelată automat când trebuie desenată componenta. y).verifică dacă această componentă conţine punctul p. umplând componenta cu culoarea de fond. . public void paintAll(Graphics g) .verifică dacă această componentă conţine punctul de coordonate (x. în sistemul de coordonate propriu al componentei. int height) dreptunghiul specificat al componentei. public void paint(Graphics g) . public void repaint() public void repaint(long tm) . int width.redesenează public void repaint(int x. int x. Această componentă şi părinţii săi sunt marcaţi că necesită poziţionare. int y. în sistemul de coordonate propriu al componentei.invalidează componenta. int x. .Intoarce null dacă această componentă nu este afişabilă.desenează această componentă şi toate subcomponentele sale. int y) . public boolean contains(Point p) 391 . int h) . public void print(Graphics g) - .desenează componenta.creează o imagine din producătorul de imagine specificat.apelează metoda update în tm milisecunde.setează cursorul pentru această componentă. .actualizează desenul componentei. public void invalidate() .tipăreşte componenta şi toate subcomponentele ei. public void printAll(Graphics g) public boolean imageUpdate(Image img. public void update(Graphics g) . (2) se setează culoarea de primplan în contextul grafic pentru această componentă. public void repaint(long tm.redesenează componenta când s-a modificat imaginea pe care o conţine. ca răspuns la invocarea metodelor repaintupdate sau repaint. int infoflags. public Image createImage(ImageProducer producer) . int w.tipăreşte componenta. public boolean contains(int x. .întoarce cursorul setet pentru această componentă sau pentru părintele ei. int y. int height) redesenează dreptunghiul specificat al componentei după tm milisecunde.

elimină ascultătorul punctul p. public void addComponentListener(ComponentListener l) componente un ascultător de evenimente generate de către ea. y).adaugă un ascultător de evenimente .elimină de evenimente de metodă de intrare. public void removeInputMethodListener(InputMethodListener l) ascultătorul de evenimente de metodă de intrare. public void removeKeyListener(KeyListener l) de tastă. public void addMouseListener(MouseListener l) de mouse. public void removeComponentListener(ComponentListener l) de evenimente de componentă specificat.adaugă un ascultător de evenimente de . public void removeMouseMotionListener(MouseMotionListener l) ascultătorul de evenimente de mişcare a mouse-ului.adaugă un ascultător .elimină ascultătorul de .adaugă un ascultător de .elimină ascultătorul de .adaugă un ascultător .întoarce subcomponenta care conţine .adaugă un ascultător de evenimente . public void addMouseMotionListener(MouseMotionListener l) de evenimente de mişcare a mouse-ului.adaugă acestei . public void addKeyListener(KeyListener l) .elimină ascultătorul de focalizare. public void addFocusListener(FocusListener l) . 392 .Severin Bumbaru public Component getComponentAt(int x.întoarce subcomponenta care conţine punctul de coordonate (x. public Component getComponentAt(Point p) .elimină ascultătorul de evenimente . public void removeHierarchyListener(HierarchyListener l) de evenimente de ierarhie.elimină tastă. int y) . public void removeFocusListener(FocusListener l) evenimente de focalizare. public void addInputMethodListener(InputMethodListener l) . public void addHierarchyListener(HierarchyListener l) evenimente de ierarhie. public void removeMouseListener(MouseListener l) evenimente de mouse.

protected void firePropertyChange(String propertyName. . Se foloseşte numai pentru depanarea programului. int indent) .Programarea orientata pe obiecte în limbajul Java public EventListener[] getListeners(Class listenerType) .class)) public void add(PopupMenu popup) .întoarce un şir de caractere care reprezintă starea componentei. pentru proprietatea specificată prin primul argument. PropertyChangeListener listener) . indentat cu indent.adaugă un ascultător de evenimente de schimbare a proprietăţilor. pentru a obţine tabloul ascultătoarelor de evenimente de mouse adăugate componentei c se pune instrucţiunea: MouseListener[] mls = (MouseListener[])(c.scrie listingul acestei componente public void list(PrintStream out) public void list(PrintStream out. public void setComponentOrientation(ComponentOrientation o) .getListeners(MouseListener. public void remove(MenuComponent popup) protected String paramString() . public void addPropertyChangeListener(String propertyName.întoarce reprezentarea sub formă de şir a acestei componente.adauga la componentă meniul popup specificat.scrie listingul acestei componente în fluxul out. public void addPropertyChangeListener(PropertyChangeListener listener) - adaugă un ascultător de evenimente de schimbare a proprietăţilor. Object newValue) .elimină meniul popup specificat.scrie listingul acestei componente în fluxul out. public void removePropertyChangeListener(String propertyName. int indent) în fluxul out.setează orientarea componentei. public void list(PrintWriter out) .suport pentru raportarea modificărilor de proprietăţi. Object oldValue.elimină ascultătorul de evenimente de schimbare a proprietăţilor. indentat cu indent. public String toString() public void list() . De exemplu. . Metoda poate fi apelată când s-a modificat o proprietate şi ea va transmite un PropertyChangeEvent către toţi acsultătorii de evenimente de proprietate înregistraţi la această componentă. 393 . pentru proprietatea specificată prin primul argument.afişează listingul acestei componente pe System. public void list(PrintWriter out.scrie listingul acestei componente în fluxul out. . public void removePropertyChangeListener(PropertyChangeListener listener) - elimină ascultătorul de evenimente de schimbare a proprietăţilor. .out. PropertyChangeListener listener) .întoarce un tablou de ascultătoare de evenimente ataşate acestei componente şi având tipul dat ca argument.

se adaugă componenta comp cu restricţiile date de obiectul constraints.construieşte un nou container.întoarce contextul accesibil. public void add(Component comp. public Component getComponent(int n) . Constructor public Container() .Severin Bumbaru public ComponentOrientation getComponentOrientation() . 394 . deoarece şi acestea sunt sunt tot componente). Componentele adăugate în container sunt păstrate într-o listă. Object constraints) . Ordinea din această listă este cea în care componentele sunt luate în consideraţie de către gestionarul de poziţionare. int index) poziţia din lista de componente cu indicele index.întoarce numărul de componente conţinute în acest container. la care se adaugă următoarele: public int getComponentCount() . public Component[] getComponents() . public void add(Component comp. public Component add(Component comp) componente a containerului. Object constraints.întoarce orientarea componentei.se adaugă componenta comp cu restricţiile date de obiectul constraints. Adăugarea se face la sfârşitul listei de componente. Clasa Container public class Container extends Component Containerele sunt componente care pot conţine alte componente (inclusiv alte containere. Metode Metodele clasei Component.adaugă componenta comp la sfârşitul listei de . Adăugarea se face pe poziţia de indice index a listei de componente.întoarce un tablou cu toate componentele conţinute în container.întoarce componenta care are indicele i în lista de componente a containerului. public Insets getInsets() .întoarce lăţimea bordurii containerului (sub forma unui . int index) . public Component add(Component comp.se adaugă componenta comp pe obiect din clasa Insets). public AccessibleContext getAccessibleContext() .

WindowClosing. WindowClosed. .setează gestionarul de poziţionare al public LayoutManager getLayout() public void setLayout(LayoutManager mgr) containerului. Clasa Dialog public class Dialog extends Window Fereastra de dialog este o fereastră de cel mai înalt nivel (care poate fi plasată direct pe ecranul nativ).adaugă un ascultător de .desenează fiecare componentă din acest . .întoarce gestionarul de poziţionare al containerului. .pune în acţiune gestionarul de poziţionare al containerului. public void doLayout() . Când proprietarul este ascuns sau minimizat. fereastra de dialog este de asemenea ascunsă.elimină toate componentele conţinute în container.y).Programarea orientata pe obiecte în limbajul Java public void remove(int index) public void removeAll() . Managerul de poziţionare implicit este BorderLayout.elimină ascultătorul public void paintComponents(Graphics g) container. WindowDeactivated. WindowActivated. int y) . . Fereastra de dialog poate fi modală sau nemodală (implicit este nemodală). cu excepţia celor care au ca proprietar chiar această fereastră de dialog. O fereastră modală blochează toate intrările către orice altă fereastră de cel mai înalt nuvel şi descendentele lor.întoarce componenta care conţine punctul de coordonate (x.elimină componenta de indice index. Generează următoarele evenimente de fereastră: WindowOpened.întoarce componenta care conţine punctul p. 395 . public Component findComponentAt(Point p) .tipăreşte toate componentele din acest . public void printComponents(Graphics g) container. public void removeContainerListener(ContainerListener l) de evenimente de container specificat. Ea are bordură şi este folosită în special pentru dialogul (schimbul de informaţii interactiv) cu utilizatorul. public Component findComponentAt(int x. Fereastra de dialog are ca proprietar o altă fereastră din clasa Frame sau Dialog. public void addContainerListener(ContainerListener l) evenimente de container.

public void setTitle(String title) public boolean isResizable() . Clasa Dimension public class Dimension extends Dimension2D implements Serializable 396 .specifică dacă această fereastră de dialog va fi sau nu redimensionabilă.construieşte o fereastră de dialog cu proprietar altă fereastră de dialog. public String getTitle() .întoarce titlul ferestrei de dialog (poate fi şi null). având ca public Dialog(Frame owner. cu proprietarul owner. . boolean modal) .setează titlul ferestrei de dialog. public Dialog(Dialog owner. boolean modal) de dialog. public Dialog(Frame owner. . titlul şi dacă este sau nu modală.construieşte o ferestră de dialog. public void setResizable(boolean resizable) . String title) . public Dialog(Dialog owner) . String title.construieşte o fereastră indicându-se proprietarul şi titlul ferestrei. la care se adaugă următoarele: public boolean isModal() . String title. având ca proprietar altă fereastră de dialog.construieşte o fereastră de dialog fără titlu. public Dialog(Dialog owner. având ca . .îndică dacă fereastra de dialog este sau nu redimensionabilă. indicându-se proprietarul.indică dacă fereastra de dialog este sau nu modală.construieşte o fereastră de dialog cu titlu. boolean modal) Metode Metodele clasei Window. . specificându-se dacă ea este sau nu modală.specifică dacă fereastra de dialog va fi sau nu public void setModal(boolean b) modală.construieşte o fereastră de dialog fără titlu.Severin Bumbaru Constructori public Dialog(Frame owner) proprietar cadrul owner.construieşte o fereastră de dialog fără titlu. String title) titlu. . având ca proprietar altă fereastră de dialog şi indicându-se dacă este sau nu modală. public Dialog(Frame owner.

int height) . deşi începând cu JDK 1. public boolean equals(Object obj) . int height) conţinând lăţimea width şi înălţimea height.lăţimea. conţinând dimensiuni . Câmpuri public int width . argumentele fiind de tip int.1 ea a fost înlocuită prin clasa AWTEvent. double height) argumentele fiind de tip double.redefineşte metoda equals din clasa Object. public Dimension(Dimension d) public Dimension(int width. public double getHeight() public void setSize(double width. Clasa Event public class Event extends Object implements Serializable Clasa Event este clasa evenimentelor generate de interfaţa utilizator grafică utilizată în JDK 1. .setează lăţimea şi înălţimea. exprimate ca numere întregi.înălţimea. public int height Constructori public Dimension() .construieşte o copie a lui d. nule. .construieşte o instanţă a clasei Dimension.întoarce înălţimea. . public void setSize(int width.setează lăţimea şi înălţimea. Metode public double getWidth() .întoarce lăţimea. Clasa FlowLayout 397 .construieşte o instanţă a clasei Dimension.0 (în prima versiune a Java API) şi menţinută în continuare pentru compatibilitate.Programarea orientata pe obiecte în limbajul Java Instanţele acestei clase conţin dimensiunile orizontală şi vericală ale unei componente. .

public FlowLayout(int align) . de la stânga la dreapta şi de sus în jos. FlowLayout. . int hgap. public int getHgap() . la care se adaugă următoarele: public int getAlignment() .setează alinierea. public static final int CENTER public static final int RIGHT . public FlowLayout() .construieşte un FlowLayout cu aliniere implicită a componentelor (la centru) şi cu spaţii libere între componente de 5 unităţi. cu denumirile modurilor de aliniere a componentelor.CENTER. Parametrul align poate fi din câmpurile: FlowLayout. în cazul când ordinea de plasare este de la stânga la dreapta). ca literele dintr-un text. la dreapta sau pe centru (alinierea implicită este pe centru).RIGHT. cu alinierea componentelor specificată.întoarce alinierea. public static final int TRAILING Constructori . Parametrul align poate fi unul din câmpurile: FlowLayout.aliniere la dreapta . public void setHgap(int hgap) 398 . . Clasa conţine câmpuri statice finale. FlowLayout. Alinierea componentelor poate fi făcută la stânga.aliniere la muchia frontală pentru orientarea dată a containerului (adică aliniere la stânga. Dacă se modifică dimensiunile containerului. unul public void setAlignment(int align) .construieşte un nou FlowLayout. dacă ordinea de plasare a componentelor este de la stânga la dreapta). public FlowLayout(int align. dar putând trece de pe o linie pe alta.construieşte un nou FlowLayout. public static final int LEADING .RIGHT. FlowLayout.Severin Bumbaru Gestionarul de poziţionare FlowLayout plasează componentele pe suprafaţa containerului pe linii succesive.întoarce spaţiul liber între componente pe orizontală.aliniere la centru.LEFT.CENTER.aliniere la muchia terminală. ţinând cont de orientarea dată a containerului (deci aliniere la dreapta. menţinându-şi ordinea şi dimensiunile.setează spaţiul liber între componente pe orizontală. Câmpuri public static final int LEFT . componentele se rearanjează. int vgap) Metode metodele din interfaţa LayoutManager. fiind specificate alinierea şi spaţiile libere între componente pe orizontală şi pe verticală. FlowLayout. Fiecare componentă are deimensiunile ei preferate.LEFT.aliniere la stânga.

Numele fontului poate fi "Serif". Aceste fonturi există pe toate maşinile virtuale Java. Font.ITALIC sau Font. . aldine). public void setVgap(int vgap) Clasa Font public class Font extends Object implements Serializable Instanţele clasei Font reprezintă fonturi şi încorporează fiecare informaţii privind forma. italic. adică mici liniuţe prin care se termină liniile principale care formează caracterul respectiv.ITALIC. 399 .toate caracterele au aceeaşi lăţime. Cele mai răspândite fonturi folosite în programele Java sunt: Serif . bold.setează spaţiul liber între componente pe verticală. de exemplu W este mai lat decât I). public static final int ITALIC Constructori . La alcătuirea mapării atributelor se folosesc numai cheile definite în clasa TextAttribute (pentru detalii se va consulta Java API).Programarea orientata pe obiecte în limbajul Java public int getVgap() . ca cele de la maşina de scris.toate caracterele au serifuri. dar pot fi instalate şi alte fonturi. stilul şi mărimea. folosind atributele specificate prin argument.BOLD. Câmpuri statice finale pentru stiluri public static final int PLAIN public static final int BOLD . SansSerif . public Font(Map attributes) Metode principale public static Font getFont(Map attributes) .stilul BOLD (caractere îngroşate. "SansSerif". . int style. Caracterele sunt simbolurile tipografice folosite în texte. int size) . public Font(String name. Stiluol poate fi Font.stilul italic (cursiv). dar au lăţimea variabilă.se construieşte un nou font. bold+italic. . mărimea şi stilul unui caracter. lăţimea caracterelor este variabilă.întoarce spaţiul liber între componente pe verticală.PLAIN. "Monospaced" sau alt stil existent pe maşina virtuală Java respectivă. public AffineTransform getTransform() . Mărimea fontului (înălţimea literei majuscule) se exprimă în puncte tipografice. Monospaced .întoarce fontul care corespunde cel mai bine setului de atribute specificat ca argument.stilul PLAIN (normal).BOLD|Font. Font.întoarce transformarea asociată acestui font. fiind specificate numele fontului.construieşte un nou font. Stilurile sunt: plain (normal).caracterele nu au serifuri.

Severin Bumbaru public String getFamily() .întoarce numele getFontName() pentru a afla numele fontului.întoarce fontul str. Ca parametru se dă numele proprietăţii.întoarce fontul din lista de proprietăţi a sistemului.întoarce stilul fontului. int). similar acestuia. .întoarce un nou font. float size) pe care îl descrie argumentul . public String getFontName() public int getStyle() public int getSize() . . public boolean isItalic() . La partea superioară i se poate pune o bară de meniu (MenuBar). dar cu stilul specificat. . care să aibă aceeaşi formă cu acesta. dar să aibă stilul şi mărimea specificate. similar acestuia.întoarce mărimea fontului. îngroşat). public Font deriveFont(int style) .indică dacă stilul caracterului este PLAIN (normal). Dacă argumentul este null. public boolean isPlain() public boolean isBold() . Iniţial. care pot fi ascultate cu un WindowListener sau WindowAdapter.indică dacă stilul caracterului este ITALIC (cursiv). public Font deriveFont(int style. dar poate fi făcut vizibil invocând setVisible(true). ambele fiind metode ale clasei Component.întoarce un nou font. Clasa Frame public class Frame extends Window implements MenuContainer Face parte din pachetul java.întoarce un nou font. logic al acestui font. dar cu mărimea specificată.awt. se întoarce un font implicit. cadrul este invizibil. exprimată în puncte tipografice.întoarce numele familiei de fonturi din care face parte acest font. . Un Frame este o fereastră care are chenar şi bară de titlu. public String getPSName() . public static Font getFont(String nm) public static Font decode(String str) . Generează evenimente de fereastră (din clasa WindowEvent). iar dimensiunile se stabilesc prin setSize(int. deci poate fi plasată direct pe ecranul fizic.indică dacă stilul caracterului este BOLD (aldin. public Font deriveFont(float size) .întoarce numele PostScript al acestui font. Se va folosi public String getName() .întoarce numele fontului. 400 . Este o fereastră de cel mai înalt nivel (top-level window). Instanţele acestei clase sau ale subclaselor ei sunt folosite ca ferestre pr4incipale ale aplicaţiilor.

public void setState(int state) public int getState() . public void remove(MenuComponent m) public static Frame[] getFrames() . public MenuBar getMenuBar() . Implicit. .întoarce tabloul tuturor cadrelor (Frame) deschise de o aplicaţie sau accesibile unui applet.construieşte un cadru public Frame(String title. public void setTitle(String title) public Image getIconImage() .setează imaginea care trebuie afişată ca minimizarea acestui cadru.construieşte un cadru (Frame) cu titlul title. GraphicsConfiguration gc) (Frame) cu titlul title şi cu configuraţia grafică gc. deci şi pe cele ale claselor Container şi Component. public Frame(GraphicsConfiguration gc) public Frame(String title) .setează pentru acest cadru bara de meniu mb. într-un sistem multiecran). Metode public String getTitle() .elimină bara de meniu specificată. . nu există.Programarea orientata pe obiecte în limbajul Java Constructori public Frame() .pune titlul title în bara de titlu.construieşte un cadru (Frame) fără titlu. . public void setIconImage(Image image) pictogramă la minimizarea acestui cadru.setează starea acestui cadru.construieşte un cadru (Frame) folosind configuraţia grafică gc (poate fi folosită pentru a afişa cadrul pe alt ecran decât cel principal.îmtoarce bara de meniu a acestui cadru. . dacă ea .întoarce starea acestui cadru. 401 . Clasa Frame moşteneşte şi toate metodele clasei Window.întoarce imaginea care trebuie afişată ca pictogramă la .setează dacă acest cadru poate sau nu să fie redimensionat de către utilizator. . toate instanţele clasei Frame sunt redimensionabile.indică dacă acest cadru poate fi redimensionat de către utilizator (prin tragere cu mouse-ul). public void setMenuBar(MenuBar mb) public boolean isResizable() . sau null.întoarce titlul cadrului (cel din bara de titlu). public void setResizable(boolean resizable) .

int hgap.întoarce numărul de coloane al grilei. la care se adaugă următoarele: public int getRows() . 402 . Pentru utilizarea acestei clase şi. care permite să se alinieze orizontal şi vertical componente de dimensiuni diferite. Clasa GridLayout public class GridLayout extends Object implements LayoutManager. Fiecare celulă a grilei conţine o singură componentă. int vgap) . int cols. public void setRows(int rows) public int getColumns() . Serializable Este un gestionar de poziţionare flexibil. Pentru folosirea acestei clase recomandăm să se consulte Tutorialul Java şi să se folosească documentaţia Java API originală. deci.construieşte un GridLayout cu o singură linie de componente. pentru a putea realiza desene mult mai complexe.întoarce numărul de linii al grilei. int cols) . Constructori public GridLayout() . care extinde clasa Graphics. public GridLayout(int rows.construieşte un GridLayout cu rows cols coloane. recomandăm să se consulte documentaţia originală Java API şi capitolul 2D Graphics din Tutorialul Java. Unul din cele două argumente (dar nu ambele) poate fi 0 (zero). a aplica în Java tehnicile de grafică 2D. specificându-se numărul de linii şi de coloane şi spaţiile libere între componente pe orizontală şi pe verticală.construieşte un nou GridLayout.setează numărul de linii al grilei. Serializable Gestionarii de poziţionare din clasa GridLayout aranjează componentele în container sub forma unei grile rectangulare.Severin Bumbaru Clasa Graphics2D public abstract class Graphics2D extends Graphics Este noul context grafic. Metode Metodele interfeţei LayoutManager. linii şi public GridLayout(int rows. Clasa GridBagLayout public class GridBagLayout extends Object implements LayoutManager2. .

Programarea orientata pe obiecte în limbajul Java public void setColumns(int cols) public int getHgap() .setează distanţarea pe orizontală a componentelor.setează distanţarea pe verticală a componentelor. public void setHgap(int hgap) public int getVgap() .marginea din stânga . public void setVgap(int vgap) Clasa Insets public class Insets extends Object implements Cloneable. Class Panel public class Panel extends Container implements Accessible Panoul este cea mai simplă clasă de containere. Câmpuri public int top .întoarce distanţarea pe orizontală a componentelor. .marginea de sus . Serializable Instanţele acestei clase conţin lăţimile marginilor libere ale containerelor (care nu conţin componente).construieşte o instanţă a clasei Insetws. Marginea respectivă poate fi complet liberă. stânga. int right) Metode Cele moştenite de la clasa Object. inclusiv alte panouri. Constructor . Un panou este un dreptunghi fără bordură pe suprafaţa căruia se pot plasa diferite componente ale interfeţei grafice. int left.marginea de jos public int left public int bottom public int right . sau poate conţine o bordură sau un titlu. fiind specificate marginile de sus. public Insets(int top.întoarce distanţarea pe verticală a componentelor. 403 . .setează numărul de coloane al grilei.marginea din dreapta. . jos şi dreapta. int bottom.

cu gestionarul de FlowLayout. int y) punctului. Clasa Rectangle Instanţele acestei clase sunt suprafeţe de formă dreptunghiulară. cu laturile dispuse orizontal şi vertical. int dy) că noile coordonate vor fi x+dx. y+dy.înălţimea dreptunghiului. exprimate prin numere întregi. . astfel public void setLocation(int x. . int y) .Severin Bumbaru Constructori public Panel() . Clasa Point public class Point extends Point2D implements Serializable Fiecare instanţă a acestei clase conţine coordonatele (x.întoarce coordonata x. 0). 404 . public void translate(int dx.construieşte un punct de coordonate (x.construieşte un nou panou. Constructori public Point() . având gestionarul de poziţionare implicit . pentru care se dau următoarele elemente: x.setează noile valori ale coordonatelor .întoarce coordonata y.efectuează o translaţie a acestui punct. Metode Metodele clasei Container şi superclaselor acesteia.construieşte o copie a punctului p. height .construieşte un nou panou. y) ale unui punct. Valorile acestor elemente sunt exprimate prin numere întregi. public Point(Point p) public Point(int x. y .coordonatele colţului din stânga sus. Metode principale public double getX() public double getY() . y).construieşte un punct de coordonate (0. public Panel(LayoutManager layout) poziţionare specificat.lăţimea dreptunghiului. . width .

public void translate(int dx. public Rectangle(Dimension d) şi dimensiunile d. int y. public Point getLocation() . Metode mai frecvent utilizate public double getX() public double getY() .construieşte un dreptunghi cu originea în punctul p şi . .translatează dreptunghiul. int y. int width. public Rectangle(Rectangle r) . 405 public void setSize(Dimension d) . 0) şi dimensiunile .întoarce coordonata x a colţului stânga-sus. public Rectangle(int x. int height) public Rectangle(Point p. 0) dimensiuni nule. int dy) coordonate devin (x+dx. pentru care sunt specificate coordonatele originii (x. public Dimension getSize() . y).setează dimensiunile dreptunghiului. int height) elementele date ca parametri. . .setează punctul de origine (colţul stânga-sus).construieşte un dreptunghi cu originea în punctul (0. . Dimension d) .setează toate public double getWidth() public double getHeight() public void setBounds(int x. public Rectangle(Point p) . public Rectangle(int width. int height) . . . public void setBounds(Rectangle r) .setează elementele acestui dreptunghi la fel ca la dreptunghiul r. nule.construieşte un dreptunghi cu coordonatele (0.întoarce înălţimea.Programarea orientata pe obiecte în limbajul Java Constructori public Rectangle() .construieşte un dreptunghi. int y) (colţul stânga-sus).setează coordonatele punctului de origine . astfel că noile public void setLocation(Point p) public void setLocation(int x. int width.întoarce punctul de origine (colţul stânga-sus). .întoarce coordonata y a colţului stânga-sus.construieşte o copie a dreptunghiului r.construieşte un dreptunghi cu originea în punctul de coordonate (0 0) şi având specificate lăţimea şi înălţimea. lăţimea şi înălţimea.întoarce dimensiunile dreptunghiului. y+dy).construieşte un dreptunghi cu originea în punctul p şi dimensiunile d.întoarce lăţimea.

indică dacă acest dreptunghi conţine punctul public boolean contains(int x.indică dacă acest dreptunghi conţine punctul p. Constructori public Window(Frame owner) . . având ca proprietar o . public Window(Window owner) fereastră din clasa Window.întoarce dreptunghiul cel mai mic care conţine în întregime acest dreptunghi şi dreptunghiul r. int y. GraphicsConfiguration gc) . public Rectangle union(Rectangle r) Clasa Window public class Window extends Container implements Accessible Instanţele acestei clase sunt ferestre de cel mai înalt nivel (pot fi plasate direct pe eranul nativ).indică dacă acest dreptunghiul r.setează dimensiunile dreptunghiului. public boolean intersects(Rectangle r) .se construieşte o nouă fereastră. public Window(Window owner. public boolean contains(Rectangle r) .se construieşte o nouă fereastă.se construieşte o nouă fereastră. o fereastră de dialog sau o altă instanţă a clasei Window. fără bordură şi fără bară de meniu. Metode Metodele clasei Container. Trebuie să aibă drept proprietar un cadru. public Rectangle intersection(Rectangle r) cu dreptunghiul r. int height) dreptunghi conţine dreptunghiul ale cărui elemente sunt specificate.întoarce intersecţia acestui dreptunghi dreptunghiul r. în sistemele cu mai multe ecrane). y).indică dacă acest dreptunghi conţine . int height) public boolean contains(Point p) .Severin Bumbaru public void setSize(int width. int width. . .indică dacă acest dreptunghi intersectează . având proprietarul owner şi configuraţia grafică gc (poate fi afişată şi pe un alt ecran fizic. public boolean contains(int x. la care se adaugă următoarele: 406 . int y) de coordonate (x. având ca proprietar altă instanţă a clasei Frame.

public void toFront() public void toBack() .întoarce textul de avertizare. public void addWindowListener(WindowListener l) evenimente de fereastră. ScrollPaneLayout.ButtonAreaLayout.întoarce proprietarul ferestrei.adaugă un ascultător de .întoarce tabloul ferestrelor. . întoarce fereastra copil care este deţine focalizarea. BasicOptionPaneUI. BasicInternalFrameUI. public Window getOwner() .plasează fereastra deasupra celorlalte de pe ecran. public void pack() public void show() public void hide() . care însoţeşte public final String getWarningString() această fereastră dacă ea nu este sigură. ViewportLayout. pe care această . public void removeWindowListener(WindowListener l) evenimente de fereastră specificat.face fereastra vizibilă pe ecran.dacă fereastra este activă.DividerLayout 407 .ascunde fereastra (o face invizibilă).TitlePaneLayout. . BasicTabbedPaneUI.InternalFrameLayout.ComboBoxLayoutManager. Interfaţa LayoutManager Defineşte interfaţa pentru clasele care gestionează poziţionarea componentelor în container. după care fereastra este făcută afişabilă şi este validată.TabbedPaneLayout. BasicInternalFrameTitlePane. public Component getFocusOwner() . Clase care implementează această interfaţă: GridLayout. BasicSplitPaneDivider.întoarce un tablou al tuturor ascultătoarelor de evenimente adăugate la această fereastră. BasicComboBoxUI. FlowLayout.elimină ascultătorul de public Window[] getOwnedWindows() fereastră le deţine ca proprietar.Programarea orientata pe obiecte în limbajul Java .plasează fereastra în spatele celorlalte de pe ecran. public EventListener[] getListeners(Class listenerType) . .face ca fereastra să fie dimensionată la dimensiunea preferată şi componentele ei să fie aranjate de către gestionarul de poziţionare. . BasicScrollBarUI.

la origine. 408 .întoarce un număr în intervalul 0.0. public float getLayoutAlignmentY(Container target) public void invalidateLayout(Container target) .se face redimensionarea şi poziţionarea componentelor din containerul specificat. 1. Metode Are toate metodele interfeţei LayoutManager la care se adaugă următoarele metode: public void addLayoutComponent(Component comp.la centru.la extremitatea dreaptă. care indică modul în care se face alinierea componentelor pe axa oX: 0. care indică modul în care se face alinierea componentelor pe axa oY: 0. BorderLayout. Component comp) container componenta comp cu numele name. public Dimension minimumLayoutSize(Container parent) . 1.se invalidează gestionarul de poziţionare. public Dimension preferredLayoutSize(Container parent) .întoarce un număr în intervalul 0.RootLayout. public void layoutContainer(Container parent) .0 .elimină din container componenta specificată. JRootPane.întoarce dimensiunile minime ţinând cont de componentele din containerul părinte specificat. 1..la origine.0 .adaugă la . public Dimension maximumLayoutSize(Container target) .întoarce dimensiunea maximă a containerului.. OverlayLayout.întoarce dimensiunile preferate ţinând seama de componentele din containerul părinte specificat.0 . 0. GridBagLayout. public float getLayoutAlignmentX(Container target) . .adaugă . 0. descărcându-se informaţia pe care o conţine. BasicSplitPaneUI. public void removeLayoutComponent(Component comp) . 1.la extremitatea de jos.5 .5 . Interfaţa LayoutManager2 public interface LayoutManager2 extends LayoutManager Clase care implementează această interfaţă: CardLayout. Object constraints) componenta comp respectând restricţiile constraints. BoxLayout.0 .la centru.0 .0 .BasicHorizontalLayoutManager Interfaţă pentru clasele de gestionare a poziţionării care folosesc un obiect de restricţii (care stabileşte restricţiile pe care trebuie să le satisfacă poziţionarea).0.Severin Bumbaru Metode public void addLayoutComponent(String name.

mască pentru a detecta dacă tasta meta era apăsată .mască pentru a detecta dacă tasta ctrl era apăsată . la care se adaugă următoarele: public String getActionCommand() .mască pentru a detecta dacă tasta shift era apăsată.mască pentru a detecta dacă tasta alt era apăsată. public int getModifiers() . public static final int CTRL_MASK public static final int META_MASK public static final int ALT_MASK . era apăsată tasta alt. Aceasta se obţine intersectănd masca cu valoarea întoarsă de metoda getModifiers().Programarea orientata pe obiecte în limbajul Java Clasa ActionEvent public class ActionEvent extends AWTEvent Eveniment semantic.întoarce valoarea curentă a mărimii ajustate. Câmpuri public static final int SHIFT_MASK .întoarce un şir. Metode Metodele clasei AWTEvent. un buton a fost apăsat). public int getValue() . public String paramString() .întoarce obiectul ajustabil care a generat acest eveniment. care identifică acţiunea de comandă indicată de acest eveniment. câmpul ALT_MASK permite sa se determine dacă. De exemplu. Cu ajutorul măştilor date drept câmpuri statice finale se pot determina anumite caracteristici ale evenimentului produs. care indică faptul că asupra unei componente a fost exercitată o acţiune specifică acelei componente (de exemplu. Clasa AdjustmentEvent public class AdjustmentEvent extends AWTEvent Instanţele acestei clase sunt evenimente. 409 .întoarce modificatorii evenimentului (ce taste de control erau apasate când s-a produs evenimentul). generate atunci când este ajustată o mărime specifică sursei de eveniment respective.întoarce un şir. care conţine parametrii evenimentului şi este util în special la depanare. Metode public Adjustable getAdjustable() . în momentul generării evenimentului.

utili pentru depanare. Penteru a crea un ascultător de evenimente de componentă. Constructor public ComponentAdapter() Metode Toate metodele interfeţei ComponentListener.întoarce tipul de ajustare. care conţine parametri necesari. BLOCK_DECREMENT. pentru redimensionarea şi repoziţionarea componentelor). WindowEvent. Evenimentele de componentă sunt date numai pentru scopuri de notificare (în mod obişnuit nu sunt folosite explicit în programul de aplicaţie. InputEvent.întoarce un şir. modificare a vizibilităţii. care poate fi următoarele: UNIT_INCREMENT. cum sunt ContainerEvent. Clasa conţine toate metodele interfeţei ComponentListener. public String paramString() unul din . dar aceste metode nu fac nimic (au corpul vid). FocusEvent. . UNIT_DECREMENT. Clasa ComponentEvent public class ComponentEvent extends AWTEvent Clasa evenimentelor generate la modificarea stării unei componente: deplasare. la depanare. în special. Clasa ComponentAdapter public abstract class ComponentAdapter extends Object implements ComponentListener Clasă abstractă. servind drept prototip pentru realizarea claselor ascultătoare de evenimente de componentă. se crează o subclasă a clasei ComponentAdapter. Este. modificare a stării. în care se redefinesc numai metodele efectiv necesare.întoarce componenta care a generat evenimentul. TRACK. BLOCK_INCREMENT. superclasă pentru alte evenimente de componentă. 410 . de asemenea. Metode public Component getComponent() public String paramString() .Severin Bumbaru public int getAdjustmentType() . PaintEvent. ci numai în mod implicit.întoarce un şir de parametri.

mască pentru tasta META. Metode public boolean isShiftDown() .mască pentru tasta ALT_GRAPH. Conţine câmpuri statice finale.la generarea evenimentului. tasta CTRL era apăsată.la generarea evenimentului.mască pentru tasta ALT.mască pentru butonul 3 de mouse. . tasta ALT era apăsată. Conţine. . public static final int ALT_GRAPH_MASK public static final int BUTTON1_MASK public static final int BUTTON2_MASK public static final int BUTTON3_MASK . . . . tasta ALT_GRAPH era public boolean isAltGraphDown() apăsată.mască pentru tasta CTRL.mască pentru butonul 1 de mouse. de asemenea.întoarce modificatorii (din care.întoarce momentul de timp când a avut loc evenimentul (dat de ceasul sistemului).la generarea evenimentului. .Programarea orientata pe obiecte în limbajul Java Clasa InputEvent public abstract class InputEvent extends ComponentEvent Clasă abstractă. . Câmpuri statice finale public static final int SHIFT_MASK public static final int CTRL_MASK public static final int META_MASK public static final int ALT_MASK . public long getWhen() . care constituie rădăcina ierarhiei de clase pentru evenimente de intrare. Are ca subclase directe KeyEvent şi MouseEvent. ale căror valori sunt măşti pentru recunoaşterea tipului de eveniment. public int getModifiers() 411 . tasta SHIFT era apăsată. .mască pentru tasta SHIFT. tasta META era apăsată. metode pentru recunoaşterea diferitelor situaţii existente la generarea evenimentelor de intrare.la generarea evenimentului. . . public boolean isControlDown() public boolean isMetaDown() public boolean isAltDown() .la generarea evenimentului.mască pentru butonul 2 de mouse. folosind măştile) se pot obţine caracteristicile evenimentului.

public void keyPressed(KeyEvent e) public void keyReleased(KeyEvent e) 412 . Metode public ItemSelectable getItemSelectable() .întoarce articolul afectat de către acest eveniment. se face o subclasă în care se redefinesc numai metodele necesare în aplicaţia respectivă. Clasa conţine toate metodele din interfaţa KeyListener.întoarce schimbarea de stare care a provocat evenimentului (poate fi ItemEvent.Severin Bumbaru Clasa ItemEvent public class ItemEvent extends AWTEvent Eveniment semantic. dar aceste metode nu fac nimic (au corpul vid). Clasa KeyAdapter public abstract class KeyAdapter extends Object implements KeyListener Adaptor pentru ascultătoarele de evenimente de tastă. care conţine parametrii evenimentului (poate fi util la depanare). Constructor public KeyAdapter() Metode public void keyTyped(KeyEvent e) .întoarce un şir.întoarce articolul care a generat acest eveniment. . generarea public int getStateChange() . care arată că un articol a fost selectat sau deselectat. taste. Pentru a obţine un ascultător de evenimente de tastă.DESELECTED) public String paramString() .a avut loc apăsarea şi eliberarea imediată a unei . Este generat de către obiecte selectabile (de exemplu articolele de listă).a fost apăsată o tastă.a fost eliberată o tastă.SELECTED sau ItemEvent. public Object getItem() .

Principalele câmpuri statice finale public static final int KEY_TYPED .tasta CapsLock (blocare pe litere majuscule) public static final int VK_PAUSE public static final int VK_CAPS_LOCK public static final int VK_ESCAPE public static final int VK_SPACE . .tasta a fost eliberată.a fost acţionată tasta ENTER.tasta cu săgeată spre stânga public static final int VK_HOME public static final int VK_LEFT public static final int VK_UP . public static final int KEY_PRESSED public static final int KEY_RELEASED public static final int VK_ENTER .tasta Pause .tasta BackSpace public static final int VK_BACK_SPACE public static final int VK_TAB .tasta Home .tasta de spaţiu liber .Programarea orientata pe obiecte în limbajul Java Clasa KeyEvent public class KeyEvent extends InputEvent Eveniment care indică faptul că a fost acţionată o tastă. .tasta Alt .tasta Tab .tasta a fost apăsată.tasta cu săgeata în sus 413 .tasta End . . Evenimentul este generat de componenta care este activă în momentul acţionării tastei.tasta PageDown (o pagină în jos) public static final int VK_PAGE_UP public static final int VK_PAGE_DOWN public static final int VK_END .tasta Esc (Escape) .tasta PageUp (o pagină în sus) . Clasa conţine câmpuri statice finale.tasta Shift . care permit identificarea tastei care a fost apăsate şi a modificatorilor corespunzători (a tastelor auxiliare care erau apăsate în momentul când s-a acţionar tasta generatoare de eveniment).tasta a fost apăsată şi eliberată imediat.tasta Ctrl public static final int VK_SHIFT public static final int VK_CONTROL public static final int VK_ALT .

Y. . N. W.tasta punct şi virgulă (caracterul ". 7. . 8. . 3. .caracterul separator public static final int VK_SEPARATER 414 . 6.caracterul "+" de pe tastatura numerică . 7."). public static final int VK_A public static final int VK_B . . X. F.") public static final int VK_EQUALS . . similar VK_2. 3. Z public static final int VK_OPEN_BRACKET . VK_3. . O.tasta cu litera B . . . L. 9 public static final int VK_SEMICOLON . .tasta cu virgula (caracterul ". . 5. 9 de pe tastatura numerică public static final int VK_MULTIPLY public static final int VK_ADD . . . . 8. . similar pentru literele C. ."). .tasta cu minus (caracterul "-").tasta cu cifra zero . 4. . M. . . . D. G. P. . 4. . . V. E. . VK_7. .tasta cu săgeata în jos .tasta 1 de pe tastatura numerică. VK_4. . T. . VK_9 respectiv pentru cifrele 2.caracterul paranteză dreaptă închisă public static final int VK_CLOSE_BRACKET (caracterul "]" ) public static final int VK_NUMPAD0 public static final int VK_NUMPAD1 . . VK_8.tasta paranteză dreaptă deschisă (caracterul "[" ) public static final int VK_BACK_SLASH . I.tasta cu linia de fracţie (caracterul "-"). VK_5. 5. J. public static final int VK_COMMA public static final int VK_MINUS public static final int VK_PERIOD public static final int VK_SLASH public static final int VK_0 public static final int VK_1 . similar pentru tastele 2. VK_6. . S.tasta cu punctul (caracterul ". 6. .Severin Bumbaru public static final int VK_RIGHT public static final int VK_DOWN .tasta cu cifra 1 . . .tasta cu litera A . . . . K. K.caracterul bară inversă (caracterul "\" ) . Q.caracterul "*" de pe tastatura numerică .tasta egal (caracterul "="). . . U. R.tasta cu săgeata la dreapta .tasta 0 (zero) de pe tastatura numerică. . .

caracterul împărţire de pe tastatura numerică .tasta NumLock (trecerea pe tastatura numerică) tasta ScrollLock (blocarea defilării) public static final int VK_NUM_LOCK public static final int VK_SCROLL_LOCK public static final int VK_F1 . F21.tasta "acolada stanga" (caracterul "{" ) . F16.tasta ampersand (caracterul "&" ) public static final int VK_KP_DOWN public static final int VK_KP_LEFT public static final int VK_KP_RIGHT public static final int VK_AMPERSAND public static final int VK_ASTERISK public static final int VK_QUOTEDBL public static final int VK_LESS . .tasta "acolada dreapta" (caracterul "}" ) public static final int VK_GREATER public static final int VK_BRACELEFT public static final int VK_BRACERIGHT 415 .tasta apostrof invers (caracterul ` ) public static final int VK_BACK_QUOTE public static final int VK_QUOTE public static final int VK_KP_UP . F4. . F18. . F12. F13. .caracterul scădere de pe tastatura numerică . .Programarea orientata pe obiecte în limbajul Java public static final int VK_SUBTRACT public static final int VK_DIVIDE public static final int VK_DELETE .tasta "mai mare" (caracterul ">" ) .tasta funcţională săgeată spre stânga . . F20.tasta apostrof (caracterul ' ) . F7. similar pentru tastele speciale F2.tasta specială F1 . F24 public static final int VK_PRINTSCREEN public static final int VK_INSERT public static final int VK_HELP public static final int VK_META . . F19. F17.tasta funcţională săgeată la dreapta .tasta Help .tasta Insert .tasta Delete (ştergere) .tasta Meta . F5.tasta ghilimele (caracterul " ) . F14. . .tasta funcţională săgeată în jos . F23.tasta asterisc (caracterul "*" ) . F8.tasta "mai mic" (caracterul "<" ) . F3. F9.tasta PrintScreen (tipărirea ecranului) . . F6. . . F11. F22. F10. F15.tasta funcţională săgeată în sus .

public static String getKeyModifiersText(int modifiers) .tasta "doua puncte" (caracterul ":" ) .tasta cu simbolul valutar Euro.întoarce caracterul logic al tastei (caracterul generat la apăsarea tastei respective: de exemplu. F1.întoarce un şir.Tasta AltGraph Metode principale public int getKeyCode() . se întoarce caracterul "A".tasta paranteza dreapta (caracterul public static final int VK_RIGHT_PARENTHESIS ")" ) public static final int VK_UNDERSCORE public static final int VK_ALT_GRAPH .Severin Bumbaru public static final int VK_AT . care conţine modificatorii. adică o tastă prin care utilizatorul cere o acţiune. public static String getKeyText(int keyCode) .tasta cu semnul de exclamatie .tasta cu simbolul valutar dolar (caracterul "$" ) .paranteză stânga (caracterul "(" ) public static final int VK_EURO_SIGN public static final int VK_EXCLAMATION_MARK (caracterul "!" ) public static final int VK_LEFT_PARENTHESIS public static final int VK_NUMBER_SIGN public static final int VK_PLUS . . în timp ce dacă s-a apăsat simplu tasta A. adică tastele auxiliare apasate la generarea evenimentului respectiv. dacă s-au apăsat tastele Shift A. se întoarce caracterul "a") . care conţine textul de pe tasta al cărui cod este dat ca argument (un text cum ar fi "HOME".întoarce codul tastei asociat cu acest eveniment de intrare (cel care poate fi comparat cu unul din câmpurile statice finale de mai sus) public char getKeyChar() . F2 etc.indică dacă aceasta este o tastă de acţiune. "F1" sau "A").întoarce un şir.tasta plus (caracterul "+" ) .tasta cu simbolul numeric (caracterul "#" ) . public boolean isActionKey() 416 . (Observaţie: parametrul modifiers poate fi obţinut aplicând metoda getModifiers() a superclasei InputEvent). de exemplu: "Shift" sau "Ctrl+Shift".tasta cu caracterul at (caracterul "@" ) .tasta circumflex (caracterul "^" ) public static final int VK_COLON public static final int VK_CIRCUMFLEX public static final int VK_DOLLAR . PageDown. cum ar fi tastele PageUp.tasta underscore (caracterul "_" ) .

atunci când este acţionat mouse-ul. Metode Metodele superclaselor AWTEvent şi InputEvent. care permit ascultarea ambelor categorii de evenimente. Constructor public MouseAdapter() Metode Cele ale interfeţei MouseListener. se folosesc modificatorii obţinuţi prin metoda getModifiers() şi măştile corespunzătoare din superclasa InputEvent. intrarea cursorului de mouse pe suprafaţa componentei sau ieşirea de pe aceasta.Programarea orientata pe obiecte în limbajul Java Clasa MouseAdapter public abstract class MouseAdapter extends Object implements MouseListener Clasă abstractă. sau deplasarea cursorului de mouse pe suprafaţa componentei (fără să fie apăsat nici unul din butoanele de mouse). Extinzând această clasă. click de mouse.swing. Evenimentele de mouse sunt ascultate folosind interfaţa MouseListener. Clasa MouseEvent public class MouseEvent extends InputEvent Clasa evenimentelor generate de o componentă. programatorul poate redefini numai acele metode. Clasa conţine toate metodele interfeţei MouseListener. În pachetul javax. de asemenea. iar cele de mişcare a mouse-ului sunt ascultate prin interfaţa MouseMotionListener. dar acestea nu fac nimic (au corpul vid). la care se adaugă următoarele: 417 . Există două categorii de astfel de evenimente: . de care are nevoie.evenimente de mişcare a mouse-ului: tragerea mouse-ului pe suprafaţa componentei (deplasarea cursorului acestuia în timp ce unul din butoane este ţinut apăsat).evenimente de mouse propriu-zise: apăsarea sau eliberarea unui buton de mouse. Pentru a se afla care buton a fost apăsat. interfaţa MouseInputListener şi clasa MouseInputAdapter.event există. . iar cursorul de mouse se găseşte pe componenta respectivă. care poate fi extinsă pentru realizarea de ascultătoare de evenimente care implementează interfaţa MouseListener.

adăugând la cele două coordonate valorile dx şi dy specificate. dar aceste metode nu fac nimic (corpul lor este vid). care indică faptul că a avut loc o modificare a textului conţinut în componenta care a generat evenimentul. Pentru a realiza un ascultător de evenimente de mişcare a mouse-ului. Această clasă conţine toate metodele interfeţei MouseMotionListener. în sistemul de coordonate al componentei sursă.indică dacă acest eveniment de mouse este un trigger de menu pop-up pentru platforma dată.Severin Bumbaru public int getX() .întoarce punctuil în care se găsea cursorul de mouse în momentul producerii evenimentului. int dy) .întoarce coordonata y a cursorului de mouse din momentul producerii evenimentului. public int getY() . în sistemul de coordonate al componentei sursă. Clasa MouseMotionAdapter public abstract class MouseMotionAdapter extends Object implements MouseMotionListener Clasă abstractă pentru adaptoarele de ascultoare de evenimente de mişcare a mouse-ului. public void translatePoint(int dx. Constructor public MouseMotionAdapter() Metode Cele ale interfeţei MouseMotionListener. se extinde această clasă.întoarce numărul de clickuri (se are în vedere că este posibil să se facă succesiv. 418 .întoarce coordonata x a cursorului de mouse din momentul producerii evenimentului. redefinind numai metodele care sunt necesare efectiv. Clasa TextEvent public class TextEvent extends AWTEvent Eveniment semantic. mai multe clickuri de mouse). public Point getPoint() . la intervale mici de timp. .tranlatează punctul în care se găsea cursorul de mouse în momentul producerii evenimentului. în sistemul de coordonate al componentei sursă. public int getClickCount() public boolean isPopupTrigger() .

s-a dezactivat. Metodă utilă pentru depanare.întoarce fereastra care a generat evenimentul. care serveşte la crearea claselor ascultătoare de evenimente de fereastră. care indică faptul că a avut loc o modificare a stării unei ferestre: fereastra s-a deschis. Clasa WindowEvent public class WindowEvent extends ComponentEvent Clasă de evenimente de nivel coborât. Interfaţa ActionListener public interface ActionListener extends EventListener 419 . se crează o subclasă a clasei WindowAdapter. s-a activat. la care se adaugă următoarea: public Window getWindow() . s-a iconificat sau deiconificat. dar aceste metode nu fac nimic. Pentru a crea o clasă ascultătoare de evenimente de fereastră. Constructor public WindowAdapter() Metode Toate metodele interfeţei WindowListener. urmează să se închidă. redefinind numai metodele efectiv necesare în aplicaţia respectivă.întoarce un şir.Programarea orientata pe obiecte în limbajul Java Metodă public String paramString() . care conţine parametrii evenimentului. s-a închis. Clasa WindowAdapter public abstract class WindowAdapter extends Object implements WindowListener Clasă abstractă. Metode Metodele superclasei ComponentEvent. Conţine toate metodele interfeţei WindowListener.

deoarece tratarea lor se face automat de către AWT.componenta a fost făcută public void componentHidden(ComponentEvent e) invizibilă.componenta şi-a modificat dimensiunile. este activată metoda actionPerformed a ascultătorului. .componenta a fost făcută vizibilă. Metodă public void adjustmentValueChanged(AdjustmentEvent e) . . se poate crea o subclasă a clasei ComponentAdapter.Severin Bumbaru Această interfaţă este implementată de clasele ascultătoare de evenimente de acţiune.componenta s-a deplasat. Când componenta respectivă generează un ActionEvent.metodă invocată când se produce un Interfaţa AdjustmentListener public interface AdjustmentListener extends EventListener Interfaţă pentru ascultătoarele de evenimente de ajustare. . Interfaţa ComponentListener public interface ComponentListener extends EventListener Interfaţă pentru ascultătoarele de evenimente de componentă. public void componentMoved(ComponentEvent e) public void componentShown(ComponentEvent e) . 420 .este invocată când are loc ajustarea obiectului care generează evenimentul. Ascultarea acestor evenimente se face numai în scop de notificare. Aceste ascultătoare pot fi adăugate la componentele care suportă metoda addActionListener(actionListener l). În loc de a crea o clasă care implementează direct această interfaţă. Metodă public void actionPerformed(ActionEvent e) eveniment din clasa ActionEvent. Metode public void componentResized(ComponentEvent e) .

a fost apăsată o tastă.a fost eliberată o tastă. În loc de a se crea o clasă de ascultare care implementează direct această interfaţă. . Metodă . public void keyPressed(KeyEvent e) public void keyReleased(KeyEvent e) Interfaţa MouseListener public interface MouseListener extends EventListener Interfaţă pentru ascultătoarele de mouse care ascultă principalele evenimente generate de acesta. public void itemStateChanged(ItemEvent e) Interfaţa KeyListener public interface KeyListener extends EventListener Interfaţă pentru ascultătoarele de evenimente de tastă. se folosesc metodele şi măştile din clasa KeyEvent. În loc de creea un ascultător de evenimente care implementează direct această interfaţă.a avut loc apăsarea şi eliberarea imediată a unei . click de mouse. 421 .este invocată atunci.Programarea orientata pe obiecte în limbajul Java Interfaţa ItemListener public interface ItemListener extends EventListener Interfaţa pentru ascultătoare de evenimente de articol. când are loc o modificare a stării ogiectului care generează evenimente de articol (ItemEvent). respectiv apăsarea sau eliberarea unui buton. intrarea cursorului de mouse pe suprafaţa unei componente sau ieşirea acestuia. Pentru a afla care tastă a provocat generarea evenimentelor. taste. Metode public void keyTyped(KeyEvent e) . se poate crea o subclasă a clasei MouseAdapter. se poate extinde clasa KeyAdapter. Pentru ascultarea evenimentelor de mişcare a mouse-ului se foloseşte interfaţa MouseMotionListener.

metodă invocată când s-a produs un click de . public void mouseReleased(MouseEvent e) din butoanele de mouse. public void mousePressed(MouseEvent e) butoanele de mouse.Severin Bumbaru Metode public void mouseClicked(MouseEvent e) . Astfel de evenimente sunt generate la modificarea textului conţinut într-o componentă.metodă invocată când cursorul de mouse intră pe suprafaţa unei componente. public void mouseMoved(MouseEvent e) . Interfaţa TextListener public interface TextListener extends EventListener Interfaţă pentru clasele de ascultare a evenimentelor de text.metodă invocată când este eliberat unul mouse.mouse-ul a fost mişcat (fără să fie apăsat nici unul din butoane). public void mouseEntered(MouseEvent e) . Interfaţa MouseMotionListener public interface MouseMotionListener extends EventListener Interfaţă pentru ascultătoarele de evenimente care se produc la mişcarea mouse-ului. public void mouseExited(MouseEvent e) . Metode public void mouseDragged(MouseEvent e) .metodă invocată când cursorul de mouse iese de pe suprafaţa unei componente. În loc de a crea o clasă care implementează direct această interfaţă.metodă invocată când a avut loc o modificare a textului. se poate crea o subclasă a clasei MouseMotionAdapter.mouse-ul a fost "tras" (adică a fost deplasat menţinând unul din butoane apăsat). 422 . Metodă public void textValueChanged(TextEvent e) .metodă invocată când este apăsat unul din .

. dar el poate fi modificat prin metoda setActionCommand şi poate fi aflat prin metoda getActionCommand. 423 . Butonul poate conţine un text şi/sau o pictogramă. SwingConstants Clasă abstractă. Numele acestui eveniment (ActionCommand) este implicit identic cu textul de pe buton.metodă invocată când fereastra urmează să se închidă (a fost apăsat butonul de închidere din colţul dreapta-sus.metodă invocată când fereastra a fost .metodă invocată când fereastra a fost activată (poate primi intrări de la tastatură şi poate genera evenimente de tastă) public void windowActivated(WindowEvent e) public void windowDeactivated(WindowEvent e) .metodă invocată când fereastra a fost deschisă. public void windowDeiconified(WindowEvent e) fost deiconificată. . Metode public void windowOpened(WindowEvent e) .metodă invocată când fereastra a închisă. În loc de a crea o clasă ascultătoare care implementează direct această interfaţă.metodă invocată când fereastra a fost dezactivată (nu mai primeşte intrări de la tastatură) Clasa AbstractButton public abstract class AbstractButton extends JComponent implements ItemSelectable. public void windowClosing(WindowEvent e) public void windowClosed(WindowEvent e) . sau a fost selectat articolul Close din meniul din colţul stânga-sus).metodă invocată când fereastra a fost . Superclasă a claselor de butoane şi de articoloe de meniu. Când este apăsat (se pune pe buton cursorul de mouse şi se apasă unul din butoanele de la mouse). butonul generează un eveniment de acţiune.Programarea orientata pe obiecte în limbajul Java Interfaţa WindowListener public interface WindowListener extends EventListener Interfaţă pentru ascultătoarele de evenimente de fereastră. se poate crea o subclasă a clasei WindowAdapter. public void windowIconified(WindowEvent e) iconificată.

setează marginile dintre bordură şi text.setează mnemonica ataşată acestui buton. public void setActionCommand(String actionCommand) comandă generată la apăsarea acestui buton. . Aceasta este o tastă.întoarce marginile dintre bordură şi text. . . public void removeChangeListener(ChangeListener l) evenimente de schimbare specificat.adaugă un ascultător de . dacă ea nu există). Clasa conţine foarte multe metode. a cărei acţionare are acelaşi efect ca acţionarea butonului respectiv.întoarce mnemonica ataşată acestui buton (sau null.indică dacă acest buton sau articol de meniu este selectat.Severin Bumbaru Butonului i se poate ataşa şi o mnemonică.întoarce pictograma implicită conţinută în buton. public void setMargin(Insets m) public Insets getMargin() public Icon getIcon() .elimină ascultătorul de evenimente de schimbare. de exemplu KeyEvent. public String getActionCommand() . . 424 . indicând caracterul desenat pe tasta respectivă (de exemplu 'A').se setează numele acţiunii de public void setIcon(Icon defaultIcon) buton. specificând ca parametru codul tastei respective (codul conţinut în clasa KeyEvent. public void setText(String text) public boolean isSelected() . public int getMnemonic() . .întoarce numele acţiunii de comandă produsă de acest buton.întoarce textul butonului.VK_A ). Constructor public AbstractButton() Metode principale public String getText() . .setează mnemonica ataşată acestui buton. public void setMnemonic(char mnemonic) public void addChangeListener(ChangeListener l) . folosind metoda setMnemonic.setează pentru ascest buton sau articol de meniu public void setSelected(boolean b) starea selectat sau neselectat. public void setMnemonic(int mnemonic) . pentru cunoaşterea cărora recomandăm consultarea documentaţiei Java API.setează textul butonului.setează pictograma implicită conţinută în .

Dimension max) .elimină ascultătorul de evenimente de acţiune. public void removeItemListener(ItemListener l) evenimente de acţiune specificat. Constructor public Box.se creează un BoxFiller. public AccessibleContext getAccessibleContext() 425 .întoarce dimensiunea preferată. public void addItemListener(ItemListener l) . preferată şi maximă). Metode public void changeShape(Dimension min.elimină ascultătorul de de articol.Filler(Dimension min.Programarea orientata pe obiecte în limbajul Java public void addActionListener(ActionListener l) .întoarce contextul accesibil. Dimension max) . . public void setLabel(String label) Clasa Box. public void setEnabled(boolean b) public String getLabel() .intoarce dimensiunea minimă. Dimension pref.setează textul butonului. . preferată şi maximă.adaugă un ascultător de evenimente .se modifică dimensiunile. Este clasă imbricată în clasa Box.Filler public static class Box.întoarce textul de pe buton.adaugă un ascultător de . fiind specificate noile dimensiuni (minimă. public Dimension getPreferredSize() public Dimension getMaximumSize() . fiind specificate dimensiunile minimă. public void removeActionListener(ActionListener l) evenimente de acţiune specificat.întoarce dimensiunea maximă. Dimension pref.face ca butonul să fie sau nu valabil.Filler extends Component implements Accessible O componentă invizibilă. . public Dimension getMinimumSize() . . folosită în instanţele clasei Box pentru distanţarea altor componente.

Când se apasă un buton. un JApplet poate avea bară de meniu. la fel ca la clasa JFrame. Toate butoanele conţinute într-un grup sunt legate logic între ele. Tot ca la JFrame.se adaugă la grup butonul specificat.invocă metoda paint(g). introdusă în Swing. care era apăsat anterior.întoarce o enumeraţie a elementelor grupului. Descrierea tuturor metodelor este dată în Java API. RootPaneContainer Este o versiune extinsă a clasei Applet. Constructor public ButtonGroup() Metode principale public void add(AbstractButton b) .întoarce numărul butoanelor din grup. Explicaţii mai ample se gasesc în secţiunea Writing Applets din Tutorialul Java. Explicatii despre crearea şi utilizarea appleturilor se dau în secţiunea Applet-uri din acest curs.Severin Bumbaru Clasa ButtonGroup public class ButtonGroup extends Object implements Serializable Instanţele clasei ButtonGroup nu sunt componente grafice propriu-zise.se elimină din grup butonul specificat public void remove(AbstractButton b) public Enumeration getElements() public int getButtonCount() . rolul lor fiind de a creea grupuri de butoane. la gruparea butoanelor din clasele JRadioButton şi JRadioButtonMenuItem. Referinţa la acest container se obţine prin metoda getContentPane. de regulă. . la care se adaugă toqate celelalte componente. . se eliberează automat butonul din acelaşi grup.Se foloseşte. public void setJMenuBar(JMenuBar menuBar) 426 . . celelalte fiind în starea "eliberat". la care se adaugă: public void update(Graphics g) . adăugarea de componente nu se face direct la applet. Fiecare instanţă a clasei JApplet conţine un container numit contentPane.setează bara de meniu specificată. Clasa JApplet public class JApplet extends Applet implements Accessible. pusă prin metoda SetJMenuBar(). astfel că numai un singur buton din grup se poate găsi la un moment dat în starea "apăsat". Principala deosebire faţă de clasa Applet este că. Metode frecvent utilizate Toate metodele superclasei Applet.

Pentru a cunoaşte toate metodele.întoarce bara de meniu. Consultaţi şi secţiunea Butonul obişnuit din acest manual. a cărei apăsare are acelaşi efect cu apăsarea butonului respectiv). cu proprietăţile date de acţiunea specificată . public JButton(String text. se va consulta documentaţia Java API.creează un buton. Butonului i se poate ataşa un text volant (ToolTip) şi o mnemonică (o tastă. care conţine pictograma specificată.întoarce containerul contentPane al acestui public Container getContentPane() JApplet.creează un buton. Clasa JButton public class JButton extends AbstractButton implements Accessible Orice instanţă a acestei clase este un buton cu o singură stare stabilă (starea normală). care conţine textul specificat. Butonul poate conţine un text şi/sau o imagine (o pictogramă). care nu conţine text sau pictogramă. Metode Metodele principale sunt cele ale clasei AbstractButton.Programarea orientata pe obiecte în limbajul Java public JMenuBar getJMenuBar() . . Constructori public JButton() . Dacă butonul este apăsat (punând pe el cursorul de mouse şi apăsând butonul mouse-ului).creează un buton.creează un buton. care va conţine textul şui ca parametru. Icon icon) acţiunea specificate. Accessible Este un articol de meniu care se comportă la fel ca o casetă de validare (JCheckBox). dar revine la starea normală imediat ce este eliberat. Are aspectul unui patrat în care apare un simbol de validare (V) dacă este selectat şi nu apare 427 . .creează un buton. . Clasa JCheckBoxMenuItem public class JCheckBoxMenuItem extends JMenuItem implements SwingConstants. el îşi schimbă temporar starea şi aspectul. public JButton(Icon icon) public JButton(String text) public JButton(Action a) .

Caseta de validare poate fi însoţită de un text sau/şi o pictogramă. public JCheckBoxMenuItem(String text) specificat. Orice JComponentă poate avea o bordură. public JCheckBoxMenuItem(Icon icon) pictograma specificată. Icon icon) JChecBoxMenuItem cu textul şi pictograma specificate.construieşte un JChecBoxMenuItem fără pictogramă şi . Aici se dau numai metodele cele mai frecvent folosite. boolean b) Metode principale public boolean getState() .construieşte un JChecBoxMenuItem cu textul .construieşte un text. JApplet). boolean b) . indicând dacă în starea iniţială este sau nu selectat.construieşte un JChecBoxMenuItem cu textul specificat. public void setState(boolean b) .setează starea. indicând dacă în starea iniţială este sau nu selectat. Pentru o documentaţie completă se va consulta Java API. .Severin Bumbaru acest simbol dacă este deselectat. Icon icon. Constructori public JCheckBoxMenuItem() . JDialog. Constructor public JComponent() 428 . adică un text explicativ. Clasa JComponent public abstract class JComponent extends Container implements Serializable Clasa de bază pentru toate componentele Swing. cu excepţia containerelor de cel mai înalt nivel (JFrame.construieşte un JChecBoxMenuItem cu textul şi pictograma specificate. public JCheckBoxMenuItem(String text. public JCheckBoxMenuItem(String text.întoarce starea. Oricărei JComponente i se poate ataşa un "text volant" ("ToolTip").construieşte un JChecBoxMenuItem cu . care apare dacă se pune cursorul de mouse pe componenta respectivă. public JCheckBoxMenuItem(String text. Clasa JComponent conţine numeroase câmpuri şi metode.

public boolean contains(int x. public void setForeground(Color fg) public void setBackground(Color bg) public void setFont(Font font) .setează culoarea de fond a componentei. când se apasă tasta Tab).setează bordura componentei. .setează dacă această componentă este sau nu .întoarce dimensiunea minimă a componentei. .setează dimensiunea minimă a public void setMinimumSize(Dimension minimumSize) componentei. .întoarce dimensiunea maximă a componentei. dimensiunea preferată va fi stabilită implicit. . public boolean isFocusTraversable() public void setToolTipText(String text) . public Dimension getMinimumSize() . int y) public void setBorder(Border border) public Border getBorder() .desenează această componentă. .setează textul volant (ToolTip) pentru această componentă.întoarce bordura componentei. . public void setPreferredSize(Dimension preferredSize) public Dimension getPreferredSize() .setează dacă această componentă poate sau public Graphics getGraphics() public void setVisible(boolean aFlag) vizibilă.setează dimensiunea preferată a componentei. Este utilă la prelucrarea evenimentelor de mouse.întoarce dimensiunea preferată.indică dacă această componentă poate fi traversată la focalizare (este printre cele care sunt focalizate una după alta. . .întoarce contextul grafic al acestei componente.setează fontul componentei.indică dacă această componentă conţine punctul de coordonate (x. . .setează dimensiunea maximă public void setMaximumSize(Dimension maximumSize) a componentei.invocă metoda paint(g) pentru această componentă. Dacă este null. public Dimension getMaximumSize() .setează culoarea de prim-plan a componentei. . public void setEnabled(boolean enabled) nu primi intrări de la utilizator. 429 . y).Programarea orientata pe obiecte în limbajul Java Metode frecvent utilizate public void update(Graphics g) public void paint(Graphics g) . folosind contextul grafic g.

int x. Componentele nu se adaugă direct la fereastra JDialog. 430 .redesenează dreptunghiul r.setează dacă această componentă este sau . Fereastra JDialog poate avea şi bară de meniu. public void paintImmediately(Rectangle r) . Constructori public JDialog() . Clasa JDialog public class JDialog extends Dialog implements WindowConstants. public EventListener[] getListeners(Class listenerType) evenimente ataşaţi acestei componente.indică dacă această componentă este complet opacă.întoarce un şir. int y. Accessible.Severin Bumbaru public String getToolTipText() .întoarce locaţia textului volant componente. .întoarce ascultătorii de public void setOpaque(boolean isOpaque) nu opacă. int w. RootPaneContainer Instanţele acestei clase sunt ferestre de dialog. . public static boolean isLightweightComponent(Component c) public boolean isOpaque() . conţinut în aceasta şi care poate fi obţinut prin metoda getContentPane(). public void repaint(long tm. conţinând parametri utili la depanare. int width.redesenează imediat dreptunghiul specificat.întoarce JRoorpane care este ancestor (ascendent) al acestei componente. int height) - redesenează dreptunghiul specificat. int y. int h) dreptunghiul specificat.redesenează imediat public void paintImmediately(int x.indică dacă această componentă este "uşoară". . dacă nu există. ci la un container numit contentPane.întoarce textul volant (ToolTip) ataşat acestei . public void repaint(Rectangle r) .construieşte o fereastră de dialog fără titlu şi fără a se specifica proprietarul. public Point getToolTipLocation(MouseEvent event) (ToolTip) ataşat acestei componente. sau null. protected String paramString() . după tm milisecunde. public JRootPane getRootPane() . adică nu are ca suport o componentă nativă de pe platforma respectivă.

public JDialog(Dialog owner. sau se selectează opţiunea Close din meniul din colţul din stânga-sus). public void setDefaultCloseOperation(int operation) public int getDefaultCloseOperation() public void update(Graphics g) . String title) .fereastra este ascunsă şi disponibilizată (eliminată).întoarce containerul contentPane al acestei public Container getContentPane() ferestre de dialog. String title. boolean modal) .DO_NOTHING_ON_CLOSE .se construieşte o fereastră de dialog.întoarce bara de meniu.construieşte o fereastră de dialog. titlul şi dacă este sau nu modală. . public JDialog(Dialog owner) .HIDE_ON_CLOSE .fereasrtra este ascunsă (aceasta este opţiunea implicită). . public JDialog(Frame owner. dată ca argument. care areloc când se execută comanda Close (când se apasă butonul de închidere a ferestrei dic bolţul din dreapta sus.întoarce operaţia Close implicită. având ca proprietar altă fereastră de dialog. specificându-se proprietarul şi titlul ferestrei. public JDialog(Frame owner. String title) .Programarea orientata pe obiecte în limbajul Java . specificându-se proprietarul. 431 . dată ca argument şi specificându-se dacă este sau nu modală.setează operaţia implicită.construieşte o fereastră de dialog fără titlu. titlul şi dacă este sau nu modală. având ca proprietar cadrul owner şi indicându-se dacă este sau nu modală. public JDialog(Dialog owner. la care se adaugă: .DISPOSE_ON_CLOSE . WindowConstants.construieşte o fereastră de dialog fără titlu.construieşte o fereastră de dialog.se construieşte o fereastră de dialog.construieşte o fereastră de dialog.nu se face nimic în mod implicit. boolean modal) . având ca proprietar cadrul (Frame) specificat. . având ca proprietar altă fereastră de dialog. public void setJMenuBar(JMenuBar menu) public JMenuBar getJMenuBar() . specificându-se proprietarul şi titlul ferestrei. . public JDialog(Frame owner) public JDialog(Frame owner. String title.construieşte o fereastră de dialog.setează bara de meniu. Operaţia dată ca argument poate fiuna din următoarele: WindowConstants.invocă metoda paint(g). . specificându-se proprietarul. boolean modal) public JDialog(Dialog owner. WindowConstants. boolean modal) Metode principale Metodele clasei Dialog.

setează fişierul selectat. Clasa JEditorPane public class JEditorPane extends JTextComponent Clasă pentru realizarea panourilor de editare care suportă diferite formate de text. Class JFileChooser public class JFileChooser extends JComponent implements Accessible Instanţele clasei JFileChooser sunt selectoare de fişiere. Clasa conţine un număr mare de câmpuri. text HTML sau text RTF. Se recomandă consultarea documentaţiei Java API şi a secţiunii UsingTextComponents din Tutorialul Java. public void setSelectedFile(File file) public File[] getSelectedFiles() .întoarce fişierul selectat. constructori şi metode.construieşte un selector de fişiere cu pointer către directorul specificat prin calea dată ca argument. . Ele vizualizează pe ecran arborele directoarelor şi fişierelor de pe disc şi permit selectarea intercactivă (cu mouse-ul) a fişierului dorit.setează containerul contentPane. 432 . Are subclasa JTextPane.întoarce tabloul fişierelor selectate. Pentru o mai bună documentare se recomandă a se consulta Java API şi capitolul How to use FileChoosers din Tutorialul Java. public JFileChooser() . .Severin Bumbaru public void setContentPane(Container contentPane) . public JFileChooser(String currentDirectoryPath) . public JFileChooser(File currentDirectory) Metode frecvent utilizate public File getSelectedFile() . cum ar fi text simplu.construieşte un selector de fişiere cu pointer către directorul utilizatorului (users home directory). Constructori principali .setează ca selecate fişierele public void setSelectedFiles(File[] selectedFiles) specificate prin tabloul dat ca argument.construieşte un selector de fişiere cu pointer către directorul specificat prin calea dată ca argument.

JFileChooser. setarea gestionarului de poziţionare etc) se fac folosind metodele clasei Container. public void setCurrentDirectory(File dir) public void changeToParentDirectory() . public void removeActionListener(ActionListener l) evenimente de acţiune.asigură că fişierul dat ca argument este acestuia. Operaţiile cu acest contentPane (adăugarea şi eliminarea de componente. în clasa JFrame.trece de la directorul curent la părintele . 433 . O referinţă la contentPane se obţine prin metoda getContentPane(). numit contentPane. public int showSaveDialog(Component parent) throws HeadlessException - creează o fereastră de dialog pentru salvarea fişierului. . RootPaneContainer Este varianta Swing a clasei Frame din AWT.elimină un ascultător de evenimente de acţiune. componentele nu se mai adaugă direct la fereastra (la frame). JFileChooser.Programarea orientata pe obiecte în limbajul Java public File getCurrentDirectory() . In JFrame se poate pune. Fereastra întoarce o valoare corespunzătoare butonului pe care s-a apăsat şi care poate fi una din următoarele: JFileChooser.APPROVE_OPTION. de asemenea. public void addActionListener(ActionListener l) . Accessible. ci la un panou conţinut de aceasta. o bară de meniu. public int showOpenDialog(Component parent) throws HeadlessException creează o fereastră de dialog pentru deschiderea fişierului. fiind o subclasă a acesteia. JFileChooser.întoarce directorul curent.CANCEL_OPTION.adaugă un ascultător de . public ActionListener[] getActionListeners() Clasa JFrame public class JFrame extends Frame implements WindowConstants.CANCEL_OPTION. O deosebire importantă între cele două clase este că.APPROVE_OPTION. .ERROR_OPTION (ultima în caz de eroare). public void ensureFileIsVisible(File f) vizibil (visible) şi nu ascuns (hidden). Fereastra întoarce o valoare corespunzătoare butonului pe care s-a apăsat şi care poate fi una din următoarele: JFileChooser.ERROR_OPTION (ultima în caz de eroare). JFileChooser.setează directorul curent.întoarce tabloul ascultătoarelor de evenimente de acţiune înregistrate la acest JFileChooser.

setează containerul contentPane pentru această fereastră. public JMenuBar getJMenuBar() . Ca argument al metodei se poate da unul din următoarele: WindowConstants. JFrame. iniţial invizibil şi fără titlu.HIDE_ON_CLOSE .întoarce containerul contentPane al acestui JFrame.invocă metoda paint(g).întoarce operaţia de închidere implicită.construieşte un JFrame. iniţial invizibil. 434 . iniţial invizibil.construieşte un JFrame fără titlu. public void setDefaultCloseOperation(int operation) public int getDefaultCloseOperation() public void update(Graphics g) . cu .fereasrtra este ascunsă (aceasta este opţiunea implicită). recomandăm să se studieze capitolul UsingTop-Level Containers din Tutorialul Java. La acest container se adaugă componentele ferestrei.DISPOSE_ON_CLOSE .EXIT_ON_CLOSE .Severin Bumbaru Pentru o mai bună cunoaştere a structurii şi utilizării clasei JFrame.fereastra este ascunsă şi disponibilizată (eliminată).fereastra este închisă şi se incheie executarea aplicaţiei (opţiune permisă numai în aplicaţii. . sau se selectează opţiunea Close din meniul din stîngasus). iniţial invizibil. Metode frecvent utilizate . GraphicsConfiguration gc) cu titlul şi configuraţia grafică specificate.întoarce bara de meniu (sau null. . WindowConstants. cu titlul .DO_NOTHING_ON_CLOSE .nu se face nimic WindowConstants. Constructori public JFrame() . .se setează acţiunea care va fi efectuată. dacă nu există) public Container getContentPane() . public JFrame(String title. nu şi în appleturi).pune în JFrame bara de meniu public void setJMenuBar(JMenuBar menubar) specificată. public void setContentPane(Container contentPane) .construieşte un JFrame. public JFrame(GraphicsConfiguration gc) configuraţia grafică specificată. dacă se solicită operaţia "close" pentru acest JFrame (se apasă cu mouse-ul pe butonul de închidere din dreapta-sus.construieşte un JFrame public JFrame(String title) specificat.

. public int getHorizontalAlignment() . poate fi una public void setIcon(Icon icon) public int getVerticalAlignment() .se construieşte un JLabel. SwingConstants.setează textul.întoarce textul.TOP.CENTER sau SwingConstants.se construieşte un JLabel. public void setText(String text) public Icon getIcon() .se construieşte un JLabel. Constructori public JLabel(String text.construieşte un JLabel. care conţine textul specificat şi respectă alinierea orizontală indicată. int horizontalAlignment) . Accessible Componentă de afişare needitabilă. Al treilea parametru specifică modul în care se face alinierea pe orizontală şi poate fi una din următoarele: SwingConstants.Programarea orientata pe obiecte în limbajul Java Clasa JLabel public class JLabel extends JComponent implements SwingConstants.întoarce alinierea pe orizontală.RIGHT .BOTTOM). care conţine imaginea şi respectă alinierea orizontală date ca argumente. . . care poate să conţină un text şi/sau o imagine (o pictogramă).LEFT . Metode principale public String getText() . . . conţinând textul specificat.construieşte un JLabel care conţine imaginea specificată.întoarce imaginea.setează alinierea pe verticală (vezi mai sus). care conţine textul şi imaginea specificate.setează alinierea pe public void setHorizontalAlignment(int alignment) orizontală.CENTER . .aliniere la dreapta. public void setVerticalAlignment(int alignment) . public JLabel(Icon image. Icon icon. public JLabel(String text. int horizontalAlignment) public JLabel(String text) .întoarce alinierea pe verticală (aceasta din următoarele: SwingConstants. int horizontalAlignment) public JLabel(Icon image) public JLabel() .aliniere la centru SwingConstants. aliniat la stânga.aliniere la stânga SwingConstants.construieşte un JLabel care nu conţine nimic.setează imaginea. 435 .

public JMenuItem add(JMenuItem menuItem) .indică dacă meniul este selectat.CENTER sau SwingConstants. public int getHorizontalTextPosition() .setează dacă acest meniu este sau nu selectat. . Constructori public JMenu() . se pot crea meniuri cu structură ierarhică (arborescentă).LEFT. .setează poziţia pe în verticală a textului. public void setPopupMenuVisible(boolean b) . În acest fel. Întrucât clasa JMenu este o subclasă a JMenuItem.întoarce poziţia pe verticală a textului în raport cu imaginea (aceasta poate fi una din următoarele: SwingConstants. înseamnă că un JMenu poate fi el insuşi un articol al altui menu (un JMenuItem). care conţin articole de meniu. Clasa conţine multe metode. în raport cu imaginea.TOP. . public void setHorizontalTextPosition(int textPosition) . SWingConstants. . adică ferestre verticale.construieşte un meniu cu inscripţia s. Pentru documentare completă se va folosi Java API.BOTTOM).construieşte un meniu fără text.RIGHT).construieşte un meniu cu proprietăţile acţiunii a. SwingConstants. SwingConstants. public JMenu(String s) public JMenu(Action a) Metode frecvent utilizate public boolean isSelected() .setează dacă fereastra cu articole de meniu este sau nu vizibilă. dintre care se dau aici câteva mai frecvent utilizate. public int getVerticalTextPosition() public void setVerticalTextPosition(int textPosition) . 436 .setează poziţia pe orizontală a textului în raport cu imaginea.Severin Bumbaru . MenuElement Instanţele acestei clase sunt meniuri. Clasa JMenu public class JMenu extends JMenuItem implements Accessible.indică dacă fereastra cu articolele de meniu este public void setSelected(boolean b) public boolean isPopupMenuVisible() vizibilă.CENTER.întoarce poziţia pe orizontală a textului raport cu imaginea (aceasta poate fi una din: SwingConstants.adaugă articolul de meniu specificat.

întoarce articolul de pe poziţia pos. Pentru o documentare completă se va consulta Java API. Indicăm aici numai câteva metode mai frecvent utilizate. public JMenuItem getItem(int pos) public int getItemCount() . . public void remove(JMenuItem item) public void remove(int pos) public void removeAll() .elimină ascultătorul de meniu specificat. int pos) de meniu mi. Constructor public JMenuBar() 437 . Pentru a obţine un meniu cu bară.Programarea orientata pe obiecte în limbajul Java public JMenuItem add(String s) public void addSeparator() . Vezi şi explicaţiile din secţiunea Meniuri cu bară a acestui curs. MenuElement Instanţele aceste clase sunt folosite ca bare de meniu. Clasa JMenuBar public class JMenuBar extends JComponent implements Accessible. .elimină toate articolele din acest meniu.întoarce numărul de articole din acest meniu.elimină articolul de meniu specificat.elimină articolul de meniu de pe poziţia pos. la bara de meniu se adaugă diferite meniuri (instanţe ale clasei JMenu).adaugă un separator.adaugă ascultătorul de evenimente de . public void insertSeparator(int index) .înserează un separator pe poziţia de indice dat. public void removeMenuListener(MenuListener l) evenimente de meniu specificat.indică dacă acest meniu este de cel mai înalt nivel. inclusiv . separatorii. public JMenuItem insert(JMenuItem mi. . int pos) meniu cu inscripţia s. adică este ataşat direct la bara de meniu.înserează pe poziţia pos articolul public void insert(String s. public boolean isTopLevelMenu() public void addMenuListener(MenuListener l) . .adaugă un nou articol de meniu cu inscripţia s.înserează pe poziţia pos un nou srticol de . .

setează componenta selectată public void setSelected(Component sel) public boolean isSelected() . . MenuElement Instanţele acestei clase sunt articole de meniu. clasa JMenuItem extinde clasa AbstractButton.setează meniul de ajutor (Help) public void setHelpMenu(JMenu menu) public JMenu getHelpMenu() . Din această cauză. . Icon icon) şi pictograma specificate.indică dacă bara de meniu conţine o componentă selectată.întoarce meniul de ajutor (Help). Un astfel de obiect se comportă la fel ca un buton. public JMenuItem(String text) public JMenuItem(Action a) . public JMenuItem(String text.construieşte un articol de meniu cu pictograma . .construieşte un articol de meniu cu proprietăţile din . Clasa JMenuItem public class JMenuItem extends AbstractButton implements Accessible. JMenu şi JRadioButtonMenuItem.construieşte un articol de meniu cu textul specificat. int mnemonic) textul şi mnemonica specificate. public JMenuItem(String text. Are ca subclase JCheckBoxMenuItem. iar la apăsare generează un eveniment de acţiune). .construieşte un articol de meniu cu textul . public JMenu getMenu(int index) public int getMenuCount() .întoarce numărul de meniuri din această bară.construieşte un articol de meniu fără text sau pictogramă.întoarce meniul cu indicele specificat. Constructori public JMenuItem() . public JMenuItem(Icon icon) specificată. numai că este plasat într-un meniu.se adaugă la această bară un nou meniu.Severin Bumbaru Metode principale public JMenu add(JMenu c) . Metode principale Metodele din clasa AbstractButton. la care se adaugă: 438 . Instanţele acestei clase se comportă ca butoane obişnuite (au o singură stare stabilă.construieşte un articol de meniu cu acţiunea specificată.

întoarce tabloul componentelor submeniului public MenuElement[] getSubElements() acestui articol.adaugă un .setează dacă articolul de meniu este sau nu "armat" )dacă butonul de mouse este eliberat când cursorul este pe acest articol. public void addMenuKeyListener(MenuKeyListener l) . Pentru documentare completă recomandăm să se consulte Java API.întoarce acceleratorul. public void setArmed(boolean b) public boolean isArmed() . public void removeMenuDragMouseListener(MenuDragMouseListener l) ascultătorul de tragere a mouse-ului. 439 .setează combinaţia de taste care generează aceeaşi acţiune ca acest articol de meniu.indică dacă acest articol este "armat". Clasa conţine un mare număr de câmpuri. public void setEnabled(boolean b) . având un format predefinit. public void setAccelerator(KeyStroke keyStroke) public KeyStroke getAccelerator() .elimină ascultătorul de tastă pentru articol de meniu. public Component getComponent() .elimină articol.setează articolul pentru a fi sau nu activ. classa conţine metode satatice pentru realizarea fiecărui tip de fereastră. fără a mai parcurge ierarhia meniului. se va genera evenimentul de acţiune). Recomandăm să se consulte şi capitolul Utilizarea ferestrelor de dialog din acest manual. Class JOptionPane public class JOptionPane extends JComponent implements Accessible Clasa JoptionPane permite să se creeze cu uşurinţă ferestre de dialog frecvent utilizate. .adaugă un ascultător de tastă pentru articolul de meniu. constructori şi metode. public void removeMenuKeyListener(MenuKeyListener l) . public void addMenuDragMouseListener(MenuDragMouseListener l) ascultător de tragere a mouse-lui pentru meniu. În acest scop. . dintre care vom da aici numai câteva metode statice frecvent utilizate.întoarce componenta utilizată pentru a desena acest .Programarea orientata pe obiecte în limbajul Java .

public static int showConfirmDialog(Component parentComponent. specificându-se în plus tipul mesajului. sau JOptionPane. Acest tip poate fi unul din: JOptionPane. Fereastra conţine mesajul specificat.YES_NO_OPTION. Object message. public static String showInputDialog(Object message) public static String showInputDialog(Component parentComponent. JOptionPane. JOPtionPane.ERROR_MESSAGE. sau JOptionPane. care poate fi unul din următoarele: JOptionPane. JOPtionPane. public static int showConfirmDialog(Component parentComponent. int messageType) . int messageType. dar se specifică în plus titlul ferestrei şi tipul mesajului.creează o fereastră de dialog de intrare.se creează o fereastră de dialog de confirmare.WARNING_MESSAGE.similar metodei precedente.YES_NO_CANCEL_OPTION.similar cu metoda precedentă. No şi Cancel. titlul ferestrei şi tipul de opţiune. Tipul mesajului poate fi unul din următoarele: JOptionPane. care conţine mesajul specificat. int optionType. Tipul opţiunii poate fi unul din următoarele: JOptionPane. String title. String title. Această fereastră conţine mesajul "Select an option" şi trei butoane: Yes. int messageType. public static String showInputDialog(Component parentComponent. Fereastra conţine mesajul specificat ca parametru. int messageType) .similar cu metoda precedentă. public static void showMessageDialog(Component parentComponent. int optionType) .Severin Bumbaru Metode frecvent utilizate . urmat de un câmp de text în care utilizatorul poate introduce datele solicitate. având ca părinte componenta specificată prin primul parametru.creează o fereastră de dialog de intrare. String title. JOptionPane.INFORMATION_MESSAGE. Object message. Pe fereastră va apare o pictogramă corespunzătoare tipului de mesaj. fiind specificate: componenta părinte. Icon icon) .PLAIN_MESSAGE.PLAIN_MESSAGE. specificându-se în plus o pictogramă. public static int showConfirmDialog(Component parentComponent.INFORMATION_MESSAGE.WARNING_MESSAGE. JOptionPane.ERROR_MESSAGE.se creează o fereastră de dialog. Object message. Object message. public static void showMessageDialog(Component parentComponent. dar se specifică în plus titlul ferestrei şi tipul mesajului.similar cu metoda precedentă. JOptionPane. FOptionPane. JOptionPane.QUESTION_MESSAGE. plus un câmp de text pentru introducerea şirului de intrare. public static void showMessageDialog(Component parentComponent. String title.ERROR_MESSAGE. int messageType) . sub forma unui şir de caractere. String title.se creează o fereastră de dialog de confirmare. JOptionPane. Object message) .INFORMATION_MESSAGE.PLAIN_MESSAGE.WARNING_MESSAGE. sau JOptionPane. String title. Object message. int optionType. public static int showConfirmDialog(Component parentComponent. Object message. Object message) .QUESTION_MESSAGE.Icon icon) .QUESTION_MESSAGE. sau JOptionPane.similar 440 . mesajul conţinut de fereastră. Object message) .

Metode principale Cele moştenite de la superclase Class JPasswordField public class JPasswordField extends JTextField Instanţele acestei clase sunt câmpuri de text folosite la introducerea parolei.construieşte un JPanel cu gestionarul de poziţionare implicit . Metode principale . public JPasswordField(int columns) specificată.construieşte un JPanel cu gestionarul de (FlowLayout). Se deosebesc de JTextField prin faptul că parola introdusă în câmp de la tastatură nu este vizibilă pe ecran. care apar pe ecran ca nişte suprafeţe dreptunghiulare. Constructori principali public JPanel() .Programarea orientata pe obiecte în limbajul Java cu metoda de mai sus.construieşte un câmp de text. pe care se pot plasa diferite componente. Caracterul de înlocuire implicit este '*'.construieşte un câmp de parolă cu lungimea . public void setEchoChar(char c) 441 . panourile din această clasă pot avea şi bordură.construieşte un câmp de parolă fără text şi cu lungimea 0 . public JPasswordField(String text. coloane. Instanţele acestei clase sunt containere. int columns) specificându-se textul conţinut şi lungimea câmpului. aranjate cu ajutorul unui gestionar de poziţionare. public JPanel(LayoutManager layout) poziţionare specificat. fiind substituită printr-un şir de caractere de înlocuire.se setează caracterul de ecou (care va înlocui în câmpul de pe ecran caracterele efective ale parolei). Având în vedere că clasa JPanel extinde clasa JComponent. Constructori public JPasswordField() . Clasa JPanel public class JPanel extends JComponent implements Accessible Clasa JPanel din Swing are un rol similar cu clasa Panel din AWT. specificându-se în plus o pictogramă.

Pe ecran. Metode frecvent utilizate public void setOrientation(int newOrientation) JProgressBar.. public JProgressBar(int orient) . care poate fi .întoarce un tablou de caractere. Bara poate fi orientată orizontal sau vertical.creează o bară de progres orientată orizontal.Severin Bumbaru public char getEchoChar() . Accessible Instanţele acestei clase sunt bare de progres. public JProgressBar(int orient. Intervalul de variaţie este 0 .seteazo orientarea. public JProgressBar(int min. int max) orientarea şi intervalul de variaţie specificate. variaţie 0 .VERTICAL sau JProgressBar. 442 .00.HORIZONTAL.00 . Clasa JProgressBar public class JProgressBar extends JComponent implements SwingConstants.creează o bară de progres cu cu intervalul de variaţie specificat. public void setBorderPainted(boolean b) Implicit este true. public int getOrientation() . int max) .creează o bară de progres cu care poate fi JProgressBar. folosite în special gradul de realizare a unui eveniment în curs de desfăşurare. cu intervalul de orientarea specificată. public double getPercentComplete() număr real în intervalul 0.creează o bară de progres orientată orizontal.. 1.adaugă un ascultător de public void addChangeListener(ChangeListener l) evenimente de schimbare.setează dacă bara are sau nu bordură. .HORIZONTAL. apare ca o bară a cărei lungime este proporţională cu un număr întreg. public char[] getPassword() . 100. int min. Constructori public JProgressBar() . 100. într-un interval de variaţie dat. sub forma unui .întoarce gradul de progresare. . . public boolean isBorderPainted() .indică dacă bara are sau nu bordură. Implicit este '*'..VERTICAL sau JProgressBar.întoarce caracterul de ecou (de înlocuire pe ecran a caracterelor parolei).întoarce orientarea. care conţine parola.

public JRadioButtonMenuItem(String text. un singur buton din grup se găseşte în starea selectat. public JRadioButtonMenuItem(String text) cu textul specificat.elimină un ascultător de evenimente de schimbare. public int getValue() .construieşte un JRadioButtonMenuItem cu textul specificat.construieşte un JRadioButtonMenuItem cu . public JRadioButtonMenuItem(String text.setează valoarea (un număr întreg.setează valoarea maximă (marginea superioară a public int getMinimum() public int getMaximum() public void setValue(int n) variaţie impus). . la un moment dat.întoarce valoarea maximă (marginea superioară a intervalului). public JRadioButtonMenuItem(Icon icon.setează valoarea minimă (marginea inferioară a . Icon icon) JRadioButtonMenuItem cu textul şi pictograma specificate. public void setMinimum(int n) intervalului).construieşte un JRadioButtonMenuItem fără text şi fără . boolean selected) . indicând dacă este sau nu selectat.întoarce valoarea indicată de bară. public JRadioButtonMenuItem(Icon icon) pictograma specificată. Clasa JRadioButtonMenuItem public class JRadioButtonMenuItem extends JMenuItem implements Accessible Articol de meniu care se comportă ca un buton radio (JRadioButton). public void setMaximum(int n) intervalului). indicând dacă este sau nu selectat. Mai multe butoane radio pot fi grupate folosind un ButtonGroup.construieşte un pictogramă. astfel încât.întoarce valoarea minimă (marginea inferioară a intervalului). . Este un buton cu două stări stabile (selectat şi deselectat). . boolean selected) 443 . Constructori public JRadioButtonMenuItem() .construieşte un JRadioButtonMenuItem . .Programarea orientata pe obiecte în limbajul Java public void removeChangeListener(ChangeListener l) . cuprins în intervalul de .construieşte un JRadioButtonMenuItem cu pictograma specificată.

.awt. Orientarea poate fi una din valorile HORIZONTAL şi VERTICAL definite în interfaţa Adjustable din pachetul java. care pot fi orientate orizontal sau vertical. public void setOrientation(int orientation) public int getValue() . valoarea. public void setMaximum(int maximum) public boolean getValueIsAdjusting() 444 . . int value. public void setMinimum(int minimum) public int getMaximum() .se creează o bară de defilare verticală. Accessible Instanţele acestei clase sunt bare de defilare. int extent.întoarce valoarea maximă. 100. intervalul 0 .creează o bară de defilare. public void setValue(int value) public int getMinimum() . Icon icon. intervalul 0 . indicând dscă este sau nu selectat. valoarea la care exte poziţionat cursorul şi extensia. extensia. . . Constructori public JScrollBar(int orientation.setează valoarea maximă. valoarea 0 şi extensia 100. fiind specifiacte orientarea. int min. .setează valoarea minimă.întoarce valoarea indicată de bara de defilare. . public JScrollBar(int orientation) public JScrollBar() .se creează o bară de defilare cu orientarea specificată.Severin Bumbaru public JRadioButtonMenuItem(String text. int max) .întoarce orientarea.întoarce valoarea minimă. 100. Se stabilesc orientarea. Clasa JScrollBar public class JScrollBar extends JComponent implements Adjustable. valorile minimă şi maximă. boolean selected) construieşte un JRadioButtonMenuItem cu textul şi pictograma specificate..setează orientarea. valoarea 0 şi extensia 100. Metode Cele din superclase. . Metode frecvent utilizate public int getOrientation() . valoarea minimă şi valoarea maximă.setează valoarea indicată de bara de defilare.indică dacă cursorul poate fi tras cu mause-ul.

iar barele de defilare apar numai când sunt necesare (când componenta este mai mare decât partea vizibilă). int vsbPolicy.bara apare numai dacă este necesară. Constructori public JScrollPane(Component view.face ca poziţia cursorului să poată sau nu fi schimbată. Clasa JScrollPane public class JScrollPane extends JComponent implements ScrollPaneConstants. public void removeAdjustmentListener(AdjustmentListener l) ascultător de evenimente de ajustare. în JScrollPane se poate pune orice altă componentă Swing.VERTICAL_SCROLLBAR_AS_NEEDED .VERTICAL_SCROLLBAR_NEVER . JScrollPane. public void addAdjustmentListener(AdjustmentListener l) de evenimente de ajustare. public JScrollPane(Component view) 445 . JScrollPane.VERTICAL_SCROLLBAR_ALWAYS .bara apare numai dacă este necesară. . Dacă dorim să-i punem bare de defilare. un astfel de JPanel se pune ca singură componentă într-un JScrollPane.elimină un fie tras cu mouse-ul.se construieşte un JScrollPane.pentru bara de defilare orizontală: JScrollPane.adaugă un ascultător . Accessible Instanţele acestei clase sunt panouri cu bare de defilare orizontală şi/sau verticală. Pentro o documentare completă se recomandă consultarea documentatiei Java API. În Swing.bara nu apare niciodată.HORIZONTAL_SCROLLBAR_ALWAYS . Se pot adopta diferite "politici" privind modul de comportare al celor bare de defilare: . JScrollPane. JScrollPane.Programarea orientata pe obiecte în limbajul Java public void setValueIsAdjusting(boolean b) .se construieşte un JScrollPane care conţine componenta specificată.setează dacă cursorul poate sau nu să .bara nu apare niciodată. .HORIZONTAL_SCROLLBAR_NEVER .HORIZONTAL_SCROLLBAR_AS_NEEDED .pentru bara de defilare verticală: JScrollPane. public void setEnabled(boolean x) . unde se cer "politicile" adoptate pentru comportamentul barelor de defilare. dar una singură. In loc de un panou. fiind specificate componenta pe care o vizualizează şi politicile adoptate pentru comportările barelor de defilare verticală şi orizontală. instanţele clasei JPanel nu au bare de defilare.bara apare întotdeauna.bara apare întotdeauna. int hsbPolicy) . Aceste constante se folosesc ca parametri în constructori şi metode.

.constuieşte un JScrollPane.construieşte un separator orizontal. pentru a grupa articolele de meniu în grupuri logice. public JSeparator(int orientation) Metode principale public int getOrientation() .întoarce bordura yonei vizibile. Constructori public JSeparator() . 446 . În loc de a folosi în mod explicit această clasă. public void setVerticalScrollBarPolicy(int policy) de defilare verticală. public JScrollPane() Metode frecvent utilizate public int getVerticalScrollBarPolicy() .construieşte un separator. specificând orientarea acestuia.HORIZONTAL sau SwingConstants. public void setHorizontalScrollBarPolicy(int policy) bara de defilare orizontală. public int getHorizontalScrollBarPolicy() . public JScrollPane(int vsbPolicy. la care barele de defilare orizontală şi verticală apar numai când sunt necesare. public Border getViewportBorder() . .setează orientarea separatorului public void setOrientation(int orientation) (orizontală sau verticală).întoarce politica pentru bara de defilare .setează politica pentru bara verticală. se pot utiliza metodele addSeparator(). Accessible Instanţele acestei clase sunt separatori folosiţi în meniuri.VERTICAL.Severin Bumbaru .construieşte un JScrollPane. specificând politicile pentru barele de defilare verticală şi orizontală.întoarce politica pentru bara de defilare . int hsbPolicy) .întoarce orientarea separatorului.setează politica pentru orizontală. care poate fi una din următoarele: SwingConstants. .setează bordura zonei public void setViewportBorder(Border viewportBorder) vizibile. Class JSeparator public class JSeparator extends JComponent implements SwingConstants. existente în clasele JMenu şi JPopupMenu.

se construieşte un JSplitPane. continuitatea în zona de scindare şi cele două componente conţinute. public JSplitPane(int newOrientation) . public int getDividerSize() . Component newRightComponent) . Clasa conţine un număr mare de câmpuri. 447 .întoarce componenta din stânga (sau de sus).creează un nou JSplitPane. public void setLeftComponent(Component comp) de sus). Scindarea se poate face vertical sau orizontal.setează componenta din stânga (sau (exprimată în pixeli). Component newRightComponent) . public JSplitPane(int newOrientation. Component newLeftComponent. în care cele două componente sunt puse una lângă alta. exprimată în pixeli. indicându-se orientarea scindării. public JSplitPane(int newOrientation.setează componenta de sus (sau din public void setTopComponent(Component comp) stânga). Pentru documentare completă recomandăm să se consulte Java API. fiind specificate orientarea scindării. public Component getLeftComponent() . Orientarea scindării este specificată prin una constantele JSplitPane. boolean newContinuousLayout.HORIZONTAL_SPLIT sau JSplitPane. constructori şi metode.creează un JSplitPane. Metode frecvent utilizate public void setDividerSize(int newSize) .setează lăţimea divizorului dintre cele două zone. public JSplitPane(int newOrientation.creează un JSplitPane.VERTICAL_SPLIT . indicându-se specificarea şi cele două componente conţinute.se creează un JSplitPane.întoarce lăţimea divizorului dintre cele două zone . Component newLeftComponent. fiecare din aceste zone conţinând câte o singură componentă.Programarea orientata pe obiecte în limbajul Java Clasa JSplitPane public class JSplitPane extends JComponent implements Accessible Instenţele clasei JSplitPane sunt panouri scindate în două zone. orizontal. fiind specificate orientarea şi dacă aspectul este sau nu continuu (dacă este sau nu vizibil locul de îmbinare). . boolean newContinuousLayout) . Constructori public JSplitPane() .

Amplasarea "călăreţilor" (tabLayoutPlacement) poate fi sus. care conţine fişe plasate una în spatele celeilalte.întoarce componenta de jos (sau din dreapta). Clasa JTabbedPane public class JTabbedPane extends JComponent implements Serializable. 448 . JTabbedPane.Severin Bumbaru public Component getTopComponent() . stânga sau dreapta şi se indică prin constantele: JTabbedPane. JTabbedPane. jos. . SwingConstants Fiecare instanţă a clasei JTabbedPane realizează metaforic un "clasor".BOTTOM. . de asemenea. public int getOrientation() . public Component getRightComponent() .setează componenta de jos (sau public void setBottomComponent(Component comp) din dreapta).TOP.indică dacă în zona de scindare există sau nu continuitate.setează orientarea. Modul de prezentare a călăreţilor (layoutPolicy) poate fi unul din: JTabbedPane. public void setContinuousLayout(boolean newContinuousLayout) .WRAP_TAB_LAYOUT (toţi "călăreţii" sunt vizibili) or JTabbedPane. public void setOrientation(int orientation) . fişa respectivă iese deasupra celorlalte.setează continuitatea în zona de scindare.SCROLL_TAB_LAYOUT ("călăreţii" defilează). La apăsarea acestui "călăreţ".întoarce componenta din dreapta (sau de jos). public Component getBottomComponent() .setează componenta dein dreapta public void setRightComponent(Component comp) (sau de jos).LEFT sau JTabbedPane.întoarce orientarea.întoarce componenta de sus (sau din stânga). Fiecare astfel de "fişă" este o componentă a panoului şi are plasat pe ea un "călăreţ" (tab) care seamănă cu un buton. public boolean isContinuousLayout() .RIGHT. Accessible. Clasa conţine numeroase câmpuri şi metode. astfel că pentru o mai bună documentare se recomandă consultarea documentaţiei Java API. Este utilă. consultarea capitolului How to Use Tabbed Panes din Tutorialul Java.

setează componenta selectată. Icon icon. Component component. public void addTab(String title.WRAP_TAB_LAYOUT) la partea superioară. 449 .setează indicele subpanoului selectat.ca şi metoda precedentă. textul volant şi indicele. public void addTab(String title. Component component.întoarce indicele subpanoului selectat.setează politica de public void setTabLayoutPolicy(int tabLayoutPolicy) vizibilitate a "călăreţilor".construieşte un JTabbedPane cu (JTabbedPane. componenta.întoarce componenta selectată.Programarea orientata pe obiecte în limbajul Java Constructori public JTabbedPane() . pictograma. . . int tabLayoutPolicy) Metode frecvent utilizate public void addChangeListener(ChangeListener l) . int index) . fiind specificate atât amplasarea. . pictograma. public ChangeListener[] getChangeListeners() .se construieşte un JTabbedPane. specificându-se titlul.construieşte un JTabbedPane. componenta şi textul volant. public void removeChangeListener(ChangeListener l) evenimente de schimbare. public JTabbedPane(int tabPlacement.elimină un ascultător de evenimente de schimbare.setează amplasarea "călăreţilor". public void setSelectedIndex(int index) public Component getSelectedComponent() public void setSelectedComponent(Component c) public void insertTab(String title. public int getSelectedIndex() . Icon icon.adaugă un ascultător de .elimină un ascultător de evenimente de schimbare. cât şi politica de vizibilitate a "călăreţilor". Icon icon. String tip) .întoarce politica de vizibilitate a "călăreţilor". . . Component component) . String tip.întoarce amplasarea "călăreţilor". respectând amplasarea specificată a "călăreţilor". specificându-se: titlul. dar fără text volant.se înserează un "călăreţ". public void setTabPlacement(int tabPlacement) public int getTabLayoutPolicy() . "călăreţii" plasaţi vizibil public JTabbedPane(int tabPlacement) . public int getTabPlacement() .se adaugă un "călăreţ" (după cele deja existente). împreună cu subpanoul corespunzător. .

elimină toţi "călăreţii". . public int getTabCount() public String getTitleAt(int index) public Icon getIconAt(int index) .întoarce numărul de "călăreţi".întoarce titlul de la indicele specificat.Severin Bumbaru public void addTab(String title. public void removeTabAt(int index) .se elimină "călăreţul" de indice specificat. public void removeAll() . public Component getComponentAt(int index) . ListSelectionListener. 450 . Accessible Clasa JTable permite crearea de componente sub formă de tabele bidimensionale editabile. Se recomandă consultarea documentaţiei Java API şi a secţiunii UsingTextComponents din Tutorialul Java.întoarce componenta de la indicele specificat. Scrollable. împreună cu subpanoul respectiv.întoarce pictograma de la indicele specificat. . . Pentru utilizarea acestei clase se recomandă consultarea documentaţiei Java API şi a capitolului How to Use Tables din Tutorialul Java.întoarce textul volant de la indicele public String getToolTipTextAt(int index) specificat. TableColumnModelListener. dar fără pictogramă.ca şi metoda precedentă. Clasă pentru realizarea panourilor de editare care permit să se folosească stiluri diferite pentru fiecare paragraf. Component component) . CellEditorListener. JTextPane public class JTextPane extends JEditorPane Subclasă a clasei JEditorPane. Clasa JTable public class JTable extends JComponent implements TableModelListener.

butonul respectiv trece. public JToggleButton(String text. Clasa JWindow public class JWindow extends Window implements Accessible. validat) şi starea eliberat (neselectat.creează un buton. . 451 .creează un buton. iar starea iniţială este dată de al treilea parametru. RootPaneContainer Instanţele clasei JWindow sunt ferestre fără bară de titlu. La fiecare acţionare cu mouse-ul asupra unei instanţe a clasei JToggleBox sau a subclaselor sale. închis. Adăugarea componentelor nu se face direct la fereastră. public JToggleButton(Icon icon. public JToggleButton(String text. iar starea iniţială este cea indicată de al treilea parametru. boolean selected) public JToggleButton(String text) .creează un buton cu textul specificat. Dacă nu se specifică altfel. starea iniţială implicită este "eliberat".creează un buton cu textul specificat. în cealaltă stare. Pentru o documentare completă se va consulta Java API.creează un buton cu pictograma specificată ca public JToggleButton(Icon icon) parametru. la care starea iniţială este indicată de al treilea parametru. Are ca subclase JCheckBox şi JRadioButton.creează un buton. Constructori public JToggleButton() . boolean selected) Metode principale Metodele principale sunt cele din clasa AbstractButton. care pot fi plasate oriunde pe ecran (sunt ferestre de cel mai înalt nivel). Icon icon.creează un buton fără text sai pictogramă. care conţine pictograma specificată. dar fără text.Programarea orientata pe obiecte în limbajul Java Clasa JToggleButton public class JToggleButton extends AbstractButton implements Accessible Este clasa generică pentru butoane cu două stări stabile: starea acţionat (selectat. care poate fi obţinut prin metoda getContentPane(). nevalidat). . nu conţine text. . boolean selected) public JToggleButton(Action a) . . ci la un container conţinut în aceasta numit contentPane. cu proprietăţile din acţiunea specificată. din starea în care se gaseşte. deschis. care are textul şi pictograma specificate.

având proprietarul owner şi configuraţia grafică gc. Clasa ListDataEvent public class ListDataEvent extends EventObject Eveniment care indică apariţia unor modificări într-o listă.s-au adăugat la listă unul sau mai multe articole 452 .setează panoul contentPane.awt. public JWindow(Window owner. fiind specificată sursa acestuia.construieşte o fereastră fără un proprietar specificat. componentele ferestrei. având ca proprietar cadrul . având ca proprietar fereastra specificat ca argument.se creează un ChangeEvent.construieşte o fereastră. GraphicsConfiguration gc) .CONTENTS_CHANGED .construieşte o fereastră. . public JWindow(Frame owner) . Constructor public ChangeEvent(Object source) . public JWindow(Window owner) specificată ca argument.INTERVAL_ADDED .construieşte o fereastră cu configuraţia public JWindow(GraphicsConfiguration gc) grafică specificată. Tipul evenimentului are valoarea unuia din următoare câmpuri statice finale: ListDataEvent.s-a modificat conţinutul listei. public void setContentPane(Container contentPane) Clasa ChangeEvent public class ChangeEvent extends EventObject Evenimentele din această clasă semnalează schimbarea stării componentei sursă.întoarce containerul la care se adaugă . ListDataEvent. Metode principale Metodele clasei Window din pachetul java.Severin Bumbaru Constructori public JWindow() . la care se adaugă: public Container getContentPane() . Ele sunt ascultate cu un ChangeListener.construieşte o fereastră.

INTERVAL_REMOVED . Clasa MenuEvent public class MenuEvent extends EventObject 453 .întoarce tipul evenimentului.întoarce indicele ultimului articol al intervalului în care s-a produs modificarea Clasa ListSelectionEvent public class ListSelectionEvent extends EventObject Eveniment care indică modificarea selecţiei dintr-o listă.întoarce indicele primului articol din intervalul selectat. fiind specificate: sursa evenimentului.indică dacă acest eveniment face parte dintr-o public boolean getValueIsAdjusting() serie de evenimente care au loc rapid.Programarea orientata pe obiecte în limbajul Java care sunt situate unul după altul ListDataEvent. Constructor public ListSelectionEvent(Object source. indicii inceputului şi sfârşitului intervalului şi dacă acest eveniment este sau nu unul dintr-o serie rapidă de evenimente. Metode public int getFirstIndex() public int getLastIndex() . Constructor public ListDataEvent(Object source.întoarce indicele primului articol al intervalului în care s-a produs modificarea public int getIndex1() . .se creează un ListDataEvent fiind specificate: obiectul sursă. int lastIndex. tipul evenimentului (unul din cele menţionate mai sus). int firstIndex.întoarce indicele ultimului articol din intervalul selectat. boolean isAdjusting) . int index1) . public int getIndex0() . indicii marginilor intervalului de articole în care s-a produs modificarea. int index0. . Metode public int getType() . int type.s-au eliminat din listă unul sau mai multe articole situate unul după altul. Se consideră că schimbarea selecţiei este limitată la un interval de articole.creează un ListSelectionEvent.

Severin Bumbaru Evenimentele din această clasă se produc atunci când a avut loc o modificare într-un meniu: obiectul sursă a fost pus. specificându-se sursa evenimentului. în care rafinează numai acele metode. folosită ca prototip pentru clasele ascultătoare de evenimente de mouse.creează un PopupMenuEvent. Clasa PopupMenuEvent public class PopupMenuEvent extends EventObject Evenimente generate de meniurile derulante (pop-up). dar aceste metode nu fac nimic (au corpul vid). specificându-se sursa. 454 . Programatorul poate crea clase derivate. selectat sau eliminat. Constructor public MenuEvent(Object source) . Constructor public PopupMenuEvent(Object source) . Interfaţa ChangeListener public interface ChangeListener extends EventListener Interfaţă pentru clasele de ascultători de evenimente de schimbare a stării. care sunt efectiv necesare în aplicaţia respectivă.creează un eveniment de meniu. Clasa MouseInputAdapter public abstract class MouseInputAdapter extends Object implements MouseInputListener Clasă abstractă. Constructor public MouseInputAdapter() Metode Metodele interfeţei MouseInputListener. Clasa conţine toate metodele interfeţei MouseInputListener.

invocată când a avut loc o eliminare sau înserare de articole în listă public void intervalRemoved(ListDataEvent e) de articole din listă public void contentsChanged(ListDataEvent e) . Metode public void menuSelected(MenuEvent e) .invocată când s-a modificat selecţia dintr-o listă Interfaţa MenuListener public interface MenuListener extends EventListener Interfaţă pentru ascultătoarele de evenimente de meniu. 455 .invocată când a avut loc o schimbare de stare Interfaţa ListDataListener public interface ListDataListener extends EventListener Interfaţă pentru ascultătoarele de evenimente de modificare a conţinutului unei liste.Programarea orientata pe obiecte în limbajul Java Metodă public void stateChanged(ChangeEvent e) . Metode public void intervalAdded(ListDataEvent e) .invocată când a avut loc o modificare în listă mai complexă decât cele două precedente.invocată când a avut loc o adăugare .invocată când meniul este selectat. De exemplu. când a fost înlocuit un articol. Interfaţa ListSelectionListener public interface ListSelectionListener extends EventListener Interfaţă pentru ascultătoarele de evenimente de selecţie în liste Metodă public void valueChanged(ListSelectionEvent e) .

metodă invocată când este eliberat unul mouse. care cumulează metodele celor două interfeţe pe care le extinde: MouseListener şi MouseMotionListener. Interfaţa PopupMenuListener public interface PopupMenuListener extends EventListener Interfaţă pentru ascultătoarele de evenimente generate de meniurile derulante (pop-up). public void mouseDragged(MouseEvent e) menţinând unul din butoane apăsat).m