..
. Totusi, folosirea marcajului de sfârşit de paragraf nu este obligatorie. Atunci când documentul este vizualizat în browser, fiecare paragraf începe de la capăt de linie. În interiorul paragrafului, trecerea la linie nouă se face automat, când se ajunge la marginea din dreapta a paginii. Se poate, totuşi, forţa trecerea la linie nouă prin marcajul se pot introduce şi indicaţii privind culoarea de fond, culoarea caracterelor şi forma caracterelor din paragraful respectiv. Aceste indicaţii se dau prin parametri de forma nume=valoare. Culoarea caracterelor se indică prin parametrul color=culoare, unde culoare poate fi: black (negru), gray (gri), silver (argintiu), white (alb), red (rosu), green (verde), blue (albastru), yellow (galben), lime (verde deschis), aqua (albastru deschis), fuchsia (roz), purple (purpuriu), maroon (maron), olive (oliv), navy (bleu marin), teal (verde inchis). Remarcăm că sunt alte nume de culori decât cele din clasa java.awt.Color. Culoarea fondului se indică prin parametrul bgcolor=culoare, unde numele culorilor sunt aceleaşi ca pentru caractere. Forma caracterelor cu care este scris paragraful este indicată prin parametrul face=forma. În funcţie de platformă, se pot folosi diferite forme de caractere. Există, totuşi, trei forme care sunt disponibile pe orice platformă: Serif, sansSerif si Monospace. Primele două au caractere de lăţime variabilă (de exemplu, m este mai lat decat i), iar ultimul are toate caracterele de aceeasi lăţime (exemplu: în cuvantul lăţime, scris cu astfel de caractere, m şi i au aceeaşi lăţime). Deosebirea între Serif şi SansSerif este prezentă, respectiv absenţa serifurilor. Acestea sunt liniuţele mici care delimitează unele linii ale literelor, 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. Termenul este preluat din tipografie şi se referă la reprezentarea formei şi mărimii unui caracter. S-a menţionat mai sus cum pot fi indicate forma şi culoarea caracterelor dintr-un paragraf ca parametri în marcajul
. Exista însă şi situaţii în care un anumit font se foloseşte numai într-o porţiune de paragraf, sau se extinde pe mai multe paragrafe. În acest scop, se foloseşte marcajul text. Parametrii din marcajul sunt face=formă, color=culoare şi size=mărime. Forma şi culoarea se indică în acelaşi mod ca în marcajul . Mărimea este un număr întreg cu sau 294 "+ "Revenire la text normal
Programarea orientata pe obiecte în limbajul Java fără semn. Dacă se foloseşte un număr întreg fără semn, acesta indică mărimea absolută a fontului. Mărimea indicată ca numar intreg cu semn în intervalul [-3, +3] arată mărimea relativă, faţă de cea pentru care este setat browserul utilizat. Aşa dar, de exemplu, parametrii size=3 si size=+3 indică fonturi de mărimi diferite. Exemplu Textul HTML următor: proba de text
va apare scris pe ecran sub forma
proba de text Nu este obligatoriu să se indice toţi cei trei parametri. Se folosesc numai cei prin care noul font diferă de cel anterior.
Indicarea stilului În afară de forma, marimea şi culoarea fontului, textul se caracterizează şi prin stil: păstrând forma fontului, textul poate să apară îngroşat, cursiv, subliniat etc. În HTML, stilul textului se indică prin marcaje speciale: ... pentru text aldin, îngrosat (engleză: bold); ... pentru text cursiv (engleză: italic); ... pentru text subliniat (engleză: underline); ... pentru text tăiat cu o linie (engleză: strikethrough); ... text scris mai mic şi mai jos decât textul de bază (engleză: subscript); ... text scris mai mic şi mai sus decât cel de bază (engleză: superscript). Aceste stiluri pot fi şi combinate. De exemplu, textul HTML text aldin, cursiv şi subliniat
apare pe ecran sub forma: text aldin, cursiv şi subliniat
Marcarea titlurilor şi subtitlurilor Titlurile diferitelor secţiuni ale textului (capitole, 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, cât şi prin cel de dedesubt. Pentru marcarea titlurilor se foloseşte marcajul Primul titlu>
Al doilea titlu
Al treilea titlu
apare pe ecran sub forma
Primul titlu Al doilea titlu Al treilea titlu Se poate astfel continua până la marcajul .
295
Severin Bumbaru
Text preformatat S-a arătat mai sus că aşezarea textului în pagină se face de către browser, respectând marcajele de formatare din textul HTML. În consecinţă, dacă se modifică dimensiunile ferestrei, se modifica şi aşezarea în pagină a textului. Spaţiile şi caracterele speciale din textul HTML, 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. Există, totuşi un marcaj care impune ca textul sa fie aşezat pe ecran aşa cum este el în pagina HTML. Acest marcaj este text preformatat
. De exemplu, textul un exemplu de text preformatat scris pe trei linii
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, care sunt taguri de forma: text de legătură Parametrul HREF (Hypertext Reference) reprezintă indicarea locului în care poate fi găsit documentul către care se face trimiterea (referinţa la document). Această referinţă nu este vizibilă în fereastra de browser în care este afişat documentul. În schimb, este vizibil textul de legătură, sub forma unui text subliniat şi având o culoare diferită de a restului documentului. Referinţa la document depinde de locul în care acesta se găseşte. a/ Documentul ţintă se găseşte pe acelasi calculator. În acest caz, referinţa poate fi: a1/ Referinţa absolută, de forma: cale/document unde cale (engleza: path) este succesiunea de directoare parcurse de la rădăcina arborelui de directoare, până la directorul în care se găseşte fişierul care conţine documentul; pentru separarea directoarelor se foloseşte bara (slash, /), conform convenţiei din sistemul de operare Unix. De exemplu: "C:/d1/d2/d3/docum.html"
este o referinţă la documentul docum.html, care se găseşte pe discul C, urmând calea d1/d2/d3/ unde d1, d2 si d3 sunt directoare. Dacă documentul ţintă se găseşte pe acelaşi disc cu documentul în care apare această referinţă, discul poate fi omis, punând referinţa sub forma "/d1/d2/d3/docum.html"
dar având grijă să înceapă cu "/", ceeace înseamnă că se porneşte de la rădăcină, deci este o referinţă absolută. a2/ Referinţa relativă, în care calea se trasează pornind de la directorul în care se găseşte documentul sursă.La indicarea căii, simbolul .. (doua puncte succesive) înseamnă deplasare cu un director înapoi, iar / înseamna deplasare cu un director înainte. De exemplu, referinţa: "../../d2/d3/docum.html"
are semnificaţia următoare: pornind de la directorul în care se găseşte documentul sursă, ne deplasăm două directoare "înapoi" către rădacină, după care parcurgem "înainte" calea d2/d3 şi ajungem la documentul docum.html. b/ Documentul ţintă se găseşte pe un alt calculator. În acest caz, referinţa la document este
296
Programarea orientata pe obiecte în limbajul Java un URL (engleză: Uniform Resource Locator), care este modul de adresare caracteristic pentru WWW. Iată exemple de URL-uri: "http://www.w3.org/default.html" "http://java.sun.com/docs/books/jls/html/index.html" "http://lib.cs.ugal.ro/~sbumbaru/CursJava/Sapt01/poo.html"
Prima parte a URL-ului (în cazul de faţă http:) reprezintă protocolul de transmisie folosit. Cele două bare (//) indică modul de acces (în cazul de faţă - adresa pe Internet a unui calculator, de exemplu java.sun.com). Urmeaza calea absolută parcursă pe calculatorul respectiv (de exemplu /docs/books/jls/html/) şi numele documentului (index.html).
Modul de adresare pe Internet este, în principiu, următorul: Internetul este împărţit în domenii, care pot fi domenii naţionale (de exemplu: ro - Romania, fr - Franta, uk - Marea Britanie, de - Germania etc) sau domenii profesionale (com - comercial, edu - educaţional, org - organizaţii, net - retele). Fiecare domeniu este imparţit în subdomenii (de ex.: în domeniul ro există subdomeniul ugal - Universitatea din Galati, iar în domeniul com există subdomeniul sun - firma Sun Microsystems). Subdomeniile pot fi împărţite în subsubdomenii s.a.m.d până se ajunge la calculatoare individuale. De exemplu, locaţia atlas.stud.ugal.ro înseamnă calculatorul atlas din subreţeaua stud, din subdomeniul ugal al domeniului ro.
Marcajul APPLET Pentru a introduce într-un document HTML o referinţă la un applet, se foloseşte marcajul (tagul) APPLET, care are forma următoare: în care: fişier_class - fişierul cu extensia .class, în care se află bytecode-ul appletului (indicarea extensiei nu este obligatorie), de exemplu: CODE=TestFlowAp.class sau CODE=TestFlowAp localizare - referinţa la directorul în care se găseşte bytecode-ul appletului; această referinţă poate fi absolută, relativă sau sub forma de URL, la fel ca în cazul legăturilor către alte documente, cu observaţia că nu se mai termină prin numele documentului ţintă, acesta fiind cel din parametrul CODE; dacă fişierul bytecode al appletului se găseşte în acelaşi director cu fişierul HTML în care acesta este invocat, parametrul CODEBASE lipseşte; lăţime si înălţime - numere întregi, reprezentând lăţimea şi înălţimea appletului; aliniere - alinierea appletului în pagina de browser, 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, top - aliniere cu elementul cel mai înalt din linie (fie el text, imagine sau alt applet), texttop - aliniere cu cel mai înalt element de text din linia respectivă, middle - mijlocul appletului se aliniază cu mijlocul liniei de bază a textului, absmiddle - mijlocul appletului se aliniază cu mijlocul elementului cel mai mare din linie, baseline sau bottom - baza appletului se aliniază cu linia de bază a textului, absbottom - baza appletului va fi elementul cel mai de jos din linie. text_de_înlocuire- un text care va apare în locul appletului, dacă browserul folosit pentru vizualizarea documentului HTML nu este capabil sa utilizeze appleturi.
297
Severin Bumbaru Dacă este necesar, marcajul APPLET poate să conţină unul sau mai mulţi parametri, care se vor transmite appletului la lansarea acestuia. Aceşti parametri apar în subtagul PARAM, pentru fiecare din ei indicându-se un nume şi o valoare.
Exemplul 1: marcajul se foloseşte pentru a include în documentul HTML a unui applet, al cărui fişier de bytecode este CBGroupAp.class şi se găseşte în acelasi director cu documentul HTML în care există acest tag. Appletul va avea lăţimea 180 şi înălţimea 80. Dacă browserul folosit nu suportă appleturi java, în locul rezervat appletului va apare textul de înlocuire "Testarea clasei CheckboxGroup". Exemplul 2: marcajul 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, dar pe acelaşi disc. În CODEBASE s-a folosit forma relativa a căii. Exemplul 3: marcajul are aceeaşi semnificaţie ca cel din exemplul anterior, dar în CODEBASE s-a folosit forma absolută a căii. Exemplul 4: marcajul are aceeaşi semnificaţie ca cel din exemplul anterior, dar în CODEBASE se foloseşte un URL la care poate fi găsit appletul respectiv.
Folosirea de parametri în appleturi În marcajul APPLET pot fi introduşi şi unul sau mai mulţi parametri, folosind în acest scop sub-marcajul []* Atât numele, cât şi valoarea sunt şiruri. 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, fără să mai
298
Programarea orientata pe obiecte în limbajul Java fie necesar să se modifice şi să se recompileze programul appletului. Exemplu: În fişierul DouaTexte.java este dat un exemplu de applet în care sunt preluaţi doi parametri, cu numele textul1 si textul2. Aceşti parametri sunt şiruri de caractere, care se afişează alternativ într-o etichetă. Schimbarea textului se face la apăsarea pe buton. Acest applet este inclus în pagina HTML din fişierul DouaTexte.html prin următorul marcaj: Pentru a se afişa alte texte, este suficient să se modifice în mod corespunzător valorile parametrilor din acest marcaj, fără a se face modificări în programul appletului.
Utilizarea marcajelor HTML în textele pentru componentele JFC/Swing În mod obişnuit, 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, folosind fontul SansSherif, culoarea neagra şi o mărime implicită. Începând cu platforma Java 2 (SDK 1.2) în textele introduse în componentele JFC/Swing (cum ar fi cele din clasele JButton, JLabel, JPanel etc.) pot fi folosite marcaje HTML. Dacă textul introdus prin metoda setText() începe cu marcajul , el este interpretat ca un text HTML şi tratat în mod corespunzător. Aceasta înseamnă că textul poate să apară pe suprafaţa componentei respective pe mai multe linii, să aibă diferite fonturi, culori şi stiluri, conform cu marcajele HTML utilizate. Dacă, însă, sintaxa HTML nu este respectată, metoda generează o excepţie.
Exemplu În fişierul TextHTML.java este dat un exemplu de aplicaţie, în care se experimentează folosirea textelor HTML în componentele interfeţei grafice. În fereastra aplicaţiei sunt plasate următoarele componente: - o arie de text (JTextArea), în care se afişează un text iniţial, care poate fi apoi modificat de utilizator; - o etichetă (JLabel) pe suprafaţa căreia se afişează textul existent în aria de text din partea stângă; - un buton cu inscripţia Vizualizare text, a cărui acţionare are ca efect afişarea pe suprafaţa etichetei a textului din aria de text; - un al doilea buton, cu inscripţia Reset, a cărui acţionare are ca efect revenirea la textul
299
Severin Bumbaru afişat iniţial în aria de text. Înscripţiile de pe cele două butoane au fost formatate folosind marcaje HTML. În aria de text este introdus iniţial un text HTML, care poate fi vizualizat apăsând pe butonul Vizualizare text. Acest text poate fi însă modificat în fereastra din stânga şi vizualizat în eticheta din dreapta, apăsând pe acelaşi buton. Dacă se doreşte, apoi, revenirea la textul iniţial, se apasă butonul Reset. Se pot experimenta, astfel, diferite modificări ale textului iniţial sau se poate introduce oricând un text obişnuit sau un hipertext nou. /* Experimentarea folosirii marcajelor HTML in textele pentru componente JFC/Swing */ import java.awt.*; import java.awt.event.*; import javax.swing.*; class TextHTML extends JFrame { JTextArea ta; JLabel label; Sfarsit sfarsit; /* Textul introdus initial in aria de text */ String textInitial="\nProba HTML
Text normal
\n"+ "Text italic Text italic aldin
\n"+ " \n"+ " Text albastru cu font serif\n \n
cu fond aqua\n"; /* Constructorul clasei TextHTML construieste interfata grafica */ TextHTML() { super("Incercare de texte HTML"); Container cp=getContentPane(); sfarsit=new Sfarsit(); // incheierea executarii aplicatiei addWindowListener(sfarsit); ta=new JTextArea(15,10); // aria in care se introduce textul HTML ta.setLineWrap(true); ta.setWrapStyleWord(true); ta.append(textInitial); ta.setBorder(BorderFactory.createTitledBorder( "Introduceti aici un text HTML")); Box vb=Box.createVerticalBox(); Box hb=Box.createHorizontalBox(); vb.add(ta); String textButon=""+ "Vizualizare text"; JButton buton=new JButton(textButon); // butonul de comanda a // vizualizarii textului buton.addActionListener(new Vizualizare()); buton.setBorder(BorderFactory.createRaisedBevelBorder()); hb.add(buton); JButton reset=new JButton(""+ "Reset"); // butonul de revenire la textul initial reset.setBorder(BorderFactory.createRaisedBevelBorder()); reset.addActionListener(new Reset()); hb.add(reset); vb.add(hb);
300
Programarea orientata pe obiecte în limbajul Java
cp.add(vb,BorderLayout.WEST); label=new JLabel(); // eticheta pe care se vizualizeaza textul HTML label.setBorder(BorderFactory.createTitledBorder( "Vizualizarea textului HTML")); label.setOpaque(true); label.setBackground(Color.white); cp.add(label,BorderLayout.CENTER); setLocation(50,50); setSize(450,300); setVisible(true); } /* Clasa de ascultare a inchiderii ferestrei principale*/ class Sfarsit extends WindowAdapter { public void windowClosing(WindowEvent e) { System.exit(0); } } /* 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.setText(ta.getText()); } catch(Exception ex) { // s-a constatat o eroare in textul HTML label.setText("Eroare de sintaxa HTML"); } } } /* Clasa de ascultare a butonului de Reset */ class Reset implements ActionListener { public void actionPerformed(ActionEvent e) { ta.setText(textInitial); label.setText(""); } } public static void main(String args[]) { TextHTML text=new TextHTML(); // instantierea aplicatiei } }
Remarcăm că, în această aplicaţie, s-au introdus următoarele abordări noi faţă de aplicaţiile anterioare: - s-a considerat că interfaţa grafică este însăşi clasa principala TextHTML, derivata din clasa JFrame. În consecinţă, adăugarea componentelor la fereastra principală se face în constructorul clasei TextHTML; - clasele interioare şi câmpurile clasei TextHTML nu au mai fost declarate statice, în schimb, în metoda main() s-a creat o instanţă a acestei clase. Desigur că acest mod de construire a aplicaţiei nu are legătura cu tema acesteia, fiind doar o ilustrare a unui alt mod de lucru posibil în Java.
301
Severin Bumbaru
Applet-uri Miniaplicaţia (engleză: applet) este un mic program cu interfaţă utilizator grafică, care nu poate rula în mod independent, ci este înglobat într-o altă aplicaţie, numită context de applet. 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). În mod normal, contextul de executare a unui applet este un navigator de Web (engleză: web browser), cum sunt Netscape Navigator, Internet Explorer sau HotJava. Pentru testare, appletul poate fi executat, de asemenea, folosind drept context un program de vizualizare special, existent in SDK, numit appletviewer. Orice applet este realizat ca o clasă, derivată din clasa Applet, existentă în pachetul java.applet, sau derivată din clasa JApplet, care extinde clasa Applet şi există în pachetul javax.swing. Întrucât utilizarea clasei JApplet este mai complicată, ne vom rezuma aici la descrierea şi exemplificarea utilizării clasei Applet.
Clasa Applet Clasa Applet se găseşte în pachetul java.applet şi este o subclasă a clasei Panel din pachetul java.awt. În consecinţă, applet-ul este, de fapt, un caz special de container. Clasa Applet este superclasa tuturor miniaplicaţiilor care sunt încorporate în pagini Web sau pot fi vizualizate cu un Java Applet Viewer. Clasa Applet moşteneşte metodele superclaselor sale Component, Container şi Panel, oferind şi metode specifice. Dintre acestea, cele mai importante sunt : init(), start(), stop() şi destroy(). Aceste metode sunt apelate de către browser în momentele importante ale ciclului de viaţă al unui applet, respectiv în momentul încărcării acestuia în memorie, în momentul începerii sau întreruperii execuţiei şi înainte ca appletul să fie distrus. Aşa cum sunt ele oferite de clasa Applet, aceste metode nu fac nimic. Ele pot fi însă redefinite de programatori în subclasele clasei Applet, astfel încât să execute anumite acţiuni specifice momentelor în care sunt invocate. Metoda init() este utilizată pentru a crea partea "statică" a applet-ului: adăugarea de componente la applet, înregistrarea ascultătorilor de evenimente etc. Ea este redefinită în marea majoritate a applet-urilor. 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. În fine, metoda destroy() se foloseşte în special pentru a distruge firele de execuţie paralele care au fost create de către applet, sau a elibera anumite resurse ocupate de acesta.
Principalele metode ale clasei Applet: Vom prezenta aici metodele mai frecvent utilizate. Pentru celelalte recomandăm consultarea documentaţiei originale. public void init()
- metoda este invocată de către browser sau appletviewer atunci
302
Programarea orientata pe obiecte în limbajul Java când appletul este încărcat în memorie, deci înainte de prima invocare a metodei start(); public void start() - metoda este invocată de către browser atunci când appletul trebuie să îşi înceapă execuţia, adică atunci când este vizitată sau revizitată pagina Web în care acesta este inclus; public void stop() - metoda este invocată de către browser atunci când pagina de Web, în care se găseşte appletul, este înlocuită de alta, fără a fi însă eliminată din memorie. Întrucât appletul nu mai este vizibil pe ecran, acesta poate sa îşi înceteze temporar execuţia; metoda este invocată, de asemenea, înaintea invocării metodei destroy(); public void destroy() - metoda este invocată de către browser înainte de distrugerea appletului; public boolean isActive() - determină dacă appletul este activ; public String getAppletInfo() - dacă este redefinită în subclase, metoda poate intoarce informaţii despre applet: autorul, versiunea, drepturi de autor etc. În clasa Applet metoda întoarce null; public AppletContext getAppletContext() - întoarce o referinţă către contextul appletului; public URL getCodeBase() - întoarce URL-ul (locaţia pe Internet) la care se găseşte bytecode-ul appletului; public URL getDocumentBase() - întoarce URL-ul la care se găseşte documentul care conţine appletul; public String getParameter(String name) - întoarce valoarea parametrului cu numele dat ca argument, conţinut în tagul APPLET al documentului HTML.
Dăm în continuare trei exemple de applet-uri, împreună cu fişierele HTML în care se afişeaza acestea. Pentru compatibilitate, s-au utilizat numai componente din pachetele java.applet şi java.awt.
Exemplul 1: În introducere a fost deja dat un exemplu de applet simplu, în care nu se redefineşte nici o metodă a clasei Applet, folosindu-se numai o invocare de metodă prin care se scrie un text pe suprafaţa appletului. Programul acestui applet se găseşte în fişierul PrimApplet.java, iar fişierul HTML în care este folosit acest applet este PrimApplet.html. Exemplul 2: În fişierul CBGroupAp.java este dat un applet de testare a unui grup de casete de validare (butoane radio) din fişierul TestCheckboxGroup.java. Remarcăm următoarele deosebiri faţă de o aplicaţie similară: - nu mai există o fereastră principală sub formă de cadru (Frame sau JFrame) ca în cazul aplicaţiei, acest rol fiind îndeplinit chiar de către applet; - în consecinţă, nu mai este necesară o clasă care sa intercepteze evenimentele generate de fereastra principală; - adăugarea componentelor la applet, setarea culorilor şi înregistrarea interceptorului de evenimente, care în cazul aplicaţiei se fac în metoda main() sau în constructorul interfeţei utilizator grafice, acum se fac în metoda init(); - având în vedere că, pentru clasa Applet, gestionarul de poziţionare implicit este 303
Severin Bumbaru FlowLayout, pentru a utiliza gestionarul BorderLayout acesta a trebuit adăugat în mod explicit. Pentru vizualizarea appletului se foloseste fişierul CBGroupAp.html. Exemplul 3: În fişierul TestFlowAp.java se prezintă un applet de testare a gestionarului de poziţionare FlowLayout. Vizualizarea din browser a acestui applet se face folosind fişierul TestFlow.html. Pe suprafaţa appletului apar două butoane de comandă ("Pune" şi "Elimina") pentru adaugarea sau eliminarea de etichete şi trei butoane radio, prin care se selectează modul de aliniere a etichetelor pe suprafaţa containerului ("Stânga", "Centru", "Dreapta"). Acţionand aceste butoane se poate testa modul de aranjare al etichetelor pentru diferite tipuri de aliniere. Oricare din aceste applet-uri poate fi vizionat şi într-un appletviewer, dacă (din fereastra Xwindow sau MS-DOS) se dă comanda: appletviewer fisierHTML
De exemplu, pentru a vizualiza applet-ul TestFlowAp, se dă comanda appletviewer TestFlow.html
unde TestFlow.html este fişierul HTML în care este invocat acest applet.
Întrebări Nivel 1 1. Ce este un hipertext? 2. Ce sunt nodurile hipertextului? 3. Ce este WWW? 4. Ce este un browser de Web? 5. Ce este HTTP? 6. Ce este HTML? 7. Ce formă au marcajele HTML? 8. Care este marcajul cu care începe şi se termină un document HTML? 9. Care este structura unui document HTML? 10. În ce zonă a documentului HTML se specifică titlul acestuia? 11. Cum se specifică titlul unui document HTML? 12. Prin ce se marchează, într-un document HTML, legăturile către alte pagini ale hipertextului? 13. La ce serveşte marcajul APPLET şi ce conţine el? 14. Cum sunt folosite marcajele HTML în componentele JFC/Swing? 15. Ce este un applet? 16. Ce clase se folosesc pentru realizarea applet-urilor? 17. Ce este un context de applet? 18. Ce contexte de applet cunoaşteţi? 19. Din ce clasă este derivată clasa Applet? dar clasa JApplet? 20. Care sunt principalele metode ale unui applet şi de către ce program sunt invocate ele? 21. La ce serveşte metoda init() în cazul unui applet? 22. Când sunt invocate metodele start() şi stop() ale unui applet? 23. În ce scop se foloseşte metoda destroy() a unui applet?
304
Programarea orientata pe obiecte în limbajul Java 24. Cum este utilizat un appletviewer?
Nivel 2 1. Cum se marchează paragrafele într-un document HTML? 2. Este absolut necesar ca un paragraf să se încheie cu marcajul
305
Severin Bumbaru
Fluxuri de intrare/ieşire şi fişiere Fluxuri de intrare/ieşire Introducere Pachetul java.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.
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, este necesar să se transmită date între diferite componente cum sunt: memoria internă, tastatura, ecranul, fişierele de pe disc, reţeaua de calculatoare etc. Poate fi necesar, de asemenea, să se transmită date între două aplicaţii sau între două fire de execuţie ale aceleeaşi aplicaţii. În limbajul Java, fluxul (engleză: stream) este o cale de comunicaţie între o sursă de date şi o destinaţie (Figura 1).
306
Programarea orientata pe obiecte în limbajul Java - Figura 1 Fluxul este un concept situat pe un nivel înalt de abstractizare, fiind privit ca o simplă succesiune de octeţi sau de caractere care se transmite între sursă şi destinaţie. Nu prezintă importanţă nici natura sursei sau a destinaţiei, nici modul în care trebuie interpretată secvenţa de octeti sau de caractere respectivă. De exemplu, 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. Această abstractizare permite să se trateze în mod unitar toate tipurile de transmisii de date. Se disting doua feluri de fluxuri: de ieşire şi de intrare. Pentru un proces dat, toate fluxurile transmise de acesta către exterior se numesc fluxuri de ieşire, iar cele primite din exterior se numesc fluxuri de intrare. În consecinţă, acelaşi flux este de ieşire în raport cu sursa şi de intrare în raport cu destinaţia. Principalele operaţii care au loc asupra unui flux sunt:
La sursă (flux de ieşire)
La destinaţie (flux de intrare)
- Deschiderea fluxului - cât timp (există date de transmis) scriere în flux -Închiderea fluxului
-Deschiderea fluxului - cât timp (există date de citit) citire din flux -Închiderea fluxului
Programatorului procesului sursă îi revine obligaţia de a pregăti, sub forma unei succesiuni de caractere sau de octeţi, datele care urmează a fi transmise pe fluxul de ieşire. Interpretarea şi tratarea datelor conţinute în flux se face de către procesul de destinaţie, deci întreaga responsabilitate îi revine celui care programează acest proces. Desigur că este necesar ca interpretarea datelor din flux la destinaţie să corespundă cu cea de la sursă. Programarea operaţiilor de intrare/ieşire poate fi destul de complicată, 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, grupate în pachetul java.io.
Pachetul java.io În Java 2 SDK se consideră că fluxurile pot fi de caractere saude octeţi. În primul caz, de la sursă la destinaţie se transmite o succesiune de caractere Unicode (de câte 16 biţi), iar în al doilea caz - o succesiune de octeţi (de 8 biţi). În mod corespunzător, 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. Pentru fluxurile de caractere, rădăcinile ierarhiilor de clase sunt clasele abstracte Reader şi Writer.Pentru fluxurile de octeţi, rădăcinile acestor ierarhii sunt clasele abstracte InputStream şi OutputStream. Aceste ierarhii de clase sunt reprezentate în figurile 2, 3, 4 şi 5. În afară de cele patru ierarhii menţionate, în pachetul java.io există şi clase auxiliare şi interfete. Distingem trei tipuri de clase, care sunt reprezentate în aceste figuri prin culori diferite: - clase abstracte (culoare albastră); - 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);
307
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).
- Figura 2 - Ierarhia claselor pentru fluxuri de intrare de caractere
- Figura 3 - Ierarhia claselor pentru fluxuri de ieşire de caractere
308
Programarea orientata pe obiecte în limbajul Java
- Figura 4 - Ierarhia claselor pentru fluxuri de intrare de octeţi
- Figura 5 - 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. De exemplu, în cazul fluxurilor de caractere, unui BufferedReader îi corespunde un BufferedWriter, unui CharArrayReader îi corespunde un CharArrayWriter etc. În mod similar, în cazul fluxurilor de octeţi, unui FileInputStream îi corespunde un FileOutputStream, unui PipedInputStream îi corespunde un PipedOutputStream etc. Aceasta reflectă "simetria" operaţiilor de intrare şi de ieşire. 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).
În JDK 1.0 existau numai clasele de fluxuri de octeţi. Fluxurile de caractere au fost introduse începand cu JDK 1.1. În prezent se folosesc ambele categorii de fluxuri. Pentru transmiterea textelor sau a datelor reprezentate în format extern şi codificate în Unicode este preferabil, evident, să se folosească fluxuri de caractere. 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.
309
Severin Bumbaru Fluxurile pot fi înlănţuite, astfel încât ieşirea unui flux poate fi intrare a altui flux. Astfel, î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, care o converteşte în fluxul de caracrtere flux2, iar acesta - la rândul lui - este preluat fe fluxul de intrare de caractere cu zonă tampon BufferedReader.
- Figura 6- Î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, iar acesta face conversia într-un flux de octeţi, pe care îl transmite la un OutputStream (de exemplu la un PrintStream sau la un FileOutputStream).
- Figura 7 - Înlănţuire de fluxuri de ieşire Având în vedere complexitatea programării operaţiilor de intrare/ieşire, în cele ce urmează vom căuta să facem o prezentare graduală, de la simplu la complex. Vom începe însă cu prezentarea comparativă a claselor abstracte care constituie rădăcinile celor patru ierarhii de clase de fluxuri. Aceasta ne va permite să ne formăm o vedere de ansamblu asupra principalelor metode folosite în lucrul cu fluxuri.
Clasele de bază ale ierarhiilor de fluxuri de intrare/ieşire Clasa Reader Clasa abstractă java.io.Reader este rădăcina ierarhiei de clase de fluxuri de intrare de caractere. Metode: citeşte din fluxul de intrare un singur caracter; întoarce caracterul citit (în domeniul 0 .. 16383) sau -1 dacă s-a ajuns la sfârşit de fişier; metoda produce blocarea procesului în care este invocată, până când apare un caracter în fluxul de intrare; public int read(char[] cbuf) throws IOException - citeşte din flux o secvenţă de caractere şi le depune într-o zonă tampon (buffer) constituită din tabloul de caractere cbuf; întoarce numărul de caractere citite sau -1 dacă s-a atins sfârşitul de fişier; metoda produce blocarea procesului până când apar caractere în fluxul de intrare, sau se ajunge la sfârşit de fişier; public int read() throws IOException -
310
Programarea orientata pe obiecte în limbajul Java public abstract int read(char[] cbuf, int off, int len) throws IOException - acţionează asemănător cu metoda precedentă, dar depunerea caracterelor
citite în zona tampon de destinaţie se face începând de la poziţia off (offset), iar numărul maxim de caractere citite este len; public long skip(long n) throws IOException - se sare peste n caractere din fluxul de intrare, care nu vor fi citite; procesul apelant este blocat pană când apare cel puţin un caracter în fluxul de intrare; dacă se întâlneşte sfârşitul de fişier, se generează o excepţie de intrare/ieşire; întoarce numărul de caractere sărite efectiv; public boolean ready() - întoarce true dacă fluxul de intrare este gata pentru a putea fi citit; public void mark(int readAheadLimit) throws IOException - marchează poziţia curentă în fluxul de intrare, pentru a se putea reveni la ea ulterior; argumentul readAheadLimit indică numărul de caractere care vor putea fi ulterior citite din flux,fără ca acest marcaj să se piardă; excepţia de intrare/ieşire apare dacă fluxul nu suportă marcarea sau dacă se produce altă eroare de intrare/ieşire; public boolean markSupported() - indică dacă fluxul suportă marcarea; public void reset() throws IOException - dacă fluxul a fost marcat, este readus la poziţia corespunzătoare ultimului marcaj; dacă fluxul nu a fost marcat sau nu suportă resetarea, se generează o excepţie de intrare/ieşire; public abstract void close() throws IOException - închide fluxul; din acest moment, invocarea metodelor read(), ready(), mark() sau reset pentru acest flux va genera o excepţie de intrare/ieşire.
Clasa Writer Clasa abstractă java.io.Writer este rădăcina ierarhiei de clase pentru fluxuri de ieşire de caractere. Metode: public void write(int c) throws IOException -
scrie în fluxul de ieşire
caracterul c; public void write(char[] cbuf) throws IOException -
scrie în fluxul de ieşire
caracterele conţinute în tabloul cbuf; public abstract void(char[] cbuf, int off, int len) throws IOException
scrie în fluxul de ieşire len caractere din tabloul cbuf, începând de la poziţia off (offset); public void write(String str) throws IOException - scrie în flux caracterele existente în şirul str; -
public void write(String str, int off, int len) throws IOException -
scrie în flux len caractere din şirul str, începând de la poziţia off (offset); public abstract void flush() throws IOException - "descarcă" fluxul de ieşire; dacă fluxul a salvat într-o zonă tampon anumite caractere scrise cu metodele write(), aceste caractere sunt scrise efectiv în fluxul de destinaţie; dacă această destinaţie este tot un flux, invocă şi metoda flush() a acestuia, astfel că se "descarcă" întregul lanţ de fluxuri; public abstract void close() throws IOException - se închide fluxul de ieşire; invocarea ulterioară a metodelor write() sau flush() pentru acest flux va produce o excepţie de intrare/ieşire.
311
Severin Bumbaru
Clasa InputStream Clasa java.io.InputStream este rădăcina ierarhiei de clase pentru fluxuri de intrare organizate pe octeţi. Metode: citeşte din fluxul de intrare un singur octet; întoarce octetul citit (in domeniul 0 .. 255) sau -1 dacă s-a ajuns la sfârşit de fişier; metoda produce blocarea procesului în care este invocată, până când apare un octet în fluxul de intrare; public int read(byte[] buf) throws IOException - citeşte din flux o secvenţă de octeţi şi îi depune într-o zonă tampon (buffer) constituită din tabloul de octeţi buf; întoarce numărul de octeţi citiţi sau -1 dacă s-a atins sfârşitul de fişier; metoda produce blocarea procesului până când apar octeţi în fluxul de intrare, sau se ajunge la sfârşit de fişier; public int read() throws IOException -
public abstract int read(byte[] buf, int off, int len) throws IOException - acţionează asemănător cu metoda precedentă, dar depunerea octeţilor citiţi în tabloul de destinaţie byte[] se face începând de la poziţia off (offset), iar numărul maxim
de octeţi citiţi este len; public long skip(long n) throws IOException - se sare peste n octeţi din fluxul de intrare, care nu vor fi citiţi; procesul apelant este blocat până când apare cel puţin un octet în fluxul de intrare; dacă se întâlneşte sfârşitul de fişier se generează o eroare de intrare/ieşire; întoarce numărul de octeţi săriţi efectiv; public int available() throws IOException - întoarce numărul de octeţi disponibili pentru citire în fluxul de intrare; public void mark(int readAheadLimit) throws IOException - marchează poziţia curenta în fluxul de intrare, pentru a se putea reveni la ea ulterior; argumentul readAheadLimit indică numărul de octeţi care vor putea fi ulterior citiţi din flux, fără ca acest marcaj să se piardă; excepţia de intrare/ieşire apare dacă fluxul nu suportă marcarea sau dacă se produce altă eroare de intrare/ieşire; public boolean markSupported() - indică dacă fluxul suportă marcarea; public void reset() throws IOException - dacă fluxul a fost marcat, este readus la poziţia corespunzătoare ultimului marcaj; dacă fluxul nu a fost marcat sau nu suporta resetarea, se generează o excepţie de intrare/ieşire; public abstract void close() throws IOException - închide fluxul; din acest moment, invocarea metodelor read(), ready(), mark() sau reset() pentru acest flux va genera o excepţie de intrare/ieşire.
Clasa OutputStream Clasa java.io.OutputStream este rădăcina ierarhiei de clase pentru fluxuri de iesire de octeţi. Metode: public void write(int c) throws IOException -
scrie în fluxul de ieşire ultimul
octet al numărului c; public void write(byte[] buf) throws IOException -
scrie în fluxul de ieşire
octeţii conţinuti în tabloul buf; public abstract void(byte[] buf, int off, int len) throws IOException -
scrie în fluxul de ieşire len octeţi din tabloul buf, începând de la poziţia off (offset); public abstract void flush() throws IOException - "descarcă" fluxul de
312
Programarea orientata pe obiecte în limbajul Java ieşire; dacă fluxul a salvat într-o zonă tampon anumiţi octeţi scrişi cu metodele write(), aceşti octeţi sunt scrişi efectiv în fluxul de destinaţie; dacă această destinaţie este tot un flux, invocă şi metoda flush() a acestuia, astfel că se "descarcă" întregul lanţ de fluxuri; public abstract void close() throws IOException - se închide fluxul de ieşire; invocarea ulterioară a metodelor write() sau flush() pentru acest flux va produce o excepţie de intrare/ieşire.
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), cât şi ca funcţionalitate. Metodele read(), skip(), mark(), markSupported(), reset() şi close() există în ambele clase. Deosebirea este ca în clasa Reader metoda read() citeşte din fluxul de intrare un caracter, iar în clasa InputStream citeşte un octet. Metodele read() pentru citirea de secvenţe de caractere, respectiv de octeţi, se deosebesc numai prin aceea ca în clasa Reader se folosesc ca destinaţie tablouri de caractere, iar în clasa InputStream se folosesc tablouri de octeţi. Metodele claselor Writer şi OutputStream sunt, de asemenea, similare ca signatură şi funcţionalitate. Metodele write(), flush() şi close() există în ambele clase, însă în clasa Writer metoda write() scrie în fluxul de ieşire un caracter, iar în clasa OutputStream scrie un octet. În cazul că în metodele write() se scrie în flux conţinutul unui tablou, în clasa Writer acesta este un tablou de caractere, iar in clasa OutputStream este un tablou de octeţi. Remarcăm că ierarhiile de clase Reader şi Writer, introduse începând cu JDK 1.1, nu înlocuiesc pe cele anterioare, având ca rădăcini clasele InputStream şi OutputStream, ci le completează. Se vor putea deci folosi, după necesităţi, atât clasele de fluxuri de caractere, cât şi cele de fluxuri de octeţi.
Clasele PrintStream şi PrintWriter Clasele java.io.PrintStream şi java.io.PrintWriter se folosesc pentru a transmite către un flux se ieşire date formatate pentru tipărire (afişare). Se ştie că forma internă a datelor diferă de forma externă. De exemplu, numerele întregi sunt reprezentate intern sub formă binară, în timp ce pe ecranul calculatorului sau la imprimantă apar sub forma unor şiruri de cifre zecimale, precedate eventual de semn. Metodele claselor PrintStream şi PrintWriter fac această conversie din forma internă în cea externă a diferitelor tipuri de date, generând reprezentările datelor respective sub forma de şiruri de octeţi (caractere în codul ASCII) sau, respectiv, de caractere Unicode. Aceste clase nu se folosesc în mod independent, ci adaugă altui flux de ieşire (de octeţi sau, respectiv, de caractere) capacitatea de formatare a datelor în vederea tipăririi.
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), în timp ce cele cu numele print() sau println() formatează datele, respectând convenţia de codificare (pe octeti sau pe caractere) specifică platformei pe care ruleaza aplicaţia respectivă. Totuşi, se recomandă ca pentru a obţine fluxuri de caractere să se folosească clasa PrintWriter. Deosebirea dintre print() şi println() este că metodele cu numele println() adaugă, la sfârşitul şirului de octeţi generat, un caracter de sfârşit de linie ('\n'). În consecinţă, dacă se 313
Severin Bumbaru foloseşte metoda print(), afişarea se face fără a se trece la o linie nouă, în timp ce dacă se foloseşte metoda println(), după afişare se trece la linie nouă. Dacă fluxul este cu descărcare automată, metoda println() provoacă, de asemenea, descărcarea acestuia (flush). Constructori: public PrintStream(OutputStream out) - creează un nou flux de formatare pentru tipărire, conectat la fluxul de ieşire out; acest flux nu se descarcă automat; public PrintStream(OutputStream out, boolean autoFlush) - creeaza un nou flux de formatare a datelor pentru tipărire, conectat la fluxul de ieşire out; 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.
Metode: public void flush() -
descarcă fluxul (goleşte zonele tampon, transmiţând
conţinutul lor la ieşire); public void close() - închide fluxul; public void write(int b) - scrie în fluxul
de ieşire un singur octet (ultimul octet al
argumentului); se scriu în fluxul de ieşire len octeţi din tabloul de octeti buf (buffer), începând de la poziţia off (offset); public void print(boolean b) - transmite în fluxul de ieşire forma externă a valorii variabilei booleene b, respectiv cuvântul true sau false; public void print(char c) - se afişează caracterul c (pe unul sau doi octeţi, depinzând de platformă); public void print(int i) - se afişează numărul întreg i; public void print(long l) - se afişează numărul întreg lung l; public void print(float f) - se afişează numărul real în simplă precizie f; public void print(double d) - se afişează numărul real în dublă precizie d; public void print(char[] s) - se afişează conţinutul tabloului de caractere s; public void print(String s) - se afişează şirul de caractere s; public void print(Object obj) - se afişeaza obiectul obj convertit în şir de caractere prin aplicarea metodei String.valueOf(obj) care, la rândul ei, apeleaza metoda obj.toString() din clasa căreia îi aparţine obiectul; public void print() - introduce în fluxul de ieşire codul caracterului '\n' (linie nouă); public void println(boolean b) - transmit în fluxul de ieşire forma externă a valorii variabilei booleene b, respectiv cuvântul true sau false; public void println(char c) - se afişează caracterul c (pe unul sau doi octeţi, depinzând de platformă); public void println(int i) - se afişează numărul întreg i; public void println(long l) - se afişează numărul întreg lung l; public void println(float f) - se afişează numărul real în simplă precizie f; public void println(double d) - se afişează numărul real în dublă precizie d; public void println(char[] s) - se afişează conţinutul tabloului de caractere s; public void println(String s) - se afişează şirul de caractere s; public void println(Object obj) - se afişează obiectul obj convertit în şir de caractere prin aplicarea metodei String.valueOf(obj); public void write(byte[] buf, int off, int len) -
314
Programarea orientata pe obiecte în limbajul Java
Clasa PrintWriter Constructori: - creează un nou flux de formatare pentru afişare, fără descărcare automată, conectându-l la fluxul de ieşire pe caractere out; public PrintWriter(Writer out, boolean autoFlush) - la fel ca şi constructorul precedent, dar al doilea argument specifică dacă are loc descărcarea automată a fluxului; public PrintWriter(OutputStream out) - creează un nou flux de formatare pe caractere, fără descărcare automată, conectându-l la fluxul de ieşire pe octeţi out; el creează şi un OutputStreamWriter intermediar, care face conversia caracterelor pe unul sau doi octeţi, dependent de platformă; public PrintWriter(OutputStream out, boolean autoFlush) - la fel ca şi constructorul precedent, dar al doilea argument indică dacă se face descărcare automată a fluxului. public PrintWriter(Writer out)
Metode: Această clasa implementează aceleaşi metode ca şi clasa PrintStream, cu excepţia celor care scriu octeţi bruti (write()).
Fişiere În memoria externă a calculatorului, datele se păstrează sub forma de fişiere. Fişierul (engleză: File) este o colecţie de înregistrări situată, de regulă, pe un suport extern şi identificată printr-un nume. Fiecare înregistrare (engleză: Record) este o grupare de informaţii sau de date care poate fi tratată în mod unitar. Fişierele pot fi clasificate după diferite criterii. După formatul înregistrărilor, distingem fişiere de text şi fişiere de date. În fişierele de text, fiecare înregistrare este o linie de text, adică un şir de caractere care se termină cu un marcaj de trecere la linie nouă. Acest marcaj depinde de platformă. De exemplu, în fişierele MS-DOS marcajul de sfârşit de linie este format din secvenţa de caractere "\r\n", adică din caracterul de întoarcere la cap de linie (Carriage Return, '\r' ) şi caracterul de linie nouă (New Line, '\n'), care au codurile ASCII 0x0D şi respectiv 0x0A. Pe platforme Unix, marcajul de sfârşit de linie este constituit numai din caracterul '\n' (New Line, 0x0A). Liniile textului pot avea lungimi diferite. Codificarea caracterelor în fişier depinde, de asemenea, de platformă. În prezent, pentru fişierele de text se foloseşte cel mai frecvent codul ASCII, dar pot exista şi platforme pe care se foloseşte Unicode sau o altă convenţie de codificare. În fişierele de date, înregistrările au, de regulă, lungime predefinită, iar fiecare înregistrare este constituită din mai multe câmpuri de date. În principiu, toate înregistrările unui fişier de date au acelaşi format. Prin formatul înregistrării se înţelege descrierea structurii acesteia, care constă din specificarea câmpurilor de date pe care le conţine, a lungimii fiecărui câmp, a tipului de date conţinut în fiecare câmp şi a modului de reprezentare a datelor. Datele din câmpuri pot fi reprezentate fie sub forma lor externă, fie sub formă binară, iar formatul înregistrărilor diferă de la un fişier la altul.
315
Severin Bumbaru După modul de exploatare, fişierele pot fi de intrare, de ieşire sau de intrare/ieşire (de manevră). În cazul fişierelor de intrare, din momentul deschiderii fişierului şi până în momentul închiderii acestuia se pot efectua numai operaţii de citire. În cazul fişierelor de ieşire, între momentele de deschidere şi de închidere a fişierului respectiv se pot face numai operaţii de scrieire. Desigur însă că, după ce s-a încheiat scrierea într-un anumit fişier de ieşire şi acesta a fost închis, el poate fi deschis ca fişier de intrare. Acelaşi fişier poate fi citit de mai multe ori. Fişierele de intrare/ieşire permit ca, după ce au fost deschise, să se efectueze atât operaţii de scriere, cât şi de citire. După modul de acces fişierele pot fi cu acces secvenţial sau cu acces direct. Fişierele cu acces secvenţial se caracterizează prin faptul că înregistrările lor pot fi parcurse într-un singur sens, în ordinea în care acestea sunt plasate în fişier. În cazul fişierelor cu acces direct, numite şi fişiere cu acces aleator (engleză: random access file) ordinea de parcurgere a înregistrărilor din fişier este arbitrară, î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, fişierul este privit ca sursa sau destinaţia unui flux. În cazul citirii din fişier, datele se transmit de la acesta către memoria internă sub forma unui flux de intrare. În cazul operaţiei de scriere, datele se transmit de la memoria internă la fişier sub forma unui flux de ieşire. În principiu, comunicarea între memoria internă şi un fişier de text se face sub forma unui flux de caractere. Totuşi, pe platformele pe care reprezentarea caracterelor se face pe un octet (de exemplu în cod ASCII), acesta poate fi tratat şi ca un flux de octeţi. În cazul fişierelor de date, 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). Dacă însă există şi câmpuri de date în format binar, legatura dintre memoria internă şi fişierul de date se face, de regula, prin fluxuri de octeţi. Operaţiile cu fişierul se fac în ordinea următoare: 1/ se deschide fişierul, în care scop trebuie să se comunice sistemului de operare numele fişierului, 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, pentru scriere sau în ambele moduri); 2/ se exploatează fişierul, efectuând o succesiune de operaţii de citire/scriere; 3/ se închide fişierul. În limbajul Java, se consideră că, în operaţiile de intrare/ieşire, între fişier şi memorie se transmit numai fluxuri de caractere sau de octeţi, fară să se ia în consideraţie informaţia pe care o conţin aceste fluxuri. Întreaga responsabilitate privind interpretareaacestor fluxuri revine programelor care le prelucrează.
Clasa File Instanţele clasei java.io.File conţin informaţii privind numele fişierului şi calea pe care se găseste acesta (engleza: Path). Clasa File oferă, de asemenea, metode prin care se pot face unele operaţii legate de prezenţa fişierului respectiv: se poate afla dacă fişierul există, dacă el poate fi citit sau scris, se poate crea un fişier nou, se poate şterge un fişier existent etc.
316
Programarea orientata pe obiecte în limbajul Java Calea indică modul în care poate fi localizat fişierul de pe disc. Calea poate fi absolută sau relativă. 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ă. Calea relativă, arată cum se poate ajunge de la directorul curent la fişierul căutat. Se ştie că, pe diferite platforme, calea se reprezintă în moduri diferite. De exemplu, în sistemul Unix, calea relativa "../../alpha/beta/fisier1.txt" indică faptul că, pornind de la directorul curent, se face o deplasare către rădăcină cu doua directoare, după care se merge înainte (către frunzele arborelui director) trecând la subdirectorul alpha şi de aici la subdirectorul beta, în care se găseşte fişierul căutat cu numele fişier1.txt. Remarcăm că separarea directoarelor se face prin caracterul '/' (slash). Pe platformele firmei Microsoft (MS-DOS, Windows), ca separator se foloseşte caracterul '\' (backslash), care în limbajele C şi Java se reprezintă sub forma '\\'. În consecinţă, aceeaşi cale relativă se va scrie pe o astfel de platforma sub forma "..\\..\\alpha\\beta\\fisier1.txt". În clasa File, reprezentarea căii se face sub o formă independentă de platformă. În acest scop, în instanţele clasei File, calea se păstrează sub forma unui tablou de şiruri de caractere, în care se memoreaza numele fiecărui director conţinut în cale. 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. În acest fel, portabilitatea programului creşte, întrucât nu trebuie modificate căile fişierelor folosite în program atunci când se trece de pe o platformă pe alta. ATENŢIE: pentru asigurarea portabilităţii programelor sursă, este recomandabil ca, în căile date ca argumente ale metodelor clasei File, să se folosească numai varianta Unix de separatori. Compilatorul javac de pe platformele Microsoft înlocuieşte automat separatorul '/' prin ' \\' in timp ce pe platformele Unix (Linux) nu se face înlocuirea inversă. Remarcăm că numele clasei File poate să ne inducă în eroare, lăsându-ne să credem că instanţele acestei clase sunt fişiere. În realitate, instanţele ei conţin căile şi numele fişierelor.
317
Severin Bumbaru
Clasa File prezentată în detaliu Câmpuri: conţine caracterul prin care se separă directoarele dintr-o cale; acest carecter este dependent de platforma, fiind '/' (slash) pe platforme Unix şi '\' (backslash) pe platforme Microsoft; public static final String separator - conţine caracterul de separare (separatorChar) sub forma de String; public static final char pathSeparatorChar - conţine caracterul de separare a căilor; acest caracter este dependent de platformă, fiind ':' (două puncte) sub Unix şi ';' (punct şi virgulă) pe platforme Microsoft; public static final String pathSeparator - caracterul de separare a căilor (pathSeparatorChar) sub formă de String. NOTĂ: aceste câmpuri se completează automat, în funcţie de platforma pe care rulează programul. public static final char separatorChar -
Constructori: public File(String pathname) -
creează o instanţă a clasei File, care conţine calea
dată ca argument; public File(String parent, String child) - creează o instanţă a clasei File, î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); public File(File parent, String child) - se deosebeşte de constructorul precedent numai prin faptul că "părintele" este o instanţă a clasei File.
Metode: Specificăm aici principalele metode ale clasei File. public String getName() - întoarce numele fişierului (ultimul nume din cale); dacă această cale este vidă, întoarce un şir vid; public String getParent() - întoarce calea părinte; public File getParentFile() - întoarce calea părinte sub forma de instanţă a clasei File; public String getPath() - întoarce calea conţinută în această instanţă; calea va conţine separatorii impliciţi de pe platforma curentă; public boolean isAbsolute() - intoarce true dacă această cale este absolută (dacă este prefixată cu '/' pe platformele Unix sau cu '\\' pe platformele Microsoft); public String getAbsolutePath() - întoarce calea absolută corespunzătoare căii conţinute în această instanţă; public File getAbsoluteFile() - întoarce o instanţă a clasei File care conţine calea absolută corespunzatoare celei din instanţa curentă; public URL toURL() - întoarce un URL (Uniform Resource Locator) corespunzător căii din această instanţă; 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); public boolean canRead() - testează dacă aplicaţia poate citi fişierul indicat de această instanţă a clasei File; public boolean canWrite() - testează dacă aplicaţia poate scrie în fişierul indicat; public boolean exists() - testează dacă fişierul indicat există; public boolean isDirectory() - testează dacă ultimul nume din această cale este al unui director;
318
Programarea orientata pe obiecte în limbajul Java public boolean isFile() -
testează dacă ultimul nume din această cale este al unui
fişier; 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() - întoarce lungimea fişierului indicat de această instanţă (în octeţi); public boolean createNewFile() throws IOException - dacă fişierul indicat în această cale nu există, creează un fişier nou vid; public boolean delete() - şterge fişierul; întoarce truedacă ştergerea a avut loc; public void deleteOnExit() - 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); public String[] list() - întoarce un tablou de şiruri, care conţine numele de directoare şi de fişier din această cale; public File[] listFile() - dacă această cale nu se încheie cu un nume de director, întoarce null; altfel întoarce un tablou de instanţe ale clasei File, câte una pentru fiecare nume de fişier din directorul indicat de această cale. public long lastModified() - întoarce
Exemplu: În fişierul TestFile.java este dat un exemplu de aplicaţie, în care se testează utilizarea metodelor clasei File. Metodele se aplică pentru un fişier situat în directorul curent, pentru un director şi pentru un fişier situat în alt director.
Citirea fişierelor Citirea fluxurilor de octeţi: clasa FileInputStream Clasa java.io.FileInputStream permite citirea datelor din fişiere sub forma de fluxuri de octeţi. Orice instanţă a acestei clase este un flux de intrare, care are ca sursă un fişier. La crearea acestei instanţe se caută şi se deschide fişierul indicat ca argument al constructorului. Dacă fişierul nu există, sau nu poate fi deschis pentru citire, se generează o excepţie.
319
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, fără a le da nici o interpretare. Constructori: public FileInputStream(String name) throws FileNotFoundException - se creează un flux de intrare de octeţi având ca sursă fişierul name; (name este numele fişierului; dacă acesta nu se află în directorul curent, atunci şirul name conţine şi calea); public FileInputStream(File file) throws FileNotFoundException - se creează un flux de intrare de octeţi având ca sursă fişierul indicat de instanţa file a clasei File; public FileInputStream(FileDescriptor fdObj) - se creează un nou flux de intrare de octeţi, care este conectat la fluxul de intrare fdObj deja existent.
Metode: public int read() throws IOException - citeşte din fişier un singur octet; dacă octetul nu este înca disponibil în fluxul de intrare, programul intră în aşteptare; public int read(byte[] b) throws IOException - se citesc din fişier cel mult b.length octeţi, care se pun în tabloul b; întoarce numărul de octeţi citit efectiv, sau zero dacă s-a intâlnit sfârşitul de fisier fără să se citească nici un octet; dacă în fluxul de intrare nu mai sunt octeţi de citit, dar nu s-a întâlnit sfârşitul de fişier, programul intră în aşteptare; public int read(byte[] b, int off, int len) throws IOException - se citesc din fluxul de intrare cel mult len octeţi, care se pun în tabloul b începând de la poziţia off (offset); întoarce numărul de octeţi citit efectiv; dacă s-a întâlnit sfârşitul de fişier fără să se citească nici un octet, intoarce -1; dacă nu s-a întâlnit sfârşitul de fişier şi nu sunt octeţi disponibili pentru citire în fluxul de intrare, programul intră în aşteptare; public long skip(long n) throws IOException - se sare peste n octeţi din fişierul de intrare; se întoarce numărul de octeţi săriţi efectiv; public int available() throws IOException - întoarce numărul de octeţi disponibili pentru citire din fluxul de intrare; public void close() throws IOException - închide fişierul; public final FileDescriptor getFD() throws IOException - întoarce un descriptor al acestui fişier.
NOTA: descriptorii de fişiere sunt obiecte care aparţin clasei java.io.FileDescriptor şi pot fi folosiţi ca argument al constructorului pentru a crea un nou flux conectat la un fişier deja deschis. Clasa FileDescriptor conţine, de asemenea, câmpurile statice in, out şi err, care sunt descriptori ai fluxurilor de intrare/ieşire standard. În consecinţă, dacă se foloseşte ca argument al constructorului clasei FileInputStream obiectul FileDescriptor.in, se creaza un flux care citeşte datele de la tastatura. Exemplu: În fişierul TestFileInput.java este un exemplu de aplicaţie, în care se testeaza metodele clasei FileInputStream. În aplicaţie se deschide fişierul f1, prin care se citesc octeţi dintr-un fişier de text, al cărui nume se dă ca parametru în linia de comandă, după care octeţii respectivi se afişează. Întrucât se ştie că f1 este un fişier de text, octeţii sunt afişati convertiţi în caractere. Se deschide apoi un al doilea flux, f2, care este echivalent cu f1, deoarece au acelaşi descriptor. În consecinţă, în continuare fluxurile f1 şi f2 citesc date din acelaşi fişier. În final, se creează un nou flux (cu referinţa f1), care citeşte datele de la tastatura, deoarece la creare s-
320
Programarea orientata pe obiecte în limbajul Java a folosit descriptorul FileDescriptor.in. Acesta este câmpul in din clasa java.io.FileDescriptor şi este o referinţă la fluxul de intrare standard, deci tratează fluxul de la tastatură ca pe un fişier folosit pentru citire.
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, ci şi o instanţă a clasei FileReader. Deosebirea este că această ultimă clasă creează un flux de caractere, în loc de un flux de octeţi. Chiar dacă fişierul nu este codificat în Unicode, ci în alt cod de caractere (de cele mai multe ori ASCII), se face automat conversia în Unicode. Clasa java.io.FileReader este derivată din clasa java.io.InputStreamReader şi foloseşte metodele acesteia. 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); public FileReader(File file) - throws FileNotFoundException - deschide ca flux de intrare de caractere fişierul cu calea file; public FileReader(FileDescriptor fd) - deschide un nou flux de intrare de caractere şi îl conectează la fluxul deja existent, al cărui descriptor este fd. Metode: Clasa FileReader nu are metode proprii, 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 int read(char[] buf, int off, int len) throws IOException -
citeşte din fluxul de intrare cel mult len caractere, pe care le pune în tabloul buf începând de la poziţia off (offset); public boolean ready() throws IOException - verifică dacă fluxul de intrare este gata pentru citire (dacă conţine caractere care pot fi citite); public void close() throws IOException - închide fluxul de intrare; public String getEncoding() - întoarce numele canonic al codului folosit pentru caractere. Exemplu: În fişierul TestFileReader.java este dat un exemplu de aplicaţie în care se testează metodele clasei FileReader. Fişierul care se citeşte poate fi acelaşi ca şi în cazul citirii cu un flux de octeţi (din clasa FileInputStream). În această aplicaţie, citirea fişierului se face de trei ori, folosind diverse metode.
321
Severin Bumbaru
Scrierea în fişiere Clasa FileOutputStream Fiecare instanţă a clasei java.io.FileOutputStream este un flux de octeţi de ieşire conectat la un fişier, în care se sriu octeţii primiţi din flux. Fluxul se poate conecta şi la un flux de octeti de ieşire deja existent.
Constructorii şi metodele clasei FileOutputStream Constructori: public FileOutputStream(String name) throws FileNotFoundException -
Deschide pentru scriere fişierul cu numele (şi, eventual, calea) name şi creează un flux de octeţi către acest fişier; dacă fişierul nu există, se va crea pe disc un fişier nou, cu numele dat ca argument; excepţia se generează dacă fişierul nu există şi nici nu poate fi creat; scrierea în fişier se va face de la începutul acestuia ("peste" ceeace, eventual, exista deja scris); public FileOutputStream(String name, boolean append) throws FileNotFoundException - acţionează la fel ca în cazul constructorului precedent,
dar dacă al doilea parametru este true, scrierea se va face în coada fişierului deja existent (scrierea începe după ultima înregistrare deja existentă); public FileOutputStream(File file) throws IOException - se deschide pentru scriere fişierul indicat de calea file şi se creează un flux de octeţi către acesta; dacă fişierul nu există, se creează unul nou; scrierea se face de la începutul fişierului; public FileOutputStream(FileDescriptor fd) - creeaza un nou flux de octeţi de ieşire, care se conectează la fluxul deja existent cu descriptorul fd. Metode: public void write(int b) throws IOException -
scrie în fişier un singur octet,
conţinut în argumentul b; public void write(byte[] b) throws IOException -
scrie în fişier toti octeţii
conţinuti în tabloul b; public void write(byte[] b, int off, int len) throws IOException -
scrie
în fişier len octeţi din tabloul b începând de la poziţia off (offset); public void close() throws IOException - închide fişierul; public final FileDescriptor getFD() throws IOException - întoarce un
descriptor al acestui fişier;
Exemplu: În fişierul TestFileOutput.java se dă un exemplu de aplicaţie, în care se testează metodele clasei FileOutputStream. Se deschide un fişier cu numele "ProbaScriere.txt" (dacă nu există, se creează unul nou). În fişier se scrie textul dat în linia de comandă. În acest scop, lansarea în execuţie se face sub forma java TestFileOutput text_de_scris_în_fişier După ce s-a scris textul, fişierul este închis, apoi este redeschis pentru citire şi conţinutul este afişat pe ecran. Se închide şi se redeschide iarăşi, dar de data aceasta pentru scriere "în coada" conţinutului existent. Se scriu cuvintele "Text adăugat", după care se închide, se redeschide pentru citire şi se afişează. Metoda de scriere în fişier folosită de fiecare dată este cea în care
322
Programarea orientata pe obiecte în limbajul Java se scrie un tablou de octeţi. Pentru afişare pe ecran, a doua oară s-a folosit tot un flux creat ca instanţă a clasei FileOutputStream, dar care a fost conectat la fluxul standard de iesire java.ioFileDescriptor.out, fiind astfel tratat acest flux ca un fişier.
Clasa FileWriter Scrierea într-un fişier de text se poate face, de asemenea, folosind clasa FileWriter. Instanţele acestei clase sunt fluxuri de ieşire de caractere, prin care se face scrierea într-un fişier. Clasa FileWriter este derivată din java.io.OutputStreamWriter şi foloseşte metodele acesteia. Constructori: public FileWriter(String fileName) throws IOException - deschide fişierul fileName pentru scriere şi creează un flux de caractere de ieşire conectat la acest fişier; dacă fişierul nu există, îl creează; public FileWriter(String fileName, boolean append) throws IOException
la fel ca în cazul constructorului precedent, dar, dacă al doilea parametru este true, scrierea în fişier se va face în coada celui deja existent; public FileWriter(File file) throws IOException - deschide pentru scriere fişierul indicat prin calea file şi creează un flux de caractere de ieşire conectat la acest fişier; public FileWriter(FileDescriptor fd) - creează un flux de caractere de ieşire şi îl conectează la fluxul deja existent, cu descriptorul fd; -
Metode: Metodele clasei FileWriter sunt moştenite de la clasa OutputStreamWriter. public void write(int c) throws IOException -
scrie în fişier un singur
caracter; public void write(char[] cbuf, int off, int len) throws IOException -
scrie în fişierul de ieşire len caractere din tabloul de caractere cbuf, începând de la poziţia off (offset); public void write(String str, int off, int len) throws IOException -
scrie în fişier len caractere din şirul str începând de la poziţia off; public void flush() throws IOException - goleşte conţinutul zonei tampon, descărcându-l în fişierul de ieşire; public void close() throws IOException - închide fişierul de ieşire; public String getEncoding() - întoarce numele canonic al codului de caractere utilizat de acest flux. Exemplu: În fişierul TestFileWriter.java este dat un exemplu similar cu cel din fişierul TestFileOutput.java, în care în locul claselor FileInputStream şi FileOutputStream s-au folosit clasele FileReader şi, respectiv, FileWriter.
323
Severin Bumbaru
Fişiere cu acces direct Fişierele cu acces direct, numite şi fisiere cu acces aleator (engl.: Random Access File), 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. De regulă, astfel de fişiere pot fi utilizate atât pentru citire, cât şi pentru scriere. Pentru ca înregistrările sale să poată fi parcurse într-o ordine arbitrară, fişierul cu acces direct trebuie să fie stocat pe un suport adresabil, cum ar fi discul magnetic, discul optic, memoria RAM sau ROM. În JDK, fişierele cu acces direct sunt instanţe ale clasei RandomAccessFile.
Clasa RandomAccessFile Clasa java.io.RandomAccessFile este derivată direct din clasa Object, deci nu face parte din niciuna din cele patru ierarhii de fluxuri de intrare/ieşire prezentate anterior, deşi face parte, ca şi acestea, din pachetul java.io. 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ă). Există un cursor al fişierului (numit în engleză File Pointer), care se comportă ca un indice al acestui tablou. 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(). Orice citire sau scriere se face începând de la poziţia pe care se găseşte acest cursor. La sfârşitul operaţiei, cursorul se deplasează pe o distanţă corespunzatoare cu numarul de octeţi care au fost citiţi sau scrişi efectiv. Fişierul cu acces direct poate fi deschis în modul read (numai pentru citire), write (numai pentru scriere) sau read/write. În ultimul caz, este posibil să se efectueze atât citiri , cât şi scrieri.
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), cât şi în mod binar, la fel ca în fişierele de date, în care scrierea s-a făcut folosind un DataOutputStream. În consecinţă, clasa RandomAccessFile oferă atât metode de scriere şi de citire de octeţi, cât şi metode de scriere şi de citire pentru toate tipurile de date primitive şi pentru şiruri de caractere, la fel ca în cazul claselor DataOutputStream şi DataInputStream. Este evident că, la citirea din fişier, trebuie să se respecte modul în care acesta a fost scris. Dacă la citire se întâlneşte sfârşitul de fişier, se generează o excepţie de sfârşit de fişier din clasa EOFException (End of File Exception), 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).
Constructori public RandomAccessFile(String file, String mode) throws FileNotFoundException - deschide fişierul cu acces direct cu numele file în
modul de exploatare mode. Modul poate fi "r" (numai citire) sau "rw" (citire si scriere); dacă este "rw"
324
Programarea orientata pe obiecte în limbajul Java şi fişierul nu există, se creează un fişier nou; public RandomAccessFile(File file, String mode) throws IOException -
acţionează asemănător cu constructorul precedent, dar calea şi numele fişierului care se deschide sunt date de instanţa file a clasei File. Metode public final FileDescriptor getFD() throws IOException - întoarce
descriptorul de fişier; citeşte din fişier un singur octet (sau întoarce -1 dacă s-a atins sfârşitul fişierului); dacă în fluxul de intrare nu este disponibil nici un octet, se intră în aşteptare; public int read(byte[] b) throws IOException - citeşte maximum b.length octeţi pe care îi pune în tabloul b; întoarce numărul de octeţi citit efectiv; public int read() throws IOException -
public int read(byte[] b, int offset, 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; întoarce numărul de octeţi cititi efectiv sau -1; public final void readFully(byte[] b) throws IOException - citeşte exact b.length octeţi, pe care îi pune în tabloul b; se blochează dacă nu are sufucienţi octeţi, iar la întâlnirea sfârşitului de fişier generează o EOFException; public final void readFully(byte[] b, int offset, int length) throws IOException - citeşte exact length octeţi, pe care îi depune în tabloul b începând de la
poziţia offset; public int skipBytes(int n) - throws IOException - încearca
să sară peste n
octeţi; întoarce numărul de octeţi săriţi efectiv; public void write(int n) throws IOException - scrie în fişier un singur octet; public void write(byte[] b) throws IOException - scrie în fişier conţinutul
tabloului b; public void write(byte[] b, int offset, int length)throws IOException -
scrie length octeţi din tabloul b începând cu cel de pe poziţia offset; public long getFilePointer() throws IOException - întoarce poziţia
cursorului de fişier; public void seek(long pos) throws IOException -
deplasează cursorul de fişier
pe poziţia pos; public long length() throws IOException - întoarce lungimea fişierului
(exprimată în octeti); public void setLength(long newLength) throws IOException -
setează noua
lungime a fişierului; public void close() throws IOException - închide fişierul; public final boolean readBoolean() throws IOException -
citeşte o valoare
booleană (un octet); public final byte readByte() throws IOException -
citeşte o valoare primitivă
de tip byte; citeşte un singur octet, pe care îl interpretează ca număr întreg fără semn (în intervalul 0 .. 255); public final short readShort() throws IOException - citeşte un întreg scurt (pe doi octeţi); public final int readUnsignedShort() throws IOException - citeşte doi octeţi, pe care îi interpretează ca un numar întreg scurt fără semn; public final char readChar() throws IOException - citeşte doi octeţi, pe care îi interpretează ca un caracter Unicode; public final int readUnsignedByte() throws IOException -
325
Severin Bumbaru public final int readInt() throws IOException -
citeşte un int (pe patru
octeţi); public final long readLong() throws IOException -
citeşte un long (pe opt
octeţi); public final float readFloat() throws IOException -
citeşte un float (pe
patru octeţi); public final double readDouble()throws IOException -
citeşte un double (pe
opt octeţi); citeşte din fişier o linie de text, adică un şir de caractere încheiat prin marcajul de sfârşit de linie ('\n' pe platforme Unix sau '\r' '\n' pe platforme Microsoft); public final String readUTF() throws IOException - citeşte un şir de caractere în format UTF-8; public final void writeBoolean(boolean b) throws IOException - scrie o valoare booleană (pe un octet); public final void writeByte(byte v) throws IOException - scrie o valoare de tip byte; public final void writeShort(short v) throws IOException - scrie un short (pe doi octeţi); public final void writeChar(char v) throws IOException - scrie un caracter Unicode (pe doi octeţi); public final void writeInt(int v) throws IOException - scrie un int (pe patru octeţi); public final void writeLong(long v) throws IOException - scrie un long (pe opt octeţi); public final void writeFloat(float v) throws IOException - scrie un float (pe patru octeţi); public final void writeDouble(double v) throws IOException - scrie un double (pe opt octeţi); public final void writeBytes(String s) throws IOException - scrie un şir de caractere convertit în secvenţă de octeţi (fiecare caracter este reprezentat pe un octet, eliminându-se octetul superior al codului caracterului); public final void writeChars(String s) throws IOException - scrie un şir de caractere Unicode; public final void writeUTF(String s) throws IOException - scrie un şir de caractere în format UTF-8. public final String readLine() throws IOException -
Exemplu În fişierul AccesDirect.java este dat un exemplu de aplicaţie, în care se creează şi se utilizează un fişier cu acces direct, cu numele "Proba.fad". Prima dată fişierul este deschis în mod "rw" (read/write). Se fac două serii de scrieri de date, care apoi sunt citite şi afişate. Înainte de fiecare citire a unei serii de date se poziţionează cursorul de fişier la începutul seriei respective, iar datele se citesc respectând modul în care acestea au fost scrise. Fişierul este apoi închis şi redeschis în mod "r" ("read"), după care se poziţionează cursorul la începutul celei de a doua serii de date, care este citită şi afişată.
326
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. Clasele de fluxuri de prelucrare din Java API au fost prezentate pe scurt la descrierea pachetului java.io. În această secţiune ne vom ocupa de două categorii de fluxuri de prelucrare: fluxurile de date şi fluxurile de obiecte.
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, char, byte, short, int, long, float sau double) şi şiruri de caractere. În acest scop, pot fi folosite clasele java.io.DataOutputStream şi java.io.DataInputStream.Se pot citi cu un DataInputStream numai date care au fost scrise cu un DataOutputStream. Instanţele acestor clase nu sunt fluxuri de intrare/ieşire propriu-zise, ci fluxuri de prelucrare. În consecinţă, ele nu se conectează direct la sursă sau la destinaţie, ci la alte fluxuri. Astfel, ieşirea unui DataOutputStream se poate conecta la intrarea unui FileOutputStream, ByteArrayOutputStream sau PipedOutputStream. Se poate conecta, de asemenea la intrarea unui BufferedOutputStream care, la rândul lui, este conectat la oricare din cele trei menţionate anterior. În mod similar, intrarea unui DataInputStream poate fi conectată la ieşirea unui FileInputStream, ByteArrayInputStream sau PipedInputStream.
Clasa DataOutputStream Clasa java.io.DataOutputStream este derivată din clasa java.io.FilterOutputStream şi implementează interfaţa java.io.DataOutput. Ea permite să se transmită date primitive către un flux de ieşire într-o formă portabilă (independentă de platformă), cu condiţia ca aceste date să fie citite ulterior printr-un DataInputStream. Constructor: - creează un nou flux de ieşire de date, conectat la ieşire la un OutputStream (adică la o instanţă a unei clase derivate din clasa OutputStream). public DataOutputStream(OutputStream out)
Metode: Aceasta clasă conţine metodele clasei java.io.OutputStream, la care se adaugă următoarele metode specifice, destinate scrierii în fluxul de ieşire a datelor primitive sau a unor şiruri de caractere: public final void writeBoolean(boolean v) throws IOException
- scrie o
valoare booleană; public final void writeChar(char v) throws IOException
- scrie o valoare de
tip char, în format Unicode; public final void writeByte(byte v) throws IOException
- scrie o valoare de
tip byte pe un octet; public final void writeShort(short v) throws IOException
- scrie o valoare
de tip short pe doi octeţi; public final void writeInt(int v) throws IOException
327
- scrie o valoare de tip
Severin Bumbaru int pe 4 octeţi; public final void writeLong(long v) throws IOException
- scrie o valoare de
tip long pe 8 octeţi; public final void writeFloat(float v) throws IOException
- scrie o valoare
de tip float pe 4 octeţi; public final void writeDouble(double v) throws IOException
- scrie o
valoare de tip double pe opt octeţi; public final void writeBytes(String v) throws IOException - scrie un şir de caractere, convertit într-un şir de octeţi prin suprimarea octetului superior al fiecărui caracter; public final void writeChars(String v) throws IOException - scrie în flux un şir de caractere (în Unicode); public final void writeUTF(String v) throws IOException - 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, apoi fiecare caracter din şir pe câte un singur octet); public final int size() - întoarce numărul de octeţi scrişi în acest flux de ieşire.
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ă. Se pot citi cu DataInputStream numai date care au fost scrise cu DataOutputStream. Clasa java.io.DataInputStream este derivată din clasa java.io.FilterInputStream şi implementează interfaţa java.io.DataInput.
Constructor: public DataInputStream(InputStream in) - creează un citeşte date din fluxul de intrare in, primit ca argument.
flux de date de intrare, care
Metode: Aceasta clasă conţine toate metodele clasei java.io.InputStream, la care se adaugă următoarele metode specifice, prin care se implementează interfaţa java.io.DataInput: - citeşte din fluxul de intrare un număr de octeţi egal cu lungimea tabloului b, primit ca argument, şi îi pune în acest tablou. Dacă în fluxul de intrare nu sunt înca suficienţi octeţi, dar nu s-a atins sfârşitul de fişier, procesul este pus în aşteptare până apar noi octeţi. Dacă se întâlneşte sfârşitul de fişier (EOF - End of File), se generează o EOFException; public final void readFully(byte[] b) throws IOException
public final void readFully(byte[] b, int off, int len) throws IOException - acţionează similar cu metoda precedentă, dar se citesc len octeţi, care sunt
depuşi în tabloul b, începand de la poziţia off; public final void skipBytes(int n) throws IOException - sare peste n octeţi din fluxul de intrare; întoarce numărul de octeţi săriţi efectiv (este posibil să nu reuşească să sară n octeti, de exemplu dacă a întalnit sfârşitul fluxului); public final boolean readBoolean() throws IOException - citeşte un octet din fluxul de intrare şi îl converteşte în valoare booleană; public final byte readByte() throws IOException - citeşte din fluxul de intrare
328
Programarea orientata pe obiecte în limbajul Java un singur octet, pe care îl tratează ca un număr întreg cu semn în intervalul [-128, 127]; se consideră că a fost scris cu writeByte(byte v); public final int readUnsignedByte() throws IOException - citeşte din fluxul de intrare un singur octet, pe care îl tratează ca număr întreg fără semn în intervalul [0, 255] şi îl întoarce sub formă de int; public final short readShort() throws IOException - citeşte doi octeţi din fluxul de intrare şi îi interpretează ca un număr de tip short, scris anterior cu writeShort(short v); public final int readUnsignedShort() throws IOException - citeşte din fluxul de intrare doi octeţi, pe care îi interpretează ca număr întreg fără semn şi-l întoarce sub formă de int; public final char readChar() throws IOException - citeşte din fluxul de intrare un char (doi octeţi, format Unicode); public final int readInt() throws IOException - citeşte patru octeţi si îi interpretează ca un număr de tip int scris cu writeInt(int v); public final long readLong() throws IOException - citeste opt octeţi si îi interpretează ca un număr de tip long, scris cu writeLong(long v); public final float readFloat() throws IOException - citeşte patru octeţi si îi interpretează ca un număr de tip float, scris cu writeFloat(float v); public final double readDouble() throws IOException - citeşte opt octeţi si îi interpretează ca un număr de tip double, scris cu writeDouble(double v); public final String readUTF() throws IOException - citeşte un şir de caractere în format UTF (care a fost scris cu writeUTF(String str)); Exemplu În fişierul FisierDate.java se dă un exemplu de aplicaţie, în care se creează un fişier de date şi se scriu date în acest fişier folosind un DataOutputStream legat la un FileOutpusStream. După ce au fost scrise datele, se închide fişierul pentru scriere şi se redeschide pentru citire, după care se citesc datele în aceeaşi ordine în care au fost scrise. Datele scrise în fişier şi cele citite sunt afişate pe ecran pe perechi, pentru comparaţie.
Fluxuri de obiecte Fluxurile de obiecte sunt fluxuri de prelucrare care permit să se transmită obiecte. În acest scop, obiectele transmise trebuie să fie serializate, înainte de a fi transmise, adică să fie puse sub forma unei serii de octeti, într-un format care să permită la destinaţie reconstituirea în memorie a obiectului respectiv. Astfel de obiecte se numesc serializabile. Pe platforma Java 2, fluxurile de obiecte se realizează prin clasele java.io.ObjectOutputStream şi java.io.ObjectInputStream. Obiectele transmise de aceste fluxuri trebuie sa implementeze interfaţa java.io.Serializable.
Interfaţa Serializable Orice obiect care se transmite pe un flux trebuie să aparţină unei clase care implementează interfaţa java.io.Serializable. Aceasta inseamnă că trebuie îndeplinite următoarele condiţii:
329
Severin Bumbaru - la declararea clasei respective, se pune clauza implements Serializable; - clasa trebuie să conţină un constructor fără argumente; - toate câmpurile obiectului trebuie să fie serializabile, adică fie să aparţina unor tipuri de date, primitive, fie unor clase care implementează interfaţa Serializable. Interfaţa Serializable nu conţine câmpuri sau metode. Clauza implements Serializable constituie doar o indicaţie pentru compilatorul Java să o pună sub forma serializabilă.
Dacă, la transmiterea obiectelor pe flux, se constată că unul din acestea nu este serializabil, se generează excepţia NotSerializableException. Clasele care necesită o manipulare specială la serializare sau deserializare trebuie să conţina metode cu signaturile următoare: private void writeObject(java.io.ObjectOutputStream out) throws IOException private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException;
O prezentare mai amplă a acestei interfeţe se găseşte în documentaţia Java API.
Clasa ObjectOutputStream Clasa java.io.ObjectOutputStream este clasa fluxurilor de prelucrare pentru obiecte, având rolul de a serializa obiectele care urmează să fie puse într-un flux de ieşire. Fluxurile de obiecte se conectează la ieşire la un alt flux, de preferinţă la un FileOutputStream, ByteArrayOutputStream sau PipedOutputStream, iar utilizarea lor este asemănătoare cu cea a fluxurilor de date (DataOutputStream). Într-un flux de obiecte se pot scrie atât obiecte serializate, cât şi date primitive sau şiruri. Clasa ObjectOutputStream conţine toate metodele de scriere a datelor primitive şi a şirurilor, care există şi în clasele DataOutputStream şi RandomAccessFile. În plus, ea conţine metode necesare pentru scrierea în flux a obiectelor, cea mai frecvent folosită fiind următoarea: public final void writeObject(Object obj)throws IOException - scrie în fluxul de ieşire obiectul obj sub formă serializată; Informaţii mult mai ample despre această clasă pot fi găsite în documentaţia Java API.
Clasa ObjectInputStream Clasa java.io.ObjectInputStream serveşte pentru citirea (deserializarea) fluxurilor de obiecte care au fost scrise folosind clasa java.io.ObjectOutputStream. Intrarea unui ObjectInputStream este conectată la ieşirea unui alt flux de intrare, de preferinţă FileInputStream, ByteArrayInputStream sau PipedInputStream. Clasa ObjectInputStream conţine toate metodele de citire a datelor primitive şi a şirurilor existente în clasa DataInputStream. În plus, ea conţine metode necesare pentru citirea
330
Programarea orientata pe obiecte în limbajul Java obiectelor serializate, dintre care cea mai frecvent folosită este public final Object readObject() throws OptionalDataException, ClassNotFoundException, IOException
Informaţii mai ample despre această clasă se găsesc în documentaţia Java API. Exemplu În fişierul FisierObiecte.java este dat un exemplu de aplicaţie, în care se testează clasele ObjectOutputStream şi ObjectInputStream. În prima parte a metodei main(), se creează un fişier (Proba1.dat) în care se scriu atât obiecte (din clasele Persoana şi Student), cât şi date primitive, şiruri şi tablouri. Pentru scrierea obiectelor şi a tablourilor se foloseşte metoda void writeObject(Object obj), iar pentru datele primitive şi pentru şiruri se folosesc metodele specifice pentru scrierea tipurilor respective. După ce s-a încheiat scrierea datelor, se închide fişierul Proba1.dat. În partea a doua a metodei main() se deschide fişierul Proba1.dat pentru citire şi se citesc din el toate datele scrise anterior, în ordinea în care au fost scrise. Întrucât metoda Object readObject() întoarce un Object, acesta este convertit prin cast într-un obiect din clasa căruia îi aparţine în realitate. În ultima parte a metodei main() se afişează pe ecran datele citite, putându-se astfel verifica faptul că serializarea şi deserializarea s-au făcut corect. Remarcăm că, în afară de date primitive şi obiecte, au fost scrise în fişier (prin metoda writeObject) şi tablouri unidimensionale şi bidimensionale, care au fost apoi citite corect (prin metoda readObject). 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), 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.
Întrebări Nivel 1 1. Ce este un stream? 2. Ce deosebire este între fluxurile de ieşire şi cele de intrare? 3. Care sunt etapele de utilizare a unui flux de iesire? 4. Care sunt etapele de utilizare a unui flux de intrare? 5. Ce conţine pachetul java.io? 6. Ce deosebire este între fluxurile de caractere şi cele de octeţi? 7. Care sunt rădăcinile ierarhiilor de clase pentru fluxuri de caractere? 8. Care sunt rădăcinile ierarhiilor de clase pentru fluxuri de octeţi? 9. Ce sunt fluxurile de prelucrare? 10. Ce este un fişier? 11. Care sunt clasele folosite pentru citirea fişierelor? 12. Care sunt clasele folosite pentru scrierea fişierelor? 13. Cum se deschide un fişier? 14. Cum se închide un fişier? 15. Ce clase se folosesc pentru a scrie date într-un fişier de octeţi şi pentru a citi date
331
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
care
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,
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
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 acest caz, executarea celor două fire, Alpha şi Beta, are loc intercalat, deoarece, după fiecare parcurgere a unui ciclu într-un fir, se invocă metoda yield() , cedându-se procesorul sistemului în favoarea celuilalt fir. Aceasta nu s-ar fi întâmplat, dacă cele doua fire ar fi avut priorităţi diferite.
Exemplul 3 În fişierul DouaFireB.java s-a reluat aplicaţia din Exemplul 1, aducându-i-se următoarele modificări: - î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, pentru a mări în mod artificial durata de execuţie; în locul acestuia se putea pune, evident, orice alta secvenţa de instrucţiuni cu durata de execuţie comparabilă; - cele două cicluri (pe i şi pe j) au fost introduse şi în metoda main(), pentru a putea urmări executarea acesteia după lansarea firelor Alpha şi Beta. Fragmentele de program nou adăugate sunt puse în evidenţă în textul de mai jos cu caractere aldine (îngroşate). /* Crearea si utilizarea unei clase de fire de executie. In metoda run a firului nu se folosesc metodele sleep() sau yield(), dar se parcurge un ciclu de contorizare (pe j) de 100000000 ori pentru a mari durata de executie a ciclului exterior (pe indicele i). Se creeaza doua fire de aceeasi prioritate (Thread.NORM_PRIORITY). */
342
Programarea orientata pe obiecte în limbajul Java
class DouaFireB { /* 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<5; i++) { for(int j=0; j<100000000; j++); System.out.println("Firul "+getName()+" ciclul i="+i); } } } /* incheierea clasei Fir */ public static void main(String args[]) throws Exception { Fir fir1, fir2, fir3; System.out.println("Se creeaza firele Alpha si Beta"); fir1=new Fir("Alpha"); fir2=new Fir("Beta"); System.out.println("Se pun in executie cele doua fire"); fir1.start(); fir2.start(); for (int i=0; i<5; i++) { for(int j=0; j<100000000; j++); System.out.println("main() ciclul i="+i); } System.out.println("Sfarsitul metodei main()"); } /* 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
Severin Bumbaru
main() ciclul i=4 Sfarsitul metodei main() Firul Alpha ciclul i=4 Firul Beta ciclul i=4
Constatăm că, î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, Beta si main()) au aceeaşi prioritate (Thread.NORM_PRIORITY), se aplică o strategie de partajare a timpului, astfel încât timpul de funcţionare al procesorului este alocat sub forma de tranşe succesive fiecăruia dintre procese. În consecinţă, se creeaza impresia că cele trei procese se desfăşoară în paralel, simultan în timp.
Exemplul 4 În fişierul DouaFireC.java se reia aplicaţia din exemplul precedent, dar s-a renunţat la ciclurile interioare (cu contorul j), î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. Această metodă aruncă excepţia InterruptedException care trebuie captată. În mod similar s-a procedat şi în ciclul din metoda main. Având însă în vedere că metoda main() nu se găseşte într-o clasa derivata din Thread, la invocarea metodei statice sleep a fost necesar să se indice clasa căreia îi aparţine, deci invocarea s-a făcut sub forma Thread.sleep(1000).
/* Crearea şi utilizarea unei clase de fire de execuţie. În metoda run a firului se foloseste metoda sleep(1000) pentru a pune firul in asteptare pe o durata de 1000 milisecunde. Similar se procedeaza in metoda main() */ class DouaFireC { /* 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<5; i++) { System.out.println("Firul "+getName()+" ciclul i="+i); try { sleep(1000); } catch(InterruptedException e) {}
344
Programarea orientata pe obiecte în limbajul Java
} } } /* incheierea clasei Fir */ public static void main(String args[]) throws Exception { Fir fir1, fir2, fir3; System.out.println("Se creeaza firele Alpha si Beta"); fir1=new Fir("Alpha"); fir2=new Fir("Beta"); System.out.println("Se pun in executie cele doua fire"); fir1.start(); fir2.start(); for (int i=0; i<5; i++) { System.out.println("main() ciclul i="+i); try { Thread.sleep(1000); } catch(InterruptedException e) {} } System.out.println("Sfarsitul metodei main()"); } /* 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", se pot executa alte fire, chiar dacă ele sunt de prioritate inferioară!
345
Severin Bumbaru
Interfaţa Runnable Interfaţa java.lang.Runnable trebuie implementată de orice clasă care nu este descendentă a clasei java.lang.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. 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. Motivul ar putea fi, de exemplu, cel că clasa nou creată, B, trebuie sa extindă o alta clasă, A, care nu este descendentă a clasei Thread Se ştie că în Java nu există moştenire multiplă, deci clasa B nu poate avea ca superclase atât clasa A, cât şi clasa Thread. În acest caz, vom crea o clasă B care extinde clasa A şi implementeaza interfaţa Runnable, care conţine metoda run(). Utilizarea instanţelor claselor cu interfaţa Runnable se face, punându-le ca argumente ale următorilor constructori ai clasei Thread: public Thread(Runnable target) public Thread(Runnable target, String name) instanţă a clasei Thread creată cu un astfel de constructor,
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.
Exemplul 1 În fişierul DouaFireAR.java se dă un exemplu de aplicaţie similară cu cea din fişierul DouaFireA1.java, cu deosebirea că clasa Fir nu extinde clasa Thread, ci implementează interfaţa Runnable. Fragmentele de program modificate sunt puse în evidenţa în textul sursă de mai jos prin caractere aldine (ingroşate). /* Crearea si utilizarea unei clase cu interfata Runnable. Se foloseste metoda yield() pentru a ceda controlul altui fir de aceeasi prioritate. Se creeaza doua fire de aceeasi prioritate (Thread.NORM_PRIORITY), utilizand ca argument al constructorului instante ale clasei Fir cu interfata Runnable. */ class DouaFireAR { /* Clasa cu interfata Runnable */ static class Fir implements Runnable { /* Definirea metodei run() din interfata Runnable */ public void run() { System.out.println("Incepe executarea firului "+ Thread.currentThread().getName()); for(int i=0; i<6; i++) { System.out.println("Firul "+
346
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
351
Severin Bumbaru
*/ class Consumator extends Thread { public void run() { System.out.println("Incepe executarea firului Consumator"); int tab[]; for(int i=0; i
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
Programarea orientata pe obiecte în limbajul Java
Clase (ierarhiile de clase de intrare/ieşire sunt prezentate în cap.11, secţiunea pachetul java.io din acest manual) BufferedInputStream - clasa fluxurilor de intrare de octeţi, cu zonă tampon – v. cap.11 si completarea de la pag.373 BufferedOutputStream - clasa fluxurilor de ieşire de octeţi, cu zonă tampon – v.cap.11 şi completarea de la pag. 373. BufferedReader - clasa fluxurilor de intrare de caractere, cu zonă tampon – v.cap.11 şi completarea de la pag. 374. BufferedWriter - clasa fluxurilor de ieşire de caractere, cu zonă tampon – v.cap.11 şi completarea de la pag. 374. ByteArrayInputStream - clasa fluxurilor care citesc dintr-un tablou de octeţi situat în memoria internă + v.cap.11 şi completarea de la pag. 374. ByteArrayOutputStream - clasa fluxurilor care scriu într-un tablou de octeţi situat în memoria internă + v.cap.11 şi completarea de la pag. 374. CharArrayReader - clasa fluxurilor care citesc dintr-un tablou de caractere situat în memoria internă – v. cap.11 şi pag. 376. CharArrayWriter - clasa fluxurilor care scriu într-un tablou de caractere situat în memoria internă – v. cap.11 şi pag.376 DataInputStream - clasa fluxurilor de octeţi de intrare pentru date - v. cap.11 DataOutputStream - clasa fluxurilor de octeţi de ieşire de date – v. cap.11 File - clasă ale cărei instanţe conţin informaţii despre fişiere – v. cap.11 FileDescriptor - clasa descriptorilor de fişiere – v. cap.11 şi pag.377 FileInputStream - clasa fluxurilor de octeţi de intrare din fişiere (clasa fişierelor deschise pentru intrare) – v. cap.11 FileOutputStream - clasa fluxurilor de octeţi de ieşire în fişiere (clasa fişierelor deschise pentru ieşire) – v. cap.11. FileReader - clasa fluxurilor de caractere de citire din fişiere – v. cap.11 FileWriter - clasa fluxurilor de caractere de scriere în fişiere – v. cap.11 FilterInputStream - clasa fluxurilor de intrare de octeţi cu filtru – v. cap.11 şi pag. 377. FilterOutputStream - clasa fluxurilor de ieşire de octeţi cu filtru – v.cap.11 şi pag. 378. FilterReader - clasa flucurilor de intrare de caractere cu filtru – v. cap.11 şi pag. 378. FilterWriter - clasa flucurilor de ieşire de caractere cu filtru – v. cap.11 şi pag.378. InputStream - clasa fluxurilor de intrare de octeţi – v. cap.11 ObjectInputStream - clasa fluxurilor de intrare de obiecte – v. cap.11 ObjectOutputStream - clasa fluxurilor de ieşire de obiecte – v. cap.11 OutputStream - clasa fluxurilor de ieşire de octeţi – v. cap.11 PrintStream - clasa fluxurilor de imprimare de octeţi – v. cap.11 PrintWriter - clasa fluxurilor de imprimare de caractere – v. cap.11 RandomAccessFile - clasa fişierelor cu acces direct (acces aleator). – v. cap.11 Reader - clasa fluxurilor de intrare de caractere – v. cap.11 Writer - clasa fluxurilor de ieşire de caractere – v. cap.11
Interfeţe Serializable - interfaţă pe care trebuie să o aibă obiectele serializabile (care pot fi scrise cu ObjectOutputStream şi citite cu ObjectInputStream) – v. cap.11
357
Severin Bumbaru
Pachetul java.util Clase EventObject - clasa obiectelor care conţin informaţii despre evenimente – v. cap. 7 şi pag. 379
Interfeţe EventListener - interfaţă generică pentru ascultătoarele de evenimente. – v. cap.7 şi pag. 379
Pachetul java.awt Clase AWTEvent - superclasa ascultătoarelor de evenimente generate de componentele interfeţei grafice – v. cap.7 şi pag. 380. BorderLayout - gestionar de poziţionare – v. cap.7 şi pag. 381. Button - clasa butoanelor simple – v. cap.8 şi pag. 382. Canvas - clasă specială de componente pe care se trasează desene - v. cap.9 şi pag. 383 CardLayout - gestionar de poziţionare – v. cap. 7 şi pag. 383 Color - clasa culorilor – v. cap.9 şi pag. 384 Component - superclasa tuturor claselor de componente ale interfeţei grafice. – v. cap.7 şi pag. 387 Container - clasa containerelor (componente care conţin alte componente) – v. cap.7 şi pag. 393. Dialog - clasa ferestrelor de dialog + v. cap.9 şi pag. 394. Dimension - dimensiunile unei componente – v. cap.9 şi pag. 396. Event - clasa evenimentelor din JDK1.0 (înlocuită acum prin clasa AWTEvent) – v. cap.7 şi pag. 396. FlowLayout - gestionar de poziţionare – v. cap.7 şi pag. 397. Font - clasa fonturilor – v. cap.9 şi pag. 398. Frame - clasa ferestrelor principale ale aplicaţiilor. – v. cap.7 şi pag. 399. Graphics - clasa contextelor grafice simple – v. cap.9 Graphics2D - clasa contextelor grafice 2D – v. cap.9 şi pag. 401. GridBagLayout - gestionar de poziţionare – v. cap.7 şi pag. 401. GridLayout - gestionar de poziţionare – v. cap.7 şi pag. 401. Insets - clasa inserţiilor (marginilor libere ale containerelor) + v. pag. 402. Panel - clasa panourilor – v. cap.7 şi pag. 402. Point - clasa punctelor – v. pag. 403. Rectangle - clasa dreptunghiurilor – v. pag. 404. Window - clasa ferestrelor. + v. cap.7 şi pag. 405.
Interfeţe LayoutManager - interfaţă pentru clsasele de gestionare a poziţionării – v. cap.7 şi pag. 406 LayoutManager2 - interfaţă pentru clasele de gestionare a poziţionării cu restricţii – v. cap.7 şi pag. 407.
358
Programarea orientata pe obiecte în limbajul Java
Pachetul java.awt.event Clase ActionEvent - eveniment de acţiune – v. cap.8 şi pag. 408. AdjustementEvent - eveniment de ajustare – v. cap.8 şi pag. 408. ComponentAdapter - adaptor pentru ascultătoarele de evenimente de componentă.- v.cap.8 şi pag. 409. ComponentEvent - eveniment de componentă – v.cap.8 şi pag. 409. InputEvent - clasă abstractă. Rădăcina ierarhiei claselor de evenimente de intrare – v.cap.7 şi pag.410. ItemEvent - eveniment de articol (selectare sau deselectare) – v.cap.8 şi pag.411. KeyAdapter - adaptor pentru ascultarea evenimentelor de tastă – v.cap.7 şi pag.411. KeyEvent - eveniment de tastă – v.cap.7 şi pag.412. MouseAdapter - adaptor pentru ascultarea evenimentelor de mouse – v.cap.7 şi pag.416. MouseEvent - eveniment de mouse – v.cap.7 şi pag.416. MouseMotionAdapter - adaptor pentru ascultarea evenimentelor de mişcare a mouse-ului – v.cap.7 şi pag.417. TextEvent - eveniment de text - v.cap.8 şi pag.417. WindowAdapter - adaptor pentru ascultarea evenimentelor de fereastră – v.cap.7 şi pag.418. WindowEvent - eveniment de fereastră - v. cap.7 şi pag.418.
Interfeţe ActionListener - interfaţă pentru ascultătoarele de evenimente de acţiune – v.cap.8 şi pag.419 AdjustmentListener - interfaţă pentru ascultătoarele de evenimente de ajustare – v.cap.8 şi pag.420. ComponentListener - interfaţă pentru ascultătoarele de evenimente de componentă – v.cap.8 şi pag.420. ItemListener - interfaţă pentru ascultătoarele de evenimente de articol – v.cap.8 şi pag.421. KeyListener - interfaţă pentru ascultătoare de evenimente de tastă – v.cap.7 şi pag.421. MouseListener - interfaţă pentru ascultătoare de evenimente de mouse v.cap.7 şi pag.421. MouseMotionListener - interfaţă penteru ascultătoare de evenimente de mişcare a mouseului – v.cap.7 şi pag.422. TextListener - interfaţă pentru ascultătoare de evenimente de text – v.cap.8 şi pag.422. WindowListener - interfaţă pentru ascultătoare de evenimente de fereastră – v.cap.7 şi pag.423
Pachetul javax.swing Clase AbstractButton - clasă abstractă. Superclasa claselor de butoane – v.cap.8 şi pag. 423. BorderFactory - clasă care permite producerea de borduri pentru componentele Swing – v. cap.8. Box - container sub formă de casetă – v. cap.8. Box.Filler - clasa componentelor invizibile, folosite pentru distanţare în instanţele clasei Box + v. cap.8 şi pag.425. BoxLayout - gestionar de poziţionare în casetă – v. cap.7.
359
Severin Bumbaru ButtonGroup - clasa grupurilor de butoane – v.cap.8 şi pag.426. JApplet - clasa applet-urilor din Swing – v.cap.10 şi pag. 426. JButton - clasa butoanelor – cap.8 şi pag.427. JCheckBox - clasa casetelor de validare – v. cap.8. JCheckBoxMenuItem - clasa articolelor de meniu cu casetă de validare – v. cap.8 şi pag.427. JColorChooser - clasa selectorului de culori + v.cap.9. JComboBox - clasa listelor ascunse – v. cap.8. JComponent - rădăcina ierarhiei de clase de componente Swing – v.cap.8 şi pag.428. JDialog - clasa ferestrelor de dialog – v.cap.9 şi pag.430. JEditorPane - clasă pentru editoare de text formatat – v.cap.8 şi pag.432. JFileChooser - clasa selectoarelor de fişiere – v.cap.8 şi pag.432. JFrame - clasă folosită în special pentru ferestrele principale ale aplicaţiilor – v.cap.7 şi pag.433. JLabel - clasa etichetelor (componente de afişare needitabile) + v.cap.8 şi pag.435. JList - clasa listelor afişabile în interfaţa grafică – v. cap.8. JMenu - clasa meniurilor – v. cap.8 şi pag.436. JMenuBar - clasa barelor de menu – v. cap.8 şi pag.437. JMenuItem - clasa articolelor de meniu – v. cap.8 şi pag.438. JOptionPane - clasă cu metode pentru realizarea unor ferestre de dialog standard – v. cap.9 şi pag.439. JPanel - clasa panourilor (containere simple) – v.cap.7 şi pag.441. JPasswordField - clasa câmpurilor pentru introducerea parolei – v. cap.8 şi pag.441. JPopupMenu - clasa meniurilor volante (meniuri pop-up) – v. cap.8. JProgressBar - clasa barelor de progres – v. cap.8 şi pag.442. JRadioButton - clasa butoanelor radio – v. cap.8. JRadioButtonMenuItem - clasa articolelor de meniu cu buton radio – v. cap.8 şi pag.443. JScrollBar - clasa barelor de defilare – v. cap.8 şi pag. 444. JScrollPane - clasa panourilor cu bare de defilare – v. cap.7 şi pag.445. JSeparator - clasa separatoarelor de meniu v. cap.8 şi pag.446. JSlider - clasa riglelor cu cursor – v. cap.8. JSplitPane - clasa panourilor care pot fi scindate - v. cap.7 şi pag.447. JTabbedPane - clasa panourilor tabulate – v. cap.8 şi pag.448. JTable - clasa tabelelor – v. cap.8 şi pag. 450. JTextArea - clasa ariilor de text – v. cap.8. JTextField - clasa câmpurilor de text – v. cap.8. JTextPane - clasă pentru editoare de text stilizat – v. cap.8 şi pag.450. JToggleButton - superclasa butoanelor cu două stări stabile – v. cap.8 şi pag.451 JWindow - clasa ferestrelor – v. cap.7 şi pag. 451.
Pachetul javax.swing.event Clase ChangeEvent - eveniment de schimbare a stării sursei – v. cap.7 şi pag.452. ListDataEvent - eveniment de modificare a datelor dintr-o listă – v.cap.8 şi pag.452. ListSelectionEvent - clasa evenimentelor de selectare a articolelor de listă v.cap.8 şi pag.453 MenuEvent - clasa evenimentelor de meniu – v. cap.8 şi pag.453. MouseInputAdapter - adaptor pentru ascultătoarele de evenimente de mouse – v. cap.7 şi
360
Programarea orientata pe obiecte în limbajul Java pag.454. PopupMenuEvent - clasa evenimentelor generate de meniuri pop-up – v.cap.8 şi pag.454.
Interfeţe ChangeListener - ascultător de evenimente de schimbare a stării – v.cap.7 şi pag.454. ListDataListener - ascultător de evenimente de modificare a conţinutului unei liste – v.cap.8 şi pag.455. ListSelectionListener - ascultător de evenimente de modificare a articolelor selectate dintr-o listă – v. cap.8 şi pag.455. MenuListener - ascultător al evenimentelor de meniu – v. cap.8 şi pag.455. MouseInputListener - ascultător de mouse - v. cap.7 şi pag.456. PopupMenuListener - ascultător al evenimentelor de meniu pop-up v. cap.8 şi pag.456.
361
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, cum sunt functiile trigonometrice, radacina patrata si altele. Campuri: public static final double E public static final double PI
- numarul e (baza logaritmilor naturali); - numarul pi (raportul dintre circumferinta cercului si
diametru). Metode: public static double sin(double a)- intoarce sinusul
trigonometric sin a, unde unghiul
a este in radiani. public static double cos(double a)- intoarce cosinusul
trigonometric cos a, unde
unghiul a este in radiani; public static double tan(double a)- intoarce tangenta trigonometrica
tg a, unde
unghiul a este in radiani; public static double asin(double a)- intoarce arcsin
a in intervalul [-pi/2, pi/2];
public static double acos(double a)- intoarce arccos
a in intervalul [0.0, pi];
public static double atan(double a)- intoarce arctg
a in intervalul [-pi/2, pi/2];
public static double toRadians(double angdeg)- converteste
argumentul angDeg din
grade in radiani; public static double toDegrees(double angrad)- converteste
argumentul angrad din
radiani in grade; public static double exp(double a)- calculeaza functia
exponentiala ea;
public static double log(double a)- calculeaza logaritmul public static double sqrt(double a)- calculeaza radacina
natural ln a;
patrata a argumentului a.
Daca argumentul este negativ sau NaN, rezultatul este NaN. public static double IEEEremainder(double f1, double f2)- calculeaza restul impartirii f1/f2 conform prescriptiilor standardului IEEE 754. Restul este egal matematic cu
362
Programarea orientata pe obiecte în limbajul Java valoarea expresiei f1-f2*n, unde n este numarul intreg cel mai apropiat de valoarea exacta a raportului f1/f2. Daca restul este zero, el are semnul primului argument. public static double ceil(double a)- intoarce,
sub forma de valoare double, cel mai mic numar intreg care nu este mai mic decat argumentul (rotunjire prin adaos); public static double floor(double a)- intoarce,
sub forma de valoare double, cel mai mare numar intreg care nu este mai mare decat argumentul (rotunjire prin micsorare); public static double rint(double a)- intoarce,
sub forma de valoare double, numarul
intreg cel mai apropiat de argument; public static double atan2(double a, double b)- calculeaza arctg(a/b) in
intervalul [-pi, pi] tinand seama de semnele argumentelor a si b (se considera ca se calculeaza argumentul theta la conversia din coordonate carteziene (b, a) in coordonate polare (r, theta)). b
public static double pow(double a, double b)- calculeaza a . Daca (a==0 sau daca (a<=0 si b nu este un numar intreg) se genereaza o exceptie aritmetica.
si b<=0)
public static int round(float a)- se intoarce numarul
intreg cel mai apropiat de argument. Daca acest intreg este mai mic decat marginea inferioara pentru tipul int, rezultatul este Integer.MIN_VALUE. Daca acest intreg este mai mare decat marginea superioara pentru tipul int, se obtine rezultatul Integer.MAX_VALUE. public static long round(double a)- intoarce numarul
intreg cel mai apropiat de
argument (cu aceleasi observatii ca la metoda precedenta). public static double random()- intoarce un
numar pseudoaleator in intervalul [0.0, 1.0], avand o lege de repartitie (aproximativ) uniforma in acest interval. public static int abs(int a)- intoarce modului
argumentului a (valoarea absoluta);
public static long abs(long a)- intoarce modului public static float abs(float a)- intoarce
argumentului a (valoarea absoluta);
modulul argumentului a (valoarea
absoluta); public static double abs(double a)- intoarce modulul
argumentului a (valoarea
absoluta); public static int max(int a, int b)- intoarce cel
mai mare din cele doua argumente;
public static long max(long a, long b)- intoarce
cel mai mare din cele doua
argumente; public static float max(float a, float b)- intoarce
argumente;
363
cel mai mare din cele doua
Severin Bumbaru public static double max(double a, double b)- intoarce
cel mai mare din cele doua
argumente; public static int min(int a, int b)- intoarce cel
mai mic din cele doua argumente;
public static float min(float a, float b)intoarce cel
mai mic din cele doua
argumente; public static double min(double a, double b)intoarce cel
mai mic din cele doua
argumente;
Class Object java.lang.Object -------------------------------------------------------------------------------public class Object
Clasa Object este radacina ierarhiei de clase Java. Orice alta clasa ore clasa Object ca superclasa. Toate celelalte clase, inclusiv tablourile, implementeaza metodele acestei clase ------------------------------------------------------------------------------Constructor: public Object()
Metode: protected
Object clone()
Creaza si intoarce o copie a acestui obiect. public boolean equals(Object obj)
Indica daca acest obiect este sau nu "egal cu" obiectul obj primit ca argument. protected
void finalize()
Este apelata de colectorul de reziduuri atunci cand acesta constata ca nu mai exista referinte la obiectul respectiv. public Class getClass()
Intoarce clasa caruia ii apartine obiectul. public int hashCode()
Intoarce codul de dispersie al obiectului public void notify()
Notifica un singur fir de executie dintre cele care asteapta acest obiect.
364
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. public void wait()
Pune firul de executie curent in asteptare, 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, sau pana cand exprira intervalul de timp dat timeout dat ca argument. Timpul este exprimat in milisecunde. public void wait(long timeout, int nanos)
Pune firul de executie curent in asteptare, pana cand alt fir de executie invoca metoda notify sau notifyAll() pentru acest obiect, sau pana cand exprira intervalul de timp dat timeout dat ca argument, sau pana cand alt fir de asteptare il intrerupe pe cel curent. Timpul de asteptare, exprimat in nanosecunde, este in acest caz 1000000*timeout+nanos, unde nanos este un intreg in intervalul 0..999999.
Clasa String public final class String extends Object implements Serializable, Comparable
Instantele clasei String sunt siruri de caractere. Orice literal sir in limbajul Java, de exemplu "abc", este un astfel de obiect. Sirurile sunt constante, deci continutul lor nu poate fi modificat. Pentru a obtine siruri modificabile se va folosi clasa StringBuffer. Nota: amintim ca in limbajul Java reprezentarea interna a caracterelor se face pe 16 biti, in Unicode. Campuri: public static Comparator CASE_INSENSITIVE_ORDER Campul contine un Comparator care ordoneaza obiectele-sir
cand ele sunt comparate
cu metoda comparetoIgnoreCase(). Constructori: public String()
Creeaza un sir vid. public String(byte[] bytes)
Creeaza un obiect al clasei String care contine caracterele din tabloul de octeti primit ca argument. Se considera ca in acest tablou caracterele sunt reprezentate pe 8 biti, in codul local valabil pe calculatorul pe care se executa programul. Daca referinta la tablou este nula se genereaza o NullPointerException. 365
Severin Bumbaru public String(byte[] bytes, int offset, int length)
Actioneaza similar cu constructorul precedent, cu observatia ca se preiau din tabloul bytes numai length octetii de pe pozitiile care incep de la indicele offset. Pot fi generate NullPointerException daca referinta la tablou este nula, sau o IndexOutOfBoundsException daca indicii sunt gresiti. public String(byte[] bytes, int offset, int length, String enc)
Actioneaza similar cu constructorul precedent, dar la conversia din octet in Unicode se foloseste sistemul de codificare a caracterelor enc. Pot fi generate NullPointerException daca referinta la tablou este nula, sau o IndexOutOfBoundsException daca indicii sunt gresiti,sau UnsupportedEncodingException daca argumentul enc este gresit. public String(byte[] bytes, String enc)
Construieste un sir care contine caracterele din tabloul de octeti bytes. Se considera ca in acest tablou caracterele sunt reprezentate in codul enc. Se genereaza NullPointerException daca referinta la tablou este nula, sau UnsupportedEncodingException daca argumentul enc este gresit.. public String(char[] value)
Construieste un sir care contine caracterele din tabloul de caractere value. 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, int offset, int count)
Actioneaza similar cu constructorul precedent, dar preia din tabloul value numai count caractere, incepand cu cel de pe pozitia offset. Pot fi generate NullPointerException daca referinta la tablou este nula, sau o IndexOutOfBoundsException daca indicii sunt gresiti. public String(String value)
Creeaza un nou sir, in care il copiaza pe cel dat ca argument. public String(StringBuffer buffer)
Creeaza un nou sir, care contine aceleasi caractere ca cele din argumentul buffer, care apartine clasei StringBuffer (deci este o zona-tampon pentru siruri). Metode: public char charAt(int index)
Intoarce caracterul situat in sir pe pozitia index. Se genereaza IndexOutOfBoundsException daca indicele este gresit. public int compareTo(Object o) Compara acest sir cu obiectul o
primit ca argument. Daca acest obiect nu este un sir, se genereaza o exceptie de incompatibilitate de clase (ClassCastException). Daca o este un sir, atunci compararea se face la fel ca in metoda urmatoare. public int compareTo(String anotherString) Compara acest sir cu sirul anotherString primit
ca argument. Daca cele doua siruri sunt identice, intoarce 0 (zero). Daca acest sir il precede pe o intoarce o valoare negativa, iar
366
Programarea orientata pe obiecte în limbajul Java daca ii succede lui o intoarce o valoare pozitiva. Compararea sirurilor se face in ordine lexicografica (in ordinea in care ar fi plasate intr-un dictionar). public int compareToIgnoreCase(String str) Compara lexicografic acest sir cu sirul str primit
ca argument, ignorand deosebirea
dintre literele majuscule si cele minuscule. public String concat(String str)
Concateneaza acest sir cu sirul str primit ca argument. public static String copyValueOf(char[] data)
Intoarce un sir care contine aceleasi caractere cu cele din tabloul data. Se poate genera NullPointerException daca referinta la tablou este nula. public static String copyValueOf(char[] data, int offset, int count) Similar cu metoda precedenta, dar se preiau din tabloul data numai count caractere incepand cu pozitia offset. Se poate genera NullPointerException daca referinta la tablou
este nula public boolean endsWith(String suffix)
Testeaza daca acest sir se termina cu subsirul suffix. public boolean equals(Object anObject)
Testeaza daca acest sir este "egal" cu obiectul anObject. public boolean equalsIgnoreCase(String anotherString)
Testeaza daca acest sir contine aceleasi caractere ca argumentul anotherString, ignorand deosebirea dintre literele mici si cele mari. public byte[] getBytes()
Converteste acest sir intr-un tablou de octeti, luind in consideratie codificarea locala de pe calculatorul pe care ruleaza programul. public byte[] getBytes(String enc)
Similara cu metoda precedenta, dar conversia se face folosind codificarea enc. Se genereaza UnsupportedEncodingException daca argumentul enc este gresit. public void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) Copiaza caracterele din acest sir in tabloul de caractere de destinatie char[]. Copierea incepe de la caracterul de pe pozitia srcBegin si se termina la caracterul de pe pozitia srcEnd-1. Plasarea in tabloul de destinatie incepe cu pozitia dstBegin. Se poate genera
NullPointerException daca referinta la tablou este nula sau IndexOutOfBoundsException daca indicii sunt gresiti.. public int hashCode()
Intoarce codul de dispersie pentru acest sir. public int indexOf(int ch)
Intoarce indicele la care se gaseste in sir prima aparitie a caracterului ch. Daca acest caracter nu exista in sir, intoarce -1.
367
Severin Bumbaru public int indexOf(int ch, int fromIndex)
Similar cu metoda precedenta, dar cautarea in sir incepe de la pozitia fromIndex. public int indexOf(String str)
Intoarce indicele pozitiei de pe care in acest sir apare prima data subsirul str. public int indexOf(String str, int fromIndex)
Similar cu metoda precedenta, dar cautarea in acest sir incepe de la pozitia fromIndex. public String intern()
Intoarce o reprezentare canonica a acestui obiect-sir. public int lastIndexOf(int ch)
Intoarce indicele ultimei pozitii pe care apare caracterul ch in acest sir. public int lastIndexOf(int ch, int fromIndex)
Intoarce indicele ultimei pozitii pe care se gaseste caracterul ch daca se face cautarea inapoi incepand de la pozitia fromIndex. public int lastIndexOf(String str)
Intoarce indicele ultimei aparitii in acest sir a subsirului str. public int lastIndexOf(String str, int fromIndex)
Similar cu metoda precedenta, dar cautarea inapoi se face de la pozitia fromIndex. publicint length()
Intoarce lungimea acestui sir (numarul de caractere continute). public boolean regionMatches(boolean ignoreCase, int toffset, String other, int ooffset, int len) Testeaza daca o regiune din acest sir este egala cu o regiune din sirul other primit ca argument. Daca primul argument (ignoreCase) are valoarea true, comparatia se face ignorand deosebirea dintre caracterele mari si cele mici. Argumentele tooffset si ooffset
reprezinta indicii pozitiilor de la care incep regiunile comparate in acest sir si, respectiv, in sirul-argument other. Argumentul len este lungimea celor doua zone comparate. public boolean regionMatches(int toffset, String other, int ooffset, int len)
Similar cu metoda precedenta, dar se ia in consideratie deosebirea intre literele mici si cele mari. public String replace(char oldChar, char newChar)
Intoarce un nou sir, care are acelasi continut cu acest sir, dar in care toate aparitiile caracterului oldChar sunt inlocuite prin caracterul newChar. public boolean startsWith(String prefix) Testeaza daca acest sir incepe cu subsirul prefix. public boolean startsWith(String prefix, int toffset) Testeaza daca subsirul prefix incepe in acest sir de pe pozitia index.
368
Programarea orientata pe obiecte în limbajul Java public String substring(int beginIndex)
Intoarce un nou sir, care contine caracterele acestui sir incepand de la pozitia beginIndex, pana la sfarsit. public String substring(int beginIndex, int endIndex) Intoarce subsirul situat intre pozitiile beginIndex si endIndex-1. public char[] toCharArray()
Converteste acest sir intr-un tablou de caractere. public String toLowerCase()
Intoarce un nou sir, in care literele mari ale acestui sir sunt inlocuite cu litere mici. public String toLowerCase(Locale locale)
Similar cu metoda precedenta, dar inlocuirea literelor mari cu cele mici se face respectand conventia locale. public String toString()
Intoarce chiar acest sir. public String toUpperCase()
Intoarce un nou sir, provenit din acest sir, in care toate literele mici au fost inlocuite cu litere mari. public String toUpperCase(Locale locale)
Similar cu metoda precedenta, dar conversia se face respectand conventia locale. public String trim()
Intoarce un nou sir, 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. public static String valueOf(char c)
Intoarce un sir care contine numai caracterul c. public static String valueOf(char[] data)
Intoarce reprezentarea sub forma de sir a tabloului de caractere data. Se genereaza NullPointerException daca referinta la tablou este nula. public static String valueOf(char[] data, int offset, int count) Intoarce reprezentarea sub forma de sir a subtabloului de lungime count cuprins tabloul data incepand de la indicele offset. Se genereaza NullPointerException daca
referinta la tablou este nula. 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.
369
in
Severin Bumbaru public static String valueOf(int i)
Intoarce reprezentarea ca sir a unui argument de tip int. public static String valueOf(long l)
Intoarce reprezentarea ca sir a unui argument de tip long. public static String valueOf(Object obj) Intoarce reprezentarea ca sir a obiectului obj.
Metode mostenite de la clasa java.lang.Object: clone, finalize, getClass, notify, notifyAll, wait
Clasa StringBuffer public final class StringBuffer extends Object implements Serializable
Un StringBuffer implementeaza un sir de caractere care poate fi modificat. El reprezinta o zona tampon din memorie, in care se ppoate plasa un sir de caractere. Operatiile principale asupra unui StringBuffer sunt metodele append si insert. Fiecare din ele converteste o data intr-un String, pe care apoi il adauga la sirul din StringBuffer sau il insereaza in acesta pe o pozitie data. Fiecare StringBuffer are o capacitate si o lungime. Lungimea este numarul efectiv de caractere continute, iar capacitatea este numarul maxim de caractere care incap in zona tampon rezervata in memorie. Daca, printr-o noua adaugare de caractere, lungimea depaseste capacitatea, atunci capacitatea se mareste in mod automat.
Constructori: public StringBuffer()
- construieste un StringBuffer vid cu capacitatea 16 caractere.
public StringBuffer(int length)- construieste un StringBuffer vid de Daca length este negativ, se genereaza o NegativeArraySizeException. public StringBuffer(String str)- construieste iar capacitatea este lungimea lui str plus 16.
lungime length.
un StringBuffer care contine sirul str,
Metode: public int length()-
intoarce lungimea sirului continut in StringBuffer (numarul de
caractere). public int capacity()- intoarce
capacitatea curenta a zonei tampon. 370
Programarea orientata pe obiecte în limbajul Java public void ensureCapacity(int minimumCapacity)- asigura capacitatea minima a zonei tampon. Daca capacitatea curenta este mai mica decat minimumCapacity, se aloca in
memorie o noua zona tampon si se transfera in ea sirul curent. Capacitatea noului StringBuffer este cea mai mare dintre valoarea argumentului minimumCapacity si dublul vechii capacitati. public void setLength(int newLength)- seteaza noua lungime a acestui StringBuffer. Daca noua lungime newLength este mai mica decat cea existenta, sirul este trunchiat. Daca newLength este mai mare decat cea curenta, se adauga un numar suficient de caractere nule
(\0000) pentru a se obtine noua lungime. Daca argumentul newLength este negativ se genereaza o exceptie IndexOutOfBoundsException. public char charAt(int index)- intoarce
caracterul de pe pozitia de indice index. Daca indicele nu se incadreaza in lungimea sirului curent, se genereaza o IndexOutOfBoundsException. public void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)
Caracterele situate in StringBuffer intre pozitiile srcBegin si srcEnd-1 sunt copiate in tabloul de caractere dst incepand de la pozitia dstBegin. Daca dst este null se genereaza o NullPointerException. Daca srcBegin, srcEnd sau dstBegin nu sunt corecte, se genereaza o IndexOutOfBondsException. public void setCharAt(int index, char ch)- se pune caracterul ch Daca index este incorect, se genereaza o IndexOutOfBoundsException. public StringBuffer append(Object obj)- se adauga obiectul obj
pe pozitia index.
convertit in sir.
public StringBuffer append(String str)- se adauga sirul str. public StringBuffer append(char[] str)- se adauga toate caracterele tabloul str.
continute in
public StringBuffer append(char[] str, int offset, int len)- se adauga la acest StringBuffer len caractere din tabloul str, incepand de la pozitia offset din acest tablou. public StringBuffer append(boolean b)- se
adauga valoarea booleana b convertita in
sir. public StringBuffer append(char c)- se adauga
caracterul c.
public StringBuffer append(int i)- se adauga intregul i
convertit in sir.
public StringBuffer append(long l)- se adauga numarul
intreg llung l convertit in sir.
public StringBuffer append(float f)- se adauga numarul
real f convertit in sir.
public StringBuffer append(double d)- se adauga numarul
371
real d convertit in sir.
Severin Bumbaru public StringBuffer delete(int start, int end)- se elimina caracterele de pe pozitiile de la indicele start pana la end-1. Daca start este negativ, mai mare ca lungimea sau mai mare ca end se genereaza o StringIndexOutOfBoundsException. public StringBuffer deleteCharAt(int index)- se elimina caracterul index sau se genereaza o StringIndexOutOfBoundsException.
de pe pozitia
public StringBuffer replace(int start, int end, String str)- caracterele situate in StringBuffer pe pozitiile de la start la end-1 se inlocuiesc prin subsirul str. Daca indicii start sau end nu sunt corecti se genereaza o StringIndexOutOfBoundsException. public String substring(int start)- intoarce subsirul sau genereaza o StringIndexOutOfBoundsException.
care incepe de la pozitia start
public String substring(int start, int end)- intoarce subsirul pozitia end-1 sau genereaza o StringIndexOutOfBoundsException.
de la pozitia start la
public StringBuffer insert(int index, char[] str, int offset, int len)
Incepand de la pozitia index insereaza in StringBuffer len caractere situate in tabloul str de la pozitia offset sau se genereaza o StringIndexOutOfBoundsException. public StringBuffer insert(int offset, Object obj)- insereaza incepand
de la pozitia offset obiectul obj reprezentat ca sir. Daca offset nu este corect se genereaza o StringingIndexOutOfBoundsException. public StringBuffer insert(int offset, String str)- se insereaza incepand pozitia offset sirul str. Daca offset este incorect se genereaza o StringIndexOutOfBoundsException.
de la
public StringBuffer insert(int offset, char[] str)- incepand de la pozitia offset se insereaza caracterele din tabloul str. Daca offset este incorect se genereaza o StringIndexOutOfBoundsException. public StringBuffer insert(int offset, boolean b)- se insereaza incepand pozitia offset valoarea booleana b convertita in sir, sau se genereaza o StringIndexOutOfBoundsException. public StringBuffer insert(int offset, char c)- pe pozitia offset caracterul c sau se genereaza o StringIndexOutOfBoundsException. public StringBuffer insert(int offset, int i)- incepand insereaza numarul intreg i convertit in sir sau se genereaza o StringIndexOutOfBoundsException.
372
se insereaza
de la pozitia offset se
public StringBuffer insert(int offset, long l)- incepand
insereaza numarul intreg lung l convertit in sir, sau se genereaza o StringIndexOutOfBoundsException.
de la
de la pozitia offset se
Programarea orientata pe obiecte în limbajul Java public StringBuffer insert(int offset, float f)- incepand
de la pozitia offset se
insereaza numarul real f convertit in sir sau se genereaza o StringIndexOutOfBoundsException. public StringBuffer insert(int offset, double d)- incepand
de la pozitia offset se
insereaza numarul real f convertit in sir sau se genereaza o StringIndexOutOfBoundsException. public StringBuffer reverse()- se pun
caracterele din StringBuffer in ordine inversa
celei actuale. public String toString()- intoarce un String StringBuffer.
care are acelasi continut cu acest
-------------------------------------------------------------------------------Metode mostenite de la clasa Object: clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait
Interfaţa Comparable java.lang.Comparable
Interfaţa este implementată de clasele ale căror instanţe pot fi comparate între ele, deci fac parte dintr-o mulţime ordonată. Interfaţa conţine o singură metodă: - compară obiectul de care aparţine cu obiectul obj primit ca argument. Valoarea întoarsă este: 0 (zero) - dacă cele două obiecte sunt egale; valoare negativă, dacă obiectul propriu îl precede pe obj; valoare pozitivă, dacă obiectul propriu este succesor al lui obj. public int compareTo(Object obj)
Fie a şi b două obiecte, aparţinând unei clase cu interfaţa Comparable. În acest caz: a.compareTo(b)<0 dacă a0 dacă a>b (a succede lui b).
Clasa BufferedInputStream Face parte din pachetul java.IO şi extinde clasa FilterInputStream. Instanţele acestei clase sunt fluxuri de intrare de octeţi, care conţin o zonă tampon (buffer). Octeţii sunt citiţi unul câte unul din această zonă tampon. Când zona tampon se goleşte, ea se
373
Severin Bumbaru umple din nou, în mod automat, prin citirea din fluxul de intrare căruia acest BufferedInputStream îi este ataşat.
Constructori public BufferedInputStream(InputStream in) ataşat fluxului de intrare in.
- se creează un BufferedInputStream
public BufferedInputStream(InputStream in, int size) - se creează un BufferedInputStream ataşat fluxului de intrare in, lungimea zonei tampon fiind de size
octeţi.
Metode Aceleaşi ca în clasa InputStream.
Clasa BufferedOutputStream Face parte din pachetul java.io şi extinde clasa FilterOutputStream
Constructori public BufferedOutputStream(OutputStream out) - 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 BufferedOutputStream(OutputStream out, int size) - 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;
Metode Aceleaşi ca în clasa OutputStream.
Clasa BufferedReader Face parte din pachetul java.io şi extinde clasa Reader.
Constructori - creează un flux de intrare de caractere, cu zonă tampon de lungime implicită, conectat la ieşirea fluxului de intrare de caractere in. public BufferedReader(Reader in)
374
Programarea orientata pe obiecte în limbajul Java public BufferedReader(Reader in, cu zonă tampon de lungime sz, conectat
- creează un flux de intrare de caractere, la ieşirea fluxului de intrare de caractere in. int sz)
Metode Aceleaşi ca în clasa Reader.
Clasa BufferedWriter Face parte din pachetul java.io şi extinde clasa Writer. Caracterele primite sunt acumulate într-o zonă tampon şi sunt transmise la ieşire numai când această zonă tampon s-a umplut, sau când se execută metoda flush().
Constructori - creează un flux de ieşire de caractere, cu zonă tampon de lungime implicită, conectat la ieşire la fluxul de caractere out. public BufferedWriter(Writer out)
public BufferedWriter(Writer out, int sz) - creează un flux de ieşire de caractere, zonă tampon de lungime sz, conectat la ieşire la fluxul de caractere out.
cu
Metode Aceleaşi ca în clasa Writer.
Clasa ByteArrayInputStream Face parte din pachetul java.io şi extinde clasa InputStream. Acest flux conţine o zonă tampon (buffer) din care se citesc datele, situată în memoria internă.
Câmpuri protected byte[] buf - tabloul de octeţi din care se face citirea, situat în memoria internă. protected int pos - indicele următorului octet care va fi citit din tabloul de octeţi de intrare buf[]. protected int mark - poziţia marcată din flux (este iniţializată implicit la zero şi poate fi modificată prin metoda mark()). protected int count - 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) - creează un citeşte din tabloul buf[] situat în memoria internă.
375
flux de intrare de octeţi, care
Severin Bumbaru public ByteArrayInputStream(byte[] buf, int offset, int length) - creează un flux de intrare de octeţi, 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.
Metode Aceleaşi ca la clasa InputStream.
Clasa ByteArrayOutputStream Face parte din pachetul java.io şi extinde clasa OutputStream. Flux de ieşire de octeţi, care scrie într-un tablou de octeţi situat în memoria internă. 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ă. Referinţa la zona tampon pentru scriere se obţine prin metoda toByteArray().
Câmpuri protected byte[] buf - tabloul de octeţi în care se face scrierea, situat în memoria protected int count - numărul de octeţi valizi existenţi în tabloul buf[].
internă.
Constructori - 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, dacă este necesar. public ByteArrayOutputStream()
- 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, dar capacitatea creşte automat, dacă este necesar. public ByteArrayOutputStream(int size)
Metode Metodele sunt cele din clasa OutputStream, la care se adaugă: public void writeTo(OutputStream out) throws IOException - scrie în fluxul ieşire out întregul conţinut al tabloului (yonei tampon) buf, ca şi când s-ar fi fi făcut invocarea de metodă out.write(buf, 0, cont). public byte[] toByteArray() - întoarce un conţinutul valid al yonei tampon buf.
de
nou tablou de octeţi, în care este copiat
public int size() - întoarce dimensiunea curentă a zonei tampon (valoarea câmpului count).
Clasa CharArrayReader
376
Programarea orientata pe obiecte în limbajul Java Face parte din pachetul java.io şi extinde clasa Reader. Instanţele acestei clase sunt fluxuri de intrare de carractere, care citesc dintr-un tablou de caractere situat in memoria internă.
Constructori public CharArrayReader(char[] buf) - creează un flux de intrare de caractere, citeşte din tabloul de caractere buf[], situat ]n memoria internă.
care
public CharArrayReader(char[] buf, int offset, int length) - creează un flux intrare de caractere, care citeşte din tabloul de caractere buf[], situat ]n memoria internă. Citirea începe de la poziţia de indice offset, iar yona de citire are lungimea length.
de
Metode Aceleaşi ca în clasa Reader.
Clasa CharArrayWriter Face parte din pachetul java.io şi extinde clasa Writer. Instanţele sunt fluxuri de ieşire de caractere, care scriu într-o zonă tampon sub formă de tablou de caractere extensibil, situat în memoria internă. Datele din zona tampon de ieşire pot fi obţinute prin metodele toCharArray() şi toString().
Constructori - creează un flux de ieşire de caractere, care scrie într-o zonă tampon situată în memoria internă, a cărei lungime este dată implicit. public CharArrayWriter()
- creează un flux de ieşire de caractere, care scrie într-o zonă tampon situată în memoria internă, a cărei lungime este initialSize. public CharArrayWriter(int initialSize)
Metode Aceleaşi ca în clasa Writer, la care se adaugă: public void writeTo(Writer out) throws IOException în fluxul de ieşire de caractere out.
- scrie datele din zona tampon
public char[] toCharArray() - întoarce un tablou de caractere, având acelaşi conţinut cu zona tampon de ieşire. public int size()
- întoarce lungimea curentă a zonei tampon.
public String toString()
- întoarce un şir, care are acelaşi conţinut cu zona tampon.
Clasa FileDescriptor 377
Severin Bumbaru Face parte din pachetul java.io. Instanţele clasei FileDescriptor servesc ca manipulatori ai unor fişiere sau socluri deja deschise. Principala utilizare este la crearea unor fluxuri din clasele FileInputStream sau FileOutputStream, conectate la fişiere deja deschise.
Câmpuri public static final FileDescriptor in sistemului, System.in.
- descriptorul fişierului de intrare standard a
public static final FileDescriptor out sistemului, System.out
- descriptorul fişierului de ieşire standard a
public static final FileDescriptor err a sistemului, System.err
- descriptorul fişierului de ieşire pentru erori
Constructori public FileDescriptor()
- creează o instanţă a clasei Filedescriptor, 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 - existentă în clasele FileInputStream şi FileOutputStream. Această metodă întoarce descriptorul fişierului respectiv.
Metode public boolean valid()
- indică dacă acest descriptor de fişier este valid (se referă la un
fişier sau soclu deschis). public void sync() throws SyncFailedException
- forţează sincroniăarea zonelor
tampon ale sistemului pentru dispozitivul corespunzător.
Clasa FilterInputStream Face parte din pachetul java.io. Este superclasa claselor de fluxuri de intrare de octeţi, care realizează anumite operaţii de filtrare (prelucrare) a datelor de intrare. De fapt, metodele acestei clase sunt cele moştenite de la superclasa InputStream, deci nu fac nici o prelucrare. Aceste metode pot fi însă redefinite în subclase, pentru a realiza astfel de prelucrări. În pachetul java.io există subclasele DataInputStream, BufferedInputStream şi PushbackInputStream. Putem crea şi propriile noastre subclase.
Constructor protected FilterInputStream(InputStream in) filtru, care preia fluxul de intrare in.
Metode Aceleaşi ca în clasa InputStream.
378
- creează un flux de intrare de octeţi cu
Programarea orientata pe obiecte în limbajul Java
Clasa FilterOutputStream Face parte din pachetul java.io. Este superclasa claselor de fluxuri de ieşire de octeţi, care realizează anumite operaţii de filtrare (prelucrare) a datelor de ieşire. De fapt, metodele acestei clase sunt cele moştenite de la superclasa OutputStream, deci nu fac nici o prelucrare. Aceste metode pot fi însă redefinite în subclase, pentru a realiza astfel de prelucrări. În pachetul java.io există subclasele DataOutputStream, BufferedOutputStream, PrintStream şi altele. Putem crea şi propriile noastre subclase.
Constructor - creează un flux de ieşire de octeţi cu filtru, care transmite datele la fluxul de ieşire de octeţi out. public FilterOutputStream(OutputStream out)
Metode Metodele sunt aceleaşi ca în clasa OutputStream.
Clasa FilterReader Face parte din pachetul java.io. Este superclasa claselor de fluxuri de intrare de caractere, care realizează anumite operaţii de filtrare (prelucrare) a datelor de intrare. De fapt, metodele acestei clase sunt cele moştenite de la superclasa Reader, deci nu fac nici o prelucrare. Aceste metode pot fi însă redefinite în subclase, pentru a realiza astfel de prelucrări. În pachetul java.io există subclasa PushbackReader. Putem crea şi propriile noastre subclase.
Constructor protected FilterReader(Reader in) care preia fluxul de intrare in.
- creează un flux de intrare de caractere cu filtru,
Metode metodele sunt la fel cele din superclasa Reader.
Clasa FilterWriter Face parte din pachetul java.io. Este superclasa claselor de fluxuri de ieşire de caractere, care realizează anumite operaţii de filtrare (prelucrare) a datelor de ieşire. De fapt, metodele acestei clase sunt cele moştenite de la superclasa Writer, deci nu fac nici o prelucrare. Aceste metode pot fi însă redefinite în subclase, pentru a realiza astfel de prelucrări.
379
Severin Bumbaru
Constructor protected FilterWriter(Writer out) - creează un flux de ieşire de caractere cu filtru, care transmite datele la fluxul de ieşire de caractere out.
Metode Aceleaşi ca în superclasa Writer.
Clasa EventObject public class EventObject extends Object implements Serializable Face parte din pachetul java.util. Este rădăcina ierarhiei de clase de evenimente. Fiecare eveniment este generat de o sursă (source). Fiecare instanţă a clasei EventObject conţine o referinţă la această sursă şi o metodă prin care ea este obţinută.
Constructor public EventObject(Object source)
- se generează un eveniment, indicându-se sursa.
Metode public Object getSource() public String toString()
- întoarce sursa evenimentului.
- întoarce reprezentarea sub formă de String a evenimentului.
Interfaţa EventListener public interface EventListener Face parte din pachetul java.util. Este o interfaţă generică, pe care trebuie să o extindă direct sau indirect - orice interfaţă de ascultătoare de evenimente. Interfaţa nu conţine nici o metodă.
Clasa AWTEvent public abstract class AWTEvent extends EventObject Face parte din pachetul java.awt. Este superclasa tuturor claselor de evenimente AWT. Orice eveniment AWT are un identificator, reprezentat prin câmpul id. Clasa conţine câmpuri
380
Programarea orientata pe obiecte în limbajul Java statice, care au ca valori măşti pentru selectarea după id a diferitelor tipuri de evenimente. 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. Clasa AWTEvent înlocuieşte clasa Event din JDK 1.0, care a fost menţinută în pachet numai pentru compatibilitate. Subclasele directe ale clasei AWTEvent sunt: ActionEvent, AdjustmentEvent, AncestorEvent, ComponentEvent, HierarchyEvent, InputMethodEvent, InternalFrameEvent, InvocationEvent, ItemEvent, TextEvent. Ele se găsesc în pachetul java.awt.event, cu excepţia clasei InternalFrameEvent, care se găseşte în pachetul javax.swing.event.
Câmpuri protected int id
- identificatorul tipului de eveniment.
public static final long COMPONENT_EVENT_MASK
- masca pentru selectarea
evenimentelor de componentă. public static final long CONTAINER_EVENT_MASK
- masca pentru selectarea
evenimentelor de container. public static final long FOCUS_EVENT_MASK
- masca pentru selectarea evenimentelor
de focalizare public static final long KEY_EVENT_MASK
- masca pentru selectarea evenimentelor de
tastă. public static final long MOUSE_EVENT_MASK
- masca pentru selectarea evenimentelor
de mouse. public static final long MOUSE_MOTION_EVENT_MASK
- masca pentru selectarea
evenimentelor de mişcare a mouse-ului. public static final long WINDOW_EVENT_MASK
- masca pentru selectarea evenimentelor
de fereastră. public static final long ACTION_EVENT_MASK
- masca pentru selectarea evenimentelor
de acţiune. public static final long ADJUSTMENT_EVENT_MASK
- masca pentru selectarea
evenimentelor de ajustare. public static final long ITEM_EVENT_MASK
- masca pentru selectarea evenimentelor de
articol. public static final long TEXT_EVENT_MASK
- masca pentru selectarea evenimentelor de
text. public static final long INPUT_METHOD_EVENT_MASK
evenimentelor de metodă de intrare.
381
- masca pentru selectarea
Severin Bumbaru public static final long PAINT_EVENT_MASK
- masca pentru selectarea evenimentelor
de desenare. public static final long INVOCATION_EVENT_MASK
- masca pentru selectarea
evenimentelor de invocare. public static final long HIERARCHY_EVENT_MASK
- masca pentru selectarea
evenimentelor de ierarhie. public static final long HIERARCHY_BOUNDS_EVENT_MASK
- masca pentru selectarea
evenimentelor de margini ale ierarhiei. public static final int RESERVED_ID_MAX
- valoarea maximă rezervată pentru id.
Constructori - construieşte un obiect din clasa AWTEvent, folosind paramerii unei instanţe a clasei Event. public AWTEvent(Event event)
- construieşte o nouă instanţă a clasei AWTEvent, specificându-se sursa şi tipul de eveniment. public AWTEvent(Object source, int id)
Metode principale Metodele clasei EventObject, la care se adaugă: public int getID()
- întoarce tipul de eveniment.
public String toString()
- întoarce reprezentarea sub formă de String a evenimentului.
- întoarce un şir care conţine parametrii evenimentului. Se foloseşte în special la depanarea programului. public String paramString()
Clasa BorderLayout public class BorderLayout extends Object implements LayoutManager2, Serializable Suprafaţa containerului prevăzut cu acest gestionar de poziţionare se împarte în cinci zone: NORTH, SOUTH, WEST, EAST şi CENTER. În fiecare din aceste zone poate fi pusă câte o singură componentă. Dăm aici un exemplu de utilizare a unui gestionar de poziţionare din clasa BorderLayout: p.setLayout(new BorderLayout()); p.add(new Button("OK"), BorderLayout.SOUTH);
În prima instrucţiune, pentru containerul p se setează gestionarul de poziţionare BorderLayout. În a doua instrucţiune, se pune butonul cu inscripţia "OK" în zona SOUTH a aceluiaşi container. Dacă se omite zona, se consideră implicit că adăugarea componentei se face în zona CENTER.
382
Programarea orientata pe obiecte în limbajul Java
Constructori - se creează un gestionar de poziţionare BorderLayout, fără distanţare între componente. public BorderLayout()
- se creează un gestionar de poziţionare BorderLayout, având distanţări între componente hgap pe orizontală şi vgap pe verticală. public BorderLayout(int hgap, int vgap)
Metode Metodele din interfeţele LayoutManager şi LayoutManager2, la care se adaugă următoarele: public int getHgap()
- întoarce distanţarea pe orizontală între componente.
public void setHgap(int hgap) - setează distanţarea pe orizontală între componente. public int getVgap()
- întoarce distanţarea pe verticală între componente.
public void setVgap(int vgap)
- setează distanţarea pe verticală între componente.
Clasa Button public class Button extends Component implements Accessible Instanţele acestei clase sunt butoane care conţin un text numit "etichetă" (engl: label). Când este apăsat, butonul generează un eveniment de acţiune, care poate fi ascultat cu un ActionListener.
Constructori public Button()
- construieşte un buton care nu conţine text.
public Button(String label)
- construieşte un buton care conţine eticheta specificată.
Metode Metodele sunt cele ale clasei Component la care se adaugă următoarele: public String getLabel()
- întoarce eticheta butonului.
public void setLabel(String label)
- setează eticheta butonului.
- setează numele acţiunii de comandă generată de buton. Dacă nu se foloseşte această comandă, implicit acest nume este identic cu eticheta butonului. public void setActionCommand(String command)
public String getActionCommand()
- întoarce numele acţiunii de comandă generată de
buton.
383
Severin Bumbaru public void addActionListener(ActionListener l)
- adaugă la buton un ascultător de
evenimente de acţiune. public void removeActionListener(ActionListener l)
- elimină ascultătorul de
evenimente de acţiune specificat.
Clasa Canvas public class Canvas extends Component implements Accessible Instanţele acestei clase sunt suprafeţe rectangulare albe, pe care se pot trasa desene (în engleză, canvas este pânza pe care se pictează). Pentru a realiza un desen, se creează o subclasă a clasei Canvas, pentru care se redefineşte metoda paint.
Constructori public Canvas()
- creează o nouă instanţă a clasei Canvas.
public Canvas(GraphicsConfiguration config) Canvas, folosind configuraţia grafică config.
- creează o nouă instanţă a clasei
Medtode Metodele clasei Component, dintre care cea mai utilizată este metoda: public void paint(Graphics g) folosind contextul grafic g.
- desenează pe suprafaţa acestei componente (Canvas),
Clasa CardLayout public class CardLayout extends Object implements LayoutManager2, Serializable Instanţele acestei clase sunt gestionari de poziţionare, care plasează componentele în container una peste alta, ca într-un pachet de cărţi de vizită.La un moment dat este vizibilă numai componenta de deasupra, însă componentele îşi pot schimba locurile între ele prin rotaţie.
Constructori public CardLayout()
- construieşte un CardLayout fără spaţiu liber în jurul componentelor.
public CardLayout(int hgap, int vgap) - construieşte un margini spaţiile libere hgap pe orizontală şi vgap pe verticală.
384
cardLayout care are pe
Programarea orientata pe obiecte în limbajul Java
Metode Metodele interfeţelor LayoutManager şi LayoutManager2, la care se adaugă următoarele: public int getHgap()
- întoarce spaţiul liber pe orizontală.
public void setHgap(int hgap) public int getVgap()
- setează spaţiul liber pe orizontală.
- întoarce spaţiul liber pe verticală.
public void setVgap(int vgap)
- setează spaţiul liber pe verticală.
public void first(Container parent)
- pune deasupra prima componentă din
containerul părinte specificat. public void next(Container parent)
- pune deasupra următoarea componentă a
containerului specificat. - pune deasupra componenta precedentă a containerului specificat.componenta cu numele name din containerul specificat. public void previous(Container parent)
public void show(Container parent, String name) - pune deasupra public void last(Container parent)
- pune deasupra ultima componentă din
containerul specificat.
Clasa Color Clasa Color încapsulează culorile din spaţiul de culori implicit sRGB, sau culori dintrun spqaţiu de culori arbitrar, identificat prin ColorSpace. Fiecare culoare conţine, în afară de componentele de culoare fundamentale, şi o componentă numită alpha, care semnifică opacitatea şi are valori reale în intervalul 0.0 ... 1.0 sau valori întregi în intervalul 0 .. 255. Valoarea alpha=0 înseamnă opacitate nulă (culoare total transparentă), iar valoarea maximă a lui alpha înseamnă opacitate maximă (culoare total netransparentă). În mod implicit se admite opacitatea maximă. Culorile fundamentale din sistemul sRGB (standard RGB) sunt următoarele: red (roşu), green (verde) şi blue (albastru). Acestea pot fi date prin numere întregi în intervalul 0 .. 255 sau prin numere reale în intervalul 0.0 .. 1.0. Aceste valori reprezintă intensitatea culorii fundamentale respective în culoarea dată. Orice culoare se obţine prin combinarea acestor trei componente fundamentale, cu intensităţi diferite. Explicaţii suplimentare sunt date şi în secţiunea "Clasa Color" din acest manual. Valorile componentelor fundamentale ale culorii pot fi date şi împachetate într-un singur număr de tip int, în care fiecare octet conţine una din componente (în intervalul 0 .. 255) astfel: blue - biţii 0 ..7; green: biţii 8 .. 15; red: biţii 16 .. 23; alpha: biţii 24 .. 31. Clasa Color conţine şi câmpuri finale pentru culorile tipice.
385
Severin Bumbaru
Câmpuri public static final Color white
- culoarea albă.
public static final Color lightGray public static final Color gray
- culoarea gri.
public static final Color darkGray public static final Color black public static final Color red
- culoarea gri deschis.
- culoarea gri închis.
- culoarea neagră.
- culoarea roşie.
public static final Color pink
- culoarea roz.
public static final Color orange
- culoarea portocalie (orange).
public static final Color yellow
- culoarea galbenă.
public static final Color green
- culoarea verde.
public static final Color magenta
- culoarea violet.
public static final Color cyan
- culoarea azuriu (albastru deschis)
public static final Color blue
- culoarea albastră.
Constructori - creează o instanţă a clasei Color pentru cu culoarea cu componentele RGB specificate prin numere întregi cuprinse între 0 şi 255. public Color(int r, int g, int b)
- 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. public Color(int r, int g, int b, int a)
- creează o instanţă a clasei Color, dându-i ca argument un număr de tip int (pe 4 octeţi), care în primii trei octeţi conţine cele trei componente fundamentale. public Color(int rgb)
public Color(int rgba, boolean hasalpha) - creează o instanţă a clasei Color, dându-i ca argument un număr de tip int (pe 4 octeţi), care în primii trei octeţi conţine cele trei componente fundamentale, iar în ultimul octet componenta alpha. Al doilea argument indică dacă există sau nu componenta alpha. public Color(float r, float g, float b) - creează o instanţă a clasei Color pentru cu culoarea cu componentele RGB specificate prin numere reale cuprinse între 0.0 şi 1.0. public Color(float r, float g, float b, float a) - public Color(int r, int g, int b, int a) - creează o instanţă a clasei Color pentru cu culoarea cu componentele RGB şi componenta a (alpha) specificate prin numere reale cuprinse între 0.0 şi 1.0. 386
Programarea orientata pe obiecte în limbajul Java public Color(ColorSpace cspace, float[] components, float alpha) - creează o instanţă a clasei Color, dându-se spaţiul de culori cspace (instanţă a clasei ColorSpace), tabloul de componente components şi opacitatea alpha.
Metode public int getRed()
- întoarce componenta roşie.
public int getGreen() public int getBlue()
- întoarce componenta verde.
- întoarce componenta albastră.
public int getAlpha()
- întoarce componenta alpha.
- întoarce un int, care conţine sub formă împachetată cele patru componente (r, g, b, alpha). public int getRGB()
public Color brighter() public Color darker()
- întoarce o variantă mai deschisă a acestei culori.
- întoarce o variantă mai închisă a acestei culori.
public static Color decode(String nm) throws NumberFormatException
converteşte un şir de caractere, care reprezintă culoarea codificată în octal sau hexazecimal, şi întoarce instanţa corespunzătoare a clasei Color. - 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), generând instanţa corespunzătoare a clasei Color. public static Color getColor(String nm)
- similar cu metoda precedentă, dar se indică şi culoarea implicită v care va fi folosită dacă proprietatea de sistem cu numele nm. public static Color getColor(String nm, Color v)
public static Color getColor(String nm, int v)
- similar cu metoda precedentă, dar
culoarea implicită este dată printr-un număr întreg. public static int HSBtoRGB(float hue, float saturation, 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, reprezentată sub forma unui număr de tip int. public static float[] RGBtoHSB(int r, int g, int b, float[] hsbvals)
- face conversia culorii din RGB în HSB. Întoarce un tablou, care conţine cele trei componente fundamentale HSB, corespunzătoare componentelor de culoare RGB date ca parametri. Ultimul argument poate fi null, sau poate conţine un tablou în care se vor întoarce componwentele HSB rezultate.
387
Severin Bumbaru - întoarce o instanţă a clasei Color, care conţine culoarea pentru care s-au dat ca argumente valorile componentelor sale în sistemul HSB. public static Color getHSBColor(float h, float s, float b)
public float[] getRGBComponents(float[] compArray)
- întoarce un tablou de tip float care conţine cele trei componente RGB şi componenta alpha pentru această culoare. Parametrul compArray poate fi null, sau este un tablou cu cel puţin 4 componente de tip float, în care se vor pune valorile întoarse. public float[] getRGBColorComponents(float[] compArray)
- similar cu metoda precedentă, dar întoarce un tablou cu trei componente, care conţine numai cele trei componente RGB (fără componenta alpha). public ColorSpace getColorSpace()
- întoarce spaţiul culorilor pentru această culoare (o
instanţă a clasei ColorSpace). public PaintContext createContext(ColorModel cm, Rectangle r, Rectangle2D r2d, AffineTransform xform, RenderingHints hints) - întoarce un context de desenare, care este necesar ca argument în metodele claselor cu interfaţa Paint. public int getTransparency()
- întoarce transparenţa acestei culori (necesară pentru
implementarea interfeţei Paint).
Clasa Component public abstract class Component extends Object implements ImageObserver, MenuContainer, Serializable Face parte din pachetul java.awt. Este rădăcina ierarhiei tuturor claselor de componente ale interfeţelor grafice AWT şi JFC/Swing.
Metode public String getName()
- întoarce numele componentei.
public void setName(String name) public Container getParent()
- setează numele componentei.
- întoarce o referinţă către containerul care conţine
această componentă. - setează un obiect DropTarget pentru această componentă. Componenta va putea fi ţinta unei operaţii de "drag and drop" (tragere şi lăsare cu mausul), atunci când este activă. public void setDropTarget(DropTarget dt)
public DropTarget getDropTarget()
- întoarce obiectul DropTarget asociat acestei
componente.
388
Programarea orientata pe obiecte în limbajul Java - întoarce configuraţia grafică a acestei componente sau a containerului în care se găseşte, sau null. public GraphicsConfiguration getGraphicsConfiguration()
public final Object getTreeLock()
- î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). public Toolkit getToolkit()
- întoarce Toolkit-ul pentru această componentă.
- indică dacă această componentă este validă (este corect dimensionată şi poziţionată în containerul său părinte). public boolean isValid()
- indică dacă această componentă este afişabilă (este conectată la o resursă de ecran de afişare nativă). public boolean isDisplayable()
- indică dacă această componentă este vizibilă. Toate componentele sunt iniţial vizibile, cu excepţia celor de cel mai înalt nivel, cum sunt cele din clasele Frame şi JFrame. public boolean isVisible()
public boolean isShowing()
- indică dacă această componentă apare efectiv pe ecran.
- arată dacă această componentă este activă (poate răspunde la intrările date de utilizator şi să genereze evenimente). public boolean isEnabled()
- face ca această componentă să fie activă sau inactivă, după cum valoarea argumentului este true sau false. public void setEnabled(boolean b)
public void setVisible(boolean b) public Color getForeground()
- setează proprietatea de vizibilitate a componentei.
- întoarce culoarea de prim-plan a componentei (culoarea
textului). public void setForeground(Color c) public Color getBackground()
- întoarce culoarea de fond a componentei.
public void setBackground(Color c) public Font getFont()
- setează culoarea de prim-plan a componentei.
- setează culoarea de fond a componentei.
- întoarce fontul componentei.
public void setFont(Font f)
- setează fontul componentei.
public ColorModel getColorModel()
- întoarce modelul de culori al componentei.
- întoarce locaţia componentei (coordonatele colţului din stânga sus), în sistemul de coordonate al containerului părinte. public Point getLocation()
- întoarce locaţia componentei (coordonatele colţului din stânga sus) în sistemul de coordonate al ecranului. public Point getLocationOnScreen()
389
Severin Bumbaru - setează locaţia componentei (coordonatele colţului din stânga sus) în sistemul de coordonate al containerului părinte. public void setLocation(int x, int y)
- setează locaţia componentei (coordonatele colţului din stânga sus) în sistemul de coordonate al containerului părinte. public void setLocation(Point p)
public Dimension getSize()
- întoarce dimensiunile componentei.
public void setSize(int width, int height) public void setSize(Dimension d)
- setează dimensiunile componentei.
- setează dimensiunile componentei.
- întoarce o instanţă a clasei Rectangle (dreptunghi) care conţine lăţimea, înălţimea şi locaţia componentei. public Rectangle getBounds()
public void setBounds(int x, int y, int width, int height)
- setează
coordonatele colţului din stânga sus, lăţimea şi înălţimea componentei. public void setBounds(Rectangle r)
- setează locaţia şi dimensiunile componentei.
- întoarce coordonata x a colţului din stânga-sus (în sistemul de coordonate al containerului părinte). public int getX()
- întoarce coordonata y a colţului din stânga-sus (în sistemul de coordonate al containerului părinte). public int getY()
public int getWidth()
- întoarce lăţimea componentei.
public int getHeight()
- întoarce înălţimea componentei.
public boolean isOpaque()
- indică dacă această componentă este opacă (implicit, toate
componentele sunt opace). - întoarce true dacă această componentă nu are un suport nativ. Toate componentele Swing şi unele din componentele AWT sunt "Lightweight", adică sunt desenate în Java şi deci nu folosesc componentele grafice de pe platforma locală. public boolean isLightweight()
public Dimension getPreferredSize()
- întoarce dimensiunile preferabile ale
componentei. public Dimension getMinimumSize()
- întoarce dimensiunile minime ale componentei.
public Dimension getMaximumSize()
- întoarce dimensiunile maxime ale componentei.
public void doLayout()
- transmite gestionarului de poziţionare indicaţia de a poziţiona
componenta. public void validate()
- asigură că această componentă are un gestionar de poziţionare
valid.
390
Programarea orientata pe obiecte în limbajul Java - invalidează componenta. Această componentă şi părinţii săi sunt marcaţi că necesită poziţionare. public void invalidate()
- creează un context grafic pentru această componentă.Intoarce null dacă această componentă nu este afişabilă. public Graphics getGraphics()
public void setCursor(Cursor cursor) public Cursor getCursor()
- setează cursorul pentru această componentă.
- întoarce cursorul setet pentru această componentă sau
pentru părintele ei. public void paint(Graphics g) - desenează componenta. Această metodă este apelată automat când trebuie desenată componenta. public void update(Graphics g) - actualizează desenul componentei, ca răspuns la invocarea metodelor repaintupdate sau repaint. Aceasta înseamnă că: (1) se şterge vechiul
conţinut, umplând componenta cu culoarea de fond; (2) se setează culoarea de primplan în contextul grafic pentru această componentă; (3) se apelează metoda paint pentru a desena complet componenta. public void paintAll(Graphics g)
- desenează această componentă şi toate
subcomponentele sale. - redesenează componentă (face ca metoda update pentru această componentă să fie invocată cât mai rapid posibil). public void repaint()
public void repaint(long tm)
- apelează metoda update în tm milisecunde.
public void repaint(int x, int y, int width, int height)
- redesenează
dreptunghiul specificat al componentei. public void repaint(long tm, int x, int y, int width, int height) redesenează dreptunghiul specificat al componentei după tm milisecunde. public void print(Graphics g)
-
- tipăreşte componenta.
public void printAll(Graphics g)
- tipăreşte componenta şi toate subcomponentele ei.
public boolean imageUpdate(Image img, int infoflags, int x, int y, int w, int h) - redesenează componenta când s-a modificat imaginea pe care o conţine. public Image createImage(ImageProducer producer)
- creează o imagine din
producătorul de imagine specificat. - verifică dacă această componentă conţine punctul de coordonate (x, y), în sistemul de coordonate propriu al componentei. public boolean contains(int x, int y)
- verifică dacă această componentă conţine punctul p, în sistemul de coordonate propriu al componentei. public boolean contains(Point p)
391
Severin Bumbaru public Component getComponentAt(int x, int y)
- întoarce subcomponenta care
conţine punctul de coordonate (x, y). public Component getComponentAt(Point p)
- întoarce subcomponenta care conţine
punctul p. public void addComponentListener(ComponentListener l)
- adaugă acestei
componente un ascultător de evenimente generate de către ea. public void removeComponentListener(ComponentListener l)
- elimină ascultătorul
de evenimente de componentă specificat. public void addFocusListener(FocusListener l)
- adaugă un ascultător de evenimente
de focalizare. public void removeFocusListener(FocusListener l)
- elimină ascultătorul de
evenimente de focalizare. public void addHierarchyListener(HierarchyListener l)
- adaugă un ascultător de
evenimente de ierarhie. public void removeHierarchyListener(HierarchyListener l)
- elimină ascultătorul
de evenimente de ierarhie. public void addKeyListener(KeyListener l)
- adaugă un ascultător de evenimente de
tastă. public void removeKeyListener(KeyListener l)
- elimină ascultătorul de evenimente
de tastă. public void addMouseListener(MouseListener l)
- adaugă un ascultător de evenimente
de mouse. public void removeMouseListener(MouseListener l)
- elimină ascultătorul de
evenimente de mouse. public void addMouseMotionListener(MouseMotionListener l)
- adaugă un ascultător
de evenimente de mişcare a mouse-ului. public void removeMouseMotionListener(MouseMotionListener l)
- elimină
ascultătorul de evenimente de mişcare a mouse-ului. public void addInputMethodListener(InputMethodListener l)
- adaugă un ascultător
de evenimente de metodă de intrare. public void removeInputMethodListener(InputMethodListener l)
ascultătorul de evenimente de metodă de intrare.
392
- elimină
Programarea orientata pe obiecte în limbajul Java public EventListener[] getListeners(Class listenerType)
- întoarce un tablou de ascultătoare de evenimente ataşate acestei componente şi având tipul dat ca argument. De exemplu, pentru a obţine tabloul ascultătoarelor de evenimente de mouse adăugate componentei c se pune instrucţiunea: MouseListener[] mls = (MouseListener[])(c.getListeners(MouseListener.class)) public void add(PopupMenu popup)
- adauga la componentă meniul popup specificat.
public void remove(MenuComponent popup)
- elimină meniul popup specificat.
- întoarce un şir de caractere care reprezintă starea componentei. Se foloseşte numai pentru depanarea programului. protected String paramString()
public String toString() public void list()
- întoarce reprezentarea sub formă de şir a acestei componente.
- afişează listingul acestei componente pe System.out.
public void list(PrintStream out)
- scrie listingul acestei componente în fluxul out.
public void list(PrintStream out, int indent) în fluxul out, indentat cu indent. public void list(PrintWriter out)
- scrie listingul acestei componente
- scrie listingul acestei componente în fluxul out.
public void list(PrintWriter out, int indent) - scrie listingul acestei componente în fluxul out, indentat cu indent. public void addPropertyChangeListener(PropertyChangeListener listener)
-
adaugă un ascultător de evenimente de schimbare a proprietăţilor. public void removePropertyChangeListener(PropertyChangeListener listener)
-
elimină ascultătorul de evenimente de schimbare a proprietăţilor. public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) - adaugă un ascultător de evenimente
de schimbare a
proprietăţilor, pentru proprietatea specificată prin primul argument. public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) - elimină ascultătorul de evenimente
de schimbare a
proprietăţilor, pentru proprietatea specificată prin primul argument. protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) - suport pentru raportarea modificărilor de proprietăţi. 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ă. public void setComponentOrientation(ComponentOrientation o)
componentei.
393
- setează orientarea
Severin Bumbaru public ComponentOrientation getComponentOrientation()
- întoarce orientarea
componentei. public AccessibleContext getAccessibleContext()
- întoarce contextul accesibil.
Clasa Container public class Container extends Component Containerele sunt componente care pot conţine alte componente (inclusiv alte containere, deoarece şi acestea sunt sunt tot componente). Componentele adăugate în container sunt păstrate într-o listă. Ordinea din această listă este cea în care componentele sunt luate în consideraţie de către gestionarul de poziţionare.
Constructor public Container()
- construieşte un nou container.
Metode Metodele clasei Component, la care se adaugă următoarele: public int getComponentCount()
- întoarce numărul de componente conţinute în acest
container. public Component getComponent(int n)
- întoarce componenta care are indicele i în
lista de componente a containerului. public Component[] getComponents()
- întoarce un tablou cu toate componentele
conţinute în container. public Insets getInsets()
- întoarce lăţimea bordurii containerului (sub forma unui
obiect din clasa Insets). public Component add(Component comp)
- adaugă componenta comp la sfârşitul listei de
componente a containerului. public Component add(Component comp, int index) poziţia din lista de componente cu indicele index.
- se adaugă componenta comp pe
public void add(Component comp, Object constraints) - se adaugă componenta comp cu restricţiile date de obiectul constraints. Adăugarea se face la sfârşitul listei de
componente. public void add(Component comp, Object constraints, int index) - se adaugă componenta comp cu restricţiile date de obiectul constraints. Adăugarea se face pe poziţia de indice index a listei de componente.
394
Programarea orientata pe obiecte în limbajul Java public void remove(int index) public void removeAll()
- elimină componenta de indice index.
- elimină toate componentele conţinute în container.
public LayoutManager getLayout()
- întoarce gestionarul de poziţionare al containerului.
public void setLayout(LayoutManager mgr)
- setează gestionarul de poziţionare al
containerului. public void doLayout()
- pune în acţiune gestionarul de poziţionare al containerului.
public void paintComponents(Graphics g)
- desenează fiecare componentă din acest
container. public void printComponents(Graphics g)
- tipăreşte toate componentele din acest
container. public void addContainerListener(ContainerListener l)
- adaugă un ascultător de
evenimente de container. public void removeContainerListener(ContainerListener l)
- elimină ascultătorul
de evenimente de container specificat. public Component findComponentAt(int x, int y)
- întoarce componenta care conţine
punctul de coordonate (x,y). public Component findComponentAt(Point p)
- întoarce componenta care conţine
punctul p.
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). Ea are bordură şi este folosită în special pentru dialogul (schimbul de informaţii interactiv) cu utilizatorul. Managerul de poziţionare implicit este BorderLayout. Generează următoarele evenimente de fereastră: WindowOpened, WindowClosing, WindowClosed, WindowActivated, WindowDeactivated. Fereastra de dialog are ca proprietar o altă fereastră din clasa Frame sau Dialog. Când proprietarul este ascuns sau minimizat, fereastra de dialog este de asemenea ascunsă. Fereastra de dialog poate fi modală sau nemodală (implicit este nemodală). O fereastră modală blochează toate intrările către orice altă fereastră de cel mai înalt nuvel şi descendentele lor, cu excepţia celor care au ca proprietar chiar această fereastră de dialog.
395
Severin Bumbaru
Constructori public Dialog(Frame owner) proprietar cadrul owner.
- construieşte o fereastră de dialog fără titlu, având ca
public Dialog(Frame owner, boolean modal) - construieşte o fereastră de dialog fără titlu, cu proprietarul owner, specificându-se dacă ea este sau nu modală. public Dialog(Frame owner, String title)
- construieşte o ferestră de dialog,
indicându-se proprietarul şi titlul ferestrei. public Dialog(Frame owner, String title, boolean modal)
- construieşte o fereastră
de dialog, indicându-se proprietarul, titlul şi dacă este sau nu modală. public Dialog(Dialog owner)
- construieşte o fereastră de dialog fără titlu, având ca
proprietar altă fereastră de dialog. public Dialog(Dialog owner, String title)
- construieşte o fereastră de dialog cu
titlu, având ca proprietar altă fereastră de dialog. - construieşte o fereastră de dialog cu titlu, având ca proprietar altă fereastră de dialog şi indicându-se dacă este sau nu modală. public Dialog(Dialog owner, String title, boolean modal)
Metode Metodele clasei Window, la care se adaugă următoarele: public boolean isModal()
- indică dacă fereastra de dialog este sau nu modală.
public void setModal(boolean b)
- specifică dacă fereastra de dialog va fi sau nu
modală. public String getTitle()
- întoarce titlul ferestrei de dialog (poate fi şi null).
public void setTitle(String title) public boolean isResizable()
- setează titlul ferestrei de dialog.
- îndică dacă fereastra de dialog este sau nu
redimensionabilă. public void setResizable(boolean resizable) - specifică dacă această fereastră de dialog va fi sau nu redimensionabilă.
Clasa Dimension public class Dimension extends Dimension2D implements Serializable
396
Programarea orientata pe obiecte în limbajul Java Instanţele acestei clase conţin dimensiunile orizontală şi vericală ale unei componente, exprimate ca numere întregi.
Câmpuri public int width
- lăţimea.
public int height
- înălţimea.
Constructori public Dimension()
- construieşte o instanţă a clasei Dimension, conţinând dimensiuni
nule. public Dimension(Dimension d)
- construieşte o copie a lui d.
public Dimension(int width, int height) conţinând lăţimea width şi înălţimea height.
- construieşte o instanţă a clasei Dimension,
Metode public double getWidth()
- întoarce lăţimea.
public double getHeight()
- întoarce înălţimea.
public void setSize(double width, double height)
- setează lăţimea şi înălţimea,
argumentele fiind de tip double. public void setSize(int width, int height)
- setează lăţimea şi înălţimea,
argumentele fiind de tip int. public boolean equals(Object obj) - redefineşte metoda equals din clasa Object.
Clasa Event public class Event extends Object implements Serializable Clasa Event este clasa evenimentelor generate de interfaţa utilizator grafică utilizată în JDK 1.0 (în prima versiune a Java API) şi menţinută în continuare pentru compatibilitate, deşi începând cu JDK 1.1 ea a fost înlocuită prin clasa AWTEvent.
Clasa FlowLayout 397
Severin Bumbaru Gestionarul de poziţionare FlowLayout plasează componentele pe suprafaţa containerului pe linii succesive, de la stânga la dreapta şi de sus în jos, ca literele dintr-un text. Fiecare componentă are deimensiunile ei preferate. Alinierea componentelor poate fi făcută la stânga, la dreapta sau pe centru (alinierea implicită este pe centru). Dacă se modifică dimensiunile containerului, componentele se rearanjează, menţinându-şi ordinea şi dimensiunile, dar putând trece de pe o linie pe alta. Clasa conţine câmpuri statice finale, cu denumirile modurilor de aliniere a componentelor.
Câmpuri public static final int LEFT
- aliniere la stânga.
public static final int CENTER public static final int RIGHT
- aliniere la centru.
- aliniere la dreapta
- aliniere la muchia frontală pentru orientarea dată a containerului (adică aliniere la stânga, în cazul când ordinea de plasare este de la stânga la dreapta). public static final int LEADING
- aliniere la muchia terminală, ţinând cont de orientarea dată a containerului (deci aliniere la dreapta, dacă ordinea de plasare a componentelor este de la stânga la dreapta). public static final int TRAILING
Constructori - construieşte un FlowLayout cu aliniere implicită a componentelor (la centru) şi cu spaţii libere între componente de 5 unităţi. public FlowLayout()
- construieşte un nou FlowLayout, cu alinierea componentelor specificată. Parametrul align poate fi unul din câmpurile: FlowLayout.LEFT, FlowLayout.CENTER, FlowLayout.RIGHT. public FlowLayout(int align)
- construieşte un nou FlowLayout, fiind specificate alinierea şi spaţiile libere între componente pe orizontală şi pe verticală. public FlowLayout(int align, int hgap, int vgap)
Metode metodele din interfaţa LayoutManager, la care se adaugă următoarele: public int getAlignment()
- întoarce alinierea.
public void setAlignment(int align) - setează alinierea. Parametrul align poate fi din câmpurile: FlowLayout.LEFT, FlowLayout.CENTER, FlowLayout.RIGHT. public int getHgap()
unul
- întoarce spaţiul liber între componente pe orizontală.
public void setHgap(int hgap)
- setează spaţiul liber între componente pe orizontală.
398
Programarea orientata pe obiecte în limbajul Java public int getVgap()
- întoarce spaţiul liber între componente pe verticală.
public void setVgap(int vgap)
- setează spaţiul liber între componente pe verticală.
Clasa Font public class Font extends Object implements Serializable Instanţele clasei Font reprezintă fonturi şi încorporează fiecare informaţii privind forma, mărimea şi stilul unui caracter. Caracterele sunt simbolurile tipografice folosite în texte. Stilurile sunt: plain (normal), bold, italic, bold+italic. Mărimea fontului (înălţimea literei majuscule) se exprimă în puncte tipografice. Cele mai răspândite fonturi folosite în programele Java sunt:
Serif - toate caracterele au serifuri, adică mici liniuţe prin care se termină liniile principale care formează caracterul respectiv; lăţimea caracterelor este variabilă, de exemplu W este mai lat decât I).
SansSerif - caracterele nu au serifuri, dar au lăţimea variabilă. Monospaced - toate caracterele au aceeaşi lăţime,
ca
cele de la maşina de scris. Aceste fonturi există pe toate maşinile virtuale Java, dar pot fi instalate şi alte fonturi.
Câmpuri statice finale pentru stiluri public static final int PLAIN public static final int BOLD
- stilul PLAIN (normal).
- stilul BOLD (caractere îngroşate, aldine).
public static final int ITALIC
- stilul italic (cursiv).
Constructori - se construieşte un nou font, fiind specificate numele fontului, stilul şi mărimea. Numele fontului poate fi "Serif", "SansSerif", "Monospaced" sau alt stil existent pe maşina virtuală Java respectivă. Stiluol poate fi Font.PLAIN, Font.BOLD, Font.ITALIC sau Font.BOLD|Font.ITALIC. public Font(String name, int style, int size)
- construieşte un nou font, folosind atributele specificate prin argument. La alcătuirea mapării atributelor se folosesc numai cheile definite în clasa TextAttribute (pentru detalii se va consulta Java API). public Font(Map attributes)
Metode principale public static Font getFont(Map attributes)
- întoarce fontul care corespunde cel mai
bine setului de atribute specificat ca argument. public AffineTransform getTransform()
- întoarce transformarea asociată acestui font.
399
Severin Bumbaru public String getFamily()
- întoarce numele familiei de fonturi din care face parte acest
font. public String getPSName()
- întoarce numele PostScript al acestui font.
public String getName() - întoarce numele getFontName() pentru a afla numele fontului. public String getFontName() public int getStyle() public int getSize()
logic al acestui font. Se va folosi
- întoarce numele fontului.
- întoarce stilul fontului.
- întoarce mărimea fontului, exprimată în puncte tipografice.
public boolean isPlain() public boolean isBold()
- indică dacă stilul caracterului este PLAIN (normal).
- indică dacă stilul caracterului este BOLD (aldin, îngroşat).
public boolean isItalic()
- indică dacă stilul caracterului este ITALIC (cursiv).
- întoarce fontul din lista de proprietăţi a sistemului. Ca parametru se dă numele proprietăţii. public static Font getFont(String nm)
public static Font decode(String str) - întoarce fontul str. Dacă argumentul este null, se întoarce un font implicit.
pe care îl descrie argumentul
- întoarce un nou font, care să aibă aceeaşi formă cu acesta, dar să aibă stilul şi mărimea specificate. public Font deriveFont(int style, float size)
public Font deriveFont(float size)
- întoarce un nou font, similar acestuia, dar cu
mărimea specificată. public Font deriveFont(int style)
- întoarce un nou font, similar acestuia, dar cu stilul
specificat.
Clasa Frame public class Frame extends Window implements MenuContainer Face parte din pachetul java.awt. Instanţele acestei clase sau ale subclaselor ei sunt folosite ca ferestre pr4incipale ale aplicaţiilor. Un Frame este o fereastră care are chenar şi bară de titlu. Este o fereastră de cel mai înalt nivel (top-level window), deci poate fi plasată direct pe ecranul fizic. Generează evenimente de fereastră (din clasa WindowEvent), care pot fi ascultate cu un WindowListener sau WindowAdapter. La partea superioară i se poate pune o bară de meniu (MenuBar). Iniţial, cadrul este invizibil, dar poate fi făcut vizibil invocând setVisible(true), iar dimensiunile se stabilesc prin setSize(int, int), ambele fiind metode ale clasei Component.
400
Programarea orientata pe obiecte în limbajul Java
Constructori public Frame()
- construieşte un cadru (Frame) fără titlu.
- 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, într-un sistem multiecran). public Frame(GraphicsConfiguration gc)
public Frame(String title)
- construieşte un cadru (Frame) cu titlul title.
public Frame(String title, GraphicsConfiguration gc) (Frame) cu titlul title şi cu configuraţia grafică gc.
- construieşte un cadru
Metode public String getTitle()
- întoarce titlul cadrului (cel din bara de titlu).
public void setTitle(String title) public Image getIconImage()
- pune titlul title în bara de titlu.
- întoarce imaginea care trebuie afişată ca pictogramă la
minimizarea acestui cadru. public void setIconImage(Image image)
- setează imaginea care trebuie afişată ca
pictogramă la minimizarea acestui cadru. public MenuBar getMenuBar()
- îmtoarce bara de meniu a acestui cadru, sau null, dacă ea
nu există. public void setMenuBar(MenuBar mb)
- setează pentru acest cadru bara de meniu mb.
- indică dacă acest cadru poate fi redimensionat de către utilizator (prin tragere cu mouse-ul). Implicit, toate instanţele clasei Frame sunt redimensionabile. public boolean isResizable()
public void setResizable(boolean resizable)
- setează dacă acest cadru poate sau nu
să fie redimensionat de către utilizator. public void setState(int state) public int getState()
- setează starea acestui cadru.
- întoarce starea acestui cadru.
public void remove(MenuComponent m) public static Frame[] getFrames()
- elimină bara de meniu specificată.
- întoarce tabloul tuturor cadrelor (Frame) deschise
de o aplicaţie sau accesibile unui applet. Clasa Frame moşteneşte şi toate metodele clasei Window, deci şi pe cele ale claselor Container şi Component.
401
Severin Bumbaru
Clasa Graphics2D public abstract class Graphics2D extends Graphics Este noul context grafic, care extinde clasa Graphics, pentru a putea realiza desene mult mai complexe. Pentru utilizarea acestei clase şi, deci, a aplica în Java tehnicile de grafică 2D, recomandăm să se consulte documentaţia originală Java API şi capitolul 2D Graphics din Tutorialul Java.
Clasa GridBagLayout public class GridBagLayout extends Object implements LayoutManager2, Serializable Este un gestionar de poziţionare flexibil, care permite să se alinieze orizontal şi vertical componente de dimensiuni diferite. Pentru folosirea acestei clase recomandăm să se consulte Tutorialul Java şi să se folosească documentaţia Java API originală.
Clasa GridLayout public class GridLayout extends Object implements LayoutManager, Serializable Gestionarii de poziţionare din clasa GridLayout aranjează componentele în container sub forma unei grile rectangulare. Fiecare celulă a grilei conţine o singură componentă.
Constructori public GridLayout()
- construieşte un GridLayout cu o singură linie de componente.
public GridLayout(int rows, int cols) - construieşte un GridLayout cu rows cols coloane. Unul din cele două argumente (dar nu ambele) poate fi 0 (zero).
linii şi
- construieşte un nou GridLayout, specificându-se numărul de linii şi de coloane şi spaţiile libere între componente pe orizontală şi pe verticală. public GridLayout(int rows, int cols, int hgap, int vgap)
Metode Metodele interfeţei LayoutManager, la care se adaugă următoarele: public int getRows()
- întoarce numărul de linii al grilei.
public void setRows(int rows) public int getColumns()
- setează numărul de linii al grilei.
- întoarce numărul de coloane al grilei.
402
Programarea orientata pe obiecte în limbajul Java public void setColumns(int cols) public int getHgap()
- întoarce distanţarea pe orizontală a componentelor.
public void setHgap(int hgap) public int getVgap()
- setează numărul de coloane al grilei.
- setează distanţarea pe orizontală a componentelor.
- întoarce distanţarea pe verticală a componentelor.
public void setVgap(int vgap)
- setează distanţarea pe verticală a componentelor.
Clasa Insets public class Insets extends Object implements Cloneable, Serializable Instanţele acestei clase conţin lăţimile marginilor libere ale containerelor (care nu conţin componente). Marginea respectivă poate fi complet liberă, sau poate conţine o bordură sau un titlu.
Câmpuri public int top
- marginea de sus
public int left
- marginea din stânga
public int bottom public int right
- marginea de jos
- marginea din dreapta.
Constructor - construieşte o instanţă a clasei Insetws, fiind specificate marginile de sus, stânga, jos şi dreapta. public Insets(int top, int left, int bottom, int right)
Metode Cele moştenite de la clasa Object.
Class Panel public class Panel extends Container implements Accessible Panoul este cea mai simplă clasă de containere. Un panou este un dreptunghi fără bordură pe suprafaţa căruia se pot plasa diferite componente ale interfeţei grafice, inclusiv alte panouri.
403
Severin Bumbaru
Constructori public Panel()
- construieşte un nou panou, având gestionarul de poziţionare implicit
FlowLayout. public Panel(LayoutManager layout)
- construieşte un nou panou, cu gestionarul de
poziţionare specificat.
Metode Metodele clasei Container şi superclaselor acesteia.
Clasa Point public class Point extends Point2D implements Serializable Fiecare instanţă a acestei clase conţine coordonatele (x, y) ale unui punct, exprimate prin numere întregi.
Constructori public Point()
- construieşte un punct de coordonate (0, 0).
public Point(Point p)
- construieşte o copie a punctului p.
public Point(int x, int y) - construieşte un punct de coordonate (x, y).
Metode principale public double getX()
- întoarce coordonata x.
public double getY()
- întoarce coordonata y.
public void setLocation(int x, int y)
- setează noile valori ale coordonatelor
punctului. public void translate(int dx, int dy)
- efectuează o translaţie a acestui punct, astfel
că noile coordonate vor fi x+dx, y+dy.
Clasa Rectangle Instanţele acestei clase sunt suprafeţe de formă dreptunghiulară, cu laturile dispuse orizontal şi vertical, pentru care se dau următoarele elemente: x, y - coordonatele colţului din stânga sus; width - lăţimea dreptunghiului; height - înălţimea dreptunghiului. Valorile acestor elemente sunt exprimate prin numere întregi. 404
Programarea orientata pe obiecte în limbajul Java
Constructori public Rectangle()
- construieşte un dreptunghi cu coordonatele (0, 0) şi dimensiunile
nule. public Rectangle(Rectangle r)
- construieşte o copie a dreptunghiului r.
- construieşte un dreptunghi, pentru care sunt specificate coordonatele originii (x, y), lăţimea şi înălţimea. public Rectangle(int x, int y, int width, int height)
- construieşte un dreptunghi cu originea în punctul de coordonate (0 0) şi având specificate lăţimea şi înălţimea. public Rectangle(int width, int height)
public Rectangle(Point p, Dimension d)
- construieşte un dreptunghi cu originea în
punctul p şi dimensiunile d. public Rectangle(Point p)
- construieşte un dreptunghi cu originea în punctul p şi
dimensiuni nule. public Rectangle(Dimension d)
- construieşte un dreptunghi cu originea în punctul (0, 0)
şi dimensiunile d.
Metode mai frecvent utilizate public double getX()
- întoarce coordonata x a colţului stânga-sus.
public double getY()
- întoarce coordonata y a colţului stânga-sus.
public double getWidth()
- întoarce lăţimea.
public double getHeight()
- întoarce înălţimea.
public void setBounds(int x, int y, int width, int height)
- setează toate
elementele date ca parametri. public void setBounds(Rectangle r)
- setează elementele acestui dreptunghi la fel ca la
dreptunghiul r. public Point getLocation()
- întoarce punctul de origine (colţul stânga-sus).
public void setLocation(Point p)
- setează punctul de origine (colţul stânga-sus).
public void setLocation(int x, int y)
- setează coordonatele punctului de origine
(colţul stânga-sus). public void translate(int dx, int dy)
- translatează dreptunghiul, astfel că noile
coordonate devin (x+dx, y+dy). public Dimension getSize()
- întoarce dimensiunile dreptunghiului.
public void setSize(Dimension d)
- setează dimensiunile dreptunghiului. 405
Severin Bumbaru public void setSize(int width, int height) public boolean contains(Point p)
- setează dimensiunile dreptunghiului.
- indică dacă acest dreptunghi conţine punctul p.
public boolean contains(int x, int y)
- indică dacă acest dreptunghi conţine punctul
de coordonate (x, y). public boolean contains(Rectangle r)
- indică dacă acest dreptunghi conţine
dreptunghiul r. public boolean contains(int x, int y, int width, int height)
- indică dacă acest
dreptunghi conţine dreptunghiul ale cărui elemente sunt specificate. public boolean intersects(Rectangle r)
- indică dacă acest dreptunghi intersectează
dreptunghiul r. public Rectangle intersection(Rectangle r)
- întoarce intersecţia acestui dreptunghi
cu dreptunghiul r. - întoarce dreptunghiul cel mai mic care conţine în întregime acest dreptunghi şi dreptunghiul r. 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), fără bordură şi fără bară de meniu. Trebuie să aibă drept proprietar un cadru, o fereastră de dialog sau o altă instanţă a clasei Window.
Constructori public Window(Frame owner)
- se construieşte o nouă fereastră, având ca proprietar o
instanţă a clasei Frame. public Window(Window owner)
- se construieşte o nouă fereastră, având ca proprietar altă
fereastră din clasa Window. public Window(Window owner, GraphicsConfiguration gc) - se construieşte o nouă fereastă, având proprietarul owner şi configuraţia grafică gc (poate fi afişată şi pe un alt ecran fizic, în sistemele cu mai multe ecrane).
Metode Metodele clasei Container, la care se adaugă următoarele:
406
Programarea orientata pe obiecte în limbajul Java - face ca fereastra să fie dimensionată la dimensiunea preferată şi componentele ei să fie aranjate de către gestionarul de poziţionare, după care fereastra este făcută afişabilă şi este validată. public void pack()
public void show()
- face fereastra vizibilă pe ecran.
public void hide()
- ascunde fereastra (o face invizibilă).
public void toFront() public void toBack()
- plasează fereastra deasupra celorlalte de pe ecran.
- plasează fereastra în spatele celorlalte de pe ecran.
public final String getWarningString()
- întoarce textul de avertizare, care însoţeşte
această fereastră dacă ea nu este sigură. public Window getOwner()
- întoarce proprietarul ferestrei.
public Window[] getOwnedWindows()
- întoarce tabloul ferestrelor, pe care această
fereastră le deţine ca proprietar. public void addWindowListener(WindowListener l)
- adaugă un ascultător de
evenimente de fereastră. public void removeWindowListener(WindowListener l)
- elimină ascultătorul de
evenimente de fereastră specificat. public EventListener[] getListeners(Class listenerType)
- întoarce un tablou al
tuturor ascultătoarelor de evenimente adăugate la această fereastră. public Component getFocusOwner()
- dacă fereastra este activă, întoarce fereastra copil
care este deţine focalizarea.
Interfaţa LayoutManager Defineşte interfaţa pentru clasele care gestionează poziţionarea componentelor în container. Clase care implementează această interfaţă: GridLayout, FlowLayout, ViewportLayout, ScrollPaneLayout, BasicOptionPaneUI.ButtonAreaLayout, BasicTabbedPaneUI.TabbedPaneLayout, BasicInternalFrameTitlePane.TitlePaneLayout, BasicScrollBarUI, BasicInternalFrameUI.InternalFrameLayout, BasicComboBoxUI.ComboBoxLayoutManager, BasicSplitPaneDivider.DividerLayout
407
Severin Bumbaru
Metode public void addLayoutComponent(String name, Component comp) container componenta comp cu numele name. public void removeLayoutComponent(Component comp)
- adaugă la
- elimină din container
componenta specificată. public Dimension preferredLayoutSize(Container parent)
- întoarce dimensiunile preferate ţinând seama de componentele din containerul părinte specificat. public Dimension minimumLayoutSize(Container parent)
- întoarce dimensiunile minime ţinând cont de componentele din containerul părinte specificat. public void layoutContainer(Container parent)
- se face redimensionarea şi
poziţionarea componentelor din containerul specificat.
Interfaţa LayoutManager2 public interface LayoutManager2 extends LayoutManager Clase care implementează această interfaţă: CardLayout, BorderLayout, GridBagLayout, BoxLayout, OverlayLayout, JRootPane.RootLayout, BasicSplitPaneUI.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).
Metode Are toate metodele interfeţei LayoutManager la care se adaugă următoarele metode: public void addLayoutComponent(Component comp, Object constraints) componenta comp respectând restricţiile constraints. public Dimension maximumLayoutSize(Container target)
- adaugă
- întoarce dimensiunea
maximă a containerului. - întoarce un număr în intervalul 0.0 .. 1.0, care indică modul în care se face alinierea componentelor pe axa oX: 0.0 - la origine, 0.5 - la centru, 1.0 - la extremitatea dreaptă. public float getLayoutAlignmentX(Container target)
- întoarce un număr în intervalul 0.0 .. 1.0, care indică modul în care se face alinierea componentelor pe axa oY: 0.0 - la origine, 0.5 - la centru, 1.0 - la extremitatea de jos. public float getLayoutAlignmentY(Container target)
public void invalidateLayout(Container target)
poziţionare, descărcându-se informaţia pe care o conţine.
408
- se invalidează gestionarul de
Programarea orientata pe obiecte în limbajul Java
Clasa ActionEvent public class ActionEvent extends AWTEvent Eveniment semantic, care indică faptul că asupra unei componente a fost exercitată o acţiune specifică acelei componente (de exemplu, un buton a fost apăsat). Cu ajutorul măştilor date drept câmpuri statice finale se pot determina anumite caracteristici ale evenimentului produs. De exemplu, câmpul ALT_MASK permite sa se determine dacă, în momentul generării evenimentului, era apăsată tasta alt. Aceasta se obţine intersectănd masca cu valoarea întoarsă de metoda getModifiers().
Câmpuri public static final int SHIFT_MASK
- mască pentru a detecta dacă tasta shift era
apăsată. public static final int CTRL_MASK
- mască pentru a detecta dacă tasta ctrl era apăsată
public static final int META_MASK
- mască pentru a detecta dacă tasta meta era apăsată
public static final int ALT_MASK
- mască pentru a detecta dacă tasta alt era apăsată.
Metode Metodele clasei AWTEvent, la care se adaugă următoarele: public String getActionCommand()
- întoarce un şir, care identifică acţiunea de comandă
indicată de acest eveniment. public int getModifiers()
- întoarce modificatorii evenimentului (ce taste de control erau apasate când s-a produs evenimentul). public String paramString()
- întoarce un şir, care conţine parametrii evenimentului şi
este util în special la depanare.
Clasa AdjustmentEvent public class AdjustmentEvent extends AWTEvent Instanţele acestei clase sunt evenimente, generate atunci când este ajustată o mărime specifică sursei de eveniment respective.
Metode public Adjustable getAdjustable()
- întoarce obiectul ajustabil care a generat acest
eveniment. public int getValue()
- întoarce valoarea curentă a mărimii ajustate.
409
Severin Bumbaru public int getAdjustmentType() - întoarce tipul de ajustare, care poate fi următoarele: UNIT_INCREMENT, UNIT_DECREMENT, BLOCK_INCREMENT, BLOCK_DECREMENT, TRACK. public String paramString()
unul din
- întoarce un şir, care conţine parametri necesari, în special,
la depanare.
Clasa ComponentAdapter public abstract class ComponentAdapter extends Object implements ComponentListener Clasă abstractă, servind drept prototip pentru realizarea claselor ascultătoare de evenimente de componentă. Clasa conţine toate metodele interfeţei ComponentListener, dar aceste metode nu fac nimic (au corpul vid). Penteru a crea un ascultător de evenimente de componentă, se crează o subclasă a clasei ComponentAdapter, în care se redefinesc numai metodele efectiv necesare.
Constructor public ComponentAdapter()
Metode Toate metodele interfeţei ComponentListener.
Clasa ComponentEvent public class ComponentEvent extends AWTEvent Clasa evenimentelor generate la modificarea stării unei componente: deplasare, modificare a stării, modificare a vizibilităţii. Este, de asemenea, superclasă pentru alte evenimente de componentă, cum sunt ContainerEvent, FocusEvent, InputEvent, PaintEvent, WindowEvent. Evenimentele de componentă sunt date numai pentru scopuri de notificare (în mod obişnuit nu sunt folosite explicit în programul de aplicaţie, ci numai în mod implicit, pentru redimensionarea şi repoziţionarea componentelor).
Metode public Component getComponent() public String paramString()
- întoarce componenta care a generat evenimentul.
- întoarce un şir de parametri, utili pentru depanare.
410
Programarea orientata pe obiecte în limbajul Java
Clasa InputEvent public abstract class InputEvent extends ComponentEvent Clasă abstractă, care constituie rădăcina ierarhiei de clase pentru evenimente de intrare. Are ca subclase directe KeyEvent şi MouseEvent. Conţine câmpuri statice finale, ale căror valori sunt măşti pentru recunoaşterea tipului de eveniment. Conţine, de asemenea, metode pentru recunoaşterea diferitelor situaţii existente la generarea evenimentelor de intrare.
Câmpuri statice finale public static final int SHIFT_MASK
- mască pentru tasta SHIFT.
public static final int CTRL_MASK
- mască pentru tasta CTRL.
public static final int META_MASK
- mască pentru tasta META.
public static final int ALT_MASK
- mască pentru tasta ALT.
public static final int ALT_GRAPH_MASK
- mască pentru tasta ALT_GRAPH.
public static final int BUTTON1_MASK
- mască pentru butonul 1 de mouse.
public static final int BUTTON2_MASK
- mască pentru butonul 2 de mouse.
public static final int BUTTON3_MASK
- mască pentru butonul 3 de mouse.
Metode public boolean isShiftDown()
- la generarea evenimentului, tasta SHIFT era apăsată.
public boolean isControlDown() public boolean isMetaDown() public boolean isAltDown()
- la generarea evenimentului, tasta CTRL era apăsată.
- la generarea evenimentului, tasta META era apăsată.
- la generarea evenimentului, tasta ALT era apăsată.
public boolean isAltGraphDown()
- la generarea evenimentului, tasta ALT_GRAPH era
apăsată. public long getWhen()
- întoarce momentul de timp când a avut loc evenimentul (dat de
ceasul sistemului). - întoarce modificatorii (din care, folosind măştile) se pot obţine caracteristicile evenimentului. public int getModifiers()
411
Severin Bumbaru
Clasa ItemEvent public class ItemEvent extends AWTEvent Eveniment semantic, care arată că un articol a fost selectat sau deselectat. Este generat de către obiecte selectabile (de exemplu articolele de listă).
Metode public ItemSelectable getItemSelectable()
- întoarce articolul care a generat acest
eveniment. public Object getItem()
- întoarce articolul afectat de către acest eveniment.
public int getStateChange() - întoarce schimbarea de stare care a provocat evenimentului (poate fi ItemEvent.SELECTED sau ItemEvent.DESELECTED) public String paramString()
generarea
- întoarce un şir, care conţine parametrii evenimentului
(poate fi util la depanare).
Clasa KeyAdapter public abstract class KeyAdapter extends Object implements KeyListener Adaptor pentru ascultătoarele de evenimente de tastă. Clasa conţine toate metodele din interfaţa KeyListener, dar aceste metode nu fac nimic (au corpul vid). Pentru a obţine un ascultător de evenimente de tastă, se face o subclasă în care se redefinesc numai metodele necesare în aplicaţia respectivă.
Constructor public KeyAdapter()
Metode public void keyTyped(KeyEvent e)
- a avut loc apăsarea şi eliberarea imediată a unei
taste. public void keyPressed(KeyEvent e)
- a fost apăsată o tastă.
public void keyReleased(KeyEvent e)
- a fost eliberată o tastă.
412
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ă. Evenimentul este generat de componenta care este activă în momentul acţionării tastei. Clasa conţine câmpuri statice finale, 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).
Principalele câmpuri statice finale public static final int KEY_TYPED
- tasta a fost apăsată şi eliberată imediat.
public static final int KEY_PRESSED
- tasta a fost apăsată.
public static final int KEY_RELEASED public static final int VK_ENTER
- tasta a fost eliberată.
- a fost acţionată tasta ENTER.
public static final int VK_BACK_SPACE public static final int VK_TAB
- tasta Tab
public static final int VK_SHIFT
- tasta Shift
public static final int VK_CONTROL public static final int VK_ALT
- tasta Ctrl
- tasta Alt
public static final int VK_PAUSE
- tasta Pause
public static final int VK_CAPS_LOCK public static final int VK_ESCAPE public static final int VK_SPACE
- tasta CapsLock (blocare pe litere majuscule)
- tasta Esc (Escape)
- tasta de spaţiu liber
public static final int VK_PAGE_UP
- tasta PageUp (o pagină în sus)
public static final int VK_PAGE_DOWN public static final int VK_END
- tasta BackSpace
- tasta PageDown (o pagină în jos)
- tasta End
public static final int VK_HOME
- tasta Home
public static final int VK_LEFT
- tasta cu săgeată spre stânga
public static final int VK_UP
- tasta cu săgeata în sus
413
Severin Bumbaru public static final int VK_RIGHT public static final int VK_DOWN
- tasta cu săgeata la dreapta
- tasta cu săgeata în jos
public static final int VK_COMMA
- tasta cu virgula (caracterul ",").
public static final int VK_MINUS
- tasta cu minus (caracterul "-").
public static final int VK_PERIOD public static final int VK_SLASH
- tasta cu punctul (caracterul ".").
- tasta cu linia de fracţie (caracterul "-").
public static final int VK_0
- tasta cu cifra zero
public static final int VK_1
- tasta cu cifra 1
. . . . . . . . . . . . . similar VK_2, VK_3, VK_4, VK_5, VK_6, VK_7, VK_8, VK_9 respectiv pentru cifrele 2, 3, 4, 5, 6, 7, 8, 9 public static final int VK_SEMICOLON - tasta punct şi virgulă (caracterul ";") public static final int VK_EQUALS - tasta egal (caracterul "="). public static final int VK_A
- tasta cu litera A
public static final int VK_B
- tasta cu litera B
. . . . . . . . . . . . . similar pentru literele C, D, E, F, G, K, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z public static final int VK_OPEN_BRACKET
- tasta paranteză dreaptă deschisă (caracterul
"[" ) public static final int VK_BACK_SLASH
- caracterul bară inversă (caracterul "\" )
public static final int VK_CLOSE_BRACKET
- caracterul paranteză dreaptă închisă
(caracterul "]" ) public static final int VK_NUMPAD0
- tasta 0 (zero) de pe tastatura numerică.
public static final int VK_NUMPAD1
- tasta 1 de pe tastatura numerică.
. . . . . . . . . . . . similar pentru tastele 2, 3, 4, 5, 6, 7, 8, 9 de pe tastatura numerică public static final int VK_MULTIPLY public static final int VK_ADD
- caracterul "*" de pe tastatura numerică
- caracterul "+" de pe tastatura numerică
public static final int VK_SEPARATER
- caracterul separator
414
Programarea orientata pe obiecte în limbajul Java public static final int VK_SUBTRACT
- caracterul scădere de pe tastatura numerică
public static final int VK_DIVIDE
- caracterul împărţire de pe tastatura numerică
public static final int VK_DELETE
- tasta Delete (ştergere)
public static final int VK_NUM_LOCK
- tasta NumLock (trecerea pe tastatura numerică)
public static final int VK_SCROLL_LOCK public static final int VK_F1
tasta ScrollLock (blocarea defilării)
- tasta specială F1
. . . . . . . . . . . . . similar pentru tastele speciale F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, F13, F14, F15, F16, F17, F18, F19, F20, F21, F22, F23, F24 public static final int VK_PRINTSCREEN public static final int VK_INSERT
- tasta PrintScreen (tipărirea ecranului)
- tasta Insert
public static final int VK_HELP
- tasta Help
public static final int VK_META
- tasta Meta
public static final int VK_BACK_QUOTE
- tasta apostrof invers (caracterul ` )
public static final int VK_QUOTE
- tasta apostrof (caracterul ' )
public static final int VK_KP_UP
- tasta funcţională săgeată în sus
public static final int VK_KP_DOWN
- tasta funcţională săgeată în jos
public static final int VK_KP_LEFT
- tasta funcţională săgeată spre stânga
public static final int VK_KP_RIGHT
- tasta funcţională săgeată la dreapta
public static final int VK_AMPERSAND
- tasta ampersand (caracterul "&" )
public static final int VK_ASTERISK
- tasta asterisc (caracterul "*" )
public static final int VK_QUOTEDBL
- tasta ghilimele (caracterul " )
public static final int VK_LESS
- tasta "mai mic" (caracterul "<" )
public static final int VK_GREATER
- tasta "mai mare" (caracterul ">" )
public static final int VK_BRACELEFT
- tasta "acolada stanga" (caracterul "{" )
public static final int VK_BRACERIGHT
- tasta "acolada dreapta" (caracterul "}" )
415
Severin Bumbaru public static final int VK_AT
- tasta cu caracterul at (caracterul "@" )
public static final int VK_COLON
- tasta "doua puncte" (caracterul ":" )
public static final int VK_CIRCUMFLEX public static final int VK_DOLLAR
- tasta circumflex (caracterul "^" )
- tasta cu simbolul valutar dolar (caracterul "$" )
public static final int VK_EURO_SIGN
- tasta cu simbolul valutar Euro.
public static final int VK_EXCLAMATION_MARK
- tasta cu semnul de exclamatie
(caracterul "!" ) public static final int VK_LEFT_PARENTHESIS public static final int VK_NUMBER_SIGN public static final int VK_PLUS
- paranteză stânga (caracterul "(" )
- tasta cu simbolul numeric (caracterul "#" )
- tasta plus (caracterul "+" )
public static final int VK_RIGHT_PARENTHESIS
- tasta paranteza dreapta (caracterul
")" ) public static final int VK_UNDERSCORE public static final int VK_ALT_GRAPH
- tasta underscore (caracterul "_" )
- Tasta AltGraph
Metode principale public int getKeyCode()
- î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()
- întoarce caracterul logic al tastei (caracterul generat la apăsarea tastei respective: de exemplu, dacă s-au apăsat tastele Shift A, se întoarce caracterul "A", în timp ce dacă s-a apăsat simplu tasta A, se întoarce caracterul "a") - întoarce un şir, care conţine textul de pe tasta al cărui cod este dat ca argument (un text cum ar fi "HOME", "F1" sau "A"). public static String getKeyText(int keyCode)
- întoarce un şir, care conţine modificatorii, adică tastele auxiliare apasate la generarea evenimentului respectiv, de exemplu: "Shift" sau "Ctrl+Shift". (Observaţie: parametrul modifiers poate fi obţinut aplicând metoda getModifiers() a superclasei InputEvent). public static String getKeyModifiersText(int modifiers)
- indică dacă aceasta este o tastă de acţiune, adică o tastă prin care utilizatorul cere o acţiune, cum ar fi tastele PageUp, PageDown, F1, F2 etc. public boolean isActionKey()
416
Programarea orientata pe obiecte în limbajul Java
Clasa MouseAdapter public abstract class MouseAdapter extends Object implements MouseListener Clasă abstractă, care poate fi extinsă pentru realizarea de ascultătoare de evenimente care implementează interfaţa MouseListener. Clasa conţine toate metodele interfeţei MouseListener, dar acestea nu fac nimic (au corpul vid). Extinzând această clasă, programatorul poate redefini numai acele metode, de care are nevoie.
Constructor public MouseAdapter()
Metode Cele ale interfeţei MouseListener.
Clasa MouseEvent public class MouseEvent extends InputEvent Clasa evenimentelor generate de o componentă, atunci când este acţionat mouse-ul, iar cursorul de mouse se găseşte pe componenta respectivă. Există două categorii de astfel de evenimente: - evenimente de mouse propriu-zise: apăsarea sau eliberarea unui buton de mouse, click de mouse, intrarea cursorului de mouse pe suprafaţa componentei sau ieşirea de pe aceasta. - 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), sau deplasarea cursorului de mouse pe suprafaţa componentei (fără să fie apăsat nici unul din butoanele de mouse). Evenimentele de mouse sunt ascultate folosind interfaţa MouseListener, iar cele de mişcare a mouse-ului sunt ascultate prin interfaţa MouseMotionListener. În pachetul javax.swing.event există, de asemenea, interfaţa MouseInputListener şi clasa MouseInputAdapter, care permit ascultarea ambelor categorii de evenimente. Pentru a se afla care buton a fost apăsat, se folosesc modificatorii obţinuţi prin metoda getModifiers() şi măştile corespunzătoare din superclasa InputEvent.
Metode Metodele superclaselor AWTEvent şi InputEvent, la care se adaugă următoarele:
417
Severin Bumbaru public int getX()
- întoarce coordonata x a cursorului de mouse din momentul producerii evenimentului, în sistemul de coordonate al componentei sursă. public int getY()
- întoarce coordonata y a cursorului de mouse din momentul producerii evenimentului, în sistemul de coordonate al componentei sursă. - întoarce punctuil în care se găsea cursorul de mouse în momentul producerii evenimentului, în sistemul de coordonate al componentei sursă. public Point getPoint()
- tranlatează punctul în care se găsea cursorul de mouse în momentul producerii evenimentului, adăugând la cele două coordonate valorile dx şi dy specificate. public void translatePoint(int dx, int dy)
- întoarce numărul de clickuri (se are în vedere că este posibil să se facă succesiv, la intervale mici de timp, mai multe clickuri de mouse). public int getClickCount()
public boolean isPopupTrigger()
- indică dacă acest eveniment de mouse este un trigger
de menu pop-up pentru platforma dată.
Clasa MouseMotionAdapter public abstract class MouseMotionAdapter extends Object implements MouseMotionListener Clasă abstractă pentru adaptoarele de ascultoare de evenimente de mişcare a mouse-ului. Această clasă conţine toate metodele interfeţei MouseMotionListener, dar aceste metode nu fac nimic (corpul lor este vid). Pentru a realiza un ascultător de evenimente de mişcare a mouse-ului, se extinde această clasă, redefinind numai metodele care sunt necesare efectiv.
Constructor public MouseMotionAdapter()
Metode Cele ale interfeţei MouseMotionListener.
Clasa TextEvent public class TextEvent extends AWTEvent Eveniment semantic, care indică faptul că a avut loc o modificare a textului conţinut în componenta care a generat evenimentul.
418
Programarea orientata pe obiecte în limbajul Java
Metodă public String paramString()
- întoarce un şir, care conţine parametrii evenimentului.
Metodă utilă pentru depanare.
Clasa WindowAdapter public abstract class WindowAdapter extends Object implements WindowListener Clasă abstractă, care serveşte la crearea claselor ascultătoare de evenimente de fereastră. Conţine toate metodele interfeţei WindowListener, dar aceste metode nu fac nimic. Pentru a crea o clasă ascultătoare de evenimente de fereastră, se crează o subclasă a clasei WindowAdapter, redefinind numai metodele efectiv necesare în aplicaţia respectivă.
Constructor public WindowAdapter()
Metode Toate metodele interfeţei WindowListener.
Clasa WindowEvent public class WindowEvent extends ComponentEvent Clasă de evenimente de nivel coborât, care indică faptul că a avut loc o modificare a stării unei ferestre: fereastra s-a deschis, urmează să se închidă, s-a închis, s-a activat, s-a dezactivat, s-a iconificat sau deiconificat.
Metode Metodele superclasei ComponentEvent, la care se adaugă următoarea: public Window getWindow()
- întoarce fereastra care a generat evenimentul.
Interfaţa ActionListener public interface ActionListener extends EventListener
419
Severin Bumbaru Această interfaţă este implementată de clasele ascultătoare de evenimente de acţiune. Aceste ascultătoare pot fi adăugate la componentele care suportă metoda addActionListener(actionListener l). Când componenta respectivă generează un ActionEvent, este activată metoda actionPerformed a ascultătorului. Metodă public void actionPerformed(ActionEvent e) eveniment din clasa ActionEvent.
- metodă invocată când se produce un
Interfaţa AdjustmentListener public interface AdjustmentListener extends EventListener Interfaţă pentru ascultătoarele de evenimente de ajustare.
Metodă public void adjustmentValueChanged(AdjustmentEvent e)
- este invocată când are loc
ajustarea obiectului care generează evenimentul.
Interfaţa ComponentListener public interface ComponentListener extends EventListener Interfaţă pentru ascultătoarele de evenimente de componentă. Ascultarea acestor evenimente se face numai în scop de notificare, deoarece tratarea lor se face automat de către AWT. În loc de a crea o clasă care implementează direct această interfaţă, se poate crea o subclasă a clasei ComponentAdapter.
Metode public void componentResized(ComponentEvent e)
- componenta şi-a modificat
dimensiunile. public void componentMoved(ComponentEvent e)
- componenta s-a deplasat.
public void componentShown(ComponentEvent e)
- componenta a fost făcută vizibilă.
public void componentHidden(ComponentEvent e)
invizibilă.
420
- componenta a fost făcută
Programarea orientata pe obiecte în limbajul Java
Interfaţa ItemListener public interface ItemListener extends EventListener Interfaţa pentru ascultătoare de evenimente de articol.
Metodă - este invocată atunci, când are loc o modificare a stării ogiectului care generează evenimente de articol (ItemEvent). public void itemStateChanged(ItemEvent e)
Interfaţa KeyListener public interface KeyListener extends EventListener Interfaţă pentru ascultătoarele de evenimente de tastă. În loc de creea un ascultător de evenimente care implementează direct această interfaţă, se poate extinde clasa KeyAdapter. Pentru a afla care tastă a provocat generarea evenimentelor, se folosesc metodele şi măştile din clasa KeyEvent.
Metode public void keyTyped(KeyEvent e)
- a avut loc apăsarea şi eliberarea imediată a unei
taste. public void keyPressed(KeyEvent e)
- a fost apăsată o tastă.
public void keyReleased(KeyEvent e)
- a fost eliberată o tastă.
Interfaţa MouseListener public interface MouseListener extends EventListener Interfaţă pentru ascultătoarele de mouse care ascultă principalele evenimente generate de acesta, respectiv apăsarea sau eliberarea unui buton, click de mouse, intrarea cursorului de mouse pe suprafaţa unei componente sau ieşirea acestuia. Pentru ascultarea evenimentelor de mişcare a mouse-ului se foloseşte interfaţa MouseMotionListener. În loc de a se crea o clasă de ascultare care implementează direct această interfaţă, se poate crea o subclasă a clasei MouseAdapter.
421
Severin Bumbaru
Metode public void mouseClicked(MouseEvent e)
- metodă invocată când s-a produs un click de
mouse. public void mousePressed(MouseEvent e)
- metodă invocată când este apăsat unul din
butoanele de mouse. public void mouseReleased(MouseEvent e)
- metodă invocată când este eliberat unul
din butoanele de mouse. public void mouseEntered(MouseEvent e)
- metodă invocată când cursorul de mouse
intră pe suprafaţa unei componente. public void mouseExited(MouseEvent e)
- metodă invocată când cursorul de mouse
iese de pe suprafaţa unei componente.
Interfaţa MouseMotionListener public interface MouseMotionListener extends EventListener Interfaţă pentru ascultătoarele de evenimente care se produc la mişcarea mouse-ului. În loc de a crea o clasă care implementează direct această interfaţă, se poate crea o subclasă a clasei MouseMotionAdapter.
Metode public void mouseDragged(MouseEvent e)
- mouse-ul a fost "tras" (adică a fost deplasat
menţinând unul din butoane apăsat). public void mouseMoved(MouseEvent e)
- mouse-ul a fost mişcat (fără să fie apăsat nici
unul din butoane).
Interfaţa TextListener public interface TextListener extends EventListener Interfaţă pentru clasele de ascultare a evenimentelor de text. Astfel de evenimente sunt generate la modificarea textului conţinut într-o componentă.
Metodă public void textValueChanged(TextEvent e)
modificare a textului.
422
- metodă invocată când a avut loc o
Programarea orientata pe obiecte în limbajul Java
Interfaţa WindowListener public interface WindowListener extends EventListener Interfaţă pentru ascultătoarele de evenimente de fereastră. În loc de a crea o clasă ascultătoare care implementează direct această interfaţă, se poate crea o subclasă a clasei WindowAdapter.
Metode public void windowOpened(WindowEvent e)
- metodă invocată când fereastra a fost
deschisă. - metodă invocată când fereastra urmează să se închidă (a fost apăsat butonul de închidere din colţul dreapta-sus, sau a fost selectat articolul Close din meniul din colţul stânga-sus). public void windowClosing(WindowEvent e)
public void windowClosed(WindowEvent e)
- metodă invocată când fereastra a fost
închisă. public void windowIconified(WindowEvent e)
- metodă invocată când fereastra a fost
iconificată. public void windowDeiconified(WindowEvent e)
- metodă invocată când fereastra a
fost deiconificată. - 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 dezactivată (nu mai primeşte intrări de la tastatură)
Clasa AbstractButton public abstract class AbstractButton extends JComponent implements ItemSelectable, SwingConstants Clasă abstractă. Superclasă a claselor de butoane şi de articoloe de meniu. Butonul poate conţine un text şi/sau o pictogramă. 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. Numele acestui eveniment (ActionCommand) este implicit identic cu textul de pe buton, dar el poate fi modificat prin metoda setActionCommand şi poate fi aflat prin metoda getActionCommand.
423
Severin Bumbaru Butonului i se poate ataşa şi o mnemonică, folosind metoda setMnemonic. Aceasta este o tastă, a cărei acţionare are acelaşi efect ca acţionarea butonului respectiv. Clasa conţine foarte multe metode, pentru cunoaşterea cărora recomandăm consultarea documentaţiei Java API.
Constructor public AbstractButton()
Metode principale public String getText()
- întoarce textul butonului.
public void setText(String text) public boolean isSelected()
- setează textul butonului.
- indică dacă acest buton sau articol de meniu este selectat.
public void setSelected(boolean b)
- setează pentru ascest buton sau articol de meniu
starea selectat sau neselectat. public void setMargin(Insets m) public Insets getMargin() public Icon getIcon()
- setează marginile dintre bordură şi text.
- întoarce marginile dintre bordură şi text.
- întoarce pictograma implicită conţinută în buton.
public void setIcon(Icon defaultIcon)
- setează pictograma implicită conţinută în
buton. public void setActionCommand(String actionCommand)
- se setează numele acţiunii de
comandă generată la apăsarea acestui buton. public String getActionCommand()
- întoarce numele acţiunii de comandă produsă de
acest buton. public int getMnemonic()
- întoarce mnemonica ataşată acestui buton (sau null, dacă ea
nu există). - setează mnemonica ataşată acestui buton, specificând ca parametru codul tastei respective (codul conţinut în clasa KeyEvent, de exemplu KeyEvent.VK_A ). public void setMnemonic(int mnemonic)
- setează mnemonica ataşată acestui buton, indicând caracterul desenat pe tasta respectivă (de exemplu 'A'). public void setMnemonic(char mnemonic)
public void addChangeListener(ChangeListener l)
- adaugă un ascultător de
evenimente de schimbare. public void removeChangeListener(ChangeListener l)
evenimente de schimbare specificat.
424
- elimină ascultătorul de
Programarea orientata pe obiecte în limbajul Java public void addActionListener(ActionListener l)
- adaugă un ascultător de
evenimente de acţiune. public void removeActionListener(ActionListener l)
- elimină ascultătorul de
evenimente de acţiune specificat. public void addItemListener(ItemListener l)
- adaugă un ascultător de evenimente
de articol. public void removeItemListener(ItemListener l)
- elimină ascultătorul de
evenimente de acţiune specificat. public void setEnabled(boolean b) public String getLabel()
- face ca butonul să fie sau nu valabil.
- întoarce textul de pe buton.
public void setLabel(String label)
- setează textul butonului.
Clasa Box.Filler public static class Box.Filler extends Component implements Accessible O componentă invizibilă, folosită în instanţele clasei Box pentru distanţarea altor componente. Este clasă imbricată în clasa Box.
Constructor public Box.Filler(Dimension min, Dimension pref, Dimension max)
- se creează
un BoxFiller, fiind specificate dimensiunile minimă, preferată şi maximă.
Metode public void changeShape(Dimension min, Dimension pref, Dimension max)
- se modifică dimensiunile, fiind specificate noile dimensiuni (minimă, preferată şi maximă). public Dimension getMinimumSize()
- intoarce dimensiunea minimă.
public Dimension getPreferredSize() public Dimension getMaximumSize()
- întoarce dimensiunea preferată.
- întoarce dimensiunea maximă.
public AccessibleContext getAccessibleContext()
425
- întoarce contextul accesibil.
Severin Bumbaru
Clasa ButtonGroup public class ButtonGroup extends Object implements Serializable Instanţele clasei ButtonGroup nu sunt componente grafice propriu-zise, rolul lor fiind de a creea grupuri de butoane. Toate butoanele conţinute într-un grup sunt legate logic între ele, astfel că numai un singur buton din grup se poate găsi la un moment dat în starea "apăsat", celelalte fiind în starea "eliberat". Când se apasă un buton, se eliberează automat butonul din acelaşi grup, care era apăsat anterior.Se foloseşte, de regulă, la gruparea butoanelor din clasele JRadioButton şi JRadioButtonMenuItem.
Constructor public ButtonGroup()
Metode principale public void add(AbstractButton b)
- se adaugă la grup butonul specificat.
public void remove(AbstractButton b) public Enumeration getElements() public int getButtonCount()
- se elimină din grup butonul specificat
- întoarce o enumeraţie a elementelor grupului.
- întoarce numărul butoanelor din grup.
Clasa JApplet public class JApplet extends Applet implements Accessible, RootPaneContainer Este o versiune extinsă a clasei Applet, introdusă în Swing. Principala deosebire faţă de clasa Applet este că, la fel ca la clasa JFrame, adăugarea de componente nu se face direct la applet. Fiecare instanţă a clasei JApplet conţine un container numit contentPane, la care se adaugă toqate celelalte componente. Referinţa la acest container se obţine prin metoda getContentPane. Tot ca la JFrame, un JApplet poate avea bară de meniu, pusă prin metoda SetJMenuBar(). Explicatii despre crearea şi utilizarea appleturilor se dau în secţiunea Applet-uri din acest curs. Explicaţii mai ample se gasesc în secţiunea Writing Applets din Tutorialul Java. Descrierea tuturor metodelor este dată în Java API.
Metode frecvent utilizate Toate metodele superclasei Applet, la care se adaugă: public void update(Graphics g)
- invocă metoda paint(g).
public void setJMenuBar(JMenuBar menuBar)
426
- setează bara de meniu specificată.
Programarea orientata pe obiecte în limbajul Java public JMenuBar getJMenuBar()
- întoarce bara de meniu.
public Container getContentPane()
- întoarce containerul contentPane al acestui
JApplet.
Clasa JButton public class JButton extends AbstractButton implements Accessible Orice instanţă a acestei clase este un buton cu o singură stare stabilă (starea normală). Dacă butonul este apăsat (punând pe el cursorul de mouse şi apăsând butonul mouse-ului), el îşi schimbă temporar starea şi aspectul, dar revine la starea normală imediat ce este eliberat. Butonul poate conţine un text şi/sau o imagine (o pictogramă). Butonului i se poate ataşa un text volant (ToolTip) şi o mnemonică (o tastă, a cărei apăsare are acelaşi efect cu apăsarea butonului respectiv). Consultaţi şi secţiunea Butonul obişnuit din acest manual.
Constructori public JButton()
- creează un buton, care nu conţine text sau pictogramă.
public JButton(Icon icon)
- creează un buton, care conţine pictograma specificată.
public JButton(String text) public JButton(Action a)
- creează un buton, care conţine textul specificat.
- creează un buton, cu proprietăţile date de acţiunea specificată
ca parametru. public JButton(String text, Icon icon)
- creează un buton, care va conţine textul şui
acţiunea specificate.
Metode Metodele principale sunt cele ale clasei AbstractButton. Pentru a cunoaşte toate metodele, se va consulta documentaţia Java API.
Clasa JCheckBoxMenuItem public class JCheckBoxMenuItem extends JMenuItem implements SwingConstants, Accessible Este un articol de meniu care se comportă la fel ca o casetă de validare (JCheckBox). Are aspectul unui patrat în care apare un simbol de validare (V) dacă este selectat şi nu apare
427
Severin Bumbaru acest simbol dacă este deselectat. Caseta de validare poate fi însoţită de un text sau/şi o pictogramă.
Constructori public JCheckBoxMenuItem()
- construieşte un JChecBoxMenuItem fără pictogramă şi
text. public JCheckBoxMenuItem(Icon icon)
- construieşte un JChecBoxMenuItem cu
pictograma specificată. public JCheckBoxMenuItem(String text)
- construieşte un JChecBoxMenuItem cu textul
specificat. public JCheckBoxMenuItem(String text, Icon icon)
- construieşte un
JChecBoxMenuItem cu textul şi pictograma specificate. - construieşte un JChecBoxMenuItem cu textul specificat, indicând dacă în starea iniţială este sau nu selectat. public JCheckBoxMenuItem(String text, boolean b)
- construieşte un JChecBoxMenuItem cu textul şi pictograma specificate, indicând dacă în starea iniţială este sau nu selectat. public JCheckBoxMenuItem(String text, Icon icon, boolean b)
Metode principale public boolean getState()
- întoarce starea.
public void setState(boolean b) - setează starea.
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, JDialog, JApplet). Orice JComponentă poate avea o bordură. Oricărei JComponente i se poate ataşa un "text volant" ("ToolTip"), adică un text explicativ, care apare dacă se pune cursorul de mouse pe componenta respectivă. Clasa JComponent conţine numeroase câmpuri şi metode. Aici se dau numai metodele cele mai frecvent folosite. Pentru o documentaţie completă se va consulta Java API.
Constructor public JComponent()
428
Programarea orientata pe obiecte în limbajul Java
Metode frecvent utilizate public void update(Graphics g) public void paint(Graphics g)
- invocă metoda paint(g) pentru această componentă.
- desenează această componentă, folosind contextul
grafic g. - setează dimensiunea preferată a componentei. Dacă este null, dimensiunea preferată va fi stabilită implicit. public void setPreferredSize(Dimension preferredSize)
public Dimension getPreferredSize()
- întoarce dimensiunea preferată.
public void setMaximumSize(Dimension maximumSize)
- setează dimensiunea maximă
a componentei. public Dimension getMaximumSize()
- întoarce dimensiunea maximă a componentei.
public void setMinimumSize(Dimension minimumSize)
- setează dimensiunea minimă a
componentei. public Dimension getMinimumSize()
- întoarce dimensiunea minimă a componentei.
- indică dacă această componentă conţine punctul de coordonate (x, y). Este utilă la prelucrarea evenimentelor de mouse. public boolean contains(int x, int y)
public void setBorder(Border border) public Border getBorder()
- setează bordura componentei.
- întoarce bordura componentei.
public Graphics getGraphics()
- întoarce contextul grafic al acestei componente.
public void setVisible(boolean aFlag)
- setează dacă această componentă este sau nu
vizibilă. public void setEnabled(boolean enabled)
- setează dacă această componentă poate sau
nu primi intrări de la utilizator. public void setForeground(Color fg)
- setează culoarea de prim-plan a componentei.
public void setBackground(Color bg)
- setează culoarea de fond a componentei.
public void setFont(Font font)
- setează fontul componentei.
- indică dacă această componentă poate fi traversată la focalizare (este printre cele care sunt focalizate una după alta, când se apasă tasta Tab). public boolean isFocusTraversable()
public void setToolTipText(String text)
această componentă.
429
- setează textul volant (ToolTip) pentru
Severin Bumbaru public String getToolTipText()
- întoarce textul volant (ToolTip) ataşat acestei
componente. public Point getToolTipLocation(MouseEvent event)
- întoarce locaţia textului volant
(ToolTip) ataşat acestei componente. - indică dacă această componentă este "uşoară", adică nu are ca suport o componentă nativă de pe platforma respectivă. public static boolean isLightweightComponent(Component c)
public boolean isOpaque()
- indică dacă această componentă este complet opacă.
public void setOpaque(boolean isOpaque)
- setează dacă această componentă este sau
nu opacă. public EventListener[] getListeners(Class listenerType)
- întoarce ascultătorii de
evenimente ataşaţi acestei componente. public void repaint(long tm, int x, int y, int width, int height)
-
redesenează dreptunghiul specificat, după tm milisecunde. public void repaint(Rectangle r)
- redesenează dreptunghiul r.
public void paintImmediately(int x, int y, int w, int h)
- redesenează imediat
dreptunghiul specificat. public void paintImmediately(Rectangle r)
- redesenează imediat dreptunghiul
specificat. public JRootPane getRootPane()
- întoarce JRoorpane care este ancestor (ascendent) al acestei componente, sau null, dacă nu există. protected String paramString()
- întoarce un şir, conţinând parametri utili la depanare.
Clasa JDialog public class JDialog extends Dialog implements WindowConstants, Accessible, RootPaneContainer Instanţele acestei clase sunt ferestre de dialog. Componentele nu se adaugă direct la fereastra JDialog, ci la un container numit contentPane, conţinut în aceasta şi care poate fi obţinut prin metoda getContentPane(). Fereastra JDialog poate avea şi bară de meniu.
Constructori public JDialog()
- construieşte o fereastră de dialog fără titlu şi fără a se specifica
proprietarul.
430
Programarea orientata pe obiecte în limbajul Java - construieşte o fereastră de dialog fără titlu, având ca proprietar cadrul (Frame) specificat. public JDialog(Frame owner)
public JDialog(Frame owner, boolean modal) - construieşte o fereastră de dialog fără titlu, având ca proprietar cadrul owner şi indicându-se dacă este sau nu modală. public JDialog(Frame owner, String title)
- construieşte o fereastră de dialog,
specificându-se proprietarul şi titlul ferestrei. - construieşte o fereastră de dialog, specificându-se proprietarul, titlul şi dacă este sau nu modală. public JDialog(Frame owner, String title, boolean modal)
- se construieşte o fereastră de dialog, având ca proprietar altă fereastră de dialog, dată ca argument. public JDialog(Dialog owner)
- se construieşte o fereastră de dialog, având ca proprietar altă fereastră de dialog, dată ca argument şi specificându-se dacă este sau nu modală. public JDialog(Dialog owner, boolean modal)
public JDialog(Dialog owner, String title)
- construieşte o fereastră de dialog,
specificându-se proprietarul şi titlul ferestrei. - construieşte o fereastră de dialog, specificându-se proprietarul, titlul şi dacă este sau nu modală. public JDialog(Dialog owner, String title, boolean modal)
Metode principale Metodele clasei Dialog, la care se adaugă: - setează operaţia implicită, care areloc când se execută comanda Close (când se apasă butonul de închidere a ferestrei dic bolţul din dreapta sus, sau se selectează opţiunea Close din meniul din colţul din stânga-sus). Operaţia dată ca argument poate fiuna din următoarele: WindowConstants.DO_NOTHING_ON_CLOSE - nu se face nimic în mod implicit. WindowConstants.HIDE_ON_CLOSE - fereasrtra este ascunsă (aceasta este opţiunea implicită). WindowConstants.DISPOSE_ON_CLOSE - fereastra este ascunsă şi disponibilizată (eliminată). public void setDefaultCloseOperation(int operation)
public int getDefaultCloseOperation() public void update(Graphics g)
- întoarce operaţia Close implicită.
- invocă metoda paint(g).
public void setJMenuBar(JMenuBar menu) public JMenuBar getJMenuBar()
- setează bara de meniu.
- întoarce bara de meniu.
public Container getContentPane()
- întoarce containerul contentPane al acestei
ferestre de dialog.
431
Severin Bumbaru public void setContentPane(Container contentPane)
- setează containerul
contentPane.
Clasa JEditorPane public class JEditorPane extends JTextComponent Clasă pentru realizarea panourilor de editare care suportă diferite formate de text, cum ar fi text simplu, text HTML sau text RTF. Are subclasa JTextPane. Se recomandă consultarea documentaţiei Java API şi a secţiunii UsingTextComponents din Tutorialul Java.
Class JFileChooser public class JFileChooser extends JComponent implements Accessible Instanţele clasei JFileChooser sunt selectoare de fişiere. Ele vizualizează pe ecran arborele directoarelor şi fişierelor de pe disc şi permit selectarea intercactivă (cu mouse-ul) a fişierului dorit. Clasa conţine un număr mare de câmpuri, constructori şi metode. Pentru o mai bună documentare se recomandă a se consulta Java API şi capitolul How to use FileChoosers din Tutorialul Java.
Constructori principali - construieşte un selector de fişiere cu pointer către directorul utilizatorului (users home directory). public JFileChooser()
- construieşte un selector de fişiere cu pointer către directorul specificat prin calea dată ca argument. public JFileChooser(String currentDirectoryPath)
- construieşte un selector de fişiere cu pointer către directorul specificat prin calea dată ca argument. public JFileChooser(File currentDirectory)
Metode frecvent utilizate public File getSelectedFile()
- întoarce fişierul selectat.
public void setSelectedFile(File file) public File[] getSelectedFiles()
- setează fişierul selectat.
- întoarce tabloul fişierelor selectate.
public void setSelectedFiles(File[] selectedFiles)
specificate prin tabloul dat ca argument.
432
- setează ca selecate fişierele
Programarea orientata pe obiecte în limbajul Java public File getCurrentDirectory()
- întoarce directorul curent.
public void setCurrentDirectory(File dir) public void changeToParentDirectory()
- setează directorul curent.
- trece de la directorul curent la părintele
acestuia. public void ensureFileIsVisible(File f)
- asigură că fişierul dat ca argument este
vizibil (visible) şi nu ascuns (hidden). public int showOpenDialog(Component parent) throws HeadlessException
creează o fereastră de dialog pentru deschiderea fişierului. Fereastra întoarce o valoare corespunzătoare butonului pe care s-a apăsat şi care poate fi una din următoarele: JFileChooser.CANCEL_OPTION, JFileChooser.APPROVE_OPTION, JFileChooser.ERROR_OPTION (ultima în caz de eroare). public int showSaveDialog(Component parent) throws HeadlessException
-
creează o fereastră de dialog pentru salvarea fişierului. Fereastra întoarce o valoare corespunzătoare butonului pe care s-a apăsat şi care poate fi una din următoarele: JFileChooser.CANCEL_OPTION, JFileChooser.APPROVE_OPTION, JFileChooser.ERROR_OPTION (ultima în caz de eroare). public void addActionListener(ActionListener l)
- adaugă un ascultător de
evenimente de acţiune. public void removeActionListener(ActionListener l)
- elimină un ascultător de
evenimente de acţiune. - întoarce tabloul ascultătoarelor de evenimente de acţiune înregistrate la acest JFileChooser. public ActionListener[] getActionListeners()
Clasa JFrame public class JFrame extends Frame implements WindowConstants, Accessible, RootPaneContainer Este varianta Swing a clasei Frame din AWT, fiind o subclasă a acesteia. O deosebire importantă între cele două clase este că, în clasa JFrame, componentele nu se mai adaugă direct la fereastra (la frame), ci la un panou conţinut de aceasta, numit contentPane. O referinţă la contentPane se obţine prin metoda getContentPane(). Operaţiile cu acest contentPane (adăugarea şi eliminarea de componente, setarea gestionarului de poziţionare etc) se fac folosind metodele clasei Container. In JFrame se poate pune, de asemenea, o bară de meniu.
433
Severin Bumbaru Pentru o mai bună cunoaştere a structurii şi utilizării clasei JFrame, recomandăm să se studieze capitolul UsingTop-Level Containers din Tutorialul Java.
Constructori public JFrame()
- construieşte un JFrame, iniţial invizibil şi fără titlu.
public JFrame(String title)
- construieşte un JFrame, iniţial invizibil, cu titlul
specificat. public JFrame(GraphicsConfiguration gc)
- construieşte un JFrame fără titlu, cu
configuraţia grafică specificată, iniţial invizibil. public JFrame(String title, GraphicsConfiguration gc)
- construieşte un JFrame
cu titlul şi configuraţia grafică specificate, iniţial invizibil.
Metode frecvent utilizate - se setează acţiunea care va fi efectuată, dacă se solicită operaţia "close" pentru acest JFrame (se apasă cu mouse-ul pe butonul de închidere din dreapta-sus, sau se selectează opţiunea Close din meniul din stîngasus). Ca argument al metodei se poate da unul din următoarele: WindowConstants.DO_NOTHING_ON_CLOSE - nu se face nimic WindowConstants.HIDE_ON_CLOSE - fereasrtra este ascunsă (aceasta este opţiunea implicită). WindowConstants.DISPOSE_ON_CLOSE - fereastra este ascunsă şi disponibilizată (eliminată). JFrame.EXIT_ON_CLOSE - fereastra este închisă şi se incheie executarea aplicaţiei (opţiune permisă numai în aplicaţii, nu şi în appleturi). public void setDefaultCloseOperation(int operation)
public int getDefaultCloseOperation() public void update(Graphics g)
- întoarce operaţia de închidere implicită.
- invocă metoda paint(g).
public void setJMenuBar(JMenuBar menubar)
- pune în JFrame bara de meniu
specificată. public JMenuBar getJMenuBar()
- întoarce bara de meniu (sau null, dacă nu există)
public Container getContentPane()
- întoarce containerul contentPane al acestui JFrame. La acest container se adaugă componentele ferestrei. public void setContentPane(Container contentPane)
contentPane pentru această fereastră.
434
- setează containerul
Programarea orientata pe obiecte în limbajul Java
Clasa JLabel public class JLabel extends JComponent implements SwingConstants, Accessible Componentă de afişare needitabilă, care poate să conţină un text şi/sau o imagine (o pictogramă).
Constructori public JLabel(String text, Icon icon, int horizontalAlignment)
- se construieşte un JLabel, care conţine textul şi imaginea specificate. Al treilea parametru specifică modul în care se face alinierea pe orizontală şi poate fi una din următoarele: SwingConstants.LEFT - aliniere la stânga SwingConstants.CENTER - aliniere la centru SwingConstants.RIGHT - aliniere la dreapta. - se construieşte un JLabel, care conţine textul specificat şi respectă alinierea orizontală indicată. public JLabel(String text, int horizontalAlignment)
public JLabel(String text)
- se construieşte un JLabel, conţinând textul specificat,
aliniat la stânga. - construieşte un JLabel, care conţine imaginea şi respectă alinierea orizontală date ca argumente. public JLabel(Icon image, int horizontalAlignment)
public JLabel(Icon image) public JLabel()
- construieşte un JLabel care conţine imaginea specificată.
- construieşte un JLabel care nu conţine nimic.
Metode principale public String getText()
- întoarce textul.
public void setText(String text) public Icon getIcon()
- setează textul.
- întoarce imaginea.
public void setIcon(Icon icon)
- setează imaginea.
public int getVerticalAlignment() - întoarce alinierea pe verticală (aceasta din următoarele: SwingConstants.TOP, SwingConstants.CENTER sau SwingConstants.BOTTOM). public void setVerticalAlignment(int alignment)
poate fi una
- setează alinierea pe verticală
(vezi mai sus). public int getHorizontalAlignment()
- întoarce alinierea pe orizontală.
public void setHorizontalAlignment(int alignment)
orizontală. 435
- setează alinierea pe
Severin Bumbaru - întoarce poziţia pe verticală a textului în raport cu imaginea (aceasta poate fi una din următoarele: SwingConstants.TOP, SwingConstants.CENTER sau SwingConstants.BOTTOM). public int getVerticalTextPosition()
public void setVerticalTextPosition(int textPosition)
- setează poziţia pe
verticală a textului, în raport cu imaginea. public int getHorizontalTextPosition() - întoarce poziţia pe orizontală a textului raport cu imaginea (aceasta poate fi una din: SwingConstants.LEFT, SwingConstants.CENTER, SWingConstants.RIGHT). public void setHorizontalTextPosition(int textPosition)
în
- setează poziţia pe
orizontală a textului în raport cu imaginea.
Clasa JMenu public class JMenu extends JMenuItem implements Accessible, MenuElement Instanţele acestei clase sunt meniuri, adică ferestre verticale, care conţin articole de meniu. Întrucât clasa JMenu este o subclasă a JMenuItem, înseamnă că un JMenu poate fi el insuşi un articol al altui menu (un JMenuItem). În acest fel, se pot crea meniuri cu structură ierarhică (arborescentă). Clasa conţine multe metode, dintre care se dau aici câteva mai frecvent utilizate. Pentru documentare completă se va folosi Java API.
Constructori public JMenu()
- construieşte un meniu fără text.
public JMenu(String s)
- construieşte un meniu cu inscripţia s.
public JMenu(Action a)
- construieşte un meniu cu proprietăţile acţiunii a.
Metode frecvent utilizate public boolean isSelected()
- indică dacă meniul este selectat.
public void setSelected(boolean b)
- setează dacă acest meniu este sau nu selectat.
public boolean isPopupMenuVisible()
- indică dacă fereastra cu articolele de meniu este
vizibilă. public void setPopupMenuVisible(boolean b) - setează dacă fereastra cu articole de meniu este sau nu vizibilă. public JMenuItem add(JMenuItem menuItem)
436
- adaugă articolul de meniu specificat.
Programarea orientata pe obiecte în limbajul Java public JMenuItem add(String s) public void addSeparator()
- adaugă un nou articol de meniu cu inscripţia s.
- adaugă un separator.
public void insert(String s, int pos)
- înserează pe poziţia pos un nou srticol de
meniu cu inscripţia s. public JMenuItem insert(JMenuItem mi, int pos)
- înserează pe poziţia pos articolul
de meniu mi. public void insertSeparator(int index) - înserează un separator pe poziţia de indice dat. public JMenuItem getItem(int pos) public int getItemCount()
- întoarce articolul de pe poziţia pos.
- întoarce numărul de articole din acest meniu, inclusiv
separatorii. public void remove(JMenuItem item) public void remove(int pos) public void removeAll()
- elimină articolul de meniu specificat.
- elimină articolul de meniu de pe poziţia pos.
- elimină toate articolele din acest meniu.
- indică dacă acest meniu este de cel mai înalt nivel, adică este ataşat direct la bara de meniu. public boolean isTopLevelMenu()
public void addMenuListener(MenuListener l)
- adaugă ascultătorul de evenimente de
meniu specificat. public void removeMenuListener(MenuListener l)
- elimină ascultătorul de
evenimente de meniu specificat.
Clasa JMenuBar public class JMenuBar extends JComponent implements Accessible, MenuElement Instanţele aceste clase sunt folosite ca bare de meniu. Pentru a obţine un meniu cu bară, la bara de meniu se adaugă diferite meniuri (instanţe ale clasei JMenu). Vezi şi explicaţiile din secţiunea Meniuri cu bară a acestui curs. Indicăm aici numai câteva metode mai frecvent utilizate. Pentru o documentare completă se va consulta Java API.
Constructor public JMenuBar()
437
Severin Bumbaru
Metode principale public JMenu add(JMenu c)
- se adaugă la această bară un nou meniu.
public JMenu getMenu(int index) public int getMenuCount()
- întoarce meniul cu indicele specificat.
- întoarce numărul de meniuri din această bară.
public void setHelpMenu(JMenu menu) public JMenu getHelpMenu()
- setează meniul de ajutor (Help)
- întoarce meniul de ajutor (Help).
public void setSelected(Component sel) public boolean isSelected()
- setează componenta selectată
- indică dacă bara de meniu conţine o componentă
selectată.
Clasa JMenuItem public class JMenuItem extends AbstractButton implements Accessible, MenuElement Instanţele acestei clase sunt articole de meniu. Un astfel de obiect se comportă la fel ca un buton, numai că este plasat într-un meniu. Din această cauză, clasa JMenuItem extinde clasa AbstractButton. Are ca subclase JCheckBoxMenuItem, JMenu şi JRadioButtonMenuItem. Instanţele acestei clase se comportă ca butoane obişnuite (au o singură stare stabilă, iar la apăsare generează un eveniment de acţiune).
Constructori public JMenuItem()
- construieşte un articol de meniu fără text sau pictogramă.
public JMenuItem(Icon icon)
- construieşte un articol de meniu cu pictograma
specificată. public JMenuItem(String text) public JMenuItem(Action a)
- construieşte un articol de meniu cu textul specificat.
- construieşte un articol de meniu cu proprietăţile din
acţiunea specificată. public JMenuItem(String text, Icon icon)
- construieşte un articol de meniu cu textul
şi pictograma specificate. public JMenuItem(String text, int mnemonic)
- construieşte un articol de meniu cu
textul şi mnemonica specificate.
Metode principale Metodele din clasa AbstractButton, la care se adaugă: 438
Programarea orientata pe obiecte în limbajul Java - setează dacă articolul de meniu este sau nu "armat" )dacă butonul de mouse este eliberat când cursorul este pe acest articol, se va genera evenimentul de acţiune). public void setArmed(boolean b)
public boolean isArmed()
- indică dacă acest articol este "armat".
public void setEnabled(boolean b)
- setează articolul pentru a fi sau nu activ.
- setează combinaţia de taste care generează aceeaşi acţiune ca acest articol de meniu, fără a mai parcurge ierarhia meniului. public void setAccelerator(KeyStroke keyStroke)
public KeyStroke getAccelerator()
- întoarce acceleratorul.
public MenuElement[] getSubElements()
- întoarce tabloul componentelor submeniului
acestui articol. public Component getComponent()
- întoarce componenta utilizată pentru a desena acest
articol. public void addMenuDragMouseListener(MenuDragMouseListener l)
- adaugă un
ascultător de tragere a mouse-lui pentru meniu. public void removeMenuDragMouseListener(MenuDragMouseListener l)
- elimină
ascultătorul de tragere a mouse-ului. public void addMenuKeyListener(MenuKeyListener l)
- adaugă un ascultător de tastă
pentru articolul de meniu. public void removeMenuKeyListener(MenuKeyListener l) - elimină ascultătorul de tastă pentru articol de meniu.
Class JOptionPane public class JOptionPane extends JComponent implements Accessible Clasa JoptionPane permite să se creeze cu uşurinţă ferestre de dialog frecvent utilizate, având un format predefinit. În acest scop, classa conţine metode satatice pentru realizarea fiecărui tip de fereastră. Clasa conţine un mare număr de câmpuri, constructori şi metode, dintre care vom da aici numai câteva metode statice frecvent utilizate. Pentru documentare completă recomandăm să se consulte Java API. Recomandăm să se consulte şi capitolul Utilizarea ferestrelor de dialog din acest manual.
439
Severin Bumbaru
Metode frecvent utilizate - creează o fereastră de dialog de intrare. Fereastra conţine mesajul specificat ca parametru, urmat de un câmp de text în care utilizatorul poate introduce datele solicitate, sub forma unui şir de caractere. public static String showInputDialog(Object message)
public static String showInputDialog(Component parentComponent, Object message) - creează o fereastră de dialog de intrare, având ca părinte componenta specificată
prin primul parametru. Fereastra conţine mesajul specificat, plus un câmp de text pentru introducerea şirului de intrare. public static String showInputDialog(Component parentComponent, Object message, String title, int messageType) - similar cu metoda precedentă, dar se
specifică în plus titlul ferestrei şi tipul mesajului. Tipul mesajului poate fi unul din următoarele: JOptionPane.ERROR_MESSAGE, JOptionPane.INFORMATION_MESSAGE, FOptionPane.WARNING_MESSAGE, JOptionPane.QUESTION_MESSAGE, sau JOptionPane.PLAIN_MESSAGE. Pe fereastră va apare o pictogramă corespunzătoare tipului
de mesaj. public static void showMessageDialog(Component parentComponent, Object message) - se creează o fereastră de dialog, care conţine mesajul specificat. public static void showMessageDialog(Component parentComponent, Object message, String title, int messageType) - similar metodei precedente, dar se
specifică în plus titlul ferestrei şi tipul mesajului. Acest tip poate fi unul din: JOptionPane.ERROR_MESSAGE, JOptionPane.INFORMATION_MESSAGE, JOptionPane.WARNING_MESSAGE, JOPtionPane.QUESTION_MESSAGE, sau JOptionPane.PLAIN_MESSAGE. public static void showMessageDialog(Component parentComponent, Object message, String title, int messageType,Icon icon) - similar cu metoda precedentă,
specificându-se în plus o pictogramă. public static int showConfirmDialog(Component parentComponent, Object message) - se creează o fereastră de dialog de confirmare. Această fereastră conţine mesajul
"Select an option" şi trei butoane: Yes, No şi Cancel. public static int showConfirmDialog(Component parentComponent, Object message, String title, int optionType) - se creează o fereastră de dialog de
confirmare, fiind specificate: componenta părinte, mesajul conţinut de fereastră, titlul ferestrei şi tipul de opţiune. Tipul opţiunii poate fi unul din următoarele: JOptionPane.YES_NO_OPTION, sau JOptionPane.YES_NO_CANCEL_OPTION. public static int showConfirmDialog(Component parentComponent, Object message, String title, int optionType, int messageType) - similar cu metoda
precedentă, specificându-se în plus tipul mesajului, care poate fi unul din următoarele: JOptionPane.ERROR_MESSAGE, JOptionPane.INFORMATION_MESSAGE, JOptionPane.WARNING_MESSAGE, JOPtionPane.QUESTION_MESSAGE, sau JOptionPane.PLAIN_MESSAGE. public static int showConfirmDialog(Component parentComponent, Object message, String title, int optionType, int messageType, Icon icon) - similar
440
Programarea orientata pe obiecte în limbajul Java cu metoda de mai sus, specificându-se în plus o pictogramă.
Clasa JPanel public class JPanel extends JComponent implements Accessible Clasa JPanel din Swing are un rol similar cu clasa Panel din AWT. Instanţele acestei clase sunt containere, care apar pe ecran ca nişte suprafeţe dreptunghiulare, pe care se pot plasa diferite componente, aranjate cu ajutorul unui gestionar de poziţionare. Având în vedere că clasa JPanel extinde clasa JComponent, panourile din această clasă pot avea şi bordură.
Constructori principali public JPanel()
- construieşte un JPanel cu gestionarul de poziţionare implicit
(FlowLayout). public JPanel(LayoutManager layout)
- construieşte un JPanel cu gestionarul de
poziţionare specificat.
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. Se deosebesc de JTextField prin faptul că parola introdusă în câmp de la tastatură nu este vizibilă pe ecran, fiind substituită printr-un şir de caractere de înlocuire. Caracterul de înlocuire implicit este '*',
Constructori public JPasswordField()
- construieşte un câmp de parolă fără text şi cu lungimea 0
coloane. public JPasswordField(int columns)
- construieşte un câmp de parolă cu lungimea
specificată. public JPasswordField(String text, int columns)
- construieşte un câmp de text,
specificându-se textul conţinut şi lungimea câmpului.
Metode principale - se setează caracterul de ecou (care va înlocui în câmpul de pe ecran caracterele efective ale parolei). public void setEchoChar(char c)
441
Severin Bumbaru public char getEchoChar()
- întoarce caracterul de ecou (de înlocuire pe ecran a caracterelor parolei). Implicit este '*'. public char[] getPassword() - întoarce un tablou de caractere, care conţine parola.
Clasa JProgressBar public class JProgressBar extends JComponent implements SwingConstants, Accessible Instanţele acestei clase sunt bare de progres, folosite în special gradul de realizare a unui eveniment în curs de desfăşurare. Pe ecran, apare ca o bară a cărei lungime este proporţională cu un număr întreg, într-un interval de variaţie dat. Bara poate fi orientată orizontal sau vertical.
Constructori public JProgressBar()
- creează o bară de progres orientată orizontal, cu intervalul de
variaţie 0 .. 100. public JProgressBar(int orient) - creează o bară de progres cu care poate fi JProgressBar.VERTICAL sau JProgressBar.HORIZONTAL. Intervalul de variaţie este 0 .. 100. public JProgressBar(int min, int max)
orientarea specificată,
- creează o bară de progres orientată orizontal,
cu intervalul de variaţie specificat. public JProgressBar(int orient, int min, int max)
- creează o bară de progres cu
orientarea şi intervalul de variaţie specificate.
Metode frecvent utilizate public void setOrientation(int newOrientation) JProgressBar.VERTICAL sau JProgressBar.HORIZONTAL. public int getOrientation()
- seteazo orientarea, care poate fi
- întoarce orientarea.
public double getPercentComplete()
- întoarce gradul de progresare, sub forma unui
număr real în intervalul 0.00 .. 1.00. public void setBorderPainted(boolean b)
- setează dacă bara are sau nu bordură.
Implicit este true. public boolean isBorderPainted()
- indică dacă bara are sau nu bordură.
public void addChangeListener(ChangeListener l)
evenimente de schimbare.
442
- adaugă un ascultător de
Programarea orientata pe obiecte în limbajul Java public void removeChangeListener(ChangeListener l)
- elimină un ascultător de
evenimente de schimbare. public int getValue()
- întoarce valoarea indicată de bară.
public int getMinimum()
- întoarce valoarea minimă (marginea inferioară a intervalului).
public int getMaximum()
- întoarce valoarea maximă (marginea superioară a intervalului).
public void setValue(int n)
- setează valoarea (un număr întreg, cuprins în intervalul de
variaţie impus). public void setMinimum(int n)
- setează valoarea minimă (marginea inferioară a
intervalului). public void setMaximum(int n)
- setează valoarea maximă (marginea superioară a
intervalului).
Clasa JRadioButtonMenuItem public class JRadioButtonMenuItem extends JMenuItem implements Accessible Articol de meniu care se comportă ca un buton radio (JRadioButton). Este un buton cu două stări stabile (selectat şi deselectat). Mai multe butoane radio pot fi grupate folosind un ButtonGroup, astfel încât, la un moment dat, un singur buton din grup se găseşte în starea selectat.
Constructori public JRadioButtonMenuItem()
- construieşte un JRadioButtonMenuItem fără text şi fără
pictogramă. public JRadioButtonMenuItem(Icon icon)
- construieşte un JRadioButtonMenuItem cu
pictograma specificată. public JRadioButtonMenuItem(String text)
- construieşte un JRadioButtonMenuItem
cu textul specificat. public JRadioButtonMenuItem(String text, Icon icon)
- construieşte un
JRadioButtonMenuItem cu textul şi pictograma specificate. - construieşte un JRadioButtonMenuItem cu textul specificat, indicând dacă este sau nu selectat. public JRadioButtonMenuItem(String text, boolean selected)
- construieşte un JRadioButtonMenuItem cu pictograma specificată, indicând dacă este sau nu selectat. public JRadioButtonMenuItem(Icon icon, boolean selected)
443
Severin Bumbaru public JRadioButtonMenuItem(String text, Icon icon, boolean selected)
construieşte un JRadioButtonMenuItem cu textul şi pictograma specificate, indicând dscă este sau nu selectat.
Metode Cele din superclase.
Clasa JScrollBar public class JScrollBar extends JComponent implements Adjustable, Accessible Instanţele acestei clase sunt bare de defilare, care pot fi orientate orizontal sau vertical. Se stabilesc orientarea, valorile minimă şi maximă, valoarea la care exte poziţionat cursorul şi extensia. Orientarea poate fi una din valorile HORIZONTAL şi VERTICAL definite în interfaţa Adjustable din pachetul java.awt.
Constructori public JScrollBar(int orientation, int value, int extent, int min, int max)
- creează o bară de defilare, fiind specifiacte orientarea, valoarea, extensia, valoarea minimă şi valoarea maximă. - se creează o bară de defilare cu orientarea specificată, intervalul 0 .. 100, valoarea 0 şi extensia 100. public JScrollBar(int orientation)
public JScrollBar()
- se creează o bară de defilare verticală, intervalul 0 .. 100, valoarea 0
şi extensia 100.
Metode frecvent utilizate public int getOrientation()
- întoarce orientarea.
public void setOrientation(int orientation) public int getValue()
- setează orientarea.
- întoarce valoarea indicată de bara de defilare.
public void setValue(int value) public int getMinimum()
- setează valoarea indicată de bara de defilare.
- întoarce valoarea minimă.
public void setMinimum(int minimum) public int getMaximum()
- setează valoarea minimă.
- întoarce valoarea maximă.
public void setMaximum(int maximum)
- setează valoarea maximă.
public boolean getValueIsAdjusting()
- indică dacă cursorul poate fi tras cu mause-ul.
444
Programarea orientata pe obiecte în limbajul Java public void setValueIsAdjusting(boolean b)
- setează dacă cursorul poate sau nu să
fie tras cu mouse-ul. public void addAdjustmentListener(AdjustmentListener l)
- adaugă un ascultător
de evenimente de ajustare. public void removeAdjustmentListener(AdjustmentListener l)
- elimină un
ascultător de evenimente de ajustare. public void setEnabled(boolean x)
- face ca poziţia cursorului să poată sau nu fi
schimbată.
Clasa JScrollPane public class JScrollPane extends JComponent implements ScrollPaneConstants, Accessible Instanţele acestei clase sunt panouri cu bare de defilare orizontală şi/sau verticală. În Swing, instanţele clasei JPanel nu au bare de defilare. Dacă dorim să-i punem bare de defilare, un astfel de JPanel se pune ca singură componentă într-un JScrollPane. In loc de un panou, în JScrollPane se poate pune orice altă componentă Swing, dar una singură. Se pot adopta diferite "politici" privind modul de comportare al celor bare de defilare: - pentru bara de defilare verticală: JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED - bara apare numai dacă este necesară; JScrollPane.VERTICAL_SCROLLBAR_NEVER - bara nu apare niciodată; JScrollPane.VERTICAL_SCROLLBAR_ALWAYS - bara apare întotdeauna; - pentru bara de defilare orizontală: JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED - bara apare numai dacă este necesară; JScrollPane.HORIZONTAL_SCROLLBAR_NEVER - bara nu apare niciodată; JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS - bara apare întotdeauna. Aceste constante se folosesc ca parametri în constructori şi metode, unde se cer "politicile" adoptate pentru comportamentul barelor de defilare. Pentro o documentare completă se recomandă consultarea documentatiei Java API.
Constructori public JScrollPane(Component view, int vsbPolicy, int hsbPolicy)
- se construieşte un JScrollPane, fiind specificate componenta pe care o vizualizează şi politicile adoptate pentru comportările barelor de defilare verticală şi orizontală. - se construieşte un JScrollPane care conţine componenta specificată, iar barele de defilare apar numai când sunt necesare (când componenta este mai mare decât partea vizibilă). public JScrollPane(Component view)
445
Severin Bumbaru - construieşte un JScrollPane, specificând politicile pentru barele de defilare verticală şi orizontală. public JScrollPane(int vsbPolicy, int hsbPolicy)
- constuieşte un JScrollPane, la care barele de defilare orizontală şi verticală apar numai când sunt necesare. public JScrollPane()
Metode frecvent utilizate public int getVerticalScrollBarPolicy()
- întoarce politica pentru bara de defilare
verticală. public void setVerticalScrollBarPolicy(int policy)
- setează politica pentru bara
de defilare verticală. public int getHorizontalScrollBarPolicy()
- întoarce politica pentru bara de defilare
orizontală. public void setHorizontalScrollBarPolicy(int policy)
- setează politica pentru
bara de defilare orizontală. public Border getViewportBorder()
- întoarce bordura yonei vizibile.
public void setViewportBorder(Border viewportBorder)
- setează bordura zonei
vizibile.
Class JSeparator public class JSeparator extends JComponent implements SwingConstants, Accessible Instanţele acestei clase sunt separatori folosiţi în meniuri, pentru a grupa articolele de meniu în grupuri logice. În loc de a folosi în mod explicit această clasă, se pot utiliza metodele addSeparator(), existente în clasele JMenu şi JPopupMenu.
Constructori public JSeparator()
- construieşte un separator orizontal.
- construieşte un separator, specificând orientarea acestuia, care poate fi una din următoarele: SwingConstants.HORIZONTAL sau SwingConstants.VERTICAL. public JSeparator(int orientation)
Metode principale public int getOrientation()
- întoarce orientarea separatorului.
public void setOrientation(int orientation)
(orizontală sau verticală).
446
- setează orientarea separatorului
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, fiecare din aceste zone conţinând câte o singură componentă. Scindarea se poate face vertical sau orizontal. Orientarea scindării este specificată prin una constantele JSplitPane.HORIZONTAL_SPLIT sau JSplitPane.VERTICAL_SPLIT . Clasa conţine un număr mare de câmpuri, constructori şi metode. Pentru documentare completă recomandăm să se consulte Java API.
Constructori public JSplitPane()
- creează un JSplitPane, în care cele două componente sunt puse una
lângă alta, orizontal. public JSplitPane(int newOrientation) - creează un JSplitPane, indicându-se orientarea scindării. public JSplitPane(int newOrientation, boolean newContinuousLayout) - creează un nou JSplitPane, fiind specificate orientarea şi dacă aspectul este sau nu continuu (dacă este sau nu vizibil locul de îmbinare). public JSplitPane(int newOrientation, Component newLeftComponent, Component newRightComponent) - se creează un JSplitPane, indicându-se specificarea şi cele două
componente conţinute. public JSplitPane(int newOrientation, boolean newContinuousLayout, Component newLeftComponent, Component newRightComponent) - se construieşte un JSplitPane, fiind specificate orientarea scindării, continuitatea în zona de scindare şi cele două componente conţinute.
Metode frecvent utilizate public void setDividerSize(int newSize)
- setează lăţimea divizorului dintre cele
două zone, exprimată în pixeli. public int getDividerSize()
- întoarce lăţimea divizorului dintre cele două zone
(exprimată în pixeli). public void setLeftComponent(Component comp)
- setează componenta din stânga (sau
de sus). public Component getLeftComponent()
- întoarce componenta din stânga (sau de sus).
public void setTopComponent(Component comp)
stânga).
447
- setează componenta de sus (sau din
Severin Bumbaru public Component getTopComponent()
- întoarce componenta de sus (sau din stânga).
public void setRightComponent(Component comp)
- setează componenta dein dreapta
(sau de jos). public Component getRightComponent()
- întoarce componenta din dreapta (sau de jos).
public void setBottomComponent(Component comp)
- setează componenta de jos (sau
din dreapta). public Component getBottomComponent()
- întoarce componenta de jos (sau din dreapta).
public void setOrientation(int orientation) - setează orientarea. public int getOrientation() - întoarce orientarea. public void setContinuousLayout(boolean newContinuousLayout) - setează continuitatea în zona de scindare. public boolean isContinuousLayout() - indică dacă în zona de scindare există sau nu continuitate.
Clasa JTabbedPane public class JTabbedPane extends JComponent implements Serializable, Accessible, SwingConstants Fiecare instanţă a clasei JTabbedPane realizează metaforic un "clasor", care conţine fişe plasate una în spatele celeilalte. 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. La apăsarea acestui "călăreţ", fişa respectivă iese deasupra celorlalte. Amplasarea "călăreţilor" (tabLayoutPlacement) poate fi sus, jos, stânga sau dreapta şi se indică prin constantele: JTabbedPane.TOP, JTabbedPane.BOTTOM, JTabbedPane.LEFT sau
JTabbedPane.RIGHT.
Modul de prezentare a călăreţilor (layoutPolicy) poate fi unul din: JTabbedPane.WRAP_TAB_LAYOUT (toţi "călăreţii" sunt vizibili) or JTabbedPane.SCROLL_TAB_LAYOUT ("călăreţii" defilează). Clasa conţine numeroase câmpuri şi metode, astfel că pentru o mai bună documentare se recomandă consultarea documentaţiei Java API. Este utilă, de asemenea, consultarea capitolului How to Use Tabbed Panes din Tutorialul Java.
448
Programarea orientata pe obiecte în limbajul Java
Constructori public JTabbedPane() - construieşte un JTabbedPane cu (JTabbedPane.WRAP_TAB_LAYOUT) la partea superioară.
"călăreţii" plasaţi vizibil
public JTabbedPane(int tabPlacement) - construieşte un JTabbedPane, respectând amplasarea specificată a "călăreţilor". - se construieşte un JTabbedPane, fiind specificate atât amplasarea, cât şi politica de vizibilitate a "călăreţilor". public JTabbedPane(int tabPlacement, int tabLayoutPolicy)
Metode frecvent utilizate public void addChangeListener(ChangeListener l)
- adaugă un ascultător de
evenimente de schimbare. public void removeChangeListener(ChangeListener l)
- elimină un ascultător de
evenimente de schimbare. public ChangeListener[] getChangeListeners()
- elimină un ascultător de evenimente
de schimbare. public int getTabPlacement()
- întoarce amplasarea "călăreţilor".
public void setTabPlacement(int tabPlacement) public int getTabLayoutPolicy()
- setează amplasarea "călăreţilor".
- întoarce politica de vizibilitate a "călăreţilor".
public void setTabLayoutPolicy(int tabLayoutPolicy)
- setează politica de
vizibilitate a "călăreţilor". public int getSelectedIndex()
- întoarce indicele subpanoului selectat.
public void setSelectedIndex(int index)
- setează indicele subpanoului selectat.
public Component getSelectedComponent()
- întoarce componenta selectată.
public void setSelectedComponent(Component c)
- setează componenta selectată.
public void insertTab(String title, Icon icon, Component component, String tip, int index) - se înserează un "călăreţ", împreună cu subpanoul corespunzător,
specificându-se: titlul, pictograma, componenta, textul volant şi indicele. public void addTab(String title, Icon icon, Component component, String tip) - se adaugă un "călăreţ" (după cele deja existente), specificându-se titlul, pictograma,
componenta şi textul volant. public void addTab(String title, Icon icon, Component component)
metoda precedentă, dar fără text volant.
449
- ca şi
Severin Bumbaru public void addTab(String title, Component component)
- ca şi metoda precedentă,
dar fără pictogramă. public void removeTabAt(int index)
- se elimină "călăreţul" de indice specificat,
împreună cu subpanoul respectiv. public void removeAll()
- elimină toţi "călăreţii".
public int getTabCount()
- întoarce numărul de "călăreţi".
public String getTitleAt(int index) public Icon getIconAt(int index)
- întoarce titlul de la indicele specificat.
- întoarce pictograma de la indicele specificat.
public String getToolTipTextAt(int index)
- întoarce textul volant de la indicele
specificat. public Component getComponentAt(int index)
- întoarce componenta de la indicele
specificat.
Clasa JTable public class JTable extends JComponent implements TableModelListener, Scrollable, TableColumnModelListener, ListSelectionListener, CellEditorListener, Accessible Clasa JTable permite crearea de componente sub formă de tabele bidimensionale editabile. Pentru utilizarea acestei clase se recomandă consultarea documentaţiei Java API şi a capitolului How to Use Tables din Tutorialul Java.
JTextPane public class JTextPane extends JEditorPane Subclasă a clasei JEditorPane. Clasă pentru realizarea panourilor de editare care permit să se folosească stiluri diferite pentru fiecare paragraf. Se recomandă consultarea documentaţiei Java API şi a secţiunii UsingTextComponents din Tutorialul Java.
450
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, închis, validat) şi starea eliberat (neselectat, deschis, nevalidat). Are ca subclase JCheckBox şi JRadioButton. La fiecare acţionare cu mouse-ul asupra unei instanţe a clasei JToggleBox sau a subclaselor sale, butonul respectiv trece, din starea în care se gaseşte, în cealaltă stare. Dacă nu se specifică altfel, starea iniţială implicită este "eliberat".
Constructori public JToggleButton()
- creează un buton fără text sai pictogramă.
public JToggleButton(Icon icon)
- creează un buton cu pictograma specificată ca
parametru, dar fără text. - creează un buton, care conţine pictograma specificată, nu conţine text, iar starea iniţială este dată de al treilea parametru. public JToggleButton(Icon icon, boolean selected)
public JToggleButton(String text)
- creează un buton cu textul specificat.
- creează un buton cu textul specificat, la care starea iniţială este indicată de al treilea parametru. public JToggleButton(String text, boolean selected)
public JToggleButton(Action a)
- creează un buton, cu proprietăţile din acţiunea
specificată. - creează un buton, care are textul şi pictograma specificate, iar starea iniţială este cea indicată de al treilea parametru. public JToggleButton(String text, Icon icon, boolean selected)
Metode principale Metodele principale sunt cele din clasa AbstractButton. Pentru o documentare completă se va consulta Java API.
Clasa JWindow public class JWindow extends Window implements Accessible, RootPaneContainer Instanţele clasei JWindow sunt ferestre fără bară de titlu, care pot fi plasate oriunde pe ecran (sunt ferestre de cel mai înalt nivel). Adăugarea componentelor nu se face direct la fereastră, ci la un container conţinut în aceasta numit contentPane, care poate fi obţinut prin metoda getContentPane().
451
Severin Bumbaru
Constructori public JWindow()
- construieşte o fereastră fără un proprietar specificat.
public JWindow(GraphicsConfiguration gc)
- construieşte o fereastră cu configuraţia
grafică specificată. public JWindow(Frame owner)
- construieşte o fereastră, având ca proprietar cadrul
specificat ca argument. public JWindow(Window owner)
- construieşte o fereastră, având ca proprietar fereastra
specificată ca argument. public JWindow(Window owner, GraphicsConfiguration gc) - construieşte o fereastră, având proprietarul owner şi configuraţia grafică gc.
Metode principale Metodele clasei Window din pachetul java.awt, la care se adaugă: public Container getContentPane()
- întoarce containerul la care se adaugă
componentele ferestrei. public void setContentPane(Container contentPane)
- setează panoul contentPane.
Clasa ChangeEvent public class ChangeEvent extends EventObject Evenimentele din această clasă semnalează schimbarea stării componentei sursă. Ele sunt ascultate cu un ChangeListener.
Constructor public ChangeEvent(Object source)
- se creează un ChangeEvent, fiind specificată sursa
acestuia.
Clasa ListDataEvent public class ListDataEvent extends EventObject Eveniment care indică apariţia unor modificări într-o listă. Tipul evenimentului are valoarea unuia din următoare câmpuri statice finale: ListDataEvent.CONTENTS_CHANGED - s-a modificat conţinutul listei; ListDataEvent.INTERVAL_ADDED - s-au adăugat la listă unul sau mai multe articole
452
Programarea orientata pe obiecte în limbajul Java care sunt situate unul după altul ListDataEvent.INTERVAL_REMOVED
- s-au eliminat din listă unul sau mai multe articole
situate unul după altul.
Constructor public ListDataEvent(Object source, int type, int index0, int index1)
- se creează un ListDataEvent fiind specificate: obiectul sursă, tipul evenimentului (unul din cele menţionate mai sus), indicii marginilor intervalului de articole în care s-a produs modificarea.
Metode public int getType()
- întoarce tipul evenimentului.
public int getIndex0() - întoarce indicele primului articol al intervalului în care s-a produs modificarea public int getIndex1() - î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ă. Se consideră că schimbarea selecţiei este limitată la un interval de articole.
Constructor public ListSelectionEvent(Object source, int firstIndex, int lastIndex, boolean isAdjusting) - creează un ListSelectionEvent, fiind specificate: sursa
evenimentului, 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()
- întoarce indicele primului articol din intervalul selectat.
- întoarce indicele ultimului articol din intervalul selectat. - indică dacă acest eveniment face parte dintr-o
public boolean getValueIsAdjusting()
serie de evenimente care au loc rapid.
Clasa MenuEvent public class MenuEvent extends EventObject
453
Severin Bumbaru Evenimentele din această clasă se produc atunci când a avut loc o modificare într-un meniu: obiectul sursă a fost pus, selectat sau eliminat.
Constructor public MenuEvent(Object source)
- creează un eveniment de meniu, specificându-se
sursa.
Clasa MouseInputAdapter public abstract class MouseInputAdapter extends Object implements MouseInputListener Clasă abstractă, folosită ca prototip pentru clasele ascultătoare de evenimente de mouse. Clasa conţine toate metodele interfeţei MouseInputListener, dar aceste metode nu fac nimic (au corpul vid). Programatorul poate crea clase derivate, în care rafinează numai acele metode, care sunt efectiv necesare în aplicaţia respectivă.
Constructor public MouseInputAdapter()
Metode Metodele interfeţei MouseInputListener.
Clasa PopupMenuEvent public class PopupMenuEvent extends EventObject Evenimente generate de meniurile derulante (pop-up).
Constructor public PopupMenuEvent(Object source)
- creează un PopupMenuEvent, specificându-se
sursa evenimentului.
Interfaţa ChangeListener public interface ChangeListener extends EventListener Interfaţă pentru clasele de ascultători de evenimente de schimbare a stării.
454
Programarea orientata pe obiecte în limbajul Java
Metodă public void stateChanged(ChangeEvent e)
- 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.
Metode public void intervalAdded(ListDataEvent e)
- invocată când a avut loc o adăugare
sau înserare de articole în listă public void intervalRemoved(ListDataEvent e)
- invocată când a avut loc o eliminare
de articole din listă public void contentsChanged(ListDataEvent e) - invocată când a avut loc o modificare în listă mai complexă decât cele două precedente. 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)
- 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.
Metode public void menuSelected(MenuEvent e)
- invocată când meniul este selectat.
455
Severin Bumbaru public void menuDeselected(MenuEvent e)
- invocată când meniul este deselectat.
public void menuCanceled(MenuEvent e) - invocată când meniul este anulat.
Interfaţa MouseInputListener public interface MouseInputListener extends MouseListener, MouseMotionListener Interfaţă de ascultare a evenimentelor de mouse, care cumulează metodele celor două interfeţe pe care le extinde: MouseListener şi MouseMotionListener. În loc de a crea o clasă care extinde direct această interfaţă, se recomandă extinderea clasei MouseInputAdapter.
Metode public void mouseClicked(MouseEvent e)
- metodă invocată când s-a produs un click de
mouse. public void mousePressed(MouseEvent e)
- metodă invocată când este apăsat unul din
butoanele de mouse. public void mouseReleased(MouseEvent e)
- metodă invocată când este eliberat unul
din butoanele de mouse. public void mouseEntered(MouseEvent e)
- metodă invocată când cursorul de mouse
intră pe suprafaţa unei componente. public void mouseExited(MouseEvent e)
- metodă invocată când cursorul de mouse
iese de pe suprafaţa unei componente. public void mouseDragged(MouseEvent e)
- mouse-ul a fost "tras" (adică a fost deplasat
menţinând unul din butoane apăsat). public void mouseMoved(MouseEvent e)
- mouse-ul a fost mişcat (fără să fie apăsat nici
unul din butoane).
Interfaţa PopupMenuListener public interface PopupMenuListener extends EventListener Interfaţă pentru ascultătoarele de evenimente generate de meniurile derulante (pop-up).
456
Programarea orientata pe obiecte în limbajul Java
Metode public void popupMenuWillBecomeVisible(PopupMenuEvent e)
- invocată când meniul
pop-up devine vizibil. public void popupMenuWillBecomeInvisible(PopupMenuEvent e)
- invocată când
meniul pop-up devine invizibil. public void popupMenuCanceled(PopupMenuEvent e)
este anulat.
457
- invocată când meniul pop-up
Severin Bumbaru
Surse de documentare 1. Documentaţie originală Pagina Web de la care puteţi porni căutarea documentaţiei originale oferite de firma Sun Microsystems pentru utilizatorii limbajului Java este java.sun.com. Pentru realizarea de aplicaţii şi miniaplicaţii în limbajul Java, puteti folosi documentaţia originală a firmei Sun Microsystems, al cărei index se găseşte pe internet la adresa: java.sun.com/docs/index.html. şi la Universitatea Tehnică Timişoara la adresa www.cs.utt.ro/ro/doc/jdk1.3.1/docs.Pe intranetul Catedrei de Calculatoare şi Informatică Aplicată de la Universitatea "Dunărea de Jos" din Galaţi gasiti aceasta documentatie la adresa lib.cs.ugal.ro/java/index.html. La realizarea aplicaţiilor şi miniaplicaţiilor Java, din această documentaţie veti folosi cel mai mult descrierea claselor din specificatia API (Application Program Interface) a platformei Java 2, intitulată "Java 2 Platform, Standard Edition, v1.4 API Specification" pe care o găsiţi la adresa următoare: java.sun.com/products/j2se/1.4/docs/api/index.html - la firma Sun Microsystems; Celor care sunt conectaţi la intranetul Catedrei de Calculatoare şi Informatică Aplicată de la Universitatea "Dunărea de Jos" din Galaţi le recomandăm să caute aceeaşi documentaţie la adresa http://lib.cs.ugal.ro/java/jdk140/api/index.html Pentru studierea mai profundă a limbajului Java, puteţi folosi specificatia riguroasa a acestuia, dată în documentul "Java Language Specification", care se găseşte la adresele urmatoare: java.sun.com/docs/books/jls/second_edition/html/j.title.doc.html .
2. O colecţie bogată de documentaţie Pentru studierea limbajului Java şi dezvoltarea de aplicaţii puteti folosi, de asemenea:
documentaţia recomandată de situl Sunsite Romania, de la Universitatea "Politehnica" din Bucureşti, în special cea de la rubrica Java Corner; documentaţia on-line a catedrei de calculatoare de la Universitatea Tehnica Timisoara, de la adresa: www.cs.utt.ro/ro/doconline.html; colectia de documentie din biblioteca studentilor specializarii de Calculatoare de la Universitatea Tehnica Iasi, situata la adresa: library.cs.tuiasi.ro/0/programmingjava.html.
3. Cărţi în limba română 1. Athanasiu Irina, Costinescu B., Drăgoi O.A., Popovici F.I. Limbajul Java. O perspectivă pragmatică. Editura Agora, Tg.Mureş 2. Prodan A., Prodan M. Mediul Java pentru Internet. Editura Promedia Plus, Cluj-Napoca, 1997. 3. Norton P., Stanek W. Ghid de programare in Java. Editura Teora, Bucureşti, 1997 458
Programarea orientata pe obiecte în limbajul Java 4. Rotariu E. Limbajul Java. Editura Agora, Tg.Mureş, 1996. 5. Fraizer C., Bond J. Java API. Pachetele API java.applet si java awt. Editura Teora, Bucureşti, 1998. 6. Lemay L., Cadenhead R. Java2 Fără profesor în 21 zile. Editura Teora, Bucureşti 7. Chan M.C., Griffith S.W., Iasi A.F. Java - 1001 secrete pentru programatori. Editura Teora, Bucureşti NOTA: cu excepţia cărţilor de la poziţiile 1, 6 si 7, care se bazează pe Java2 (JDK 1.2 sau ulterioare), toate celelalte au la bază JDK 1.0. La trecerea de la 1.0 la 1.1 s-au produs destul de multe modificări, în special în pachetele API.
4. Tutoriale şi manuale on-line Pe internet există numeroase tutoriale şi cărţi utile pentru instruire în domeniul limbajului şi platformei Java. Dintre acestea menţionăm:
manualul on-line de Java al prof. S. Bumbaru, pe intranetul Universitatii "Dunarea de Jos" din Galati; tutorialul (manualul on-line) Java recomandat de firma Sun se găseşte la adresa http://java.sun.com/docs/books/tutorial/, prezentând avantajul că este în permanenţă ţinut la curent cu evoluţia platformei Java. Acelaşi tutorial (într-o varianta neactualizată, dar cu avantajul că se obţine rapid) poate fi găsit şi pe intranetul catedrei de Calculatoare şi Informatică Aplicată http://lib.cs.ugal.ro/TutorialJava/; lista cu legături spre alte tutoriale, oferită de firma Sun Microsystems: http://developer.java.sun.com/developer/onlineTraining/ manualele din biblioteca on-line de la Universitatea Tehnica Iaşi; "Thinking in Java", by Bruce Eckel - un excelent manual de Java, în care accentul se pune nu pe sintaxă, ci pe semnificaţie.
459
Severin Bumbaru
ANEXA
Listele fişierelor sursă ale claselor date ca exemple în curs În această anexă se dau listările fişierelor sursă ale claselor care date ca exemple, care nu sunt reproduse în capitolele respective. Fişierele sunt grupate pe capitole. Capitolul 1 Capitolul 2 Capitolul 3 Capitolul 4 Capitolul 5 Capitolul 6 Capitolul 7 Capitolul 8 Capitolul 9 Capitolul 10 Capitolul 11 Capitolul 12
460 460 461 470 485 490 502 502 502 504 509 519
Capitolul 1. Fişierul PrimaAplicaţie.java class PrimaAplicatie { public static void main(String args[]) { System.out.println("Prima noastra aplicatie a reusit!"); } }
Capitolul 2. Fişierul AfisareSiruri.java /* Exersarea metodelor print si println */ class AfisareSiruri { public static void main(String args[]) { System.out.println("sirul 1"); System.out.println("sirul 2"); // se afiseaza sub sirul 1
460
Programarea orientata pe obiecte în limbajul Java System.out.println("AB"+"CDE"); // se afiseaza ABCDE System.out.println("ab"+"cd"+"ef"); // se afiseaza abcdef System.out.println(("ab"+"cd")+"ef"); // asociativitate System.out.println("ab"+("cd"+"ef")); /* Urmatoarele trei instructiuni afiseaza in continuare, pe o singura linie */ System.out.print("pqrst"); // nu se trece la linie noua System.out.print("UVW"); // se afiseaza in continuare System.out.print("xyz\n"); // echivalent cu println("xyz") /* Trecerea la linia urmatoare se face datorita prezentei caracterului de control \n in sirul "xyz\n" */ System.out.println("ultima linie afisata"); System.out.println((int)'A'+" "+(int)'q'); } }
Capitolul 3. Fişierul Repetare1.java /* Calcularea repetata a unei expresii pentru diferite valori ale lui k folosind ciclul cu test initial */ class Repetare1 { public static void main(String argv[]) { /* Se declara si initializeaza variabilele */ int k, n=12; /* Se calculeaza si afiseaza in mod repetat valoarea expresiei. Variabila k este declarata si initializata in for */ k=0; // initializarea contorului ciclului while (k<=n) { System.out.println("Pentru k="+k+" Valoarea expresiei este "+ 2*Math.exp(-0.35*k)*Math.sin(0.17*k-0.08)); k++; // Se pregateste trecerea la ciclul urmator } // Sfarsit ciclu } }
Fişierul Suma1.java /* Calcularea unei sume folosind ciclul cu test initial */ class Suma1 { public static void main(String argv[]) { int n=8, k; double a=0.72, b=-0.1735, S; /* Se calculeaza suma S */ S=0; k=0; // Se dau valorile initiale lui S si k while (k<=n) {
461
Severin Bumbaru /* Se calculeaza termenul curent al sumei si se adauga la valoarea precedenta a lui S */ S+=Math.sqrt(Math.pow(Math.sin(k*a+b),2)+ Math.pow(Math.cos(k*b-a),2)); k++; // se trece la valoarea urmatoare a lui k } // sfarsit ciclu /* Se afiseaza S */ System.out.println("Suma calculata este "+S); } }
Fişierul Serie1.java /* Calcularea sumei unei serii convergente folosind ciclul cu test initial */ class Serie1 { public static void main(String argv[]) { /* Se declara si se initializeaza variabilele din program */ double x=1.30726, S=0, t=1; int k=0; /* Se calculeaza suma S a seriei */ while (S+t!=S){ S+=t; // Se adauga termenul curent la suma partiala anterioara k++; // Se trece la indicele termenului urmator t*=x/k; // Se calculeaza valoarea termenului urmator } // sfarsit ciclu /* Se afiseaza rezultatul */ System.out.println("Suma seriei este "+S); /* Avand in vedere ca suma S calculata mai sus este dezvoltarea in serie Taylor a functiei matematice exponentiale exp(x), pentru comparatie afisam si valoarea acestei functii */ System.out.println("Pentru comparatie: "+Math.exp(x)); } }
Fişierul DeosCicluri.java /* Testarea deosebirii dintre ciclurile cu test initial si cu test final */ class DeosCicluri { public static void main(String argv[]) { int k=7; /* Situatia cand corpul ciclului cu test initial nu se executa nici o data */ while (k<0) System.out.println("Aceast text nu trebuie sa se afiseze!"); /* Situatia similara, in care insa corpului cu test final se
462
Programarea orientata pe obiecte în limbajul Java executa o singura data */ do System.out.println("Acest text trebuie sa se afiseze o singura " +"data"); while (k<0); /* Incrementari succesive cu ciclu cu test initial */ k=0; while (k<5){ System.out.println("In ciclul cu test initial k="+k); k++; } System.out.println("La iesirea din ciclul cu test initial k="+k); /* Incrementari succesive cu ciclu cu test final si aceeasi conditie de continuare a ciclului */ k=0; do { System.out.println("In ciclul cu test final k="+k); k++; } while (k<5); System.out.println("La iesirea din ciclul cu test final k="+k); } }
Fişierul Repetare2.java /* Calcularea repetata a unei expresii pentru diferite valori ale lui k folosind ciclul cu test final */ class Repetare2 { public static void main(String argv[]) { /* Se declara si initializeaza variabilele */ int k, n=12; /* Se calculeaza si afiseaza in mod repetat valoarea expresiei */ k=0; do { System.out.println("Pentru k="+k+" Valoarea expresiei este "+ 2*Math.exp(-0.35*k)*Math.sin(0.17*k-0.08)); k++; // se trece la valoarea urmatoare a lui k } while (k<=n); } }
Fişierul Suma2.java /* Calcularea unei sume folosind ciclul cu test final */ class Suma2 { public static void main(String argv[]) {
463
Severin Bumbaru int n=8, k; double a=0.72, b=-0.1735, S; /* Se calculeaza suma S */ S=0; k=0; // Se dau valorile initiale lui S si k do { /* Se calculeaza termenul curent al sumei si se adauga la valoarea precedenta a lui S */ S+=Math.sqrt(Math.pow(Math.sin(k*a+b),2)+ Math.pow(Math.cos(k*b-a),2)); k++; // se trece la valoarea urmatoare a lui k } while (k<=n); /* Se afiseaza S */ System.out.println("Suma calculata este "+S); } }
Fişierul Serie2.java /* Calcularea sumei unei serii convergente folosind ciclul cu test final */ class Serie2 { public static void main(String argv[]) { /* Se declara si se initializeaza variabilele din program */ double x=1.30726, S=0, t=1; int k=0; /* Se calculeaza suma S a seriei */ do { S+=t; // Se adauga termenul curent la suma partiala anterioara k++; // Se trece la indicele termenului urmator t*=x/k; // Se calculeaza valoarea termenului urmator } while (S+t!=S); /* Se afiseaza rezultatul */ System.out.println("Suma seriei este "+S); /* Avand in vedere ca suma S calculata mai sus este dezvoltarea in serie Taylor a functiei matematice exponentiale exp(x), pentru comparatie afisam si valoarea acestei functii */ System.out.println("Pentru comparatie: "+Math.exp(x)); } }
Fişierul TestFor.java /* Testarea instructiunii for */ class TestFor { public static void main(String arg[]) { int k, n=9; double a=2.7465,P; /* Diferite forme ale instructiunii for pentru realizarea urmatorului
464
Programarea orientata pe obiecte în limbajul Java program scris in pseudocod: P=1; pentru k de_la 5 la n executa P=P*(a+k) sfarsit_ciclu */ /* Forma de baza */ for(P=1,k=5; k<=n; k++) P*=a+k; System.out.println("P="+P); /* Varianta (a), in care initializarea se face inainte de instructiunea for, iar pregatirea pasului parcurgerii urmatoare se face in corpul ciclului. Atentie: intre parantezele lui for s-au mentinut separatorii';' */ P=1; k=5; for(;k<=n;){ P*=a+k; k++; } System.out.println("In varianta (a) P="+P); /* Varianta (b), in care s-a suprimat corpul ciclului, trecand instructiunea respectiva in zona de pregatire a parcurgerii urmatoare; corpul ciclului este acum instructiunea vida */ for(P=1,k=5;k<=n;P*=a+k,k++); System.out.println("In varianta (b) P="+P); /* Variabila "contor al ciclului" poate fi si de tip real si cresterea ei la fiecera parcurgere a ciclului poate fi de asemenea de tip real */ double v,S; for(S=0, v=2.75; v<12; v+=0.12876) S+=2*v; System.out.println("S="+S); /* Pasul de variatie al "contorului" poate sa nu fie constant */ for(S=2.87,v=12;v>0.005;v/=2.53) S+=v; System.out.println("S="+S); } }
Fişierul TestFor1.java /* Declararea unor variabile in zona de initializare a instructiunii for */ class TestFor1 { public static void main(String argv[]) { int j=0, n=7; double x=0, a=1.2073;
465
Severin Bumbaru /* Variabila k este declarata si initializata in instructiunea for */ for(int k=0; k
467
Severin Bumbaru if(k>0) break bloc1; System.out.println("Iesire din blocul interior"); } System.out.println("Iesire din blocul exterior"); } System.out.println("S-a iesit din ambele blocuri"); } }
Fişierul TestCont.java /* Testarea instructiunii continue */ class TestCont { public static void main(String argv[]) { double a=3.25, x=1.17, s, t; int k; /* Folosirea instructiunii continue fara eticheta */ System.out.println("Testul 1"); s=0; for(k=0; k<20; k++) { x*=a; s+=x; if(k<16) continue; System.out.println("k="+k+" x="+x+" s="+s); } /* Instructiunea continue care contine o eticheta produce trecerea fortata la sfarsitul corpului ciclului care poarta eticheta respectiva si continuarea acestui ciclu cat timp este satisfacuta conditia sa */ System.out.println("\nTestul 2"); ciclu1: for(int i=0; i<6; i++) { System.out.println("Control 1: i="+i); for(int j=3; j>0; j--) { System.out.println("Control 2: i="+i+" j="+j); if(i>1 && i<5) continue ciclu1; System.out.println("Control 3: i="+i+" j="+j); } // Sfarsitul ciclului interior System.out.println("Control 4: i="+i); } // Sfarsitul ciclului exterior } }
Fişierul TestExcept1.java /* Exemplu de aparitie a unei exceptii */ class TestExcept1 { public static void main(String argv[]) { int a=7, b=0, x; System.out.println("Urmeaza o exceptie de impartire la zero");
468
Programarea orientata pe obiecte în limbajul Java x=a/b; System.out.println("S-a depasit locul de aparitie a exceptiei"); } }
Fişierul TestExcept2.java /* Exemplu de aparitie a unei exceptii folosind instructiunea try */ class TestExcept2 { public static void main(String argv[]) { int a=7, b=0, x; try { System.out.println("Urmeaza o exceptie de impartire la zero"); x=a/b; System.out.println("S-a depasit locul de aparitie a exceptiei"); } catch (ArithmeticException e1) { System.out.println("S-a captat exceptia aritmetica:\n"+e1); } catch (Exception e2) { System.out.println("S-a captat exceptia:\n"+e2); } System.out.println("S-a trecut de instructiunea try"); System.out.println("Sfarsit normal al programului"); } }
Fişierul TestExcept3.java /* Exemplu de aparitie a unei exceptii folosind instructiunea try */ class TestExcept3 { public static void main(String argv[]) { int a=7, b=0, x; try { System.out.println("Urmeaza o exceptie de impartire la zero"); x=a/b; System.out.println("S-a depasit locul de aparitie a exceptiei"); } catch (Exception e) { System.out.println("S-a captat exceptia:\n"+e); } System.out.println("S-a trecut de instructiunea try"); System.out.println("Sfarsit normal al programului"); } }
Fişierul TestExcept4.java /* Exemplu de aparitie a unei exceptii folosind instructiunea try */ class TestExcept4 {
469
Severin Bumbaru public static void main(String argv[]) { int a=7, b=0, x; try { System.out.println("Urmeaza o exceptie de impartire la zero"); x=a/b; System.out.println("S-a depasit locul de aparitie a exceptiei"); } catch (ArithmeticException e1) { System.out.println("S-a captat exceptia e1:\n"+e1); } catch (Exception e2) { System.out.println("S-a captat exceptia e2:\n"+e2); } finally { System.out.println("S-a executat secventa din clauza finally"); } System.out.println("S-a trecut de instructiunea try"); System.out.println("Sfarsit normal al programului"); } }
Fişierul TestExcept5.java /* Exemplu de aparitie a unei exceptii folosind instructiunea try */ class TestExcept5 { public static void main(String argv[]) { int a=7, b=1, x; try { System.out.println("Urmeaza o impartire intreaga"); x=a/b; System.out.println("S-a efectuat impartirea fara sa apara "+ "o exceptie"); } catch (ArithmeticException e1) { System.out.println("S-a captat exceptia e1:\n"+e1); } catch (Exception e2) { System.out.println("S-a captat exceptia e2:\n"+e2); } finally { System.out.println("S-a executat secventa din clauza finally"); } System.out.println("S-a trecut de instructiunea try"); System.out.println("Sfarsit normal al programului"); } }
Capitolul 4 Fişierul TestObject.java /* Testarea clasei Object */ import java.util.*;
470
Programarea orientata pe obiecte în limbajul Java class TestObject { public static void main(String argv[]) { Object ob1=new Object(), ob2=new String("ABCD"), ob3="abcd", ob4=ob2; Object ob5=new Object(), ob6=ob5; String str1="ABCD", str2=str1; System.out.println("ob1="+ob1); System.out.println("ob2="+ob2); System.out.println("ob3="+ob3); System.out.println("str1="+str1); System.out.println("Coduri de dispersie:"); System.out.println("ob1: "+ob1.hashCode()); System.out.println("ob5: "+ob5.hashCode()); System.out.println("ob2: "+ob2.hashCode()); System.out.println("str1: "+str1.hashCode()); System.out.println("ob4: "+ob4.hashCode()); System.out.println("ob3: "+ob3.hashCode()); System.out.println("Testarea egalitatii prin == si prin equals():"); /* In clasa Obhect operatorul == si metoda equals() sunt echivalente */ System.out.println("ob1==ob5: "+(ob1==ob5)+" (ob1.equals(ob5))); System.out.println("ob5==ob6: "+(ob5==ob6)+" (ob5.equals(ob6)));
ob1.equals(ob5): "+ ob5.equals(ob6): "+
/* Pentru obiecte din clasa String operatorul == testeaza egalitatea referintelor, in timp ce metoda equals() testeaza egalitatea continutului" */ System.out.println("ob2==ob4: "+(ob2==ob4)+" ob2.equals(ob4): "+ (ob2.equals(ob4))); System.out.println("ob2==str1: "+(ob2==str1)+" ob2.equals(str1): "+ (ob2.equals(str1))); System.out.println("ob2==ob3: "+(ob2==ob3)+" ob2.equals(ob3): "+ (ob2.equals(ob3))); /* Aplicarea metodei toString() obiectelor din clasa Object */ System.out.println("Aplicarea metodei toString(): "); System.out.println("pentru ob1: "+ob1.toString()); /* Aplicarea metodei toString() obiectelor din clasa String intoarce chiar sirul pe care acestea il contin */ System.out.println("pentru ob2: "+ob2.toString()); System.out.println("pentru ob3: "+ob3.toString()); System.out.println("pentru str1: "+str1.toString()); /* De altfel, daca un obiect apare ca argument in metoda print() sau println(), aplicarea conversia lui in sir (deci aplicarea metodei toString() se face in mod implicit */ System.out.println("Aceleasi afisari, cu conversii in sir implicite:"); System.out.println(ob1); System.out.println(ob2); System.out.println(ob3); System.out.println(str1); /* Unei variabile din clasa Object i se poate atribui o referinta la un obiect din clasa String, deci instructiunea urmatoare nu produce o
471
Severin Bumbaru eroare de compilare */ ob1=str2; /* Unei variabile din clasa String nu i se poate atribui o referinta la un obiect din clasa Object. In consecinta, daca se elimina // din linia de program urmatoare, apare o eroare la compilare */ // str1=ob2; /* Daca insa suntem siguri ca variabila ob2 din clasa Object contine in realitate o referinta la un obiect din clasa String (asa cum este cazul in situatia de fata) putem cere o conversie explicita de la Object la String. Din aceasta cauza, instructiunea urmatoare nu mai constituie o eroare */ str1=(String)ob2; /* Aplicarea metodei getClass() */ System.out.println("Informatii despre clase: "); System.out.println("ob5: "+ob5.getClass()); System.out.println("ob2: "+ob2.getClass()); System.out.println("str1: "+str1.getClass()); } }
Fişierul TestStr.java /* Testarea clasei String */ class TestStr { public static void main(String args[]) { String s1="ABCdef#@&", s2, s3, s4; char ch1[]; byte tb[]; s2=new String("Un sir nou"); System.out.println("s1="+s1+" s2="+s2); System.out.println("Lungimile sirurilor: s1="+s1.length()+ " s2="+s2.length()); System.out.println("Conversie in litere mari: s1="+s1.toUpperCase()+ " s2="+s2.toUpperCase()); System.out.println("Conversie in litere mici: s1="+s1.toLowerCase()+ " s2="+s2.toLowerCase()); ch1=s1.toCharArray(); System.out.print("s1 convertit in tablou de caractere: "); for(int i=0; i
472
Programarea orientata pe obiecte în limbajul Java s1.compareTo(s2)+" "+s2.compareTo(s1)); System.out.println("s1==s3: "+(s1==s3)+" s1.equals(s3): "+ s1.equals(s3)); s4=s2.toUpperCase(); System.out.println("s2="+s2+" s4="+s4); System.out.println("s2.equals(s4): "+s2.equals(s4)+ " s2.equalsIgnoreCase(s4): "+s2.equalsIgnoreCase(s4)); System.out.println("Subsirul lui s2 intre pozitiile 3 si 8: "+ s2.substring(3,8)); System.out.println("Subsirul lui s2 de la pozitia 3 la sfarsit: "+ s2.substring(3)); } }
Fişierul TestStrB.java /* Testarea clasei StringBuffer */ class TestStrB { public static void main(String args[]) { StringBuffer stb1=new StringBuffer(), stb2; String str1="abcdefg", str2; double d=3.670283105E-3; char tc1[]={'A','B','C'}, tc2[]=new char[10]; System.out.println("Lungimea si capacitatea initiala a stb1: "+ stb1.length()+" "+stb1.capacity()); stb1.append(str1); stb1.append(d); System.out.println("stb1="+stb1+"\nLungime: "+stb1.length()+ " Capacitate: "+stb1.capacity()); str2=stb1.toString(); // Este obligatorie folosirea metodei toString() System.out.println("Caracterul de indice 3: "+stb1.charAt(3)); stb2=stb1.insert(3, "PQRS"); System.out.println("Dupa insertia sirului PQRS:\nstb1="+stb1+ "\nstb2="+stb2); stb1.append(tc1); System.out.println("Dupa adaugarea tabloului tc1, stb1="+stb1); System.out.println("Lungime: "+stb1.length()+" Capacitate: "+ stb1.capacity()); stb1.delete(3,25); System.out.println("Dupa eliminarea zonei 3..25: "+stb1); System.out.println("Lungime: "+stb1.length()+" Capacitate: "+ stb1.capacity()); stb1.reverse(); System.out.println("Dupa inversare stb1="+stb1); stb1.getChars(1,4,tc2,3); System.out.println("Dupa extragerea de caractere, lungimea "+ "tabloului tc2: "+tc2.length); System.out.print("tc2="); for(int i=0; i
473
Severin Bumbaru
Fişierul TestClass.java /* Testarea clasei Class */ class TestClass { public static void main(String args[]) { String s1="Primul sir", s2="al doilea sir"; Object obj=new Object(); Class cls1, cls2, cls3; cls1=s1.getClass(); System.out.println(cls1.getName()); System.out.println(cls1.toString()); cls2=s2.getClass(); System.out.println(cls1.isAssignableFrom(cls2)); cls3=obj.getClass(); System.out.println(cls3); System.out.println(cls1.isAssignableFrom(cls3)); System.out.println(cls3.isAssignableFrom(cls1)); System.out.println(cls1.getSuperclass()); System.out.println(cls3.getSuperclass()); System.out.println(cls1.isPrimitive()); } }
Fişierul testBoolean.java /* Testarea clasei acoperitoare Boolean */ class TestBoolean { public static void main(String args[]) { boolean b1=true, b2=false, b3, b4; Boolean bc1, bc2, bc3=Boolean.TRUE, bc4=Boolean.FALSE, bc5, bc6; boolean tb1[]={true, false, true}, tb2[][]={{true,false},{false,true}}; Boolean tcb1[]={Boolean.TRUE,Boolean.FALSE}; Boolean tcb2[][]={{Boolean.FALSE,Boolean.TRUE}, {Boolean.TRUE,Boolean.FALSE}}; String str1, str2; /* Se aplica constructorul Boolean(boolean value) */ bc1=new Boolean(b1); bc2=new Boolean(b2); /* Se afiseaza valorile variabilelor bc1 si bc2 convertite in siruri (amintim ca in argumentele metodelor print() si println() aplicarea metodei toString() este implicita) */ System.out.println("bc1="+bc1+" bc2="+bc2); /* Se afiseaza tablourile cu componente de tip primitiv boolean */ System.out.println("Tabloul tb1: "); for (int i=0; i
474
Programarea orientata pe obiecte în limbajul Java System.out.println("Tabloul tcb1: "); for (int i=0; i
str2="+str2);
} }
Fişierul TestInt.java /* Testarea clasei acoperitoare Integer */ class TestInt { public static void main(String args[]) { Integer tI[]=new Integer[5], tI1[]=new Integer[5], a; int tint[]=new int[5], i1; String ts[]={"3298","-18765","+987692","-765b32","abcde"}; /* Testarea metodei statice parseInt(String) */ for(int i=0; i<5; i++) { try { tint[i]=Integer.parseInt(ts[i]); } catch(NumberFormatException e1) { System.out.println("i="+i+" eroare in sirul: "+ts[i]); } catch(Exception e) { System.out.println("i="+i+" Exceptie "+e); } } System.out.print("tint="); for(int i=0; i
476
Programarea orientata pe obiecte în limbajul Java System.out.println("in baza "+i+" i1="+Integer.toString(i1, i)); /* Testarea metodei statice valueOf(String) poate fi facuta in acelasi mod ca pentru metoda parseInt(String) */ for(int i=0; i<5; i++) { try { tI[i]=Integer.valueOf(ts[i]); } catch(NumberFormatException e1) { System.out.println("i="+i+" eroare in sirul: "+ts[i]); } catch(Exception e) { System.out.println("i="+i+" Exceptie "+e); } } System.out.print("tI="); for(int i=0; i
Fişierul testDouble.java /* Testarea clasei acoperitoare Double */ class TestDouble { public static void main(String args[]) { Double tD[]=new Double[6], a; double td[]=new double[6]; String ts[]={"3.2987","-187.659068","+9.87692413","8.0764382e-7", "-238.0729456E8","4.687b53e7"};
477
Severin Bumbaru long b; /* Testarea metodei statice parseDouble(String) */ for(int i=0; i<6; i++) { try { td[i]=Double.parseDouble(ts[i]); } catch(NumberFormatException e1) { System.out.println("i="+i+" eroare in sirul: "+ts[i]); } catch(Exception e) { System.out.println("i="+i+" Exceptie "+e); } } System.out.print("td="); for(int i=0; i
Fişierul TestChar.java /* Testarea clasei acoperitoare Character */ class TestChar { public static void main(String args[]) {
478
Programarea orientata pe obiecte în limbajul Java Character c1=new Character('B'), c2=new Character('b'), c3; Object ob; c3=new Character('b'); ob=c3; System.out.println("'x' este litera: "+Character.isLetter('x')); System.out.println("'3' este cifra: "+Character.isDigit('3')); System.out.println("'b' este litera mica: "+Character.isLowerCase('b')); System.out.println("'*' este litera mare: "+Character.isUpperCase('*')); System.out.println("'\\n' este Whitespace: "+ Character.isWhitespace('\n')); System.out.println("'\\n' este SpaceChar: "+Character.isSpaceChar('\n')); System.out.println("'d' mare este: "+Character.toUpperCase('d')); System.out.println("In sistemul de numeratie cu baza 27 cifra 19 este: "+ Character.forDigit(19,27)); System.out.println("In acelasi sistem, litera 'M' este cifra: "+ Character.digit('M',27)); /* Testarea operatorului == si a metodei equals() */ System.out.println("c2==c3: "+(c2==c3)); System.out.println("ob==c3: "+(ob==c3)); System.out.println("c2 identic cu c3: "+c2.equals(c3)); System.out.println("c2 identic cu ob: "+c2.equals(ob)); System.out.println("c1 identic cu ob: "+c1.equals(ob)); /* Testarea metodei hashCode() */ System.out.println("Coduri de dispersie pentru c1, c2, c3 si ob:\n"+ c1.hashCode()+" "+c2.hashCode()+" "+c3.hashCode()+" "+ ob.hashCode()); } }
Fişierul InitTab1.java /* Declararea si initializarea tablourilor unidimensionale */ class InitTab1 { public static void main(String args[]) { int a=27, b=-15, c[]={-3,72,-21}, d=-5, e[]={231,-98}; String s1="un sir", ts1[]={"sirul 0","sirul 1","sirul 2"}, s2="alt sir"; float[] u={-1.24076f, 0.03254f, 27.16f}, v={2.7698E-12f,-3.876e7f}; double aa[]=new double[3], bb[]={3.76,-2.879}; String str[]=new String[2], s3="abcdef1234"; long []k={187658954760876535L, 786432098764319051L}, m={598028476093172L, -9892865429740341L, 92765201}; Object tab1[]=new Object[2],tab2=new String[3], tab3[]={"aaa","bbb","ccc"}; System.out.println("Valorile variabilelor simple:"); System.out.println("a="+a+" b="+b+" d="+d); System.out.println("s1="+s1+" s2="+s2+" s3="+s3); System.out.println("Lungimile tablourilor:"); System.out.println("c: "+c.length+" e: "+e.length+" ts1: "+ts1.length); System.out.println("u: "+u.length+" v: "+v.length+" str: "+str.length); System.out.println("aa: "+aa.length+" bb: "+bb.length);
479
Severin Bumbaru System.out.println("k: "+k.length+" m: "+m.length); System.out.println("Componentele tablourilor:"); System.out.println("Tabloul c:"); for (int i=0; i
Fişierul Tab1.java /* Utilizarea tablourilor unidimensionale */ class Tab1 { public static void main(String args[]) { double a[]={3.276, -5.83, 12.8}, b[]; String ts1[]={"aa", "bb"},ts2[]; /* Variabilelor b si ts1 li se atribuie ca valori referinte la tablouri existente, apoi se afiseaza */ b=a; ts2=ts1; System.out.println("Dupa atribuirile b=a si ts2=ts1:"); for (int i=0; i
480
Programarea orientata pe obiecte în limbajul Java System.out.println("\nTabloul a[] a ramas neschimbat:"); for (int i=0; i
Fişierul ConvTip1.java /* Conversii de tip la atribuiri de referinte la tablouri unidimensionale */ class ConvTip1 { public static void main(String args[]) { int a[]={54, 23, -17}, b[]; double u[]={-6.237429, 83.17026}, v[]; String str1[]={"abc","def"}, str2[], str3[]; Object ob1, ob2, ob3, tob1[], tob2[]; /* Atribuire permisa: Object este superclasa pentru String */ tob1=str1; /* Instructiunea urmatoare nu este permisa, deoarece String nu este superclasa a lui Object (puteti verifica suprimand // din fata ei) */ // str2=tob1; /* Deoarece stim ca tob1[] contine o referinta la un tablou String, putem face o conversie explicita prin cast */ str2=(String[])tob1; /* Tablourile a[] si u[] sunt considerate obiecte, deci variabilele bsimple din clasa Object pot primi ca valori referinte la astfel de tablouri */ ob1=a; ob2=u; /* Chiar si un tablou de obiecte este considerat tot un obiect */ ob3=str1; /* Atribuirile inverse nu sunt permise, deoarece clasele int[], double[] si String[] nu sunt superclase ale lui Object (puteti verifica!) */ // b=ob1; // v=ob2; // str3=ob3; /* Avand in vedere ca stim ca atribuirile sunt corecte, ne putem permite sa facem conversiile explicite prin cast */ b=(int[])ob1; v=(double[])ob2; str3=(String[])ob3;
481
Severin Bumbaru /* Pentru a face diferite operatii cu componentele tablourilor referite de variabilele ob1, ob2 ob3 si tob1 sunt necesare, de asemenea, conversii explicite, deoarece ob1, ob2, ob3 nu sunt tablouri */ System.out.println("Tabloul referit de ob1:"); for (int i=0; i<((int[])ob1).length; i++) System.out.print(((int[])ob1)[i]+" "); System.out.println("\nTabloul referit de ob2: "); for (int j=0; j<((double[])ob2).length; j++) System.out.print(((double[])ob2)[j]+" "); System.out.println("\nTabloul referit de ob3:"); for (int k=0; k<((String[])ob3).length; k++) System.out.print(((String[])ob3)[k]+"; "); System.out.println(); /* Pentru afisarea elementelor lui tob1[] nu este nevoie de cast, deoarece acesta este tablou de componente din clasa Object care au ca valori referinte la String, iar Object este superclasa pentru String */ System.out.println("Tabloul referit prin tob1[]:"); for (int i=0; i
Fişierul Tab2.java /* Declararea si initializarea tablourilor bidimensionale */ class Tab2 { public static void main(String args[]) { double u=5.3127, v[]={1.25, -3.12, 2.6}, w[][]={{2.31, -4.15},{0.35,-12.6, -573.2},{10.9}}; int[] a={3,2,7}, b[]={{43,28,92,-6},{},{-1,17,29}}; char[][] h1={{'a','*'},{'+','$'}}, h2=new char[2][3], h3=new char[4][]; String ts[][]={{"abc","defg"},{"AB","CD","EF"}}; System.out.println("Numarul de linii din tabloul w: "+w.length); System.out.println("Numarul de componente din fiecare linie a "+ "tabloului w:"); for (int i=0; i
482
Programarea orientata pe obiecte în limbajul Java for (int j=0; j
");
} System.out.println("Numarul de linii din tabloul b: "+b.length); System.out.println("Numarul de componente din fiecare linie "+ " a tabloului b:"); for (int i=0; i
Fişierul Tab2a.java /* Operatii cu tablouri unidimensionale si bidimensionale */ class Tab2a { public static void main(String args[]) { int a[][]={{-5,12,52},{8,-4},{},{105}}, b[]={31,-3,17,24}; System.out.println("Dupa initializare:\nTabloul bidimensional a:"); for(int i=0; i
483
Severin Bumbaru for(int i=0; i
");
} }
Fişierul Tab2b.java /* Conversii de tip la tablouri bidimensionale */ class Tab2b { public static void main(String args[]) { Object ob1, ob2, tob2[][]; int ti1[][]={{0,1},{10,11,12,13},{20,21,22}},ti2[][]; String ts[][]={{"aa","ab"},{"ba","bb","bc"},{"ca","cb"}}, ts1[][]; /* Urmatoarele doua atribuiri sunt corecte */ ob1=ti1; ob2=ts; System.out.println("Tabloul indicat de ob1:"); for(int i=0; i<((int[][])ob1).length; i++) { for(int j=0; j<((int[][])ob1)[i].length; j++) System.out.print(((int[][])ob1)[i][j]+" "); System.out.println(); } /* Urmatoarele doua atribuiri nu sunt corecte, deoarece se trece de la clasa la subclasa (incercati sa suprimati simbolul // ) */ // ti2=ob1; // ts1=ob2; /* In urmatoarele doua atribuiri s-a recurs la conversii explicite, stiind caror clase apartin efectiv obiectele referite de variabilele respective */ ti2=(int[][])ob1; ts1=(String[][])ob2; System.out.println("Tabloul ti2:"); for(int i=0; i
484
Programarea orientata pe obiecte în limbajul Java tob2=ts; ts1=(String[][])tob2; } }
Fişierul TabEterogen.java /* Testarea construirii unui tablou eterogen */ class TabEterogen { public static void main(String args[]) { /* Construirea structurii */ Object tab[]=new Object[3]; tab[0]=new int[3]; ((int[])tab[0])[0]=-87; ((int[])tab[0])[1]=23; ((int[])tab[0])[2]=164; tab[1]=new double[2]; ((double[])tab[1])[0]=32.164; ((double[])tab[1])[1]=-6.237; tab[2]=new Object[3]; ((Object[])tab[2])[0]=new String("abcd"); ((Object[])tab[2])[1]=new String("PQRS"); ((Object[])tab[2])[2]=new char[2]; ((char[])((Object[])tab[2])[2])[0]='@'; ((char[])((Object[])tab[2])[2])[1]='$'; /* Afisarea unor componente din structura */ System.out.println(((Object[])tab[2])[0]); for(int i=0; i<3; i++) System.out.print(((int[])tab[0])[i]+" "); System.out.println(); for(int i=0; i<2; i++) System.out.print(((char[])((Object[])tab[2])[2])[i]+" System.out.println(); } }
Capitolul 5 Fişierul TestRecursii.java /* Metode recursive si iterative
*/
class Recursii { /* Metode recursive */ public static long factorial(int n) throws Exception { if(n<0) throw new Exception("factorial(n): n<0"); if(n==0) return 1; return n*factorial(n-1); } public static long fibonacci(int n) throws Exception { if(n<0) throw new Exception("fibonacci(n): n<0");
485
");
Severin Bumbaru if(n==0) return 0; if(n==1) return 1; return fibonacci(n-1)+fibonacci(n-2); } /* Metode mutual recursive: fct1() o invoca pe fct2() si reciproc */ public static double fct1(int n, double x) throws Exception { if(n<0) throw new Exception("fct1: n<0"); return 2*fct2(n, 0.4*x+0.3)+x; } public static double fct2(int n, double y) throws Exception { if(n<0) throw new Exception("fct2: n<0"); if(n==0) return y; return y*fct1(n-1, 1.27*y-0.89)-1; } } class Iteratii { public static long factorial(int n) throws Exception { long fact; if(n<0) throw new Exception("factorial(n): n<0"); fact=1; for(int i=2; i<=n; i++) fact*=i; return fact; } public static long fibonacci(int n) throws Exception { if(n<0) throw new Exception("fibonacci(n): n<0"); if(n==0) return 0; if(n==1) return 1; long a=0, b=1; for(int i=2; i<=n; i++) { b+=a; a=b-a; } return b; } } /* Aplicatia TestRecursii pentru testarea claselor Recursii si Iteratii. Se pune in executie dand ca parametru in linia de comanda numarul al carui factorial se calculeaza */ class TestRecursii { public static void main(String args[]) { int n; if(args.length==0) { System.out.println("Nu ati dat ca parametru un numar intreg"); System.exit(1); } n=Integer.parseInt(args[0]); try { long fact1, fact2, fib1, fib2; long time1, time2; /* Testarea functiilor mutual recursive fct1() si fct2() */ System.out.println("fct1("+n+", 1.76)="+Recursii.fct1(n,1.76)); System.out.println("fct2("+n+", 1.76)="+Recursii.fct2(n,1.76));
486
Programarea orientata pe obiecte în limbajul Java /* Calcularea factorialului prin functie recursiva */ time1=System.currentTimeMillis(); fact1=Recursii.factorial(n); time2=System.currentTimeMillis(); System.out.println("Recursiv factorial("+n+")="+fact1+ " durata: "+(time2-time1)); /* Calcularea iterativa a factorialului */ time1=System.currentTimeMillis(); fact2=Iteratii.factorial(n); time2=System.currentTimeMillis(); System.out.println("Iterativ factorial("+n+")="+fact2+ " durata: "+(time2-time1)); /* Calcularea recursiva a numarului lui Fibonacci */ time1=System.currentTimeMillis(); fib1=Recursii.fibonacci(n); time2=System.currentTimeMillis(); System.out.println("Recursiv fibonacci("+n+")="+fib1+ " durata: "+(time2-time1)); /* Calcularea iterativa a numarului lui Fibonacci */ time1=System.currentTimeMillis(); fib2=Iteratii.fibonacci(n); time2=System.currentTimeMillis(); System.out.println("Iterativ fibonacci("+n+")="+fib2+ " durata: "+(time2-time1)); /* Calcularea numarului lui Fibonacci pentru n=35 */ n=35; time1=System.currentTimeMillis(); fib1=Recursii.fibonacci(n); time2=System.currentTimeMillis(); System.out.println("Recursiv fibonacci("+n+")="+fib1+ " durata: "+(time2-time1)); time1=System.currentTimeMillis(); fib2=Iteratii.fibonacci(n); time2=System.currentTimeMillis(); System.out.println("Iterativ fibonacci("+n+")="+fib2+ " durata: "+(time2-time1)); } catch(Exception e) { System.out.println("Eroare in date: "+e); } } }
Fişierul TestComplex.java /* Testarea clasei Complex */ class TestComplex { public static void main(String args[]) { Complex u=new Complex(1,1), v=new Complex(1,-1), w=new Complex(-1,1), z=new Complex(-1,-1); Complex x=new Complex(1,1), y; /* Testarea redefinirii metodei toString() din clasa Object */ System.out.println("u="+u+" v="+v);
487
Severin Bumbaru /* Testarea redefinirii metodei equals din clasa Object */ System.out.println("u==x: "+(u==x)+" u.equals(x): "+u.equals(x)); y=u; System.out.println("u==y: "+(u==y)+" u.equals(y): "+u.equals(y)); System.out.println("u==v: "+(u==v)+" u.equals(v): "+u.equals(v)); /* Testarea redefinirii metodei hashCode din clasa Object */ System.out.println("Coduri de dispersie:"); System.out.println("u: "+u.hashCode()+" v: "+v.hashCode()+ " w: "+w.hashCode()+" z: "+z.hashCode()); /* Testarea metodelor care intorc re, im, modul si argument */ System.out.println("Pentru u: re="+u.real()+" im="+u.imag()+ " modul="+u.modul()+" argument="+u.arg()); System.out.println("Pentru v: re="+v.real()+" im="+v.imag()+ " modul="+v.modul()+" argument="+v.arg()); System.out.println("Pentru w: re="+w.real()+" im="+w.imag()+ " modul="+w.modul()+" argument="+w.arg()); System.out.println("Pentru z: re="+z.real()+" im="+z.imag()+ " modul="+z.modul()+" argument="+z.arg()); /* Testarea metodei statice complex */ try { x=Complex.complex(1.0,0.5); // Se creeaza un nou numar complex // cu modul 1 si argument 0.5 System.out.println("Noua valoare a lui x: "+x); System.out.println("Modulul lui x: "+x.modul()); System.out.println("Argumentul lui x: "+x.arg()); y=Complex.complex(-1.0,1.2); // Gresit: modul negativ -1.0 } catch(Exception e) { System.out.println(e); } /* Operatii intre numere complexe */ Complex a=null, b=null, c=null, d=null; y=new Complex(); try { a=u.plus(v); b=u.inmultitCu(v); c=u.impartitLa(v); d=b.minus(c); System.out.println("a="+a+" b="+b+"\nc="+c+" d="+d); d=u.impartitLa(y); } catch(Exception e) { System.out.println("impartire complex la complex nul:"); System.out.println(e); } /* Operatii intre un numar complex si unul real */ try { a=u.plus(2.5); b=u.inmultitCu(3.0); c=u.impartitLa(2.0); d=u.minus(4.5); System.out.println("a="+a+" b="+b+"\nc="+c+" d="+d); d=u.impartitLa(0.0); } catch(Exception e) { System.out.println("impartire complex la real nul:"); System.out.println(e);
488
Programarea orientata pe obiecte în limbajul Java } /* Operatii intre un numar real si unul complex */ try { a=Complex.plus(2.5, u); b=Complex.inmultitCu(3.0, u); c=Complex.impartitLa(1.0,c); d=Complex.minus(4.5,u); System.out.println("a="+a+" b="+b+"\nc="+c+" d="+d); d=Complex.impartitLa(1.0,y); } catch(Exception e) { System.out.println("impartire real la complex nul:"); System.out.println(e); } try { /* Calcularea expresiei (2*u+w-3)/v */ a=(((Complex.inmultitCu(2,u)).plus(w)).minus(3)).impartitLa(v); System.out.println("Valoarea expresiei finale: "+a); /* Aceeasi expresie calculata pas cu pas */ b=Complex.inmultitCu(2,u); c=b.plus(w); d=c.minus(3); a=d.impartitLa(v); System.out.println("Aceeasi valoare obtinuta pas cu pas: "+a); } catch(Exception e) { System.out.println("La calcularea expresiei finale:\n"+e); } } }
Fişierul Referinţe.java /* Utilizarea constructorilor si operatorului new */ class Referinte { public static void main(String argv[]) { String a="un sir", b=new String(a), c, d, e; c=new String(b); d=b; e=c; System.out.println("a="+a+" b="+b+" c="+c); System.out.println("d="+d+" e="+e); /* Se modifica acum valoarea lui b, construind un nou obiect, si se reafiseaza obiectele spre care fac referinte toate variabilele */ b=new String("alt sir"); System.out.println("Dupa atribuirea unei noi valori lui b:"); System.out.println("a="+a+" b="+b+" c="+c); System.out.println("d="+d+" e="+e); /* Se mai fac acum si alte atribuiri */ e=b; a="sir nou"; c=new String(a);
489
Severin Bumbaru System.out.println("Dupa atribuirea de valori noi lui e, a si c:"); System.out.println("a="+a+" b="+b+" c="+c); System.out.println("d="+d+" e="+e); } }
Fişierul Finalizari.java class ProbaFinaliz { private int a; public ProbaFinaliz(int m) { a=m; System.out.println("S-a construit obiectul "+a); } protected void finalize() { System.out.println("Finalizarea obiectului "+a); } } class Finalizari { public static void main(String args[]) { ProbaFinaliz pf1=new ProbaFinaliz(1), pf2=new ProbaFinaliz(2); pf1=null; System.out.println("S-a anulat referinta pf1"); pf2=null; System.out.println("S-a anulat referinta pf2"); System.out.println("Se incheie executia aplicatiei"); } }
Capitolul 6 Fişierul Cercuri.java /* Declararea clasei Cerc1 cu metode ale instantei */ class Cerc1 { static final double PI=3.141592653589793; double r; double arie() { return PI*r*r; } double circumferinta() { return 2*PI*r; } } /* Declararea clasei Cerc2 cu metode ale clasei (statice) */
490
Programarea orientata pe obiecte în limbajul Java class Cerc2 { static final double PI=3.141592653589793; static double arie(double r) { return PI*r*r; } static double circumferinta(double r) { return 2*PI*r; } } /* Aplicatia in care se utilizeaza cele doua clase de cercuri declarate mai sus */ class Cercuri { public static void main(String args[]) { double r1=1, r2=7.32; Cerc1 c1=new Cerc1(), c2=new Cerc1(); c1.r=r1; c2.r=r2; System.out.println("Folosind metodele de instanta din clasa Cerc1:"); System.out.println("Pentru cercul c1: aria="+c1.arie()+ " circumferinta="+c1.circumferinta()); System.out.println("Pentru cercul c2: aria="+c2.arie()+ " circumferinta="+c2.circumferinta()); System.out.println("Folosind metodele statice din clasa Cerc2:"); System.out.println("Pentru raza r1: aria="+Cerc2.arie(r1)+ " circumferinta="+Cerc2.circumferinta(r1)); System.out.println("Pentru raza r2: aria="+Cerc2.arie(r2)+ " circumferinta="+Cerc2.circumferinta(r2)); } }
Fişierul Cercuri1.java /* Declararea clasei Cerc cu metode ale instantei */ class Cerc { public static final double PI=3.141592653589793; private double r; public Cerc(double raza) { r=raza; } public double raza() { return r; } public double arie() { return PI*r*r; } public double circumferinta() { return 2*PI*r; } public static double arie(double r) {
491
Severin Bumbaru return PI*r*r; } public static double circumferinta(double r) { return 2*PI*r; } } /* Aplicatia in care se utilizeaza cele doua clase de cercuri declarate mai sus */ class Cercuri1 { public static void main(String args[]) { double r1=1, r2=7.32; /* Instantierea a doua cercuri */ Cerc c1=new Cerc(r1), c2=new Cerc(r2); /* Utilizarea metodelor de instanta */ System.out.println("Utilizand metodele de instanta:"); System.out.println("Pentru cercul c1:\n aria="+c1.arie()+ " circumferinta="+c1.circumferinta()+" raza="+c1.raza()); System.out.println("Pentru cercul c2:\n aria="+c2.arie()+ " circumferinta="+c2.circumferinta()+" raza="+c2.raza()); System.out.println("Folosind metodele statice ale clasei Cerc:"); System.out.println("Pentru raza r1: aria="+Cerc.arie(r1)+ " circumferinta="+Cerc2.circumferinta(r1)); System.out.println("Pentru raza r2: aria="+Cerc.arie(r2)+ " circumferinta="+Cerc2.circumferinta(r2)); System.out.println("Pentru raza r=9.23 aria="+Cerc.arie(9.23)+ " circumferinta="+Cerc.circumferinta(9.23)); /* Acelasi calcul, facut calificand numele metodelor prin referinte la instante ale clasei Cerc */ System.out.println("Aria cercului cu raza 9.23: "+ c1.arie(9.23)+" "+c2.arie(9.23)); } }
Fişierul TestPers.java /* Testarea clasei Persoana */ class TestPers { public static void main(String args[]) { Pers p1=new Pers("Antoniu","Vasile",1981); Pers p2, p3, p4, p5; String s1="Vasilescu", s2="Mihai"; p2=new Pers(s1, s2, 1980); p3=new Pers(s1, "Ion", 1982); System.out.println("Numele persoanei p1: "+p1.nume()); System.out.println("Prenumele persoanei p2: "+p2.prenume()); System.out.println("Anul nasterii persoanei p3: "+p3.anNastere()); } }
492
Programarea orientata pe obiecte în limbajul Java
Fişierul TestExceptie.java /* Crearea si utilizarea unei Exceptii */ class ExceptieDomeniuFactorial extends Exception { public ExceptieDomeniuFactorial() { super(); } public ExceptieDomeniuFactorial(String str) { super(str); } } class Fact { public static double factorial(int n) throws ExceptieDomeniuFactorial { if(n<0) throw new ExceptieDomeniuFactorial(); if(n==0) return 1; return n*factorial(n-1); } } class TestExceptie { public static void main(String args[]) { int n; double fact; if(args.length==0) { System.out.println("Nu ati dat numarul intreg n ca parametru"); System.exit(1); } try { n=Integer.parseInt(args[0]); fact=Fact.factorial(n); System.out.println("Factorialul este "+fact); } catch(NumberFormatException e1) { System.out.println("Parametrul nu are format corect de numar intreg"); } catch(ExceptieDomeniuFactorial e2) { // se capteaza exceptia nou creata System.out.println("Nu se poate calcula factorial din numar negativ"); } catch(Exception e) { System.out.println("S-a produs exceptia: "+e); } } }
Fişierul Persoana1.java /* O varianta a clasei Persoana, in care campurile sunt protejate */ public class Persoana1 { protected String nume, prenume; protected int anNastere;
493
Severin Bumbaru
public Persoana1() {} // Constructor fara argumente public Persoana1(String nume, String prenume, int anNastere) { this.nume=nume; this.prenume=prenume; this.anNastere=anNastere; } public Persoana1(Persoana1 pers) { nume=pers.nume; prenume=pers.prenume; anNastere=pers.anNastere; } public String nume() { return nume; } public String prenume() { return prenume; } 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; } }
Fişierul Student1.java public class Student1 extends Persoana1 { private String fac, gr; private int anStudii; public Student1(String nume, String prenume, int anNastere, String facultate, int an, String grupa) { this.nume=nume; this.prenume=prenume; this.anNastere=anNastere; fac=facultate; anStudii=an; gr=grupa; } public Student1(Persoana1 pers, String facultate, int an, String grupa) { nume=pers.nume; prenume=pers.prenume; anNastere=pers.anNastere; fac=facultate; anStudii=an; gr=grupa; } public Student1(Student1 stud) {
494
Programarea orientata pe obiecte în limbajul Java 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; } }
Fişierul TestStud1.java /* O varianta a clasei TestStud, pentru testarea claselor Persoana1 si Student1 */ class TestStud1 { public static void main(String args[]) { Persoana1 p1=new Persoana1("Vasiliu","George",1981), p2; Student1 s1=new Student1(p1, "NIE",2,"2221a"), s2=new Student1("Ionescu","Maria", 1980, "NIE", 2, "2322b"), s3; Object ob1, ob2, ob3; Persoana1 tabPers[]=new Persoana1[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: "+((Persoana1)ob1).nume()); s3=(Student1)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
495
Severin Bumbaru
Fişierul FiguriPlane.java /* Clase de figuri plane */ /* Declararea unei clase abstracte */ abstract class FiguraPlana { public abstract double perimetru(); // metoda abstracta public abstract double arie(); // metoda abstracta } /* Clase concrete derivate din cea abstracta */ class Cerc extends FiguraPlana { private double raza; public Cerc(double raza) { this.raza=raza; } public double raza() { return raza; } public double perimetru() { // redefinirea metodei abstracte return 2*Math.PI*raza; } public double arie() { // redefinirea metodei abstacte return Math.PI*raza*raza; } public double diametru() { return 2*raza; } } class Patrat extends FiguraPlana { private double latura; public Patrat(double latura) { this.latura=latura; } public double latura() { return latura; } public double perimetru() { // redefinirea metodei abstracte return 4*latura; } public double arie() { // redefinirea metodei abstracte return latura*latura; } public double diagonala() { return latura*Math.sqrt(2); } } /* Aplicatie pentru testarea claselor. Mod de utilizare: java FiguriPlane
496
Programarea orientata pe obiecte în limbajul Java double a; /* Instructiunea urmatoare nu este corecta, deoarece o clasa abstracta nu poate fi instantiata; daca se elimina din fata // apare eroare la compilare */ // f=new FiguraPlana(); /* Se valideaza parametrul din linia de comnada */ if(args.length==0) { System.out.println("Dati ca parametru un numar real pozitiv"); System.exit(1); } try { a=Double.parseDouble(args[0]); if(a<=0) { System.out.println("Numarul nu este pozitiv"); System.exit(2); } /* Se instantiaza clasele Cerc si Patrat */ c=new Cerc(a); p=new Patrat(a); /* Variabilei f din clasa abstracta FiguraPlana i se poate da ca valoare o referinta catre o subclasa instantiabila */ f=new Cerc(2*a); /* Aplicarea metodelor */ System.out.println("Cerc: raza="+c.raza()+" perimetrul="+ c.perimetru()+"\naria="+c.arie()+" diametrul="+c.diametru()); System.out.println("Patrat: latura="+p.latura()+" perimetrul="+ p.perimetru()+"\naria="+p.arie()+" diagonala="+p.diagonala()); /* Daca spre un obiect din clasa Cerc indica o variabila din superclasa FiguraPlana, este necesara conversia de clasa pentru invocarea metodelor care nu exista in superclasa */ System.out.println("Al doilea cerc: raza="+((Cerc)f).raza()+ " perimetrul="+ f.perimetru()+"\naria="+f.arie()+ " diametrul="+((Cerc)f).diametru()); } catch(NumberFormatException e1) { System.out.println("Nu ati respectat formatul de numar real"); } catch(Exception e) { System.out.println("S-a produs exceptia: "+e); } } }
Fişierul Integrare.java /* Aplicatie in care se integreaza functt prin metoda trapezelor */ /* Declararea si utilizarea unor interfete
*/
/* Interfata pentru o clasa care ofera o functie reala de o variabila reala */ interface FunctieReala { double f(double x); }
497
Severin Bumbaru
/* Interfata pentru o clasa care ofera o metoda de calcul al integralei de la inf la sup a functiei f(x) din interfata FunctieReala */ interface Integrator { double integrala(double inf, double sup, FunctieReala func); } /* O clasa care implementeaza interfata FunctieReala pentru a oferi functia f(x)=a*sin(b*x+c)+d*cos(b*x) */ class Functie1 implements FunctieReala { private double a, b, c, d; // parametrii functiei /* Constructorul clasei introduce valorile parametrilor functiei */ public Functie1(double a, double b, double c, double d) { this.a=a; this.b=b; this.c=c; this.d=d; } /* metoda de calculare a functiei, prin care se concretizeaza metoda abstracta f(x) din interfata */ public double f(double x) { return a*Math.sin(b*x+c)+d*Math.cos(b*x); } } /* O clasa care implementeaza interfata Integrator, realizand integrarea prin metoda trapezelor a functiei f(x) cu nrPasi pasi de integrare */ class IntegrareTrapeze implements Integrator { int nrPasi; // Numarul de pasi de integrare /* Constructorul initializeaza numarul de pasi */ public IntegrareTrapeze(int nrPasi) throws Exception { if(nrPasi<=0) throw new Exception("IntegrareTrapeze: nrPasi<=0"); this.nrPasi=nrPasi; } /* Metoda de modificare a numarului de pasi */ public void puneNrPasi(int nrPasi) throws Exception { if(nrPasi<=0) throw new Exception("IntegrareTrapeze: nrPasi<=0"); this.nrPasi=nrPasi; } /* Implementarea metodei abstracte din interfata */ public double integrala(double inf, double sup, FunctieReala func) { double h,s; h=(sup-inf)/nrPasi; // pasul de integrare s=0; // initializarea sumei ordonatelor for(int i=1; i
498
Programarea orientata pe obiecte în limbajul Java
class Integrare { public static void main(String args[]) { IntegrareTrapeze inTrap; FunctieReala f1, f2; double inf, sup; // marginile intervalului de integrare int nrPasi; // numarul de pasi de integrare if(args.length<3) { System.out.println("Utilizare: java Integrare inf sup nrPasi"); System.exit(1); } try { inf=Double.parseDouble(args[0]); sup=Double.parseDouble(args[1]); nrPasi=Integer.parseInt(args[2]); f1=new Functie1(2.73, 0.15, -0.21, 2.45); f2=new Functie1(-3.527, -0.43, 0.16, 1.03); inTrap=new IntegrareTrapeze(nrPasi); System.out.println("Prima integrala: "+inTrap.integrala(inf,sup,f1)); System.out.println("A doua integrala: "+inTrap.integrala(inf,sup,f2)); inTrap.puneNrPasi(2*nrPasi); System.out.println("Dupa dublarea numarului de pasi de integrare:"); System.out.println("Prima integrala: "+inTrap.integrala(inf,sup,f1)); System.out.println("A doua integrala: "+inTrap.integrala(inf,sup,f2)); } catch(NumberFormatException e1) { System.out.println("Nu ati introdus corect parametrii aplicatiei"); } catch(Exception e) { System.out.println("S-a produs exceptia: "+e); } } }
Fişierul Integrare1.java /* O varianta a aplicatiei din fisierul Integrare.java, in care se folosesc clase imbricate si interioare */ /* Declararea si utilizarea unor interfete
*/
/* Interfata pentru o clasa care ofera o functie reala de o variabila reala */ interface FunctieReala { double f(double x); } /* Interfata pentru o clasa care ofera o metoda de calcul al integralei de la inf la sup a functiei f(x) din interfata FunctieReala */
499
Severin Bumbaru
interface Integrator { double integrala(double inf, double sup, FunctieReala func); } /* O clasa care implementeaza interfata Integrator, realizand integrarea prin metoda trapezelor a functiei f(x) cu nrPasi pasi de integrare */ class IntegrareTrapeze implements Integrator { int nrPasi; // Numarul de pasi de integrare /* Constructorul initializeaza numarul de pasi */ public IntegrareTrapeze(int nrPasi) throws Exception { if(nrPasi<=0) throw new Exception("IntegrareTrapeze: nrPasi<=0"); this.nrPasi=nrPasi; } /* Metoda de modificare a numarului de pasi */ public void puneNrPasi(int nrPasi) throws Exception { if(nrPasi<=0) throw new Exception("IntegrareTrapeze: nrPasi<=0"); this.nrPasi=nrPasi; } /* Implementarea metodei abstracte din interfata */ public double integrala(double inf, double sup, FunctieReala func) { double h,s; h=(sup-inf)/nrPasi; // pasul de integrare s=0; // initializarea sumei ordonatelor for(int i=1; i
500
Programarea orientata pe obiecte în limbajul Java System.out.println("A doua integrala: "+ inTrap.integrala(inf,sup,f2)); inTrap.puneNrPasi(2*nrPasi); System.out.println("Dupa dublarea numarului de pasi de integrare:"); System.out.println("Prima integrala: "+inTrap.integrala(inf,sup,f1)); System.out.println("A doua integrala: "+inTrap.integrala(inf,sup,f2)); /* Utilizarea clasei incuibate statice Functie2 */ Functie2 func2=new Functie2(1,-5,6); System.out.println("func2.f(sup)="+func2.f(sup)); System.out.println("Functie2.f1(inf,sup)="+Functie2.f1(inf,sup)); System.out.println("Integrala din Functie2.f(x)="+ inTrap.integrala(inf,sup,func2)); } catch(NumberFormatException e1) { System.out.println("Nu ati introdus corect parametrii aplicatiei"); } catch(Exception e) { System.out.println("S-a produs exceptia: "+e); } } /* O clasa interioara care implementeaza interfata FunctieReala pentru a oferi functia f(x)=a*sin(b*x+c)+d*cos(b*x) */ class Functie1 implements FunctieReala { private double a, b, c, d; // parametrii functiei /* Constructorul clasei introduce valorile parametrilor functiei */ public Functie1(double a, double b, double c, double d) { this.a=a; this.b=b; this.c=c; this.d=d; } /* metoda de calculare a functiei, prin care se concretizeaza metoda abstracta f(x) din interfata */ public double f(double x) { return a*Math.sin(b*x+c)+d*Math.cos(b*x); } } /* O clasa incuibata statica */ static class Functie2 implements FunctieReala { private double a, b, c; public Functie2(double a, double b, double c) { this.a=a; this.b=b; this.c=c; } public double f(double x) { return (a*x+b)*x+c; } public void puneParam(double a, double b, double c) { this.a=a; this.b=b; this.c=c; } public static double f1(double x, double y) { return 2*x*x+3*y; } } }
501
Severin Bumbaru
Capitolul 7 Toate fişierele sunt conţinute în capitolul 7 al lucrării.
Capitolul 8 Toate fişierele sunt conţinute în capitolul 8 al lucrării.
Capitolul 9 Fişierul TestRGB.java /* Alegerea culorilor in sistemul RGB (Red, Green, Blue) */ import import import import
java.awt.*; java.awt.event.*; javax.swing.*; javax.swing.event.*;
class TestRGB { static AF af=new AF(); static IUG iug=new IUG("Alegerea culorii in sistemul RGB"+ " (Red, Green, Blue)"); /* clasa imbricata pentru interfata utilizator grafica */ static class IUG extends JFrame { AjustCuloare red, green, blue; // rigle de ajustare a culorilor Box box1; // caseta riglelor de ajustare JPanel panouCuloare; // panoul pe care se prezinta culoarea Color culoare; // culoarea panoului panouCuloare IUG(String titlu) { // constructorul clasei IUG super(titlu); setSize(500, 200); setLocation(100, 50); Container cp=getContentPane(); addWindowListener(af); // adaugarea ascultatorului de fereastra /* Se creeaza caseta cu dispozitive de ajustare */ box1=Box.createVerticalBox(); red=new AjustCuloare("Rosu "); // ajustare rosu box1.add(red); green=new AjustCuloare("Verde "); // ajustare verde box1.add(green); blue=new AjustCuloare("Albastru "); // ajustare albastru blue.ajustare.setPaintLabels(true); box1.add(blue); cp.add(box1, BorderLayout.WEST); panouCuloare=new JPanel(); // crearea panoului pentru culoare cp.add(panouCuloare, BorderLayout.CENTER); puneCuloarea(); // se pune culoarea initiala setVisible(true);
502
Programarea orientata pe obiecte în limbajul Java } /* Metoda de determinare a culorii RGB */ void puneCuloarea() { culoare=new Color(red.val, green.val, blue.val); panouCuloare.setBackground(culoare); } } /* Un "dispozitiv" de ajustare a valorii unei culori */ static class AjustCuloare extends Box implements ChangeListener { JTextField valoare; // camp pentru afisarea valorii HSB JSlider ajustare; // rigla de ajustare a valorii int val=0; // valoarea RGB in intervalul 0,..,255 AjustCuloare(String culoare) { super(BoxLayout.X_AXIS); add(new JLabel(culoare)); add(Box.createHorizontalGlue()); ajustare=new JSlider(JSlider.HORIZONTAL, 0, 255, 0); ajustare.setMajorTickSpacing(50); ajustare.setMinorTickSpacing(10); ajustare.setPaintTicks(true); ajustare.addChangeListener(this); add(ajustare); add(Box.createHorizontalStrut(5)); valoare=new JTextField("0",4); valoare.setHorizontalAlignment(JTextField.RIGHT); valoare.setEditable(false); valoare.setBackground(Color.white); valoare.setMaximumSize(valoare.getMinimumSize()); add(valoare); add(Box.createHorizontalStrut(5)); } /* metoda de ascultare a deplasarii cursorului riglei */ public void stateChanged(ChangeEvent e) { val=ajustare.getValue(); // determinarea valorii culorii valoare.setText(" "+val); // afisarea valorii iug.puneCuloarea(); // modificarea culorii panoului } } /* Clasa ascultatoare de fereastra */ static class AF extends WindowAdapter { public void windowClosing(WindowEvent e) { System.exit(0); // incheierea executarii aplicatiei } } /* Metoda principala a aplicatiei */ public static void main(String args[]) { } }
503
Severin Bumbaru
Capitolul 10 Fişierul DouaTexte.java import java.awt.*; import java.awt.event.*; import java.applet.*; public class DouaTexte extends Applet { Button b=new Button("Buton pentru schimbare text"); Label lab=new Label("Textul initial"); String text1, text2; Actiune act=new Actiune(); int k=2; public void init() { text1=getParameter("textul1"); text2=getParameter("textul2"); setLayout(new GridLayout(2,1)); add(b); add(lab); setBackground(Color.cyan); b.addActionListener(act); b.setBackground(Color.magenta); setVisible(true); } class Actiune implements ActionListener { public void actionPerformed(ActionEvent e) { k++; if(k>2) k=1; if(k==1) { lab.setText(text1); lab.setBackground(Color.blue); lab.setForeground(Color.yellow); } else { lab.setText(text2); lab.setBackground(Color.green); lab.setForeground(Color.black); } setVisible(true); } } }
Fişierul PrimApplet.java /* Un prim applet */ import java.awt.*; import java.applet.*; public class PrimApplet extends Applet { public void paint(Graphics g) {
504
Programarea orientata pe obiecte în limbajul Java g.drawString("Primul nostru applet", 5,50); } }
Fişierul PrimApplet.html
Fişierul CBGroupAp.java /* Applet prin care se testeaza clasele Checkbox si CheckboxGroup. Appletul contine trei casete ("butoane radio") si o instanta a clasei Label in care se afiseaza eticheta casetei selectate in momentul respectiv */ import java.awt.*; import java.awt.event.*; import java.applet.*; /* Appletul propriu-zis. Se construiesc obiectele grafice: casetele de validare ("butoanele radio") cb1, cb2, cb3 si eticheta lab. Casetele sunt toate afectate grupului cbgr construit in prealabil. Se construieste, de asemenea, obiectul ecb care intercepteaza si trateaza evenimentele generate de casetele de validare. Interceptorul ecb este inregistrat sa asculte evenimentele generate de casetele de validare. Constructorul interceptorului primeste ca argumente referinte la grupul de casete si la o eticheta unde se va afisa eticheta casetei curenta a acestei casete. */ public class CBGroupAp extends Applet { CheckboxGroup cbgr=new CheckboxGroup(); Checkbox cb1=new Checkbox("CB1", false, cbgr), cb2=new Checkbox("CB2", true,cbgr), cb3=new Checkbox("CB3", false, cbgr); Label lab=new Label(); EvCheckboxGroup ecb=new EvCheckboxGroup(); public void init() { cb1.addItemListener(ecb); cb2.addItemListener(ecb); cb3.addItemListener(ecb); cb1.setBackground(Color.cyan); cb2.setBackground(Color.cyan);
505
Severin Bumbaru cb3.setBackground(Color.cyan); lab.setBackground(Color.green); lab.setAlignment(Label.CENTER); setLayout(new BorderLayout()); add("North",lab); add("West",cb1); add("Center",cb2); add("East",cb3); setVisible(true); } /* Clasa imbricata EvCheckboxGroup implementeaza interfata ItemtListener. Instantele ei intercepteaza evenimentele de comutare generate de Checkbox si introduc in eticheta din applet starea preluata, atunci cand ea se modifica */ class EvCheckboxGroup implements ItemListener { public void itemStateChanged(ItemEvent e) { Checkbox cb=cbgr.getSelectedCheckbox(); lab.setText("S-a selectat caseta: "+cb.getLabel()); } } }
Fişierul CBGroupAp.html
Fişierul TestFlowAp.java /* Aplet de testare a gestionarului de pozitionare FlowLayout. In cadru exista 2 butoane de comanda: Pune si Elimina. Exista, de asemenea, un grup de 3 casete de validare (butoane radio): Stanga, Centru, Dreapta. La fiecare apasare pe butonul "Pune", pe suprafata appletului se mai pune o eticheta, iar la apasarea pe butonul "Elimina" , se elimina ultima eticheta din applet. Apasarea pe oricare din cele trei butoane radio comanda alinierea corespunzatoare.Se admit cel mult 20 etichete
506
Programarea orientata pe obiecte în limbajul Java */ import java.awt.*; import java.awt.event.*; import java.applet.*; public class TestFlowAp extends Applet { Label tlab[]=new Label[20]; FlowLayout fl=new FlowLayout(); public void init() { /* Construirea obiectelor grafice */ Button pune=new Button("Pune"); Button elimina=new Button("Elimina"); CheckboxGroup cbg=new CheckboxGroup(); Checkbox stanga=new Checkbox("Stanga", false, cbg); Checkbox centru=new Checkbox("Centru", true, cbg); Checkbox dreapta=new Checkbox("Dreapta", false, cbg); /* Construirea interceptoarelor de evenimente */ ApasButon ab=new ApasButon(this); SelectAlin sa=new SelectAlin(this); /* Construirea celor 20 etichete si setarea culorii de fond */ for(int i=0; i<20; i++) { tlab[i]=new Label("Eticheta nr. "+(i+1)); tlab[i].setBackground(Color.cyan); } /* Adaugarea la componente a interceptoarelor de evenimente si setarea culorii de fond a fiecarii componente */ setBackground(Color.yellow); pune.addActionListener(ab); pune.setBackground(Color.magenta); elimina.addActionListener(ab); elimina.setBackground(Color.magenta); stanga.addItemListener(sa); stanga.setBackground(Color.green); centru.addItemListener(sa); centru.setBackground(Color.green); dreapta.addItemListener(sa); dreapta.setBackground(Color.green); /* Stabilirea dimensiunii ferestrei si a gestionarului de pozitionare folosit */ setLayout(fl); /* Adaugarea la fereastra principala a componentelor si vizualizarea */ add(pune); add(elimina); add(stanga); add(centru); add(dreapta); setVisible(true); } /* Clasa care intercepteaza si trateaza evenimentele generate de butoane */ static class ApasButon implements ActionListener { TestFlowAp ap; int contor;
507
Severin Bumbaru ApasButon(TestFlowAp ap) { this.ap=ap; contor=0; } public void actionPerformed(ActionEvent e) { String actiune=e.getActionCommand(); if(actiune.equals("Pune") && contor<20){ ap.add(ap.tlab[contor]); contor++; } else if(actiune.equals("Elimina") && contor>0) { contor--; ap.remove(ap.tlab[contor]); } ap.fl.layoutContainer(ap); ap.setVisible(true); } } /* Clasa care intercepteaza si trateaza evenimentele generate de cele trei butoane radio */ static class SelectAlin implements ItemListener { TestFlowAp ap; SelectAlin(TestFlowAp ap) { this.ap=ap; } public void itemStateChanged(ItemEvent e) { /* Se determina ce buton radio este selectat si ce eticheta are */ Checkbox cb=(Checkbox)e.getItemSelectable(); String cblab=cb.getLabel(); /* Se seteaza alinierea corespunzatoare etichetei butonului radio selectat */ if(cblab.equals("Stanga")) ap.fl.setAlignment(FlowLayout.LEFT); else if(cblab.equals("Centru")) ap.fl.setAlignment(FlowLayout.CENTER); else if(cblab.equals("Dreapta")) ap.fl.setAlignment(FlowLayout.RIGHT); /* Se efectueaza alinierea componentelor din container */ ap.fl.layoutContainer(ap); ap.setVisible(true); } } }
Fişierul TestFlow.html
508
Programarea orientata pe obiecte în limbajul Java
Capitolul 11 Fişierul TestFile.java import java.io.*; class TestFile { public static void main(String args[]) throws Exception { /* Fisier situat in directorul curent */ File fis1=new File("TestFile.java"); System.out.println("Calea absoluta: "+fis1.getAbsolutePath()); System.out.println("Fisierul exista: "+fis1.exists()); System.out.println("Pot citi fisier: "+fis1.canRead()); System.out.println("Pot scrie in fisier: "+fis1.canWrite()); System.out.println("Calea: "+fis1.getPath()); System.out.println("Parintele: "+fis1.getParent()); System.out.println("Este director: "+fis1.isDirectory()); System.out.println("Este fisier: "+fis1.isFile()); System.out.println("Ultima modificare: "+fis1.lastModified()); System.out.println("Lungimea fisierului: "+fis1.length()); System.out.println("Sub foorma de URL: "+fis1.toURL()); /* Director */ File dir1=new File("../surse"); System.out.println("Calea absoluta: "+dir1.getAbsolutePath()); System.out.println("Exista: "+dir1.exists()); System.out.println("Este director: "+dir1.isDirectory()); System.out.println("Se poate citi: "+dir1.canRead()); System.out.println("Se poate scrie: "+dir1.canWrite()); /* Fisier situat in alt director */ File fis2=new File("../surse/TestStudent.java"); System.out.println("Calea absoluta: "+fis2.getAbsolutePath()); System.out.println("Exista: "+fis2.exists()); System.out.println("Este director: "+fis2.isDirectory()); System.out.println("Se poate citi: "+fis2.canRead()); System.out.println("Se poate scrie: "+fis2.canWrite()); System.out.println("Parintele: "+fis2.getParent()); } }
Fişierul TestFileInput.java /* Testarea clasei FileInputStream La lansarea in executie, se da ca parametru in linia de comanda numele unui fisier de text care va fi citit */ import java.io.*; class TestFileInput { public static void main(String args[]) { byte b[]=new byte[30];
509
Severin Bumbaru int n, n1; long n2; File fisier=null; if(args.length==0) { System.out.println("La lansarea in executie trebuie dat ca "+ "parametru numele unui fisier de text"); System.exit(0); } else { fisier=new File(args[0]); if(!fisier.exists()) { System.out.println("Fisierul "+fisier+" nu exista!"); System.exit(0); } } try { /* Se deschide fisierul dat ca parametru si se conecteaza la fluxul de intrare f1 */ FileInputStream f1=new FileInputStream(fisier); System.out.println("S-a deschis fisierul "+fisier+ " conectat la fluxul f1"); System.out.println("Sunt disponibili "+f1.available()+ " octeti"); n1=f1.read(); System.out.println("Primul octet citit este "+n1+ " care este codul ASCII al caracterului "+(char)n1); n2=f1.skip(3); System.out.println("S-a sarit peste "+n2+" octeti"); n=f1.read(b); System.out.println("S-au mai citit urmatorii "+n+" octeti:"); for(int i=0; i
510
Programarea orientata pe obiecte în limbajul Java cu intrarea standard System.in, deci datele vor fi citite de la tastatura */ f1=new FileInputStream(FileDescriptor.in); System.out.println("Introduceti de la tastatura un sir de "+ "cel putin 10 caractere"); n=f1.read(b,0,10); System.out.print("Caracterele citite de la tastatura: "); for(int i=0; i
Fişierul TestFileReader.java import java.io.*; class TestFileReader { public static void main(String args[]) { try { /* Se deschide fisierul si se citeste caracter cu caracter */ FileReader fin=new FileReader("TextProba.txt"); System.out.println("Numele canonic al codificarii textului: "+ fin.getEncoding()); int c; while(fin.ready()) { c=fin.read(); System.out.print((char)c); } System.out.println(); fin.close(); /* Se redeschide fisierul si se citeste intr-un singur tablou de caractere */ fin=new FileReader("TextProba.txt"); char[] tab=new char[80]; int nrCar; nrCar=fin.read(tab); System.out.println("Numar caractere citite: "+nrCar); for (int i=0; i
511
Severin Bumbaru catch(Exception e) { System.out.println(e); } } }
Fişierul TestFileOutput.java /* Testarea clasei FileOutputStream. La lansarea in executie a programului se da un text oarecare in linia de comanda (sub forma java FileOutput
512
Programarea orientata pe obiecte în limbajul Java fout=new FileOutputStream(FileDescriptor.out); fout.write("\nA doua oara fisierul contine:\n".getBytes()); while((k=fin.read()) != -1) fout.write((byte)k); fout.write('\n'); // Pentru comparatie, sub forma de comentariu se da // programul de afisare obisnuit System.out.println("\nA doua oara fisierul contine:"); while((k=fin.read()) != -1) System.out.print((char)k); System.out.println();
/*
*/ fin.close(); } catch(Exception e) { System.out.println("Exceptie: "+e); } } }
Fişierul TestFileWriter.java /* Testarea clasei FileWriter. La lansarea in executie a programului se da un text oarecare in linia de comanda (sub forma java FileWriter
513
Severin Bumbaru /* Se scrie textul "\nText adaugat\n" */ str="\nText adaugat\n"; fout.write(str); fout.close(); /* Se deschide din nou fisierul pentru citire si se afiseaza. De data aceasta, fin este fisierul din care se citeste, iar fout este un nou flux de iesire, care se conecteaza la iesirea standard al sistemului (la ecran) prin intermediul descriptorului FileDescriptor.out */ fin=new FileReader("ProbaScriere.txt"); System.out.println("\nA doua oara fisierul contine:"); while((k=fin.read()) != -1) System.out.print((char)k); System.out.println(); fin.close(); } catch(Exception e) { System.out.println("Exceptie: "+e); } } }
Fişierul AccesDirect.java /* Crearea si utilizarea unui fisier cu acces direct */ import java.io.*; class AccesDirect { public static void main(String args[]) throws IOException { /* Se deschide fisierul cu acces direct "Proba.fad" in mod "rw" (citire si scriere) */ RandomAccessFile fisier=new RandomAccessFile("Proba.fad","rw"); long fp, fp1, fp2, k; int i; char c; float f; double d; String s; fp=fisier.getFilePointer(); System.out.println("Pozitia initiala a cursorului: "+fp); /* Se scriu date in fisier incepand de la pozitia 0 */ fisier.writeInt(-176534); fisier.writeDouble(176.5832987306); fisier.writeChar('#'); fisier.writeUTF("Primul sir"); /* Se memoreaza si se afiseaza pozitia curenta a cursorului de fisier */ fp1=fisier.getFilePointer(); System.out.println("Pozitia cursorului dupa prima scriere: "+fp1); /* Se scriu in continuare date in fisier */ fisier.writeLong(157832490245L); fisier.writeFloat(0.05682369543f); fisier.writeBytes("Al doilea sir\n"); fp2=fisier.getFilePointer(); System.out.println("Pozitia cursorului dupa a doua scriere: "+fp2); /* Se deplaseaza cursorul de fisier pe pozitia de la care a inceput
514
Programarea orientata pe obiecte în limbajul Java scrierea celei de a doua serii si se citesc datele in ordinea si sub forma in care au fost scrise, apoi se afiseaza */ fisier.seek(fp1); k=fisier.readLong(); f=fisier.readFloat(); s=fisier.readLine(); System.out.println("Date citite incepand de la pozitia: "+fp1); System.out.println(k+" "+f+" "+s); /* Se pozitioneaza cursorul la inceputul fisierului si se citesc datele scrise in prima serie, apoi se afiseaza */ fisier.seek(0); i=fisier.readInt(); d=fisier.readDouble(); c=fisier.readChar(); s=fisier.readUTF(); System.out.println("Date citite incepand de la pozitia 0:"); System.out.println(i+" "+d+" "+c+" "+s); /* Se inchide fisierul */ fisier.close(); /* Se redeschide fisierul, se deplaseaza cursorul in pozitia de la care a inceput scrierea celei de a doua serii de date, se citesc datele respective si se afiseaza */ fisier=new RandomAccessFile("Proba.fad","r"); fisier.seek(fp1); System.out.println("Dupa redeschiderea fisierului s-au citit:"); System.out.println(fisier.readLong()+" "+fisier.readFloat()+" "+ fisier.readLine()); /* Se inchide fisierul */ fisier.close(); } }
Fişierul FisierDate.java /* Testarea claselor DataOutputStream si DataInputStream. Scrierea datelor se face intr-un fisier, folosind un FileOutputStream conectat la iesirea unui DataOutputStream. Citirea datelor se face apoi din acelasi fisier, folosind un DataInputStream conectat la iesirea unui FileInputStream. */ import java.io.*; class FisierDate { public static void main(String args[]) throws IOException { /* Datele care vor fi scrise in fisier */ byte b=67; char c='A'; boolean t=true, f=false; short sh=10723; int i=958716; long k=847543218045433L; float fl=95.01462f; double d=3.2607643218765; String str="ABCDabcd";
515
Severin Bumbaru /* Deschiderea fisierului pentru scrierea datelor */ FileOutputStream fout=new FileOutputStream("Proba.dat"); DataOutputStream dout=new DataOutputStream(fout); // acest flux // de date este conectat la iesire la fluxul de scriere // in fisier fout deschis anterior /* Scrierea datelor in fisier */ dout.writeByte(b); // Se scrie ub octet dout.writeChar(c); // Se scrie un caracter dout.writeBoolean(t); dout.writeBoolean(f); // Se scriu valori logice dout.writeShort(sh); // Se scrie un short dout.writeInt(i); // se scrie un int dout.writeLong(k); // se scrie un long dout.writeFloat(fl); // se scrie un float dout.writeDouble(d); // se scrie un double dout.writeUTF(str); // se scrie un sir de opt caractere in // format UTF /* Inchiderea fluxului de iesire */ dout.close(); /* Deschiderea fisierului pentru a citi datele scrise anterior */ FileInputStream fin=new FileInputStream("Proba.dat"); DataInputStream din=new DataInputStream(fin); // Fluxul de citire // date este conectat la iesirea fluxului de citire din fisier // fin deschis anterior /* Citirea datelor se face in aceeasi ordine in care au fost scrise */ byte b1=din.readByte(); // Se citeste ub octet char c1=din.readChar(); // Se citeste un caracter boolean t1=din.readBoolean(), f1=din.readBoolean(); // Se citesc valori logice short sh1=din.readShort(); // Se citeste un short int i1=din.readInt(); // se citeste un int long k1=din.readLong(); // se citeste un long float fl1=din.readFloat(); // se citeste un float double d1=din.readDouble(); // se citeste un double String str1=din.readUTF(); // se citeste un sir in format UTF /* Afisarea pe ecran a perechilor de date scrise si citite */ System.out.println("Datele scrise in fisier si cele citite"); System.out.println("byte: "+b+" "+b1); System.out.println("char: "+c+" "+c1); System.out.println("boolean: "+t+" "+t1+"\n"+f+" "+f1); System.out.println("short: "+sh+" "+sh1); System.out.println("int: "+i+" "+i1); System.out.println("long: "+k+" "+k1); System.out.println("float: "+fl+" "+fl1); System.out.println("double: "+d+" "+d1); System.out.println("UTF: "+str+" "+str1); /* Inchiderea fluxului de intrare */ din.close(); } }
Fişierul FisierObiecte.java /* Testarea claselor ObjectOutputStream si ObjectInputStream. Scrierea datelor se face intr-un fisier, folosind un FileOutputStream conectat la iesirea unui ObjectOutputStream. Citirea datelor se face apoi din acelasi fisier, folosind un
516
Programarea orientata pe obiecte în limbajul Java ObjectInputStream conectat la iesirea unui FileInputStream. */ import java.io.*; class FisierObiecte { static class Persoana implements Serializable { String nume; int anNastere; Persoana(String nume, int anNastere) { this.nume=nume; this.anNastere=anNastere; } public String toString() { return "[Persoana: "+nume+" an nastere: "+anNastere+"]"; } } static class Student extends Persoana implements Serializable { int anStudii; String grupa; Student(String nume, int anNastere, int anStudii, String grupa) { super(nume, anNastere); this.anStudii=anStudii; this.grupa=grupa; } public String toString() { return "Student: "+nume+" an studii: "+anStudii+" grupa: "+ grupa+"]"; } } public static void main(String args[]) throws Exception { /* Datele care vor fi scrise in fisier */ Persoana pers1=new Persoana("Popescu Vasile", 1978), pers2=new Persoana("Vasiliu Mihaela", 1981); Student stud1=new Student("Petrescu Mihai", 1979, 2, "2221a"), stud2=new Student("Craciun Nelu", 1979, 2, "2321b"); int i=1325479; double d=3.76523476512; String str="Exemplu de sir"; int tabInt[]={12, -13, 21, 467823, -12643218}; String tabstr[]={"alpha", "beta", "gamma"}; double w[][]={{3.76521, 1.0256789e-4}, {-0.3709865, 12e7, 1e-9}}; /* Deschiderea fisierului pentru scrierea datelor */ FileOutputStream fout=new FileOutputStream("Proba1.dat"); ObjectOutputStream dout=new ObjectOutputStream(fout); // acest flux // de obiecte este conectat la iesire la fluxul de scriere // in fisier fout deschis anterior /* Scrierea obiectelor in fisier */ dout.writeObject(pers1); dout.writeObject(stud1); dout.writeDouble(d); dout.writeUTF(str); dout.writeObject(pers2); dout.writeInt(i); dout.writeObject(stud2); dout.writeObject(tabInt);
517
Severin Bumbaru dout.writeObject(tabstr); dout.writeObject(w); /* Inchiderea fluxului de iesire */ dout.close(); /* Deschiderea fisierului pentru a citi datele scrise anterior */ FileInputStream fin=new FileInputStream("Proba1.dat"); ObjectInputStream din=new ObjectInputStream(fin); // Fluxul de citire // obiecte este conectat la iesirea fluxului de citire din fisier // fin deschis anterior /* Citirea obiectelor se face in aceeasi ordine in care au fost scrise */ Persoana pers1a, pers2a; Student stud1a, stud2a; int ia, tabInta[]; double da, wa[][]; String stra, tabstra[]; pers1a=(Persoana)din.readObject(); stud1a=(Student)din.readObject(); da=din.readDouble(); stra=din.readUTF(); pers2a=(Persoana)din.readObject(); ia=din.readInt(); stud2a=(Student)din.readObject(); tabInta=(int[])din.readObject(); tabstra=(String[])din.readObject(); wa=(double[][])din.readObject(); /* Afisarea pe ecran a perechilor de date scrise si citite */ System.out.println("Afisarea datelor scrise si citite pe perechi"); System.out.println("int: "+i+" "+ia); System.out.println("double: "+d+" "+da); System.out.println("UTF: "+str+" "+stra); System.out.println(pers1+" "+pers1a); System.out.println(pers2+" "+pers2a); System.out.println(stud1+" "+stud1a); System.out.println(stud2+" "+stud2a); System.out.print("tabInt: "); for(int j=0; j
518
Programarea orientata pe obiecte în limbajul Java } }
Capitolul 12 Fişierul Bondari.java import java.awt.*; import java.awt.event.*; import javax.swing.*; public class Bondari extends JFrame { JButton nouBondar; public Bondari() { super("Bondari"); nouBondar=new JButton("Creare nou bondar"); nouBondar.addActionListener(new CreareBondar()); getContentPane().add(nouBondar, BorderLayout.NORTH); addWindowListener(new Iesire()); setSize(200,100); setLocation(new Point(0,20)); setVisible(true); } /* Clasa cu interfata Runnable pentru un fir de executie cu interfata grafica */ class Bondar extends JFrame implements Runnable { JSlider perioada, amplitudine; Fereastra fereastra; Thread fir; boolean esteViu; public Bondar() { perioada=new JSlider(JSlider.HORIZONTAL, 100, 500, 200); perioada.setBorder(BorderFactory.createTitledBorder( "Perioada saltului")); perioada.setMajorTickSpacing(200); perioada.setMinorTickSpacing(100); perioada.setPaintTicks(true); perioada.setPaintLabels(true); amplitudine=new JSlider(JSlider.HORIZONTAL, 0, 40, 10); amplitudine.setBorder(BorderFactory.createTitledBorder( "Amplitudinea saltului")); amplitudine.setMajorTickSpacing(20); amplitudine.setMinorTickSpacing(2); amplitudine.setPaintTicks(true); amplitudine.setPaintLabels(true); fereastra=new Fereastra(); fereastra.setSize(200,200); fereastra.setBackground(Color.cyan); fereastra.culoare=Color.red; Box box=Box.createVerticalBox(); box.add(perioada);
519
Severin Bumbaru box.add(amplitudine); box.add(fereastra); getContentPane().add(box); addWindowListener(new SfarsitBondar(this)); setSize(200,350); setVisible(true); } /* Definirea metodei run() a interfetei Runnable */ public void run() { Rectangle r=fereastra.getBounds(); fereastra.x=r.width/2; fereastra.y=r.height/2; esteViu=true; while(esteViu) { fereastra.ampl=amplitudine.getValue(); fereastra.repaint(); try { fir.sleep(perioada.getValue()); } catch(Exception e) { System.out.println(e); } } } } /* Sfarsitul clasei Bondar */ /* Fereastra in care evolueaza "bondarul" */ class Fereastra extends Canvas { int x, y, ampl; Color culoare; public void paint(Graphics g) { Rectangle r=getBounds(); x+=(int)(ampl*(Math.random()-0.5)); if(x<0) x=0; else if(x>=r.width) x=r.width-5; y+=(int)(ampl*(Math.random()-0.5)); if(y<0) y=0; else if(y>=r.height) y=r.height-5; g.setColor(culoare); g.fillRect(x,y,10,10); g.setColor(Color.red); g.drawRect(x,y,10,10); } } /* Sfarsitul clasei Fereastra */ /* Incheierea executarii aplicatiei */ class Iesire extends WindowAdapter { public void windowClosing(WindowEvent e) { System.exit(0); } } /* Sfarsitul clasei Iesire */ /* Crearea si lansarea unui nou fir de executie */ class CreareBondar implements ActionListener { public void actionPerformed(ActionEvent e) { int x,y; x=(int)(Math.random()*400); y=(int)(Math.random()*200); Bondar bondar=new Bondar();
520
Programarea orientata pe obiecte în limbajul Java bondar.setLocation(new Point(x,y)); Thread thread=new Thread(bondar); thread.start(); } } /* Sfarsitul clasei CreareBondar */ /* Incheierea executarii unui fir de executie */ class SfarsitBondar extends WindowAdapter { Bondar bondar; SfarsitBondar(Bondar bondar) { this.bondar=bondar; } public void vindowClosing(WindowEvent e) { bondar.esteViu=false; } } /* Sfarsitul clasei SfarsitBondar */ /* Metoda principala a aplicatiei */ public static void main(String args[]) { Bondari b=new Bondari(); } }
Fişierul Bondari1.java import java.awt.*; import java.awt.event.*; import javax.swing.*; public class Bondari1 extends JFrame { Bondar b1,b2; Thread fir1, fir2, fir3; Fereastra fereastra; CutiePostala cutiePostala; public Bondari1() { super("Doi bondari in acelasi spatiu"); b1=new Bondar(); fir1=new Thread(b1); b1.fir=fir1; b2=new Bondar(); fir2=new Thread(b2); b2.fir=fir2; Box box1=Box.createHorizontalBox(); box1.add(b1); box1.add(b2); Box box2=Box.createVerticalBox(); fereastra=new Fereastra(); fir3=new Thread(fereastra); fereastra.setSize(200,200); fereastra.setBackground(Color.cyan); box2.add(box1); box2.add(fereastra); Container cp1=getContentPane(); cp1.setLayout(new FlowLayout()); cp1.add(box2);
521
Severin Bumbaru addWindowListener(new Iesire()); setSize(500,400); setVisible(true); cutiePostala=new CutiePostala(); fir1.start(); fir2.start(); fir3.start(); } class Bondar extends JPanel implements Runnable { Thread fir; JSlider perioada, amplitudine; int x, y; public Bondar() { perioada=new JSlider(JSlider.HORIZONTAL, 100, 500, 200); perioada.setBorder(BorderFactory.createTitledBorder( "Perioada saltului")); perioada.setMajorTickSpacing(200); perioada.setMinorTickSpacing(100); perioada.setPaintTicks(true); perioada.setPaintLabels(true); amplitudine=new JSlider(JSlider.HORIZONTAL, 0, 40, 10); amplitudine.setBorder(BorderFactory.createTitledBorder( "Amplitudinea saltului")); amplitudine.setMajorTickSpacing(20); amplitudine.setMinorTickSpacing(2); amplitudine.setPaintTicks(true); amplitudine.setPaintLabels(true); Box box=Box.createVerticalBox(); box.add(perioada); box.add(amplitudine); getContentPane().add(box); } public void run() { Rectangle r=fereastra.getBounds(); x=(int)(r.width*(Math.random())); y=(int)(r.height*(Math.random())); for(; ; ) { x+=(int)(amplitudine.getValue()*(Math.random()-0.5)); if(x<0) x=0; else if(x>r.width-10) x=r.width-10; y+=(int)(amplitudine.getValue()*(Math.random()-0.5)); if(y<0) y=0; else if(y>r.height-10) y=r.height-10; cutiePostala.amPus(); try { fir.sleep(perioada.getValue()); } catch(Exception e) { System.out.println(e); } } } } class Fereastra extends Canvas implements Runnable { public void paint(Graphics g) { g.setColor(Color.green);
522
Programarea orientata pe obiecte în limbajul Java g.fillRect(b1.x,b1.y,10,10); g.setColor(Color.red); g.drawRect(b1.x,b1.y,10,10); g.setColor(Color.blue); g.fillRect(b2.x,b2.y,10,10); g.setColor(Color.red); g.drawRect(b2.x,b2.y,10,10); } public void run() { for(;;) { repaint(); cutiePostala.amLuat(); } } } class CutiePostala { boolean valoareNoua=false; synchronized void amPus() { while(valoareNoua) { try { wait(); } catch(Exception e) {} } valoareNoua=true; notifyAll(); } synchronized void amLuat() { while(!valoareNoua) { try { wait(); } catch(Exception e) {} } valoareNoua=false; notifyAll(); } } class Iesire extends WindowAdapter { public void windowClosing(WindowEvent e) { System.exit(0); } } public static void main(String args[]) { Bondari1 b=new Bondari1(); } }
523