Sunteți pe pagina 1din 454

PROGRAMARE ORIENTAT PE

OBIECTE

l.ing. Carmen ODUBTEANU

CUPRINS
l
l
l
l
l
l
l
l
l
l
l
l

INTRODUCERE N LIMBAJUL JAVA


PROGRAMARE ORIENTAT PE OBIECTE
CONCEPTE GENERALE
PROGRAMARE ORIENTAT PE OBIECTE N
LIMBAJUL JAVA
EXCEPII
FLUXURI (INTRRI-IEIRI)
INTERFEE
CLASE ABSTRACTE
CLASE INCLUSE
COLECII
INTERFETE GRAFICE (AWT, SWING)
APPLET-uri
DESENARE

BIBLIOGRAFIE
l
l
l
l
l
l

Curs practic de Java, Cristian Frsinaru


Programare orientat pe obiecte in Java,
Florian Moraru, Carmen Odubteanu
Java de la 0 la Expert, tefan Tanasa, s.a.
Java - o perspectiva pragmatic, Irina
Athanasiu, s.a.
Java Tutorial,
www.java.sun.com/docs/books/tutorial
Thinking in Java, Bruce Eckel,
www.bruceckel.com

Introducere n Java
l
l
l
l
l
l
l
l
l
l
l
l
l
l
l
l
l

Tehnologia Java
Primul program
Structura lexical
Tipuri de date
Variabile
Instruciuni
Ce este un pachet ?
Pachetele standard (J2SDK)
Importul unei clase sau interfee
Importul la cerere
Importul static
Crearea unui pachet
Organizarea fiierelor
Vectori
iruri de caractere
Argumente de la linia de comand
Arhive JAR

Limbajul de programare Java


l
l
l
l
l
l
l
l
l
l

Simplitate
Uurin n crearea de aplicaii complexe
Robustee nu exist pointeri,
administrarea automat a memoriei, GC
Complet orientat pe obiecte
Securitate
Neutralitate arhitectural
Portabililtate
Compilat i interpretat
Performan
Modelat dup C i C++

Platforme de lucru Java


J2SE (Standard Edition)
Aplicaii independente, appleturi, Java
Web Start
l J2ME (Micro Edition)
Programarea dispozitivelor mobile
l J2EE (Enterprise Edition)
l

Aplicaii complexe, pe mai multe nivele pentru


sisteme eterogene, cu baze de date distribuite,
etc.
Aplicaii i servicii Web: servleturi, pagini JSP,
etc.

Distribuiile Java sunt oferite gratuit


http://java.sun.com
J2SE 1.6 SDK

Compilat i interpretat
Limbajele de programare, n funcie de modul de
execuie a aplicaiilor:
Interpretate
+ : simplitate, portabilitate
- : viteza de execuie redus
Compilate
+ : execuia extrem de rapid
- : lipsa portabilitii
Java: compilat + interpretat
Compilator: surs - cod de octei
Interpretor: execut codul de octei
Cod octei Cod main
Cod main - procesor
Cod octei - JVM
JVM = Java Virtual Machine (mediul de execuie
al aplicaiilor Java)

Primul program
1. Scriererea codului surs
class FirstApp
{
public static void main( String args[])
{
System.out.println("Hello world!");
}
}
Definire clas class numeclasa
l Funcia principal a unei aplicaii Java
propriu-zise - public static void main( String
args[])
l Afiare - System.out.println

Primul program
2. Salvarea fiierelor surs
C:\intro\FirstApp.java
3. Compilarea aplicaiei
javac FirstApp.java
va rezulta: FirstApp.class
4. Rularea aplicaiei
java FirstApp
l

Se poate folosi un IDE (mediu integrat de


dezvoltare) pentru a realiza toi paii
anteriori (JCreator, Eclipse, NetBeans, etc.)

Structura lexical
Setul de caractere: Unicode
l nlocuiete ASCII
l un caracter se reprezint pe 2 octei
l conine 65536 de semne
l compatibil ASCII : primele 256 caractere
sunt cele din ASCII
l structurat n blocuri:
Basic, Latin, Greek, Arabic, Gothic,
Currency, Mathematical, Arrows, Musical,
etc.
l referire prin cod hexa:
\ uxxxx
\u03B1 -\u03C9: -
l http://www.unicode.org

Cuvinte cheie
l

Cuvintele rezervate sunt, cu cteva excepii,


cele din C++.

abstract, double, int, strictfp


boolean, else, interface, super
break, extends, long, switch
byte, final, native, synchronized
case, finally, new, this
catch, float, package, throw
char, for, private, throws
class, goto*, protected, transient
const*, if, public, try
continue, implements, return, void
default, import, short, volatile
do, instanceof, static, while

Incepnd cu 1.5: enum.

Identificatori
Sunt secvene nelimitate de litere i cifre
Unicode plus simbolul _, ce ncep cu o liter
sau _.
l Identificatorii nu au voie s fie identici cu
cuvintele rezervate.
Exemple: a1, FirstApp, factorial, etc.

Convenie:
l Nume de clasa: prima liter mare ( Complex)
l Nume de metod: prima liter mic ( aduna,
adunaComplex)
l Nume variabil: prima liter mic (var1)
l Nume constant: prima liter mare sau tot
numele cu litere mari (Pi, PI)
Obs: dac identificatorul este format din mai muli
atomi lexicali, atunci primele litere ale celorlali
atomi se scriu cu majuscule.

Constante
l

Intregi (10, 16 -0x, 8-0)


normali - se reprezint pe 4 octei (32 bii)
lungi - se reprezint pe 8 octei (64 bii) i se
termin cu caracterul L (sau l).

Flotani: 1.0, 2e2, 3f, 4D


s aib cel puin o zecimal dup virgul
s fie n notaie exponenial
s aib sufixul F sau f pentru valorile
normale - reprezentate pe 32 bii, respectiv
D sau d pentru valorile duble - reprezentate
pe 64 bii.

Logici: true, false

Constante
l

Caracter: J, a, v, a, \n
Caracter sau secvene escape (permit
specificarea caracterelor care nu au
reprezentare grafic i reprezentarea unor
caractere speciale precum backslash,
apostrof, etc.)
Secvenele escape predefinite n Java sunt:
\b : Backspace (BS)
\t : Tab orizontal (HT)
\n : Linie nou (LF)
\f : Pagin nou (FF)
\r : Inceput de rnd (CR)
\" : Ghilimele
\ : Apostrof
\\ : Backslash

Constante
iruri de caractere: Text
format din zero sau mai multe caractere
ntre ghilimele. Caracterele care formeaz
irul pot fi caractere grafice sau secvene
escape.
l

Separatori: indic sfritul unei uniti


lexicale i nceputul alteia.
()[];,.

Observaie: instruciunile sunt separate prin ;

Operatori
atribuirea:

=
matematici:
+, -, *, /, %, ++, -lval op= rval: x += 2 n -= 3
x++, ++x, n--, --n
logici:
&&(and), ||(or), !(not)
relaionali: <, <=, >, >=, ==, !=
pe bii:
&(and), |(or), ^ (xor),~ (not)
de translaie: <<, >>, >>> (shift la dreapta fr
semn)
if-else:
expresie-logica ? val-true: val-false

Operatori
l

operatorul , (virgul) folosit pentru evaluarea


secvenial a operaiilor:
int x=0, y=1, z=2;

operatorul + pentru concatenarea irurilor


String s1="Ana";
String s2="mere";
int x=10;
System.out.println(s1 + " are " + x + " " + s2);

operatori pentru conversii (cast) : (tip-de-data)


int a = (int)a;
char c = (char)96;
int i = 200;
long l = (long)i; //widening conversion
long l2 = (long)200;
int i2 = (int)l2; //narrowing conversion

Comentarii
Exist trei feluri de comentarii:
l

Comentarii pe mai multe linii, nchise ntre /*


i */.

Comentarii pe mai multe linii care in de


documentaie, nchise ntre /** i */.
Textul dintre cele dou secvene este
automat mutat n documentaia aplicaiei
de ctre generatorul automat de
documentaie javadoc.

Comentarii pe o singur linie, care incep cu


//.

Tipuri de date
Tipurile primitive:
l aritmetice
ntregi: byte (1 octet), short(2), int (4), long
(8)
reale: float (4), double (8)
l caracter: char (2)
l logic: boolean (true i false)
Tipul referin:
l Vectorii, clasele i interfeele
l Valoarea unei variabile de acest tip este, spre
deosebire de tipurile primitive, o referin
(adres de memorie) ctre valoarea sau
mulimea de valori reprezentat de variabila
respectiv.
Nu exist: pointer, struct i union.

Variabile
l

Declararea variabilelor:
Tip numeVariabila;

Iniializarea variabilelor:
Tip numeVariabila = valoare;

Declararea constantelor:
final Tip numeVariabila;
final double PI = 3.14;
int valoare = 100;
long numarElemente = 12345678L;
String bauturaMeaPreferata = "apa";

Categorii variabile
a. Variabile membre ale unei clase, declarate
n interiorul unei clase, vizibile pentru toate
metodele clasei respective ct i pentru alte
clase n funcie de nivelul lor de acces
b. Parametrii metodelor, vizibili doar n metoda
respectiv
c. Variabile locale, declarate ntr-o metod,
vizibile doar n metoda respectiv
d. Variabile locale, declarate ntr-un bloc,
vizibile doar n blocul respectiv.
e. Parametrii de la tratarea excepiilor

Categorii variabile
class Exemplu {
int a;
public void metoda(int b) {
a = b;
int c = 10;
for(int d=0; d < 10; d++) {
c --;
}
try {
a = b/c;
} catch(ArithmeticException e) {
System.err.println(e.getMessage());
}
}
}

Instruciuni
Instruciuni de decizie:
if-else, switch-case
Instruciuni de salt:
for, while, do-while
Instruciuni pentru tratarea excepiilor:
try-catch-finally, throw
Alte instruciuni:
break, continue, return, label:

Instruciuni de decizie
l

if-else

if (expresie-logica) {
...
}
Sau:
if (expresie-logica) {
...
} else {
...
}
l

switch-case

switch (variabila) {
case valoare1:
...
break;
case valoare2:
...
break;
default:
...
}

Instruciuni de salt
l

for

for(initializare; expresie-logica; pas-iteratie) {


//Corpul buclei
}
Exemplu:
for(int i=0, j=100 ; i < 100 && j > 0; i++, j--) {
...

}
while
while (expresie-logica) {
...
}
l do-while
do {
...
} while (expresie-logica);
l

Alte instruciuni
l
l

break: prsete forat corpul unei structuri


repetitive.
continue: termin forat iteraia curent a
unui ciclu i trece la urmtoarea iteraie.

return [valoare]: termin o metod i,


eventual, returneaz o valoare.

numeEticheta: definete o etichet.


Nu exist goto
Pot fi definite etichete folosite astfel:

l
l

break numeEticheata
continue numeEticheta

Exemplu de folosire a etichetelor


i=0;
eticheta:
while (i < 10) {
System.out.println("i="+i);
j=0;
while (j < 10) {
j++;
if (j==5) continue eticheta;
//sau: if (j==5) break eticheta;
System.out.println("j="+j);
}
i++;
}

Ce este un pachet ?

Pachet = Colecie de clase i interfee


Scopul:
l Organizarea lucrului
l Gsirea i utilizarea mai uoar a claselor
l Evitarea conflictelor de nume
l Controlul accesului

Pachetele standard (J2SDK)


java.lang - clasele de baz ale limbajului Java
java.io - intrri/ieiri, lucrul cu fiiere
java.util - clase i interfee utile
java.applet - dezvoltarea de appleturi
java.awt - interfaa grafic cu utilizatorul
java.awt.event - tratare evenimente
java.beans - scrierea de componente reutilizabile
java.net - programare de reea
java.sql - lucrul cu baze de date
java.rmi - execuie la distan
java.security - mecanisme de securitate
java.math - operaii matematice cu numere mari
java.text - lucrul cu texte, date i numere
independent de limb
java.lang.reflect - introspecie
javax.swing - interfaa grafic cu utilizatorul, mult
mbogit fa de AWT.

Folosirea membrilor unui pachet


1. specificarea numelui complet:
numePachet.NumeClasa.
Button - numele scurt al clasei
java.awt - pachetul din care face parte
java.awt.Button - numele complet al clasei
Exemplu:
java.awt.Button b1 = new java.awt.Button("OK");
java.awt.Button b2 = new java.awt.Button("Cancel");
java.awt.TextField tf1 =
new java.awt.TextField("Neplacut");
java.awt.TextField tf2 =
new java.awt.TextField("Tot neplacut");

Importul unei clase sau interfee


2. importul clasei respective
import numePachet.numeClasa;
//Pentru exemplul nostru:
import java.awt.Button;
import java.awt.TextField;
...
Button b1 = new Button("OK");
Button b2 = new Button("Cancel");
TextField tf1 = new TextField("Placut");
TextField tf2 = new TextField("Foarte placut");
//Problema:
import java.awt.Button;
import java.awt.TextField;
import java.awt.Rectangle;
import java.awt.Line;
import java.awt.Point;
import java.awt.Polygon;

Importul la cerere
3. importul ntregului pachet
import numePachet.*;
//Pentru exemplul nostru:
import java.awt.*;
...
Button b = new Button("OK");
Point p = new Point(0, 0);
import java.awt.C*; = eroare
Importate automat:
pachetul java.lang
pachetul curent
pachetul implicit (fr nume)

Ambiguiti
import java.awt.*;
// Contine clasa List
import java.util.*;
// Contine interfata List
...
List x; //Declaratie ambigua
java.awt.List a = new java.awt.List(); //corect
java.util.List b = new ArrayList(); //corect

Importul static
Referirea constantelor statice ale unei clase:
import static numePachet.NumeClasa.*;
l

// Inainte de versiunea 1.5


import java.awt.BorderLayout.*;
...
fereastra.add(new Button(), BorderLayout.CENTER);

// Incepand cu versiunea 1.5


import java.awt.BorderLayout.*;
import static java.awt.BorderLayout.*;
...
fereastra.add(new Button(), CENTER);

Crearea unui pachet


package numePachet;
//Fisierul Graf.java
package grafuri;
class Graf {...}
class GrafPerfect extends Graf {...}
//Fisierul Arbore.java
package grafuri;
class Arbore {...}
class ArboreBinar extends Arbore {...}
Pachetul implicit = directorul curent

Organizarea fiierelor surs


Organizarea surselor = foarte important
Recomandri:
l clasa - fiier
l sursa clasei C - fiierul C.java obligatoriu
pentru clase publice
l pachet - director
l clasele pachetului - fiierele directorului

Organizarea fiierelor surs


/matematica
/surse
/geometrie
/plan
Poligon.java
Cerc.java
/spatiu
Poliedru.java
Sfera.java
/algebra
Grup.java
/analiza
Functie.java
Matematica.java

Organizarea fiierelor surs


// Poligon.java
package geometrie.plan;
public class Poligon { . . . }
// Cerc.java
package geometrie.plan;
public class Cerc { . . . }
// Poliedru.java
package geometrie.spatiu;
public class Poliedru{ . . . }

// Sfera.java
package geometrie.spatiu;
public class Sfera { . . . }
// Grup.java
package algebra;
public class Grup { . . . }
// Functie.java
package analiza;
public class Functie { . . . }

Vectori
Declararea
Tip[] numeVector; sau
Tip numeVector[];
Instanierea
numeVector = new Tip[nrElemente];
Iniializarea (opional)
String culori[] ={"Rosu", "Galben"};
v = new int[10];
//aloca spatiu pentru 10 intregi: 40 octeti
c = new char[10];
//aloca spatiu pentru 10 caractere: 20 octeti

Vectori
Declararea i instanierea pot fi fcute
simultan:
Tip[] numeVector = new Tip[nrElemente];

Primul indice al unui vector este 0, deci


poziiile unui vector cu n elemente vor fi
cuprinse ntre 0 i n - 1.
l Nu sunt permise construcii de genul Tip
numeVector[nrElemente], alocarea
memoriei fcndu-se doar prin intermediul
operatorului new.
int v[10]; //ilegal
int v[] = new int[10]; //corect

Tablouri multidimensionale
Tablou multidimensional = vector de vectori.
Tip mat[][] = new Tip[nrLinii][nrColoane];
l

mat[i] este linia i a matricii i reprezint un


vector cu nrColoane elemente iar mat[i][j]
este elementul de pe linia i i coloana j.

Dimensiunea unui vector


Variabila length:
int []a = new int[5];
// a.length are valoarea 5
int m[][] = new int[5][10];
// m[0].length are valoarea 10

Copierea vectorilor
int a[] = {1, 2, 3, 4};
int b[] = new int[4];
// Varianta 1
for(int i=0; i<a.length; i++)
b[i] = a[i];
// Varianta 2
System.arrayCopy(a, 0, b, 0, a.length);
// Nu are efectul dorit
b = a;

Sortarea vectorilor - clasa Arrays


Metode din java.util.Arrays:
sort - (QuickSort -O(n log(n)))
int v[]={3, 1, 4, 2};
java.util.Arrays.sort(v);
// Sorteaza vectorul v
// Acesta va deveni {1, 2, 3, 4}
binarySearch
equals
fill
Vectori cu dimensiune variabil i eterogeni:
l Vector, ArrayList, etc. din pachetul java.util.

iruri de caractere
l
l

char[]
String
String s = "abc";
String s = new String("abc");
char data[] = {a, b, c};
String s = new String(data);
StringBuffer
Un ir de caractere constant (nu se doresc
schimbri n poriuni din coninutul su pe
parcursul execuiei programului) va fi
declarat de tipul String, altfel va fi declarat
de tip StringBuffer. StringBuffer pune la
dispoziie metode pentru modificarea
coninutului irului, cum ar fi: append, insert,
delete, reverse.

iruri de caractere
l
l

Uzual, cea mai folosit modalitate de a lucra


cu iruri este prin intermediul clasei String.
Clasa StringBuffer va fi utilizat predominant
n aplicaii dedicate procesrii textelor cum
ar fi editoarele de texte.

String s1="asd",s2="";
s1=s2+"a";
System.out.println(s1+" "+s2);
l

Testarea egalitii: equals


if (nume.equals("duke")) { ... }

iruri de caractere
l

Concatenarea: +
String s1 = "ab" + "cd";
String s2 = s1 + 123 + "xyz"
extrem de flexibil, permite concatenarea irurilor
cu obiecte de orice tip care au o reprezentare
de tip ir de caractere.

Exemple:
System.out.print("Vectorul v are" + v.length + "elem.");
String x = "a" + 1 + "b;
De fapt:
String x = new StringBuffer().append("a").append(1).
append("b").toString()
l

Obs: irul s=1+2+"a"+1+2 va avea valoarea


"3a12", primul + fiind operatorul matematic de
adunare iar al doilea +, cel de concatenare a
irurilor.

Argumente de la linia de comand


Trimiterea argumentelor
java NumeAplicatie [arg0 arg1 . . .]
java Test Java "Hello Duke" 1.5
l

Primirea argumentelor:
public static void main (String args[]){
/* args[0] va fi Java
args[1] va fi "Hello Duke
s.a.m.d.
*/
}
l Numrul argumentelor:
public static void main (String args[]) {
int numarArgumente = args.length ;
}
l

Exemplu
public class Salut {
public static void main (String args[]) {
if (args.length == 0) {
System.out.println( "Numar insuficient de
argumente!");
System.exit(-1); //termina aplicatia
}
String nume = args[0]; //exista sigur
String prenume;
if (args.length >= 1)
prenume = args[1];
else
prenume = ""; //valoare implicita
System.out.println("Salut " + nume + "
"+
prenume);
}
}

Afiarea argumentelor
public class Afisare {
public static void main (String[] args) {
for (int i = 0; i < args.length; i++)
System.out.println(args[i]);
}
}
java Afisare Hello Java
Hello
Java
java Afisare Hello Java
Hello Java

Argumente numerice
l
l

Argumentele de la linia de comand sunt siruri de


caractere
Transformarea ir - numr se face cu metode de
tipul:
Integer.parseInt
Double.parseDouble
Float.parseFloat, etc.

public class Power {


public static void main(String args[]) {
double numar = Double.parseDouble(args[0]);
int putere = Integer.parseInt(args[1]);
System.out.println("Rezultat=" + Math.pow(numar,
putere));
}
}

Adrese utile
www.java.com
Toat lumea
www.java.net
Comunitate
java.sun.com
Dezvoltatori
jguru.com
Cursuri
jars.com
Resurse
javaworld.com, javareport.com
Articole
javaalmanac.com
Exemple de cod
google:java

Arhive JAR
Java Archive = arhive ZIP + META-INF
Crearea unei arhive:
Utilitarul jar
Clase suport din java.util.jar
Beneficii:
compresare
portabilitate
minimizarea timpului de ncarcare din reea
securitate - semnare electronic
parte integrata a platformei Java

Folosirea utilitarului jar


l

Crearea unei arhive: jar cf arhiva.jar


fiier(e)-intrare

Vizualizare coninutului: jar tf nume-arhiva

Extragerea coninutului: jar xf arhiva.jar

Extragerea doar a unor fiiere


jar xf arhiva.jar fiier(e)-arhivate
l

Executarea unei aplicaii: java -jar arhiva.jar

Deschiderea unui applet arhivat


<applet code=A.class archive="arhiva.jar"...>
l

Exemple
Exemple:
l Arhivarea a dou fiiere class:
jar cf classes.jar A.class B.class
l Arhivarea tuturor fiierelor din directorul curent:
jar cvf allfiles.jar *
l Crearea unui fisier manifest
//manifest.txt
Main-Class: Matematica
l Crearea arhivei
jar cvfm mate.jar manifest.txt geometrie analiza
algebra Matematica.class
l Executia
java -jar mate.jar

Curs 2
Principiile Programrii Orientate pe
Obiecte

Programare Orientat pe Obiecte

Tehnici de programare
Programarea procedural
l
l

Modul n care este abordat programarea, din punct


de vedere al descompunerii programelor
Paradigme

Programarea procedural
l prima modalitate de programare, nc frecvent
folosit
l descompunerea programului n proceduri (funcii)
care sunt apelate n ordinea de desfurare a
algoritmului
l sunt
prevzute posibiliti de transfer a
argumentelor ctre funcii i de returnare a valorilor
rezultate
l limbajul Fortran: primul limbaj de programare
procedural .
l au urmat Algol60, Algol68, Pascal, iar C este unul
din ultimele invenii n acest domeniu.

Programarea modular (structurat)


l

l
l

l
l

accentul s-a deplasat de la proiectarea


procedurilor ctre organizarea datelor, datorit
creterii dimensiunii programelor.
stilul de programare este n continuare
procedural
datele i procedurile sunt grupate n module,
nu implic ns i o asociere strict ntre
acestea
Modul: o mulime de proceduri corelate,
mpreun cu datele pe care le manevreaz
tehnic de ascundere a datelor (data-hiding):
posibilitatea de ascundere a unor informaii
definite ntr-un modul fa de celelalte module.
modularitatea i ascunderea informaiilor sunt
caracteristici implicite n programarea orientat
pe obiecte.

Programarea orientat pe obiecte

programarea procedural i structurat:


descriere a algoritmilor ca o secven de
pai care duc de la datele iniiale la
rezultatul cutat.

limbaje de programare orientate la o clas


concret de probleme: sisteme de dirijare cu
baze de date, modelare .a.

a aprut necesitatea sporirii siguranei


programelor - interzicerea accesului
neautorizat la date.

Programarea orientat pe obiecte

dezvoltarea sistemelor orientate pe


obiecte, bazate pe programarea orientat
pe obiecte a cunoscut o amploare
deosebit n anii 90

programarea orientat pe obiecte


presupune:
1. determinarea i descrierea claselor
utilizate n program
2. crearea exemplarelor de obiecte
necesare
3. determinarea interaciunii dintre ele.

Modelul obiect
l

l
l

Reprezint aplicarea n domeniul programrii a


unei metode din tehnic (tehnologia orientat
pe obiecte, care se bazeaz pe modelul obiect)
Primele aplicaii: limbajul Simula (a stat la baza
Smaltalk), Object Pascal, C++, Clos, Ada, Eiffel
Modelul obiect al unei aplicaii implic patru
principii importante:
abstractizare;
ncapsulare;
modularitate;
ierarhizare.
Modelul obiect: un concept unificator n tiina
calculatoarelor,
aplicabil
nu
numai
n
programare, ci i n arhitectura calculatoarelor,
n proiectarea interfeelor utilizator, n baze de
date.

Programarea orientat pe obiecte


Object-oriented programming: metod de
programare n care programele sunt organizate
ca i colecii de obiecte cooperante, fiecare
dintre ele reprezentnd o instan a unei clase,
iar clasele sunt membre ale unei ierarhii de
clase, corelate ntre ele prin relaii de motenire.
l Se folosesc obiecte, nu algoritmi, ca uniti
constructive de baz.
l Fiecare obiect este o instan (un exemplar) al
unei clase.
l Clasele sunt componente ale unei ierarhii de
tip, fiind corelate ntre ele prin relaii de
motenire.
Obs: Dac lipsete una din aceste caracteristici:
programare prin abstractizarea datelor (o
clas este un tip de date abstract)
l

Limbaj de programare orientat pe


obiecte
l

Cerine:
1. Suport obiecte (instane ale unor
clase), clasele fiind tipuri definite de
utilizator (numite i tipuri abstracte de
date)
2. Tipurile (clasele) pot moteni atribute de
la alte clase, numite clase de baz

Dac un limbaj nu suport direct


motenirea ntre clase se numete limbaj
de programare bazat pe obiecte (objectbased), cum este, de exemplu, limbajul
Ada.

Principii POO: Abstractizarea


l

ignorarea unor aspecte ale informaiei


manipulate, adic posibilitatea de a se
concentra asupra esenialului
identificarea similitudinilor ntre diferite entiti,
situaii sau procese din lumea real,
concentrarea ateniei asupra acestor aspecte
comune i ignorarea pentru nceput a detaliilor
identificarea trsturilor caracteristice eseniale
ale unui obiect, care l deosebesc de toate
celelalte feluri de obiecte
fiecare obiect n sistem are rolul unui actor
abstract, care poate executa aciuni, i poate
modifica i comunica starea i poate comunica
cu alte obiecte din sistem fr a dezvlui cum
au fost implementate acele facilitai
procesele, funciile sau metodele pot fi de
asemenea abstracte

Principii POO: ncapsularea


l
l

l
l

ascunderea de informaii (data-hiding)


obiectele nu pot schimba starea intern a
altor obiecte n mod direct (ci doar prin
metode puse la dispoziie de obiectul
respectiv)
doar metodele proprii ale obiectului pot
accesa starea acestuia
procesul de compartimentare a elementelor
unei abstractizri n dou pri: structura i
comportarea
ncapsularea separ comportarea (accesat
prin interfa) de structur, definit prin
implementare
fiecare tip de obiect expune o interfa
pentru celelalte obiecte care specific modul
cum acele obiecte pot interaciona cu el

Principii POO: Modularizarea


l
l

este procesul de partiionare a unui program


n componente individuale (module)
permite reducerea complexitii programului
prin definirea unor granie bine stabilite i
documentate n program.

modularizarea const n partiionarea


programului n module care pot fi
compilate separat, dar care au conexiuni
cu alte module ale programului.

modulele servesc ca i containere n care


sunt declarate clasele i obiectele
programului.

Principii POO: Ierarhizarea


l
l
l

Modalitatea de a ordona abstractizrile


(tipurile abstracte de date).
Ierarhiile pot s denote relaii de tip sau
relaii de agregare.
Relaiile de tip sunt definite prin motenirile
ntre clase, prin care o clas (clasa derivat)
motenete structura sau comportarea
definit n alt clas (clasa de baz )
Relaiile de agregare specific compunerea
unui obiect din mai multe obiecte mai
simple.
Obs: n limbajele de programare
procedural agregarea se realiza prin
structuri de tip nregistrare (record n Pascal,
struct n C, etc).

Principii POO: Motenirea


l

l
l
l
l

permite definirea i crearea unor clase


specializate plecnd de la clase (generale)
care sunt deja definite
permite construirea unor clase noi, care
pstreaz caracteristicile i comportarea,
deci datele i funciile membru, de la una
sau mai multe clase definite anterior, numite
clase de baz, fiind posibil redefinirea sau
adugarea unor date i funcii noi.
o clas ce motenete una sau mai multe
clase de baz se numete clasa derivat.
posibilitatea refolosirii lucrurilor care
funcioneaz
organizeaz i faciliteaz polimorfismul i
ncapsularea
Anumite obiecte sunt similare dar n
acelai timp diferite.

Principii POO: Motenirea


l

Proprietatea de motenire: proprietatea


claselor prin care o clas nou construit
poate prelua datele i metodele clasei mai
vechi.

Clasa derivat se afl ntotdeauna pe un


nivel imediat inferior celui corespunztor
clasei de baz.

n Java exist doar motenire simpl, o


ierarhie de clase n care fiecare clas
derivat are o singur clas de baz.

Principii POO: Motenirea


Exemplu.
parallelogram

dreptunghi

romb

patrat
l

Clasa dreptunghi este o clas derivat


(subclas) a clasei paralelogram, iar clasa
paralelogram este o clas de baz
(supraclas) a clasei dreptunghi
Astfel, o ierarhie de concepte conduce la o
ierarhie ntre clasele care implementeaz
conceptele ierarhice respective.

Principii POO:
Polimorfismul, suprancrcarea
l

l
l

l
l

Mai multe funcii pot avea acelai nume n


acelai domeniu de definiie, dac se pot
diferenia prin numrul sau tipul
argumentelor de apel.
O funcie este polimorfic dac se poate
executa cu acelai efect asupra unor valori
de tipuri diferite (ex. operatorul & din C)
Un alt mecanism este suprancrcarea
funciilor( function overloading).
O funcie este suprancrcat dac execut
operaii diferite n contexte diferite (ex.
operatorul + din Java)
Se poate aplica doar funciilor.
Supradefinirea (overriding) ofer
posibilitatea de a redefini metode pentru
clasele derivate, metodele au acelai tip i
aceeai parametri.

Principii POO:
Polimorfismul, suprancrcarea
l

Dac n acelai domeniu sunt definite mai multe


funcii cu acelai nume, la fiecare apel se
selecteaz funcia corect prin compararea
tipurilor argumentelor reale de apel cu tipurile
argumentelor formale ale funciei.
l double abs(double);
l int abs(int);
l abs(1); // apeleaza abs(int)
l abs(1.0); // apeleaza abs(double)

Nu este admis ca funciile s difere doar prin


tipul returnat!
Dou funcii declarate cu acelai nume se
refer la aceeai funcie dac sunt n acelai
domeniu i au numr i tipuri identice de
argumente.

Concluzii POO
l

Programele: o colecie de obiecte, uniti


individuale de cod care interacioneaz
unele cu altele, n loc de simple liste de
instruciuni sau de apeluri de proceduri

Obiectele POO sunt de obicei reprezentri


ale obiectelor din viaa real

Programele sunt mai uor de neles, de


depanat i de extins dect programele
procedurale (mai ales n cazul proiectelor
software complexe i de dimensiuni mari,
care se gestioneaz fcnd apel la ingineria
programrii).

Tip abstract de date


mulime de date care au aceeai
reprezentare i pentru care este definit setul
de operaii care se pot executa asupra
elementelor mulimii respective.
are dou pri:
o parte care definete reprezentarea
datelor
o parte care definete operaiile asupra
datelor respective.

Noiunea de clas
l

O clas definete un tip abstract de date.

Definiie clas:
class nume{
lista_elementelor_membru
}
Lista elementelor membru poate conine:
declaraii de date;
implementri de funcii;
prototipuri de funcii abstracte.
Datele declarate printr-o definiie de clas se
numesc date membru
Funciile definite sau pentru care este prezent
numai prototipul n definiia clasei, se numesc
funcii membru sau metode.
Att datele ct i metodele pot avea modificatori
de acces

Modificatorii de acces
l

Modificatorii de acces sunt cuvinte


rezervate ce controleaz accesul celorlalte
clase la membrii unei clase. Specificatorii de
acces pentru variabilele i metodele unei clase
sunt: public, protected, private i cel implicit (la
nivel de pachet).

Specificator Clasa Subcls Pachet Oriunde


Private
X
Protected X
X*
Public
X
X
X
X
Implicit
X
X

Clas
Exemplu:
class Complex {
// date membru
float real;
float imag;
// functii membru publice
public void atribuire(float x, float y) {
real = x; imag=y;
}
public double retreal() {
return real;
}
public void afiscomplex(){
System.out.println(real+++imag+*i);
}
}

Obiecte
l

Un obiect este o dat de un tip definit printro clas. Se spune c obiectul este o
instaniere a clasei respective.

Formatul declaratiei unui obiect:


nume_clas nume_obiect;

Instanierea obiectelor se face folosind


operatorul new.
nume_obiect = new nume_clas(..);

Obiecte

Datele membru se aloc distinct la fiecare


instaniere a clasei. O excepie o constituie
datele membru care au clasa de memorare
static, ea este o parte comun pentru toate
instanierile clasei i exist ntr-un singur
exemplar.

Funciile membru sunt ntr-un singur


exemplar oricte instanieri ar exista.
Legtura dintre funcii membru i obiectul
pentru care se face apelul se realizeaz
folosind operatorul punct.

Obiecte
l

Exemplu de instanieri pentru clasa


complex:
Complex z;
z=new Complex();

Atunci:
z.atribuire(0,0);
z.afiscomplex();
afieaz numrul complex z (n cazul de
fa 0+0i).

Constructori
Obiectele se genereaz i se pot iniializa la
instaniere cu ajutorul constructorilor
Funcii membru ce au acelai nume cu
numele clasei
Funcii apelate automat la crearea
obiectelor.
Valorile de iniializare se transfer
constructorului i ele joac acelai rol ca
parametrii efectivi de la apelurile funciilor
obinuite.
Se pot defini mai muli constructori pentru o
clas. n acest caz ei au acelai nume, dar
difer prin numrul i/sau tipurile
parametrilor.

Constructori
Dac exist mai muli constructori, atunci la
iniializare se utilizeaz regulile de la
apelurile funciilor suprancrcate.
Funciile constructor nu ntorc valori, dar nu
sunt precedai de cuvntul void.
Dac clasa nu conine constructori, se
genereaz un constructor fr parametri,
adic un constructor implicit. El are rolul
numai de alocare a obiectelor clasei
respective, fr a le iniializa.

Constructori
Exemplu:
class Complex {
double real;
double imag;
public Complex(double x, double y)
{real = x; imag = y;}
public Complex ( )
{real = 0; imag = 0;}
}
Exemple de instaniere:
Complex z= new Complex();
Complex z1= new Complex(1,0);

// z = 0 + 0*i
// z1 = 1 + 0*

Realizarea ncapsulrii datelor


l

accesul la datele sau funciile membre ale


unei clase din orice punct al domeniului de
definiie al clasei s-ar putea rezolva simplu
prin declararea de tip public a acestora
o astfel de implementare nu respect
principiul ncapsulrii
datelor i se
recomand s fie evitat
din punct de vedere al dreptului de acces la
membrii clasei, o clas bine definit permite
ncapsularea (sau ascunderea informaiilor),
prin care un obiect poate ascunde celor
care-l folosesc modul de implementare, prin
interzicerea accesului la datele i funciile
private sau protected.

Realizarea ncapsulrii datelor


l

n general, respectnd principiul


ncapsulrii, datele membre sunt declarate
private sau protected i nu pot fi accesate
direct (pentru citire sau scriere) din funcii
nemembre ale clasei.
Pentru citirea sau modificarea unora dintre
datele membre protejate n clasa respectiv
se pot prevedea funcii membre de tip
public, care pot fi apelate din orice punct al
domeniului de definiie al clasei i fac parte
din interfaa clasei.
De exemplu, pentru clasa Complex , o
implementare care respect principiul
ncapsulrii, dar, n acelai timp permite
accesul la datele private ale clasei poate
arta astfel:

Realizarea ncapsulrii datelor


class Complex {
private double real;
private double imag;
public Complex(double x, double y)
{real = x; imag = y;}
public Complex ( )
{real = 0; imag = 0;}
public void set(double x, double y)
{ re = x; im = y; }
public void setre(double x)
{ re = x;}
public void setim(double y)
{ im = y; }
public double getre(){
return re;}
public double getim() {
return im;}

Realizarea ncapsulrii datelor


public void display(){
System.out.println(re+++im+i);}
}
class test{
public static void main(String arg[]){
Complex c1=new Complex(), c2=new
Complex(1,1);
c1.set(7.2, 9.3);
c1.display(); // afiseaza 7.2 9.3
c1.setre(1.3);
c1.setim(2.8);
c1.display(); // afiseaza 1.3 2.8 }
}
}

Clase abstracte
l
l
l
l
l

clasele pentru care programatorul nu


intenioneaz s instanieze obiecte.
clase de baz in ierarhii
se mai numesc clase abstracte de baz
o clas devine abstract dac conine una
sau mai multe declaraii de funcii abstracte
dac o clas ce motenete o clas ce
conine o funcie abstract nu
implementeaz acea funcie abstract
motenit, devine ea nsi o clas
abstract.

OBS: clasele pentru care se pot instania


obiecte se numesc clase concrete.

CLASA String

Metode i exemple

Crearea unui ir
Constructorul implicit creaz un ir vid:
String s = new String();
l String str = "abc";
este echivalent cu:
char data[] = {'a', 'b', 'c'};
String str = new String(data);
OBS. Dac elementele din vectorul data sunt
modificate dup crearea irului str, atunci
aceste modificri nu apar n acest ir.
l Construirea unui ir pe baza altui ir:
String str2 = new String(str);
l

Operaii cu iruri
l

Metoda length() returneaz lungimea unui ir


Ex: System.out.println(Hello.length()); // afieaz 5

Operatorul + este utilizat pentru concatenarea a


dou sau mai multe iruri
Ex: String myname = Harry;
String str = My name is + myname+ .;

Caracterele dintr-un ir pot fi accesate astfel:


public char charAt(int index);
Returneaz caracterul din poziia index. Domeniul
de indexare este de la 0 la length() - 1.
Ex. char ch;
ch = abc.charAt(1); // ch = b

Operaii cu iruri
l

getChars() - Copiaz caracterele din irul surs n


irul destinaie
public void getChars(int srcBegin, int srcEnd,
char[] dst, int dstBegin)
srcBegin indexul primului caracter din surs
srcEnd indexul ultimului caracter din surs
dst vectorul destinaie
dstBegin poziia de la care ncepe copierea n
vectorul destinaie
equals() Compar dou iruri la egalitate
public boolean equals(String s2)
equalsIgnoreCase()- Compar dou iruri la
egalitate fr s in cont de litere mici sau mari
public boolean equalsIgnoreCase(String s2)

Operaii cu iruri
l

startsWith() Testeaz dac irul ncepe cu prefixul


specificat (la nceput sau dintr-o anumit poziie)
public boolean startsWith(String prefix)
Ex.Figure.startsWith(Fig); // true
public boolean startsWith(String prefix, int toffset)
Ex.figure.startsWith(gure, 2); // true

endsWith() - Testeaz dac irul se termin cu sufixul


specificat
public boolean endsWith(String suffix)
Ex. Figure.endsWith(re); // true

compareTo() Compar dou iruri din punct de


vedere lexicografic
Rezultatul este
Negativ, dac irul precede irul primit ca argument
Zero, dac irurile sunt egale
Pozitiv, dac irul urmeaz irului primit ca argument
public int compareTo(String anotherString)
public int compareToIgnoreCase(String str)

Operaii cu iruri
l

indexOf Caut prima apariie a unui caracter sau


ir ntr-un alt ir. Returneaz -1 dac nu l gsete.
public int indexOf(int ch)
public int indexOf(String str)
Ex. String str = How was your day today?;
str.indexOf(o); // 1
str.indexOf(was); //4

cutare ncepnd de la o poziie specificat:


public int indexOf(int ch, int fromIndex)
public int indexOf(String str, int fromIndex)
Ex. String str = How was your day today?;
str.indexOf(a, 6); //14
str.indexOf(was, 2); //4

lastIndexOf() - Caut ultima apariie a unui caracter


sau ir ntr-un alt ir, similar lui indexOf.

Operaii cu iruri
l

substring() Returneaz un nou ir care este un


subir al irului surs.
public String substring(int beginIndex)
Ex: "unhappy".substring(2); // returneaz "happy"
public String substring(int beginIndex,
int endIndex)
Ex: "smiles".substring(1, 5); // returneaz "mile
concat() Concateneaz irul specificat la irul
surs
public String concat(String str)
"to".concat("get").concat("her"); // returneaz
"together"
replace()- Returneaz un nou ir n care toate
apariiile caracterului oldChar sunt nlocuite cu
caracterul newChar.
public String replace(char oldChar, char newChar)
Ex. "mesquite in your cellar".replace('e', 'o');
returneaz "mosquito in your collar"

Operaii cu iruri
l

trim() - Returneaz irul fr spaiile albe de la


nceput i sfrit
public String trim()
Ex. String s = Hi Mom! .trim();
S este acum Hi Mom!

valueOf() Returneaz reprezentarea sub form


de ir de caractere a argumentului
public static String valueOf(char[] data)
public static String valueOf(char c)
public static String valueOf(boolean b)
public static String valueOf(int i)
public static String valueOf(long l)
public static String valueOf(float f)
public static String valueOf(double d)

Operaii cu iruri
l

toLowerCase(): Convertete toate caracterele la


litere mici
public String toLowerCase()

toUpperCase(): Convertete toate caracterele la


litere mari
public String toUpperCase()
Ex: HELLO THERE.toLowerCase();
hello there.toUpperCase();

Operaii cu iruri
public String[] split(String regex)
mparte sirul in subsiruri folosind un sir de
delimitatori (expresie regulata)
regex expresia regulata de delimitare
returneaza un vector de String-uri
Exemplu: pentru sirul "boo:and:foo avem
urmatoarele rezultate:
regex
:
o

rezultat
{ "boo", "and", "foo" }
{ "b", "", ":and:f" }

public String[] split(String regex, int limit)


- Limit: de cate ori se aplica expresia regulata

StringBuffer
l

l
l

Este asemntor unui obiect String doar c este


modificabil n sensul c exist metode pentru
modificarea lungimii i a coninutului su append,
insert.
Crearea unui obiectStringBuffer:
StringBuffer()
StringBuffer(int size)
StringBuffer(String str)
Principalele operaii sunt adugarea, inserarea i
tergerea.
Adugarea:
StringBuffer append(String str)
StringBuffer append(int num)
Inserarea se face ntr-o anumit poziie.
StringBuffer insert(int index, String str)
StringBuffer append(int index, char ch)

Operaii cu StringBuffer
delete() - terge un subir. Subirul ncepe n
poziia specificat i se termin n poziia index de
final - 1 sau pn la sfritul irului dac nu se
specific poziie de final.
public StringBuffer delete(int start, int end)
public StringBuffer delete(int start)
l replace() nlocuiete un subir din irul surs cu
un alt ir
public StringBuffer replace(int start, int end, String
str)
l substring()
public String substring(int start)
l reverse() reversul irului (ordine invers a
caracterelor)
public StringBuffer reverse()
l length()
public int length()

Operaii cu StringBuffer
l

capacity() Returneaz capacitatea curent a


StringBuffer-ului. Capacitatea este dimensiunea
disponibil pentru adugarea de noi elemente
public int capacity()
charAt()
public char charAt(int index)
getChars()
public void getChars(int srcBegin, int srcEnd,
char[] dst, int dstBegin)
setLength() Seteaz lungimea pentru obiectul de
tip StringBuffer.
public void setLength(int newLength)

Exemple: StringBuffer
StringBuffer sb = new StringBuffer(Hello);
sb.length(); // 5
sb.capacity(); // 21 (16 caractere sunt adugate
dac nu se specific o dimensiune)
sb.charAt(1); // e
sb.setCharAt(1,i); // Hillo
sb.setLength(2); // Hi
sb.append(l).append(l); // Hill
sb.insert(0, Big ); // Big Hill
sb.replace(3, 11, ); // Big
sb.reverse(); // giB

Clasa StringTokenizer
Utilizat pentru mprirea n atomi lexicali (tokens):
public StringTokenizer(String str, String delim)
public boolean hasMoreTokens()
public String nextToken()
l

Exemplu:
StringTokenizer st = new StringTokenizer("this, is a
test., ,.);
while (st.hasMoreTokens()) {
System.out.println(st.nextToken());
}
Are urmtorul rezultat:
this
is
a
test

Curs 3
Programare Orientat pe Obiecte
n limbajul Java

Programare Orientat pe Obiecte

Obiecte i clase
Obiecte i clase
Obiecte
Clase
Constructori
Variabile i metode membre
Variabile i metode de clas
Clasa Object
Conversii automate ntre tipuri
Tipul enumerare
Clase imbricate
Clase i metode abstracte

Crearea obiectelor
l

Declararea
NumeClasa numeObiect;

Instanierea: new
numeObiect = new NumeClasa();

Iniializarea
numeObiect = new NumeClasa([argumente]);
Rectangle r1, r2;
r1 = new Rectangle();
r2 = new Rectangle(0, 0, 100, 200);

Obiecte anonime

Rectangle patrat = new Rectangle(new Point(0,0),


new Dimension(100, 100));
l

Memoria nu este pre-alocat !


Rectangle patrat;
patrat.x = 10; //Eroare

Folosirea obiectelor (1)


Aflarea unor informaii
Schimbarea strii
Executarea unor aciuni
l obiect.variabila
Rectangle patrat = new Rectangle(0, 0, 10, 200);
System.out.println(patrat.width);
patrat.x = 10;
patrat.y = 20;
patrat.origin = new Point(10, 20);
l

obiect.metoda([parametri])
Rectangle patrat = new Rectangle(0, 0, 10, 200);
patrat.setLocation(10, 20);
patrat.setSize(200, 300);

Folosirea obiectelor (2)


l

Metode de accesare:
setVariabila, getVariabila
patrat.width = -100;
patrat.setSize(-100, -200);
// Metoda poate refuza schimbarea

class Patrat {
private double latura=0;
public double getLatura()
{
return latura;
}
public double setLatura(double latura) {
this.latura = latura;
}
}

Distrugerea obiectelor
l

Obiectele care nu mai sunt referite vor fi


distruse automat.

Referinele sunt distruse:


natural
explicit, prin atribuirea valorii null.
class Test {
String a;
void init() {
a = new String("aa");
String b = new String("bb");
}
void stop() {
a = null;
}
}

Garbage Collector

Procesul responsabil cu eliberarea memoriei

System.gc
Sugereaz JVM s elibereze memoria
Finalizarea
l Metoda finalize este apelat automat nainte de
eliminarea unui obiect din memorie.
finalize destructor

Declararea claselor
[public][abstract][final] class NumeClasa
[extends NumeSuperclasa]
[implements Interfata1 [, Interfata2 ...]]
{
// Corpul clasei
}
Motenire simpl
class B extends A {...}
// A este superclasa clasei B
// B este o subclasa a clasei A
class C extends A,B // Incorect !
l

Object este rdcina ierarhiei claselor Java.

Corpul unei clase


Variabile membre
Constructori
Metode membre
Clase imbricate (interne)
// C++
class A {
void metoda1();
int metoda2() { ... }
}
A::metoda1() { ... }
// Java
class A {
void metoda1(){ ... }
void metoda2(){ ... }
}

Constructorii unei clase


class NumeClasa {
[modificatori] NumeClasa([argumente]) {
// Constructor
}
}
this apeleaz explicit un constructor al clasei.
class Dreptunghi {
double x, y, w, h;
Dreptunghi(double x1, double y1, double w1, double
h1) {
// Implementam doar constructorul cel mai general
x=x1; y=y1; w=w1; h=h1;
System.out.println("Instantiere dreptunghi");
}
Dreptunghi(double w1, double h1) {
this(0, 0, w1, h1);
// Apelam constructorul cu 4 argumente
}
l

Apel explicit constructori


Dreptunghi() {
this(0, 0);
// Apelam constructorul cu 2 argumente
}
}
super apeleaz explicit un constructor al superclasei.
class Patrat extends Dreptunghi {
Patrat(double x, double y, double d) {
super(x, y, d, d);
}
l

Atenie!
l Apelul explicit al unui constructor nu poate
aprea dect ntr-un alt constructor i
trebuie s fie prima instruciune din
constructorul respectiv.

this
this i super: Sunt folosite n general pentru a
rezolva conflicte de nume prin referirea
explicit a unei variabile sau metode
membre.
class A {
int x;
A() {
this(0);
}
A(int x) {
this.x = x;
}
void metoda() {
x ++;
}
}

super

class B extends A {
B() {
this(0);
}
B(int x) {
super(x);
}
void metoda() {
super.metoda();
}
}

Constructorul implicit
class Dreptunghi {
double x, y, w, h;
// Nici un constructor
}
class Cerc {
double x, y, r;
// Constructor cu 3 argumente
Cerc(double x, double y, double r) { ... };
}
...
Dreptunghi d = new Dreptunghi();
// Corect (a fost generat constructorul implicit)
Cerc c;
c = new Cerc();
// Eroare la compilare !
c = new Cerc(0, 0, 100);
// Varianta corect

Modificatorii de acces
l

Modificatorii de acces sunt cuvinte


rezervate ce controleaz accesul celorlalte
clase la membrii unei clase.

Specificator Clasa Subcls Pachet Oriunde


Private
X
Protected X
X*
Public
X
X
X
X
Implicit
X
X

dac nu este specificat nici un modificator de


acces, implicit nivelul de acces este la nivelul
pachetului

Declararea variabilelor
class NumeClasa {
// Declararea variabilelor
// Declararea metodelor
}
[modificatori] Tip numeVariabila [ = valoare];
unde un modificator poate fi :
public, protected, private
static, final, transient, volatile
class Exemplu {
double x;
protected static int n;
public String s = "abcd";
private Point p = new Point(10, 10);
final static long MAX = 100000L;
}

Final, transient, volatile


final:
class Test {
final int MAX;
Test() {
MAX = 100; // Corect
MAX = 200; // Eroare la compilare !
}
}
transient:
l folosit la serializarea obiectelor, pentru a
specifica ce variabile membre ale unui obiect nu
particip la serializare.
volatile:
l folosit pentru a semnala compilatorului s nu
execute anumite optimizri asupra membrilor
unei clase.
l o facilitate avansat a limbajului Java.

Declararea metodelor
[modificatori] TipReturnat numeMetoda ([argumente])
[throws TipExceptie1, TipExceptie2, ...]
{
// Corpul metodei
}
unde un modificator poate fi :
public, protected, private
static, abstract, final, native, synchronized
class Student {
...
final float calcMedie(float note[]) {
...
}
}
class StudentInformatica extends Student {
float calcMedie(float note[]) {
return 10.00;
}
}// Eroare la compilare !

Tipul returnat de o metod


l
l

return [valoare]
void nu este implicit

public void afisareRezultat() {


System.out.println("rezultat");
}
private void deseneaza(Shape s) {
...
return;
}
l return trebuie s apar n toate situaiile, atunci cnd am tip
returnat:
double radical(double x) {
if (x >= 0)
return Math.sqrt(x);
else {
System.out.println("Argument negativ !");
// Eroare la compilare
// Lipseste return pe aceasta ramura
}
}

Tip - Subtip
l
l
l

int metoda() { return 1.2;} // Eroare


int metoda() { return (int)1.2;} // Corect
double metoda() {return (float)1;} // Corect

Clas - Subclas
Poligon metoda1( ) {
Poligon p = new Poligon();
Patrat t = new Patrat();
if (...)
return p; // Corect
else
return t; // Corect
}
Patrat metoda2( ) {
Poligon p = new Poligon();
Patrat t = new Patrat();
if (...)
return p; // Eroare
else
return t; // Corect
}

Argumentele metodelor
Numele argumentelor primite trebuie s difere
ntre ele i nu trebuie s coincid cu numele nici
uneia din variabilele locale ale metodei.
l Pot s coincid cu numele variabilelor membre
ale clasei, caz n care diferenierea dintre ele se
va face prin intermediul variabile this.
class Cerc {
int x, y, raza;
public Cerc(int x, int y, int raza) {
this.x = x;
this.y = y;
this.raza = raza;
}
}

Trimiterea parametrilor (1)


TipReturnat metoda([Tip1 arg1, Tip2 arg2, ...])
l

Argumentele sunt trimise doar prin valoare


(pass-by-value).

void metoda(StringBuffer sir, int numar) {


// StringBuffer este tip referinta
// int este tip primitiv
sir.append("abc");
numar = 123;
}
...
StringBuffer s=new StringBuffer();
int n=0;
metoda(s, n);
System.out.println(s + ", " + n);
// s va fi "abc", dar n va fi 0

Trimiterea parametrilor (2)


void metoda(String sir, int numar) {
// String este tip referinta
// int este tip primitiv
sir = "abc";
numar = 123;
}
...
String s=new String(); int n=0;
metoda(s, n);
System.out.println(s + ", " + n);
// s va fi "", n va fi 0
void schimba(int a, int b) {
int aux = a;
a = b;
b = aux;
}
...
int a=1, b=2;
schimba(a, b);
// a va ramane 1, iar b va ramane 2

Trimiterea parametrilor (3)


class Pereche {
public int a, b;
}
...
void schimba(Pereche p) {
int aux = p.a;
p.a = p.b;
p.b = aux;
}
...
Pereche p = new Pereche();
p.a = 1, p.b = 2;
schimba(p);
//p.a va fi 2, p.b va fi 1

Metode cu numr variabil de


argumente
[modif] TipReturnat metoda(TipArgumente ... args)
l

Tipul argumentelor poate fi referin sau


primitiv.

void metoda(Object ... args) {


for(int i=0; i<args.length; i++)
System.out.println(args[i]);
}
...
metoda("Hello");
metoda("Hello", "Java", 1.5);

Polimorfism (1)
l
l

Suprancrcarea (overloading)
Supradefinirea (overriding)

class A {
void metoda() {
System.out.println("A: metoda fara parametru");
}
// Suprancrcare
void metoda(int arg) {
System.out.println("A: metoda cu un
parametru");
}
}
class B extends A {
// Supradefinire
void metoda() {
System.out.println("B: metoda fara parametru");
}
}

Polimorfism (2)
O metod supradefinit poate :
s ignore codul metodei printe:
B b = new B();
b.metoda();
// Afieaz "B: metoda fara parametru"
s extind codul metodei printe:
class B extends A {
// Supradefinire prin extensie
void metoda() {
super.metoda();
System.out.println("B: metoda fara parametru");
}
}
...
B b = new B();
b.metoda();
/* Afieaz ambele mesaje:
"A: metoda fara parametru"
"B: metoda fara parametru" */
l n Java nu este posibil suprancrcarea operatorilor.

Variabile de instan i variabile de


clas
class Exemplu {
int x ; //variabila de instanta
}
l variabil de instan: la fiecare creare a unui
obiect al clasei Exemplu sistemul aloc o
zon de memorie separat pentru
memorarea valorii lui x.
class Exemplu {
static int sx ; //variabila de clas
}
l Pentru variabilele de clas (statice) sistemul
aloc o singur zon de memorie la care au
acces toate instanele clasei respective,
ceea ce nseamn c dac un obiect
modific valoarea unei variabile statice ea
se va modifica i pentru toate celelalte
obiecte.

Variabile de clas
l

Deoarece nu depind de o anumit


instan a unei clase, variabilele statice
pot fi referite i sub forma:
NumeClasa.numeVariabilaStatica
Ex. Exemplu.sx

Iniializarea variabilelor de clas se


face o singur dat, la ncrcarea n
memorie a clasei respective
class Exemplu {
static final double PI = 3.14;
static long nrInstante = 0;
static Point p = new Point(0,0);
}

Variabile de instan i variabile de


clas
class Exemplu {
int x ; // Variabila de instanta
static long n; // Variabila de clasa
}

...
Exemplu o1 = new Exemplu();
Exemplu o2 = new Exemplu();
o1.x = 100;
o2.x = 200;
System.out.println(o1.x); // Afiseaza 100
System.out.println(o2.x); // Afiseaza 200
o1.n = 100;
System.out.println(o2.n); // Afiseaza 100
o2.n = 200;
System.out.println(o1.n); // Afiseaza 200
System.out.println(Exemplu.n); // Afiseaza 200
// o1.n, o2.n si Exemplu.n sunt referinte la aceeasi
// valoare

Metode de instan i metode de


clas
metodele de instan opereaz att pe
variabilele de instan ct i pe cele statice ale
clasei;
l metodele de clas opereaz doar pe variabilele
statice ale clasei.
class Exemplu {
int x ;
// Variabil de instan
static long n; // Variabil de clas
void metodaDeInstanta() {
n ++; // Corect
x --; // Corect
}
static void metodaStatica() {
n ++; // Corect
x --; // Eroare la compilare !
}
}

Metode de instan i metode de


clas
l

Intocmai ca i la variabilele statice, ntruct


metodele de clas nu depind de starea
obiectelor clasei respective, apelul lor se
poate face i sub forma:
NumeClasa.numeMetodaStatica
Exemplu.metodaStatica(); // Corect
Exemplu obj = new Exemplu();
obj.metodaStatica(); // Corect

Metodele de instan nu pot fi apelate dect


pentru un obiect al clasei respective:
Exemplu.metodaDeInstanta(); // Eroare
Exemplu obj = new Exemplu();
obj.metodaDeInstanta(); // Corect

Utilitatea membrilor de clas


l

folosii pentru a pune la dispoziie valori i metode


independente de starea obiectelor dintr-o anumit
clas.

Declararea eficient a constantelor


class Exemplu {
static final double PI = 3.14;
// Variabila finala de clasa
}
l

Numrarea obiectelor unei clase


class Exemplu {
static long nrInstante = 0;
Exemplu() {
// Constructorul este apelat la fiecare instantiere
nrInstante ++;
}
}
l

Implementarea funciilor globale

Blocuri statice de iniializare


static {
// Bloc static de initializare;
...
}
public class Test {
// Declaratii de variabile statice
static int x = 0, y, z;
// Bloc static de initializare
static {
System.out.println("Initializam...");
int t=1;
y = 2;
z = x + y + t;
}
Test() { ... }
}
}

Blocuri statice de iniializare


l

Variabilele statice ale unei clase sunt


iniializate la un moment care precede prima
utilizare activ a clasei respective.
Momentul efectiv depinde de implementarea
mainii virtuale Java i poart numele de
iniializarea clasei. n aceast etap sunt
executate i blocurile statice de iniializare
ale clasei.
Variabilele referite ntr-un bloc static de
iniializare trebuie s fie obligatoriu de clas
sau locale blocului.

Clasa Object
Object este superclasa tuturor claselor.
class Exemplu {}
class Exemplu extends Object {}
clone
equals
finalize
toString.
Exemplu obj = new Exemplu();
System.out.println("Obiect=" + obj);
//echivalent cu
System.out.println("Obiect=" + obj.toString());

Exemplu
public class Complex {
private double a, b;
...
public Complex aduna(Complex comp) {
return new Complex(a + comp.a, b + comp.b);
}
public boolean equals(Object obj) {
if (obj == null) return false;
if (!(obj instanceof Complex)) return false;
Complex comp = (Complex) obj;
return ( comp.a==a && comp.b==b);
}
public String toString() {
if (b > 0) return a + + + b + *i;
return a + + b + *i";
}
}
...
Complex c1 = new Complex(1,2);
Complex c2 = new Complex(2,3);
System.out.println(c1.aduna(c2));
System.out.println(c1.equals(c2));

// 3.0 + 5.0i
// false

Conversii automate ntre tipuri

Integer obi = new Integer(1);


int i = obi.intValue();
Boolean obb = new Boolean(true);
boolean b = obb.booleanValue();
// Doar de la versiunea 1.5 !
Integer obi = 1;
int i = obi;
Boolean obb = true;
boolean b = obb;

Curs 4
Programare Orientat pe Obiecte
n limbajul Java

Programare Orientat pe Obiecte

PDF created with pdfFactory Pro trial version www.pdffactory.com

Cuprins

Tipul enumerare
l Clase imbricate
l Clase i metode abstracte
l

Excepii

PDF created with pdfFactory Pro trial version www.pdffactory.com

Tipuri de date enumerare


enum
public class CuloriSemafor {
public static final int ROSU = -1;
public static final int GALBEN = 0;
public static final int VERDE = 1;
}
...
// Exemplu de utilizare
if (semafor.culoare == CuloriSemafor.ROSU)
semafor.culoare = CuloriSemafor.GALBEN;

// Doar de la versiunea 1.5 !


public enum CuloriSemafor { ROSU, GALBEN, VERDE };
// Utilizarea structurii se face la fel

PDF created with pdfFactory Pro trial version www.pdffactory.com

Clase imbricate
o clas membr a unei alte clase, numit
i clas de acoperire.
l

class ClasaDeAcoperire{
class ClasaImbricata1 {
// Clasa membru
// Acces la membrii clasei de acoperire
}
void metoda() {
class ClasaImbricata2 {
// Clasa locala metodei
// Acces la mebrii clasei de acoperire si
// la variabilele finale ale metodei
}
}
}
l

Identificare claselor imbricate


ClasaDeAcoperire.class
ClasaDeAcoperire$ClasaImbricata1.class
ClasaDeAcoperire$ClasaImbricata2.class

PDF created with pdfFactory Pro trial version www.pdffactory.com

Clase imbricate
class ClasaDeAcoperire{
private int x=1;
class ClasaImbricata1 {
int a=x;
}
void metoda() {
final int y=2;
int z=3;
class ClasaImbricata2 {
int b=x;
int c=y;
int d=z; // Incorect
}
}
}

PDF created with pdfFactory Pro trial version www.pdffactory.com

Clase imbricate
l

l
l
l

O clas imbricat membr (care nu este local unei


metode) poate fi referit din exteriorul clasei de
acoperire folosind expresia
ClasaDeAcoperire.ClasaImbricata
Clasele membru pot fi declarate cu modificatorii
public, protected, private sau implicit pentru a
controla nivelul lor de acces din exterior.
Clasa care conine alte clase poate avea doar
modificatorul public i cel implicit!
Pentru clasele imbricate locale unei metode nu sunt
permii aceti modificatori.
Toate clasele imbricate pot fi declarate folosind
modificatorii abstract i final.

Clase anonime
l
l

clase imbricate locale, fr nume, utilizate doar


pentru instanierea unui obiect de un anumit tip.
sunt foarte utile n crearea unor obiecte ce
implementeaz o anumit interfa sau extind o
anumit clas abstract.

PDF created with pdfFactory Pro trial version www.pdffactory.com

Clase i metode abstracte


[public] abstract class ClasaAbstracta ... {
// Declaratii uzuale
// Declaratii de metode abstracte
}
Metode abstracte
abstract class ClasaAbstracta {
abstract void metodaAbstracta(); // Corect
void metoda(); // Eroare
}
O clas abstract poate s nu aib nici o metod abstract.
O metod abstract nu poate aprea dect ntr-o clas
abstract.
Orice clas care are o metod abstract trebuie declarat
ca fiind abstract.
Exemple:
Number: Integer, Double, ...
Component: Button, List, ...

PDF created with pdfFactory Pro trial version www.pdffactory.com

Excepii
Ce sunt excepiile
Prinderea i tratarea excepiilor
Aruncarea excepiilor
Avantajele tratrii excepiilor
Ierarhia claselor ce descriu excepii
Excepii la execuie
Crearea propriilor excepii

PDF created with pdfFactory Pro trial version www.pdffactory.com

Ce sunt excepiile ?
Excepie = eveniment excepional
public class Exemplu {
public static void main(String args[]) {
int v[] = new int[10];
v [10] = 0; //Exceptie !
System.out.println("Aici nu se mai ajunge..");
}
}
"Exception in thread "main"
java.lang.ArrayIndexOutOfBoundsException :10
at excepii.main (excepii.java:4)
throw an exception
exception handler
catch the exception
Tratarea erorilor nu mai este o opiune ci o
constrngere!

PDF created with pdfFactory Pro trial version www.pdffactory.com

Prinderea i tratarea excepiilor


try - catch - finally
try {
// Instruciuni care pot genera excepii

}
catch (TipExceptie1 variabila) {
// Tratarea excepiilor de tipul 1

}
catch (TipExceptie2 variabila) {
// Tratarea excepiilor de tipul 2

}
...
finally {
// Cod care se execut indiferent
// dac apar sau nu excepii

PDF created with pdfFactory Pro trial version www.pdffactory.com

Citirea unui fiier (1)


public static void citesteFisier(String fis) {
FileReader f = null;
// Deschidem fisierul
f = new FileReader(fis);
// Citim si afisam fisierul caracter cu
// caracter
int c;
while ( (c=f.read()) != -1)
System.out.print((char)c);
// Inchidem fisierul
f.close();
}
Pot provoca excepii:
Constructorul lui FileReader
read
close

PDF created with pdfFactory Pro trial version www.pdffactory.com

Citirea unui fiier (2)


public static void citesteFisier(String fis) {
FileReader f = null;
try {
// Deschidem fisierul
f = new FileReader(fis);
// Citim si afisam fisierul caracter cu caracter
int c;
while ( (c=f.read()) != -1)
System.out.print((char)c);
}
catch (FileNotFoundException e) {
//Tratam un tip de exceptie
System.err.println("Fisierul nu a fost gasit");
}
catch (IOException e) {
//Tratam alt tip de exceptie
System.out.println("Eroare la citire");
e.printStackTrace();
}

PDF created with pdfFactory Pro trial version www.pdffactory.com

Citirea unui fiier (3)


finally {
if (f != null) {
// Inchidem fisierul
try {
f.close();
}
catch (IOException e) {
System.err.println("Fisierul nu poate fi
inchis!");
e.printStackTrace(); }
} // if
} //finally
}

PDF created with pdfFactory Pro trial version www.pdffactory.com

Aruncarea excepiilor (1)


l
l

A doua metod de lucru cu excepiile


Se utilizeaz clauza throws n antetul
metodelor care pot genera excepii:

[modific] TipReturnat metoda([argumente])


throws TipExceptie1, TipExceptie2, ...
{
...
}
Atentie !!!
l O metoda care nu trateaz o anumita
exceptie trebuie obligatoriu s o arunce.

PDF created with pdfFactory Pro trial version www.pdffactory.com

Aruncarea excepiilor (2)


public class CitireFisier {
public static void citesteFisier(String fis) throws
FileNotFoundException, IOException
{
FileReader f = null;
f = new FileReader(fis);
int c;
while ( (c=f.read()) != -1)
System.out.print((char)c);
f.close();
}

PDF created with pdfFactory Pro trial version www.pdffactory.com

Aruncarea excepiilor (3)


public static void main(String args[]) {
if (args.length > 0) {
try {
citesteFisier(args[0]);
}
catch (FileNotFoundException e){
System.err.println("Fisierul n-a fost gasit");
}
catch (IOException e) {
System.out.println("Eroare la citire");
}
}
else
System.out.println("Lipseste numele fisierului");
} // main
} // clasa

PDF created with pdfFactory Pro trial version www.pdffactory.com

try - finally
public static void citesteFisier (String fis) throws
FileNotFoundException, IOException
{
FileReader f = null;
try {
f = new FileReader (fis);
int c;
while ( (c=f.read()) != -1)
System.out.print((char)c);
}
finally {
if (f!=null)
f.close();
}
}
public static void main (String args[]) throws
FileNotFoundException, IOException {
citesteFisier(args[0]);
}

PDF created with pdfFactory Pro trial version www.pdffactory.com

Instruciunea throw
Aruncarea explicit de excepii:
Exemplu:
throw new IOException("Exceptie I/O");
l

Sau:
if (index >= vector.length)
throw new
ArrayIndexOutOfBoundsException();
Sau:
catch(Exception e) {
System.out.println ("A aparut o exceptie);
throw e;
}

PDF created with pdfFactory Pro trial version www.pdffactory.com

Avantajele tratrii excepiilor

1. Separarea codului
2. Propagarea erorilor
3. Gruparea erorilor dup tip.

PDF created with pdfFactory Pro trial version www.pdffactory.com

Separarea codului (1)

citesteFisier {
deschide fiierul;
determin dimensiunea fiierului;
aloc memorie;
citete fiierul n memorie;
nchide fiierul;
}

PDF created with pdfFactory Pro trial version www.pdffactory.com

Separarea codului (2)


Cod tradiional (spaghetti):
int citesteFisier() {
int codEroare = 0;
deschide fisierul;
if (fisierul s-a deschis) {
determina dimensiunea fisierului;
if (s-a determinat dimensiunea) {
aloca memorie;
if (s-a alocat memorie) {
citeste fisierul in memorie;
if (nu se poate citi din fisier) {
codEroare = -1;
}
} else { ...
}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}
return codEroare; }

PDF created with pdfFactory Pro trial version www.pdffactory.com

Separarea codului (3)


int citesteFisier() {
try {
deschide fiierul;
determin dimensiunea fiierului;
aloc memorie;
citete fiierul n memorie;
nchide fiierul;
}
catch (fiierul nu s-a deschis)
{trateaz eroarea;}
catch (nu s-a determinat dimensiunea)
{trateaz eroarea;}
catch (nu s-a alocat memorie)
{trateaz eroarea}
catch (nu se poate citi din fiier)
{trateaz eroarea;}
catch (nu se poate nchide fiierul)
{trateaz eroarea;}
}

PDF created with pdfFactory Pro trial version www.pdffactory.com

Propagarea erorilor
int metoda1() {
try {
metoda2();
}
catch (TipExceptie e) {
//proceseazaEroare;
}
...
}
int metoda2() throws TipExceptie {
metoda3();
...
}
int metoda3() throws TipExceptie {
citesteFisier();
...
}

PDF created with pdfFactory Pro trial version www.pdffactory.com

Gruparea erorilor dup tipul lor


Fiecare tip de excepie este descris de o clas.
l Clasele sunt organizate ierarhic.
try {
FileReader f = new FileReader("input.dat");
// Exceptie posibil: FileNotFoundException
}
catch (FileNotFoundException e) {
// Exceptie specific provocat de absena
// fiierului input.dat
} // sau
catch (IOException e) {
// Exceptie generic provocat de o operatie IO
} // sau
catch (Exception e) {
// Cea mai generic excepie soft
} //sau
catch (Throwable e) {
// Superclasa excepiilor
}
l

PDF created with pdfFactory Pro trial version www.pdffactory.com

Ierarhia claselor ce descriu


excepii

Metode:
getMessage
printStackTrace
toString

PDF created with pdfFactory Pro trial version www.pdffactory.com

Excepii la execuie
RuntimeException
l ArithmeticException
l NullPointerException
l ArrayIndexOutOfBoundsException

int v[] = new int[10];


try {
v[10] = 0;
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Atentie la indecsi!");
e.printStackTrace();
} // Corect, programul continu
v[11] = 0;
/* Nu apare eroare la compilare dar apare exceptie la
executie si programul va fi terminat.*/
System.out.println("Aici nu se mai ajunge...");

PDF created with pdfFactory Pro trial version www.pdffactory.com

ArithmeticException
l

mprirea la 0 va genera o excepie doar


dac tipul numerelor mprite este aritmetic
ntreg.
n cazul tipurilor reale (float i double) nu va
fi generat nici o excepie, ci va fi furnizat ca
rezultat o constant care poate fi, funcie de
operaie, Infinity, -Infinity, sau Nan.

int a=1, int b=0;


System.out.println(a/b); // Exceptie la executie!
double x=1, y=-1, z=0;
System.out.println(x/z); // Infinity
System.out.println(y/z); // -Infinity
System.out.println(z/z); // NaN

PDF created with pdfFactory Pro trial version www.pdffactory.com

Crearea propriilor excepii (1)


public class ExceptieProprie extends
Exception {
public ExceptieProprie(String mesaj) {
super(mesaj);
/* Apeleaza constructorul superclasei
Exception */
}
}
Exemplu:
class ExceptieStiva extends Exception {
public ExceptieStiva(String mesaj) {
super(mesaj);
}
}

PDF created with pdfFactory Pro trial version www.pdffactory.com

Crearea propriilor excepii (2)


class Stiva {
int elemente[] = new int[100];
int n=0; //numarul de elemente din stiva
public void adauga(int x) throws ExceptieStiva {
if (n==100)
throw new ExceptieStiva("Stiva este plina!");
elemente[n++] = x;
}
public int scoate() throws ExceptieStiva {
if (n==0)
throw new ExceptieStiva("Stiva este
goala!");
return elemente[--n];
}
}

PDF created with pdfFactory Pro trial version www.pdffactory.com

Fluxuri

Programare Orientat pe Obiecte

Fluxuri
Ce sunt fluxurile ?
Clasificare, ierarhie
Fluxuri primitive
Fluxuri de procesare
Intrri i ieiri formatate
Fluxuri standard de intrare i ieire
Analiza lexical
Clase independente
(RandomAccessFile, File)

Ce sunt fluxurile? (1)


Schimb de informaii cu mediul extern
l Canal de comunicaie ntre dou
procese
l

Seriale, pe 8 sau 16 bii


Productor: proces care descrie o surs
extern de date
Consumator: proces care descrie o
destinaie extern pentru date
Unidirecionale, de la productor la
consumator
Un singur proces productor
Un singur proces consumator

Ce sunt fluxurile? (2)

Un flux care citete date se numete flux de


intrare.
Un flux care scrie date se numete flux de
ieire.

Ce sunt fluxurile? (3)


Pachetul care ofer suport pentru operaiile
de intrare/ieire: java.io

Schema general de utilizare a fluxurilor:

deschide canal comunicatie


while (mai sunt informatii) {
citeste/scrie informatie;
}
inchide canal comunicatie;

Clasificarea fluxurilor
Dup direcia canalului de comunicaie:
fluxuri de intrare (citire)
fluxuri de ieire (scriere)

Dup tipul de date:


fluxuri de octei (8 bii)
fluxuri de caractere (16 bii)

Dup aciunea lor:


fluxuri primare (se ocup efectiv cu
citirea/scrierea datelor)
fluxuri pentru procesare

Ierarhia claselor pentru lucrul cu fluxuri


Caractere:
Reader

FileReader, BufferedReader,...

Writer

FileWriter, BufferedWriter,...

Octei:
InputStream

FileInputStream, BufferedInputStream..

OutputStream

FileOutputStream,
BufferedOutputStream..

Metode comune fluxurilor


Metodele comune sunt definite n
superclasele abstracte corespunztoare:

l
l

Reader
int read()
int read(char buf[])

Writer
void write()
void write(char buf[])

...

InputStream
int read()
int read(byte buf[])

OutputStream
void write()
void write(byte buf[])
void write(String str)

Inchiderea oricrui flux: close.


Excepii: IOException sau derivate.

Fluxuri primitive
In funcie de tipul sursei datelor:
l Fiier
FileReader, FileWriter,
FileInputStream, FileOutputStream
l Memorie
CharArrayReader, CharArrayWriter,
ByteArrayInputStream,
ByteArrayOutputStream,
StringReader, StringWriter
l Pipe
PipedReader, PipedWriter,
PipedInputStream, PipedOutputStream

folosite pentru a canaliza ieirea unui program


sau fir de execuie ctre intrarea altui program
sau fir de execuie.

Crearea unui flux primitiv


FluxPrimitiv numeFlux =new FluxPrimitiv
(dispozitivExtern);
l

crearea unui flux de intrare pe caractere

FileReader in = new FileReader("fisier.txt");


l

crearea unui flux de iesire pe caractere

FileWriter out = new FileWriter("fisier.txt");


l

crearea unui flux de intrare pe octeti

FileInputStream in =new FileInputStream("fisier.dat");


l

crearea unui flux de iesire pe octeti

FileOutputStream out =new


FileOutputStream("fisier.dat");

Fluxuri de procesare (1)


l

responsabile cu preluarea datelor de la un


flux primitiv i procesarea acestora pentru a
le oferi ntr-o alt form, mai util dintr-un
anumit punct de vedere.

Bufferizare
BufferedReader, BufferedWriter
BufferedInputStream,
BufferedOutputStream
Conversie octei-caractere/caractere-octei
InputStreamReader
OutputStreamWriter
Concatenare
SequenceInputStream
Serializare
ObjectInputStream, ObjectOutputStream

Fluxuri de procesare (2)


Conversie tipuri de date de tip primitiv ntr-un
format binar, independent de maina pe
care se lucreaz
DataInputStream, DataOutputStream
Numrare
LineNumberReader,
LineNumberInputStream
Citire n avans
PushbackReader, PushbackInputStream
Afiare
PrintWriter, PrintStream

Crearea unui flux de procesare


FluxProcesare numeFlux = new
FluxProcesare(fluxPrimitiv);
crearea unui flux de intrare printr-un buffer
BufferedReader in = new BufferedReader(new
FileReader("fisier.txt"));
l

//echivalent cu:
FileReader fr = new FileReader("fisier.txt");
BufferedReader in = new BufferedReader(fr);
crearea unui flux de iesire printr-un buffer
BufferedWriter out = new BufferedWriter(new
FileWriter("fisier.txt")));
l

//echivalent cu:
FileWriter fo = new FileWriter("fisier.txt");
BufferedWriter out = new BufferedWriter(fo);

Fluxuri pentru lucrul cu fiiere


FileReader, FileWriter - caractere
FileInputStream, FileOutputStream - octeti

Citirea i scrierea cu buffer


l
l

BufferedReader, BufferedWriter
BufferedInputStream, BufferedOutputStream

Introduc un buffer (zon de memorie) n


procesul de citire/scriere a informaiilor.

BufferedOutputStream out = new BufferedOutputStream


(new FileOutputStream("out.dat"), 1024);
//1024 este dimensiunea bufferului

Scopul: eficiena
- Scade numrul de accesri ale dispozitivului
extern
- Crete viteza de execuie

Metoda flush
- golete explicit bufferul
BufferedWriter out = new BufferedWriter(new
FileWriter("out.dat"), 1024);
//am creat un flux cu buffer de 1024 octeti
for(int i=0; i<1000; i++) out.write(i);
//bufferul nu este plin, in fisier nu s-a scris nimic
out.flush();
//bufferul este golit, datele se scriu in fisier

Metoda readLine
BufferedReader br = new
BufferedReader(new FileReader("in"));
String linie;
while ((linie = br.readLine()) != null) {
...
//proceseaza linie
}
br.close();

DataInputStream i
DataOutputStream
l
l

l
l

un flux nu mai este vzut ca o nsiruire de octei, ci


de date primitive.
scrierea datelor se face n format binar, ceea ce
nseamn c un fiier n care au fost scrise informaii
folosind metode writeX nu va putea fi citit dect prin
metode readX.
transformarea unei valori n format binar - serializare.
permit serializarea tipurilor primitive i a irurilor de
caractere.

Intrri formatate: java.util.Scanner

Scanner s=new Scanner(System.in);


String nume = s.next();
int varsta = s.nextInt();
double salariu = s.nextDouble();
s.close();

Ieiri formatate
PrintStream i PrintWriter :
print, println
format, printf
System.out.printf("%s %8.2f %2d %n", nume,
salariu, varsta);
l

Formatarea irurilor de caractere se


bazeaz pe clasa java.util.Formatter.

Fluxuri standard de intrare i ieire


System.in - InputStream
System.out - PrintStream
System.err - PrintStream
Afiarea informaiilor pe ecran:
System.out.print (argument);
System.out.println(argument);
System.out.printf (format, argumente...);
System.out.format (format, argumente...);
l

Afiarea erorilor:
catch(Exception e) {
System.err.println("Exceptie:" + e);
}
l

Citirea datelor de la tastatur (1)


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

Clasa DataInputStream
DataInputStream stdin = new DataInputStream(
System.in);
System.out.print("Introduceti o linie:");
String linie = stdin.readLine()
System.out.println(linie);
l

Clasa java.util.Scanner (1.5)


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

Citirea datelor de la tastatur (2)


l

Redirectarea fluxurilor standard: stabilirea


unei alte surse dect tastatura pentru citirea
datelor, respectiv alte destinaii dect ecranul
pentru cele dou fluxuri de ieire.

setIn(InputStream) - redirectare intrare


setOut(PrintStream) - redirectare ieire
setErr(PrintStream) - redirectare erori

l
l

PrintStream fis = new PrintStream( new


FileOutputStream("rezultate.txt")));
System.setOut(fis);
PrintStream fis = new PrintStream(new
FileOutputStream("erori.txt")));
System.setErr(fis);

Analiza lexical pe fluxuri:


StreamTokenizer

Clasa RandomAccessFile
permite accesul nesecvenial (direct) la
coninutul unui fiier;
este o clas de sine stttoare, subclas
direct a clasei Object;
se gsete n pachetul java.io;
ofer metode de tipul readX, writeX;
permite att citirea ct i scriere din/n fiiere
cu acces direct;
permite specificarea modului de acces al
unui fiier (read-only, read-write).
RandomAccessFile f1 = new
RandomAccessFile("fisier.txt", "r");
//deschide un fisier pentru citire

RandomAccessFile f2 =new
RandomAccessFile("fisier.txt", "rw");
//deschide un fisier pentru scriere si citire

Clasa RandomAccessFile (2)


l

Program pentru afiarea pe ecran a liniilor dintr-un fiier


text, fiecare linie precedat de numrul liniei i de un
spaiu.

import java.io.*;
class A{
public static void main(String arg[]) throws
IOException{
RandomAccessFile raf=new RandomAccessFile(
arg[0],"r");
String s;
int i=1;
while( (s=raf.readLine())!=null) {
System.out.println(i+" "+s);
i++;
}
raf.close();
}
}

Clasa File (1)


l

l
l
l

Clasa File nu se refer doar la un fiier ci poate


reprezenta fie un fiier anume, fie mulimea
fiierelor dintr-un director.
Utilitatea clasei File const n furnizarea unei
modaliti de a abstractiza dependenele cilor
i numelor fiierelor fa de maina gazd
Ofer metode pentru testarea existenei,
tergerea, redenumirea unui fiier sau director,
crearea unui director, listarea fiierelor dintr-un
director, etc.
Constructorii fluxurilor pentru fiiere accept ca
argument obiecte de tip File:
File f = new File("fisier.txt");
FileInputStream in = new FileInputStream(f);
String[ ] list()
File[ ] listFiles()
String getAbsolutePath()

Clasa File (2)


l

Listare fiiere dintr-un director dat, cu


indentare, recursiv, n subdirectoare

import java.io.*;
import java.util.*;
class Dir{
public static void main (String arg[]) throws
IOException {
String dname =".";
if (arg.length ==1) dname=arg[0];
Dir d= new Dir();
d.dirlist(new File(dname)," ");
}

Clasa File (3)


public void dirlist (File d, String sp) throws IOException
{
String [] files=d.list(); //lista numelor din obiectul d
if (files ==null ) return;
String path =d.getAbsolutePath();
//calea completa spre obiectul d
for(int i=0;i<files.length;i++){
File f = new File(d+"\\"+files[i]);
if (f.isDirectory()) {
System.out.println (sp+path+"\\"+files[i]);
dirlist (f,sp+" ");
}
else System.out.println (sp+path+"\\"+ files[i]);
}
}
}

Interfee

Programare Orientat pe Obiecte

Interfee
Ce este o interfa ?
Definirea unei interfee
Implementarea unei interfee
Interfee i clase abstracte
Motenire multipl prin interfee
Utilitatea interfeelor
Transmiterea metodelor ca parametri
Compararea obiectelor
Adaptori

Ce este o interfa ?
Colecie de metode abstracte i declaraii de
constante
Definete un set de metode dar nu specific
nici o implementare pentru ele.
Duce conceptul de clas abstract cu un pas
nainte prin eliminarea oricror implementri
de metode
Separarea modelului de implementare
Protocol de comunicare
O clas care implementeaz o interfa
trebuie obligatoriu s specifice implementri
pentru toate metodele interfeei, supunnduse aadar unui anumit comportament.
Definete noi tipuri de date
Clasele pot implementa interfee

Definirea unei interfee


[public] interface NumeInterfata
[extends SuperInterfata1, SuperInterfata2...]
{
/* Corpul interfetei:
Declaraii de constante
Declaraii de metode abstracte
*/
}

Corpul unei interfee poate conine:


l constante: acestea pot fi sau nu declarate cu
modificatorii public, static i final care sunt
implicii, nici un alt modificator neputnd aprea
n declaraia unei variabile dintr-o interfa.
Constantele unei interfee trebuie obligatoriu
iniializate.
l metode fr implementare: acestea pot fi sau
nu declarate cu modificatorul public, care este
implicit; nici un alt modificator nu poate aprea
n declaraia unei metode a unei interfee.

Definirea unei interfee


Atenie!
Variabilele unei interfee sunt implicit publice chiar
dac nu sunt declarate cu modificatorul public.
Variabilele unei interfee sunt implicit constante chiar
dac nu sunt declarate cu modificatorii static i final.
Metodele unei interfee sunt implicit publice chiar
dac nu sunt declarate cu modificatorul public.
interface Exemplu {
int MAX = 100; // echivalent cu:
public static final int MAX = 100;
int MAX; // Incorect, lipseste initializarea
private int x = 1; // Incorect, modificator nepermis
void metoda(); // Echivalent cu:
public void metoda();
protected void metoda2();
// Incorect, modificator nepermis
}

Implementarea unei interfee


class NumeClasa implements NumeInterfata
sau:
class NumeClasa implements Interfata1, Interfata2, ...
l O clas care implementeaz o interfa trebuie
obligatoriu s specifice cod pentru toate metodele
interfeei.
l O clas poate avea i alte metode i variabile
membre n afar de cele definite n interfa.
l Implementarea unei interfee poate s fie i o clas
abstract.
l Spunem c un obiect are tipul X, unde X este o
interfa, dac acesta este o instan a unei
clase ce implementeaz interfaa X.
l Atenie! Modificarea unei interfee implic
modificarea tuturor claselor care implementeaz
acea interfa.

Exemplu: implementarea unei


stive (1)
Interfaa ce descrie stiva:
public interface Stack {
void push ( Object item ) throws StackException ;
void pop () throws StackException ;
Object peek () throws StackException ;
boolean empty ();
String toString ();
}

Clasa ce definete o excepie proprie StackException:


public class StackException extends Exception {
public StackException () {
super ();
}
public StackException ( String msg) {
super (msg);
}
}

Exemplu: implementarea unei


stive folosind un vector
public class StackImpl1 implements Stack {
private Object items []; // Vect. ce contine ob.
private int n=0; // Nr. curent de elem. din stiva
public StackImpl1 ( int max ) { // Constructor
items = new Object [ max ];
}
public StackImpl1 () {
this (100) ;
}
public void push ( Object item ) throws
StackException {
if (n == items . length )
throw new StackException (" Stiva e
plina !");
items [n++] = item ;
}

Exemplu: implementarea unei


stive folosind un vector (2)
public void pop () throws StackException {
if ( empty ())
throw new StackException (" Stiva e vida !");
items [--n] = null ;
}
public Object peek () throws StackException {
if ( empty ())
throw new StackException (" Stiva e vida !");
return items [n -1];
}
public boolean empty () {
return n ==0 ;
}
public String toString () {
String s="";
for (int i=n -1; i >=0; i --)
s += items [i] + " ";
return s;
}
}

Exemplu: implementarea unei


stive folosind o lista inlantuita (1)
public class StackImpl2 implements Stack {
class Node { // Clasa interna ce reprezinta un nod al listei
Object item ; // informatia din nod
Node link ; // legatura la urmatorul nod
Node ( Object item , Node link ) {
this . item = item ;
this . link = link ;
}
}
private Node top= null ; // Referinta la varful stivei
public void push ( Object item ) {
Node node = new Node (item , top);
top = node ;
}
public void pop () throws StackException {
if ( empty ())
throw new StackException (" Stiva este vida !");
top = top . link ;
}

Exemplu: implementarea unei


stive folosind o lista inlantuita (2)
public Object peek () throws StackException {
if ( empty ())
throw new StackException (" Stiva este vida !");
return top. item ;
}
public boolean empty () {
return (top == null );
}
public String toString () {
String s="";
Node node = top;
while ( node != null ) {
s += node . item + " ";
node = node . link ;
}
return s;
}
}

Observaii
l

Dei metoda push din interfa declar


aruncarea unor excepii de tipul
StackException, nu este obligatoriu ca
metoda din clas s specifice i ea acest
lucru, atta timp ct nu genereaz excepii
de acel tip.
Invers este ns obligatoriu.

Folosirea stivei:
public class TestStiva {
public static void afiseaza ( Stack s) {
System . out. println (" Continutul stivei este : " + s);
}
public static void main ( String args []){
try {
Stack s1 = new StackImpl1 ();
s1. push ("a");
s1. push ("b");
afiseaza (s1);
Stack s2 = new StackImpl2 ();
s2. push ( new Integer (1));
s2. push ( new Double (3.14) );
afiseaza (s2);
} catch ( StackException e) {
System . err. println (" Eroare la lucrul cu stiva!");
e. printStackTrace ();
}
}
}

Interfee i clase abstracte


O clas abstract nu ar putea nlocui o interfa ?
l Unele clase sunt forate s extind o anumit clas
(de exemplu orice applet trebuie s fie subclasa a
clasei Applet) i nu ar mai putea sa extind o alt
clas. Fr folosirea interfeelor nu am putea fora
clasa respectiv s respecte diverse tipuri de
protocoale.
l Extinderea unei clase abstracte foreaz o relaie
ntre clase;
l Implementarea unei interfee specific doar
necesitatea implementrii unor anumite metode.
l Interfeele i clasele abstracte nu se exclud, fiind
folosite mpreun:
List
AbstractList
LinkedList, ArrayList
l

Motenire multipl prin interfee


l
l
l

class NumeClasa extends ClasaUnica implements


Interfata1, Interfata2, ...
interface NumeInterfata extends Interfata1, Interfata2,
...
Ierarhia interfeelor este independent de ierarhia
claselor care le implementeaz.

interface I1 {
int a=1;
void metoda1();
}
interface I2 {
int b=2;
void metoda2();
}
class C implements I1, I2 {
public void metoda1() {...}
public void metoda2() {...}
}

Ambiguiti
interface I1 {
int x=1;
void metoda();
}
interface I2 {
int x=2;
void metoda(); //corect
//int metoda(); //incorect
}
class C implements I1, I2 {
public void metoda() {
System.out.println(I1.x); //corect
System.out.println(I2.x); //corect
System.out.println(x); //ambiguitate
}
}

Utilitatea interfeelor
Definirea unor similariti ntre clase independente.
Impunerea unor specificaii: asigur c toate clasele
care implementeaz o interfa pun la dispoziie
metodele specificate n interfa - de aici rezult
posibilitatea implementrii unor clase prin mai multe
modaliti i folosirea lor ntr-o manier unitar;
Definirea unor grupuri de constante
Transmiterea metodelor ca parametri
l

Crearea grupurilor de constante:

public interface Luni {


int IAN=1, FEB=2, ..., DEC=12;
}
...
if (luna < Luni.DEC)
luna ++
else
luna = Luni.IAN;

Transmiterea metodelor ca
parametri
interface Functie {
void executa(Nod u);
}
class Graf {
void explorare(Functie f) {
...
if (explorarea a ajuns in nodul v) f.executa(v);
}
}
//Definim diverse functii
class AfisareRo implements Functie {
public void executa(Nod v) {
System.out.println("Nodul curent este: " + v);
}
}
class AfisareEn implements Functie {
public void executa(Nod v) {
System.out.println("Current node is: " + v);
}
}

Transmiterea metodelor ca
parametri (2)
public class TestCallBack {
public static void main(String args[]) {
Graf G = new Graf();
Functie f1 = new AfisareRo();
G.explorare(f1);
Functie f2 = new AfisareEn();
G.explorare(f2);
/* sau mai simplu:
G.explorare(new AfisareRo());
G.explorare(new AfisareEn());
*/
}
}

Interfaa FilenameFilter
l
l

folosit pentru a crea filtre pentru fiiere


sunt primite ca argumente de metode care listeaz
coninutul unui director, cum ar fi metoda list a
clasei File.
putem spune c metoda list primete ca argument o
alt funcie care specific dac un fiier va fi
returnat sau nu (criteriul de filtrare).
Exemplu: Listarea fiierelor din directorul curent
care au anumit extensie primit ca argument.
Dac nu se primete nici un argument , vor fi listate
toate.

import java .io .*;


class Listare {
public static void main ( String [] args ) {
try {
File director = new File (".");
String [] list ;

Interfaa FilenameFilter: exemplu


if ( args . length > 0)
list = director . list ( new Filtru ( args [0]) );
else
list = director . list ();
for (int i = 0; i < list . length ; i ++)
System . out. println ( list [i]);
} catch ( Exception e) { e. printStackTrace (); }
}
}
class Filtru implements FilenameFilter {
String extensie ;
Filtru ( String extensie ) {
this . extensie = extensie ;
}
public boolean accept ( File dir , String nume ) {
return ( nume . endsWith ("." + extensie ) );
}
}

Folosirea claselor anonime


Clasa anonim = clas intern folosit pentru
instanierea unui singur obiect.
metoda(new Interfata() {
// Implementarea metodelor interfetei
});
Exemplu:

if (args.length > 0) {
final String extensie = args[0];
list = director.list ( new FilenameFilter() {
// Clas intern anonim
public boolean accept (File dir, String nume) {
return ( nume.endsWith("." + extensie) );
}
} );
}

Compararea obiectelor
Exemplu: Clasa Persoana (fr suport pentru comparare)
class Persoana {
private int cod ;
private String nume ;
public Persoana ( int cod , String nume ) {
this .cod = cod;
this . nume = nume ;
}
public String toString () {
return cod + " \t " + nume ;
}
}
Exemplu: Sortarea unui vector de tip referin
class Sortare {
public static void main ( String args []) {
Persoana p[] = new Persoana [3];
p[0] = new Persoana (3, " Ionescu ");
p[1] = new Persoana (1, " Vasilescu ");
p[2] = new Persoana (2, " Georgescu ");
java . util . Arrays . sort (p);
System . out. println (" Persoanele ordonate dupa cod:");
for (int i=0; i<p. length ; i++) System . out. println (p[i]);
}
}

Interfaa Comparable
Interfaa Comparable impune o ordine total asupra
obiectelor unei clase ce o implementeaz. Aceast
ordine se numete ordinea natural a clasei i este
specificat prin intermediul metodei compareTo.
Definiia interfeei este:
public interface Comparable {
int compareTo(Object o);
}
l metoda compareTo trebuie s returneze:
o valoare strict negativ: dac obiectul curent (this)
este mai mic dect obiectul primit ca argument;
zero: dac obiectul curent este egal cu obiectul primit
ca argument;
o valoare strict pozitiv: dac obiectul curent este
mai mare dect obiectul primit ca argument.

Interfaa Comparable. Exemplu


Exemplu: Clasa Persoana cu suport pentru comparare
class Persoana implements Comparable {
private int cod ;
private String nume ;
public Persoana ( int cod , String nume ) {
this .cod = cod;
this . nume = nume ;
}
public String toString () {
return cod + " \t " + nume ;
}
public boolean equals ( Object o) {
if (!( o instanceof Persoana )) return false ;
Persoana p = ( Persoana ) o;
return (cod == p.cod) && ( nume . equals (p. nume ));
}
public int compareTo ( Object o) {
if (o== null ) throw new NullPointerException ();
if (!( o instanceof Persoana ))
throw new ClassCastException ("Nu pot compara !");
Persoana p = ( Persoana ) o;
return (cod - p.cod);
}
}

Interfaa Comparator
l

In cazul n care dorim s sortm elementele unui


vector ce conine referine dup alt criteriu dect
ordinea natural a elementelor
Interfaa java.util.Comparator conine metoda
compare, care impune o ordine total asupra
elementelor unei colecii.
int compare(Object o1, Object o2);

class MyComp implements Comparator{


public int compare ( Object o1 , Object o2) {
Persoana p1 = ( Persoana )o1;
Persoana p2 = ( Persoana )o2;
return (p1. nume . compareTo (p2. nume ));
}

Arrays.sort(p, new MyComp());

Interfaa Comparator
Exemplu: Sortarea unui vector folosind un comparator
import java . util .*;
class Sortare {
public static void main ( String args []) {
Persoana p[] = new Persoana [4];
p[0] = new Persoana (3, " Ionescu ");
p[1] = new Persoana (1, " Vasilescu ");
p[2] = new Persoana (2, " Georgescu ");
p[3] = new Persoana (4, " Popescu ");
Arrays . sort (p, new Comparator () {
public int compare ( Object o1 , Object o2) {
Persoana p1 = ( Persoana )o1;
Persoana p2 = ( Persoana )o2;
return (p1. nume . compareTo (p2. nume ));
}
});
System . out. println (" Persoanele ordonate dupa nume :");
for (int i=0; i<p. length ; i++)
System . out. println (p[i]);
}
}

Adaptori
l

In cazul n care o interfa conine mai multe


metode i, la un moment dat, avem nevoie de un
obiect care implementeaz interfaa respectiv dar
nu specific cod dect pentru o singur metod, el
trebuie totui s implementeze toate metodele
interfeei, chiar dac nu specific nici un cod.
interface X {
void metoda_1();
void metoda_2();
...
void metoda_n();
}
class test implements X {
public void metoda_1() {
// Singura metoda care ne intereseaza
...
}
// Trebuie sa apara si celelalte metode chiar daca nu
//au implementare efectiva

Adaptori
public void metoda_2() {}
public void metoda_3() {}
...
public void metoda_n() {}
});
l

Un adaptor este o clas abstract care implementeaz o


anumit interfa fr a specifica cod nici unei metode a
interfeei.

public abstract class XAdapter implements X {


public void metoda_1() {}
public void metoda_2() {}
...
public void metoda_n() {}
}
functie(new XAdapter() {
public void metoda_1() {
// Singura metoda care ne intereseaza
...
}
});

Colecii

Programare Orientat pe Obiecte

Colecii
Ce sunt coleciile ?
Interfee ce descriu colecii
Implementri ale coleciilor
Folosirea eficient a coleciilor
Algoritmi polimorfici
Tipuri generice
Iteratori i enumerri

Ce sunt coleciile ?
l
l

O colecie este un obiect care grupeaz mai


multe elemente ntr-o singur unitate.
Tipul de date al elementelor dintr-o colecie
este Object.

Tipuri de date reprezentate:


vectori
liste nlnuite
stive
mulimi matematice
tabele de dispersie
dicionare, etc.

Arhitectura coleciilor
Interfee: tipuri abstracte de date ce descriu
coleciile i permit utilizarea lor independent de
detaliile implementrilor.
Implementri: implementri concrete ale interfeelor
ce descriu colecii (clase); reprezint tipuri de date
reutilizabile.
Algoritmi polimorifici: metode care efectueaz
diverse operaii utile(cutare, sortare) definite
pentru obiecte ce implementeaz interfeele ce
descriu colecii. Aceti algoritmi se numesc i
polimorfici deoarece pot fi folosii pe implementri
diferite ale unei colecii, reprezentnd elementul de
funcionalitate reutilizabil.
Avantaje:
Reducerea efortului de programare
Creterea vitezei i calitii programului

Interfee ce descriu colecii


Collection - modeleaz o colecie la nivelul cel mai
general, descriind un grup de obiecte (elementele sale).
l Map - descrie structuri de date de tip cheie valoare,
asociaz fiecarui element o cheie unic, dup care poate
fi regsit.
l

Collection
Map
Set

List
SortedMap

SortedSet

AbstractCollection
AbstractMap
AbstractSet

AbstractList

Collection
public interface Collection {
// Metode cu caracter general
int size();
boolean isEmpty();
void clear();
Iterator iterator();
// Operatii la nivel de element
boolean contains(Object element);
boolean add(Object element);
boolean remove(Object element);
// Operatii la nivel de multime
boolean containsAll(Collection c);
boolean addAll(Collection c);
boolean removeAll(Collection c);
boolean retainAll(Collection c);
// Metode de conversie in vector
Object[] toArray();

Set
Mulime n sens matematic.
l O mulime nu poate avea elemente duplicate:
nu poate conine dou obiecte o1 i o2 cu
proprietatea o1.equals(o2).
l Implementri: HashSet, LinkedHashSet i
TreeSet.
l

Set (I)
AbstractSet
(clasa abstract)

SortedSet (I)
HashSet
TreeSet

LinkedHashSet

SortedSet
mulime cu elemente sortate.
l ordonarea elementelor se face
conform ordinii lor naturale, sau
conform cu ordinea dat de un
comparator specificat la crearea
coleciei
l ordinea este meninut automat la
orice operaie efectuat asupra
mulimii.
l pentru orice dou obiecte o1, o2 ale
coleciei, apelul o1.compareTo(o2)
(sau comparator.compare(o1, o2),
dac este folosit un comparator)
trebuie s fie valid i s nu provoace
excepii

SortedSet
public interface SortedSet extends Set {
// Subliste
SortedSet subSet(Object fromElement,
Object toElement);
SortedSet headSet(Object toElement);
SortedSet tailSet(Object fromElement);
// Capete
Object first();
Object last();
Comparator comparator();
}
Implementare: TreeSet help

List
liste de elemente indexate.
l pot contine duplicate i permit un control precis
asupra poziiei unui element prin intermediul indexului
acelui element.
l exist metode pentru acces poziional, cutare i
iterare avansat.
l Implementri: ArrayList, LinkedList, Vector, Stack.
l

List (I)
AbstractList (A)
ArrayList

LinkedList

Vector

Stack

List (2)
public interface List extends Collection {
// Acces pozitional
Object get(int index);
Object set(int index, Object element);
void add(int index, Object element);
Object remove(int index);
abstract boolean addAll(int index, Collection c);
// Cautare
int indexOf(Object o);
int lastIndexOf(Object o);
// Iterare
ListIterator listIterator();
ListIterator listIterator(int index);
// Extragere sublista
List subList(int from, int to);
}

Map
l

structuri de tip: cheie element, ce asociaz


fiecarui element o cheie unic, dup care
poate fi regsit.
nu pot conine chei duplicate i fiecare cheie
este asociat unui singur element.

public interface Map {


// Metode cu caracter general
int size();
boolean isEmpty();
void clear();
// Operatii la nivel de element
Object put(Object key, Object value);
Object get(Object key);
Object remove(Object key);
boolean containsKey(Object key);
boolean containsValue(Object value);

Map(2)
// Operatii la nivel de multime
void putAll(Map t);
// Vizualizari ale colectiei
public Set keySet();
public Collection values();
public Set entrySet();
// Interfata pentru manipularea unei
inregistrari
public interface Entry {
Object getKey();
Object getValue();
Object setValue(Object value);

}
}
Implementri: HashMap, TreeMap i
Hashtable.

SortedMap
Mulimea cheilor este sortat conform ordinii
naturale sau unui comparator.
public interface SortedMap extends Map {
// Extragerea de subtabele
SortedMap subMap(Object fromKey, Object
toKey);
SortedMap headMap(Object toKey);
SortedMap tailMap(Object fromKey);
// Capete
Object first();
Object last();
// Comparatorul folosit pentru ordonare
Comparator comparator();
}
l Implementare: TreeMap - help

Implementri ale coleciilor


< Implementare >< Interfata >
Interfaa
Set
SortedSet

Clasa
HashSet, LinkedHashSet
TreeSet

List

ArrayList, LinkedList,Vector, Stack

Map
HashMap, Hashtable
TreeMap
SortedMap
l Organizare ierarhic
AbstractCollection - AbstractSet, AbstractList HashSet, TreeSet... Vector-Stack
AbstractMap - HashMap, TreeMap, HashTable
In vechea ierarhie:
Dictionary - Hashtable Properties
l se observ existena unor clase care ofer aceeai
funcionalite, cum ar fi ArrayList i Vector, HashMap i
Hashtable.

Caracteristici comune
permit elementul null
sunt serializabile
au definit metoda clone
au definit metoda toString
permit crearea de iteratori
au att constructor fr argumente ct
i un constructor care accept ca
argument o alt colecie
exceptnd clasele din arhitectura
veche, nu sunt sincronizate.

Folosirea eficient a coleciilor


ArrayList sau LinkedList ?
import java . util .*;
public class TestEficienta {
final static int N = 100000;
public static void testAdd ( List lst) {
long t1 = System . currentTimeMillis ();
for (int i=0; i < N; i++)
lst.add (new Integer (i));
long t2 = System . currentTimeMillis ();
System . out. println ("Add: " + (t2 - t1));
}
public static void testGet ( List lst) {
long t1 = System . currentTimeMillis ();
for (int i=0; i < N; i++)
lst.get (i);
long t2 = System . currentTimeMillis ();
System . out. println ("Get: " + (t2 - t1));
}
l

ArrayList sau LinkedList ?


public static void testRemove ( List lst ) {
long t1 = System . currentTimeMillis ();
for (int i=0; i < N; i++)
lst. remove (0);
long t2 = System . currentTimeMillis ();
System . out. println (" Remove : " + (t2 - t1));
}
public static void main ( String args []) {
System . out. println (" ArrayList ");
List lst1 = new ArrayList ();
testAdd ( lst1 );
testGet ( lst1 );
testRemove ( lst1 );
System . out. println (" LinkedList ");
List lst2 = new LinkedList ();
testAdd ( lst2 );
testGet ( lst2 );
testRemove ( lst2 );
}
}

ArrayList sau LinkedList ?

add
get
remove

ArrayList
0.12
0.01
12.05

LinkedList
0.14
87.45
0.01

Concluzii:
exist diferene substaniale n reprezentarea
i comportamentul diferitelor implementri

alegerea unei anumite clase pentru


reprezentarea unei mulimi de elemente trebuie
s se fac n funcie de natura problemei ce
trebuie rezolvat.
l

Algoritmi polimorfici
Metode definite n clasa Collections:
cutare, sortare, etc.

Caracteristici comune:
sunt metode de clas (statice);
au un singur argument de tip colecie;
apelul lor general va fi de forma:
Collections.algoritm(colectie,[argumente]);
majoritatea opereaz pe liste dar i
pe colecii arbitrare.

Exemple de algoritmi
sort
shuffle
binarySearch
reverse
fill
copy
min
max
swap
enumeration
unmodifiableTipColectie
synchronizedTipColectie

Tipuri generice
Tipizarea elementelor unei colecii:
TipColectie < TipDeDate >
// Inainte de 1.5
ArrayList list = new ArrayList();
list.add(new Integer(123));
int val = ((Integer)list.get(0)).intValue();
// Dupa 1.5, folosind tipuri generice
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(new Integer(123));
int val = list.get(0).intValue();
// Dupa 1.5, folosind si autoboxing
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(123);
int val = list.get(0);
l Avantaje: simplitate, control (eroare la compilare
vs. ClassCastException)
l

Iteratori i enumerri
l
l

Parcurgerea secvenial a unei colecii, indiferent dac


este indexat sau nu.
Toate clasele care implementeaz colecii au metode ce
returneaz o enumerare sau un iterator pentru
parcurgerea elementelor lor.
Deoarece funcionalitatea interfeei Enumeration se
regsete n Iterator, aceasta din urm este preferat n
noile implementri ale coleciilor.

Enumeration:
// Parcurgerea elementelor unui vector v
Enumeration e = v.elements();
while (e.hasMoreElements()) {
System.out.println(e.nextElement());
}
// sau, varianta mai concisa
for(Enumeration e=v.elements(); e.hasMoreElements();){
System.out.println(e.nextElement());
}

Iterator, ListIterator
Iterator: hasNext, next, remove
// Parcurgerea elementelor unui vector si eliminarea
elementelor nule
for (Iterator it = v.iterator(); it.hasNext();) {
Object obj = it.next();
if (obj == null) it.remove();
}
l

ListIterator: hasNext, hasPrevious, next, previous,


remove, add, set
// Parcurgerea elementelor unui vector si inlocuirea
elementelor nule cu 0
for (ListIterator it = v.listIterator(); it.hasNext();) {
Object obj = it.next();
if (obj == null) it.set(new Integer(0));
}
l

Folosirea unui iterator


import java . util .*;
class TestIterator {
public static void main ( String args []) {
ArrayList a = new ArrayList ();
// Adaugam numerele de la 1 la 10
for (int i=1; i <=10; i++) a.add(new Integer (i));
// Amestecam elementele colectiei
Collections . shuffle (a);
System . out. println (" Vectorul amestecat : " + a);
// Parcurgem vectorul
for ( ListIterator it=a. listIterator (); it. hasNext (); ) {
Integer x = ( Integer ) it. next ();
// Daca elementul curent este par , il facem 0
if (x. intValue () % 2 == 0) it. set( new Integer (0));
}
System . out. print (" Rezultat : " + a);
}
}

Varianta simplificat (1.5)


Atenie!
l Deoarece coleciile sunt construite peste tipul de date
Object, metodele de tip next sau prev ale iteratorilor
vor returna tipul Object, fiind responsabilitatea noastr
de a face conversie (cast) la alte tipuri de date, dac
este cazul.
ArrayList<Integer> list=new ArrayList<Integer>();
for (Iterator i = list.iterator(); i.hasNext();) {
Integer val=(Integer)i.next();
// Proceseaza val
...
}
sau:
ArrayList<Integer> list=new ArrayList<Integer>();
for (Integer val : list) {
// Proceseaza val
...
}

Exemplu
1. S se defineasc o clas MyArray" pentru vectori
de obiecte care nu se extind dinamic i o clas
iterator pe acest vector care s implementeze
interfaa "Enumeration". Program pentru crearea
unui obiect MyArray" prin adugri succesive de
iruri i afiarea lui folosind un obiect iterator. Clasa
MyArray" are un constructor cu argument ntreg
(dimensiune vector) i metodele:
add(Object): adugare obiect la sfrit
elements(): creare iterator pentru acest vector
get(int): obiect dintr-o poziie data
size(): dimensiune vector
toString: ir cu elementele din vector.

Rezolvare
import java.util.*;
class MyArray {
private Object v[];
private int n,nmax;
public MyArray (int nmax) {
this.nmax=nmax;
n=0;
v= new Object[nmax];
}
public void add (Object e) {
if ( n < nmax)
v[n++]=e;
}

Rezolvare
public Enumeration elements() {
return new ArrayEnum(this);
}
public String toString () {
String s="";
for (int i=0;i<n;i++)
s=s+v[i]+" ";
return s;
}
public int size() {
return n;
}
public Object get(int i) {
return v[i];
}
}

Rezolvare
// clasa iterator pentru vectori
class ArrayEnum implements Enumeration {
private int i;
private MyArray a;
ArrayEnum (MyArray a) {
this.a =a;
i=0;
}
public Object nextElement() {
return a.get(i++);
}
public boolean hasMoreElements() {
return i < a.size();
}
}

Rezolvare
class ArrayDemo {
// afisare prin enumerare
public static void main ( String av[]) {
MyArray a = new MyArray(10);
for (int i=1;i<11;i++)
a.add(""+i);
Enumeration it = a.elements();
while (it.hasMoreElements())
System.out.print (it.nextElement()+",");
System.out.println();
System.out.println(a);
}
}

Interfaa grafic cu
utilizatorul - AWT

Programare Orientat pe Obiecte

Interfaa grafic cu utilizatorul


Modelul AWT
Componentele AWT
Gestionarea poziionrii
Gruparea componentelor
Tratarea evenimentelor
Tipuri de evenimente
Adaptori i clase anonime
Folosirea ferestrelor

GUI Interfaa grafic cu


utilizatorul
Comunicarea vizual ntre un program
i utilizatori.
AWT(Abstract Windowing Toolkit)
Swing - parte din JFC (Java Foundation
Classes) Sun, Netscape i IBM
Etapele crerii unei aplicaii:
Design
Crearea unei suprafete de afiare
Crearea i asezarea componentelor
Funcionalitate
Definirea unor aciuni
Ascultarea evenimentelor

Modelul AWT
l

Pachete:
java.awt, java.awt.event
Obiectele grafice:
Component, MenuComponent.
Suprafee de afiare:
Container
Gestionari de poziionare:
LayoutManager
Evenimente:
AWTEvent

Exemplu: O fereastr cu dou


butoane
import java . awt .*;
public class ExempluAWT1 {
public static void main ( String args []) {
// Crearea ferestrei - un obiect de tip Frame
Frame f = new Frame ("O fereastra ");
// Setarea modului de dipunere a componentelor
f. setLayout (new FlowLayout ());
// Crearea celor doua butoane
Button b1 = new Button ("OK");
Button b2 = new Button (" Cancel ");
// Adaugarea butoanelor
f.add(b1);
f.add(b2);
f. pack ();
// Afisarea fereastrei
f. show ();
}
}

Componentele AWT
orice obiect care poate avea o reprezentare
grafic i care poate interaciona cu
utilizatorul.
Button
Canvas
Checkbox, CheckBoxGroup;
Choice
Container
Label
List
Scrollbar
TextComponent
TextField
TextArea

Componente grafice

Componente grafice

Componente grafice

Componente grafice

Componente grafice

Proprieti comune
Poziie
getLocation, getX, getY, getLocationOnScreen
setLocation, setX, setY
Dimensiuni
getSize, getHeight, getWidth
setSize, setHeight, setWidth
Dimensiuni i poziie
getBounds
setBounds
Culoare (text i fundal)
getForeground, getBackground
setForeground, setBackground
Font
getFont
setFont
Vizibilitate
setVisible
isVisible
Interactivitate
setEnabled
isEnabled

Suprafee de afiare
l
l

un container este folosit pentru a aduga


componente pe suprafaa lui
Container superclasa pentru suprafee de afiare
Window
Frame - ferestre standard
Dialog - ferestre de dialog
Panel, Applet
ScrollPane - derulare

Metode comune:
add
remove
setLayout
getInsets
validate

Exemplu
Frame f = new Frame("O fereastra");
// Adaugam un buton direct pe fereastra
Button b = new Button("Hello");
f.add(b);
// Adaugam doua componente pe un panel
Label et = new Label("Nume:");
TextField text = new TextField();
Panel panel = new Panel();
panel.add(et);
panel.add(text);
// Adaugam panel-ul pe fereastra
// si, indirect, cele doua componente
f.add(panel);

Gestionarea poziionrii
Exemplu: Poziionarea a 5 butoane

import java . awt .*;


public class TestLayout {
public static void main ( String args []) {
Frame f = new Frame (" Grid Layout ");
f. setLayout (new GridLayout (3, 2));
Button b1 = new Button (" Button 1");
Button b2 = new Button ("2");
Button b3 = new Button (" Button 3");
Button b4 = new Button ("Long - Named Button 4");
Button b5 = new Button (" Button 5");
f.add(b1); f.add (b2); f. add(b3); f.add(b4); f.add(b5);
f. pack ();
f. show ();
}
}

Gestionarea poziionrii

Frame f = new Frame("Flow Layout");


f.setLayout(new FlowLayout());

Gestionarea poziionrii (2)


l

l
l

Un gestionar de poziionare (layout


manager) este un obiect care controleaz
dimensiunea i aranjarea (poziia)
componentelor unui container.
Fiecare obiect de tip Container are asociat
un gestionar de poziionare.
Toate clasele care instaniaz obiecte
pentru gestionarea poziionrii
implementeaz interfaa LayoutManager.
La instanierea unui container se creeaz
implicit un gestionar de poziionare asociat
acestuia. (ferestre: BorderLayout, panel-uri:
FlowLayout).

Folosirea gestionarilor de
poziionare
l

Gestionari AWT
FlowLayout, BorderLayout, GridLayout,
CardLayout, GridBagLayout
Metoda setLayout
FlowLayout gestionar = new FlowLayout();
container.setLayout(gestionar); // sau:
container.setLayout(new FlowLayout());
Dimensionarea
getPreferredSize, getMinimumSize,
getMaximumSize
Poziionarea absolut
container.setLayout(null);
Button b = new Button("Buton");
b.setSize(10, 10); b.setLocation (0, 0);
b.add();

Gestionarul FlowLayout

Gestionar implicit pentru Panel.

Gestionarul BorderLayout
Cinci regiuni: NORTH, SOUTH, EAST, WEST, CENTER
Implicit pentru Window

Gestionarul GridLayout
Organizare tabelar

Gestionarul CardLayout
Pachet de cri
Prima carte este vizibil

A doua carte este vizibil


Swing: JTabbedPane

Gestionarul GridBagLayout
GridBagLayout gridBag = new GridBagLayout();
container.setLayout(gridBag);
GridBagConstraints c = new GridBagConstraints();
//Specificam restrictiile. . .i apoi
gridBag.setConstraints(componenta, c);
container.add(componenta);

Gestionarul GridBagLayout (2)


Cele mai utilizate tipuri de constrngeri pot fi
specificate prin intermediul urmtoarelor variabile
din clasa GridBagConstraints:
gridx, gridy - celula ce reprezint colul stnga sus al
componentei;
gridwidth, gridheight - numrul de celule pe linie i
coloan pe care va fi afiat componenta;
fill - folosit pentru a specifica dac o component va
ocupa ntreg spaiul pe care l are destinat; valorile
posibile sunt HORIZONTAL, VERTICAL, BOTH,
NONE;
insets - distanele dintre component i marginile
suprafeei sale de afiare;
anchor - folosit atunci cnd componenta este mai
mic dect suprafaa sa de afiare pentru a fora o
anumit dispunere a sa: nord, sud, est, vest, etc.
weigthx, weighty - folosite pentru distribuia spaiului
liber; uzual au valoarea 1;
l

Gruparea componentelor
l
l
l

Gruparea componentelor se face folosind


clasa Panel.
Un panel este cel mai simplu model de
container.
Nu are o reprezentare vizibil, rolul su fiind
de a oferi o suprafa de afiare pentru
componente grafice, inclusiv pentru alte
panel-uri.
Aranjare eficient a componentelor unei
ferestre presupune:
gruparea componentelor nfrite;
aranjarea componentelor unui panel;
aranjarea panel-urilor pe suprafaa
ferestrei.
Gestionarul implicit este FlowLayout.

Gruparea componentelor

Folosirea ferestrelor
Window: Frame, Dialog
l Gestionar de poziionare: BorderLayout.
l Window: crearea de ferestre care nu au chenar i
nici bar de meniuri; nu interacioneaz cu
utilizatorul ci doar ofer anumite informaii.
l Metode:
show - face vizibil fereastra. Implicit, o fereastr nou
creat nu este vizibil;
hide - face fereastra invizibil fr a o distruge ns;
pentru a redeveni vizibila se poate apela metoda
show;
isShowing -testeaz dac fereastra este vizibil sau
nu;
dispose - nchide fereastra i i elibereaz toate
resursele acesteia;
pack - redimensioneaz automat fereastra la o
suprafaa optim care s cuprind toate
componentele sale; trebuie apelat n general dup
adugarea tuturor componentelor pe suprafaa
ferestrei.
l

Clasa Frame
import java.awt.*;
public class TestFrame {
public static void main(String args[]) {
Frame f = new Frame("Titlul ferestrei");
f.show();
}
}
import java.awt.*;
class Fereastra extends Frame{
// Constructorul
public Fereastra(String titlu) {
super(titlu);
...
}
}
...
Fereastra f = new Fereastra("Titlul ferestrei");
f.show();

Clasa Dialog
l

o fereastr de dialog este dependent de o alt


fereastr (normal sau tot fereastr de dialog),
numit i fereastr printe
ferestrele de dialog pot fi:

modale: care blocheaz accesul la fereastra printe


n momentul deschiderii lor,
nemodale: care nu blocheaz fluxul de intrare ctre
fereastra printe

Constructori:
l Dialog(Frame parinte)
l Dialog(Frame parinte, String titlu)
l Dialog(Frame parinte, String titlu, boolean modala)
l Dialog(Frame parinte, boolean modala)
l Dialog(Dialog parinte)
l Dialog(Dialog parinte, String titlu)
l Dialog(Dialog parinte, String titlu, boolean modala)

Clasa FileDialog
fereastr de dialog folosit pentru selectarea
unui nume de fiier n vederea ncrcrii sau
salvrii unui fiier
Constructori
l FileDialog(Frame parinte)
l FileDialog(Frame parinte, String titlu)
l FileDialog(Frame parinte, String titlu, boolean
mod)
// Dialog pentru incarcarea unui fisier
l new FileDialog(parinte, "Alegere fisier",
FileDialog.LOAD);
// Dialog pentru salvarea unui fisier
l new FileDialog(parinte, "Salvare fisier",
FileDialog.SAVE);
l Swing: JFileChooser

Interfaa grafic cu
utilizatorul - AWT

Programare Orientat pe Obiecte

Tratarea evenimentelor
Eveniment: apsarea unui buton, modificarea textului,
nchiderea unei ferestre,etc.
l Surs: component care genereaz un eveniment.
l Interceptarea evenimentelor generate de
componentele unui program se realizeaz prin
intermediul unor clase de tip listener
l Evenimentele - AWTEvent:
ActionEvent, TextEvent.
l

Asculttorii - EventListener:
l

l
l

O clas asculttor poate fi orice clas care


specific n declaraia sa c dorete s
asculte evenimente de un anumit tip.
Acest lucru se realizeaz prin
implementarea unei interfee specifice
fiecrui tip de eveniment.
Pentru ascultarea evenimentelor de tip
ActionEvent clasa respectiv trebuie s
implementeze interfaa ActionListener,
pentru TextEvent interfa care trebuie
implementat este TextListener,etc.
Toate aceste interfee sunt derivate din
EventListener.
Fiecare interfa definete una sau mai
multe metode care vor fi apelate automat la
apariia unui eveniment

Asculttorii - EventListener:
ActionListener, TextListener.
class AscultaButoane implements ActionListener {
public void actionPerformed(ActionEvent e) {
// Metoda interfetei ActionListener
...
}
}
class AscultaTexte implements TextListener {
public void textValueChanged(TextEvent e) {
// Metoda interfetei TextListener
...
}
}
class Ascultator implements ActionListener, TextListener {
public void actionPerformed(ActionEvent e) {
...
}
public void textValueChanged(TextEvent e) {
...
}
}

Asculttorii (2):
Inregistrarea/eliminare unei clase n lista
asculttorilor unei componente:
addTipEvenimentListener,
removeTipEvenimentListener.
l Tratarea evenimentelor se desfoar
astfel:
Componentele genereaz evenimente cnd
ceva interesant se ntmpl;
Sursele evenimentelor permit oricrei clase
s asculte evenimentele sale prin metode
de tip addTIPListener;
O clas care ascult evenimente trebuie s
implementeze interfee specifice fiecrui tip
de eveniment acestea descriu metode ce
vor fi apelate automat la apariia
evenimentelor.
l

Exemplu: Ascultarea evenimentelor


a dou butoane

Tratarea evenimentelor n ferestr

Tipuri de evenimente
Evenimente de nivel jos - apsare de tast, micarea
mouse-ului, etc.

Evenimente semantice
- interaciunea cu o component GUI:
apsarea unui buton, selectarea unui articol
dintr-o list, etc.

Componentele AWT i tipurile de


evenimente generate

Interfee asculttor

Evenimente de la surse multiple


l

metoda getSource returneaz obiectul responsabil cu


generarea evenimentului.

public void actionPerformed(ActionEvent e) {


Object sursa = e.getSource();
if (sursa instanceof Button) {
// A fost apasat un buton
Button btn = (Button) sursa;
if (btn == ok) {// A fost apasat butonul ok
}
...
}
if (sursa instanceof TextField) {
// S-a apasat Enter dupa editarea textului
TextField tf = (TextField) sursa;
if (tf == nume) { // A fost editata componenta nume
}
...
}
}
l

ActionEvent conine metoda getActionCommand care, implicit,


returneaz eticheta butonului care a fost apsat.

Adaptori i a clase anonime

Folosirea unui adaptor


this.addWindowListener(new Ascultator());
...
class Ascultator extends WindowAdapter {
// Supradefinim metodele care ne intereseaza
public void windowClosing(WindowEvent e) {
System.exit(0);
}
}
l
l

TipXListener - TipXAdapter
Folosirea unei clasa anonime:

this.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
// Terminam aplicatia
System.exit(0);
}
});

Structura general a unei ferestre

Structura general a unei ferestre

Metode
getFrames
setIconImage
setMenuBar
setTitle
setResizable

Tratarea evenimentelor - Exemplu


1. Program pentru afisarea unui buton cu inscriptia "Click Me" si
afisarea unei casete de dialog cu titlul "Event Fired" la fiecare clic
pe buton (cu mouse). Afisarea casetei de dialog se face astfel:
JOptionPane.showMessageDialog(new JFrame(), ", "Event
Fired !", JOptionPane.PLAIN_MESSAGE);
Se vor examina pe rand urmatoarele variante de definire a clasei
ascultator la evenimente generate de buton:
a) Cu trei clase separate: clasa ascultator, clasa derivata din
"JFrame care contine si un buton, clasa cu "main" (care
afiseaza fereastra).
b) Cu doua clase: clasa ascultator si clasa derivata din "JFrame" si
care contine metoda "main".
c) Cu o singura clasa: clasa ascultator cu nume inclusa in clasa ce
contine metoda "main"
d) Cu o singura clasa : clasa ascultator anonima, inclusa intr-un
bloc (metoda "addActionListener") din clasa ce contine metoda
"main".
e) Cu doua clase: O subclasa a clasei "JButton" care contine si
metoda "actionPerformed" si clasa care contine metoda "main".
f) Cu doua clase : clasa ascultator inclusa intr-o subclasa a clasei
"JFrame (separata de clasa ce contine metoda "main")
g) O singura clasa care extinde pe "JFrame" si implementeaza
"ActionListener (clasa este si generator si ascultator la
evenimente).

a. Cu trei clase separate: clasa ascultator, clasa


derivata din "JFrame care contine si un buton,
clasa cu "main" (care afiseaza fereastra).
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
class ascultator implements ActionListener{
public void actionPerformed(ActionEvent e){
JOptionPane.showMessageDialog(new JFrame(),"","Event
Fired !",JOptionPane.PLAIN_MESSAGE);
}
}
class jframe extends JFrame{
public jframe(){
JButton jb=new JButton("Click me!");
getContentPane().setLayout(new FlowLayout());
getContentPane().add(jb);
jb.addActionListener(new ascultator());
setSize(250,250);
setVisible(true);
}
}
class test{
public static void main(String arg[]){
JFrame jf=new jframe();
}
}

b. Cu doua clase: clasa ascultator si clasa derivata


din "JFrame" si care contine metoda "main".
class ascultator implements ActionListener{
public void actionPerformed(ActionEvent e){
JOptionPane.showMessageDialog(new
JFrame(),"","Event Fired!",
JOptionPane.PLAIN_MESSAGE);
}
}
class jframe extends JFrame{
public jframe(){
JButton jb=new JButton("Click me!");
getContentPane().setLayout(new FlowLayout());
getContentPane().add(jb);
jb.addActionListener(new ascultator());
setSize(250,250);
setVisible(true);
}
public static void main(String arg[]){
JFrame jf=new jframe();
}
}

c. Cu o singura clasa: clasa ascultator cu nume


inclusa in clasa ce contine metoda "main"
class jframe extends JFrame{
public jframe(){
JButton jb=new JButton("Click me!");
getContentPane().setLayout(new FlowLayout());
getContentPane().add(jb);
jb.addActionListener(new ascultator());
setSize(250,250);
setVisible(true);
}
class ascultator implements ActionListener{
public void actionPerformed(ActionEvent e){
JOptionPane.showMessageDialog(new
JFrame(),"","Event Fired !",JOptionPane.PLAIN_MESSAGE);
}
}
public static void main(String arg[]){
JFrame jf=new jframe();
}
}

d. Cu o singura clasa : clasa ascultator anonima,


inclusa intr-un bloc (metoda "addActionListener")
din clasa ce contine metoda "main".
class jframe extends JFrame{
public jframe(){
JButton jb=new JButton("Click me!");
getContentPane().setLayout(new FlowLayout());
getContentPane().add(jb);
jb.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
JOptionPane.showMessageDialog(new
JFrame(),"","Event Fired!",
JOptionPane.PLAIN_MESSAGE);
}
});
setSize(250,250);
setVisible(true);
}
public static void main(String arg[]){
JFrame jf=new jframe();
}
}

g. O singura clasa care extinde pe "JFrame" si


implementeaza "ActionListener (clasa este si
generator si ascultator la evenimente).
class jframe extends JFrame implements ActionListener{
public jframe(){
JButton jb=new JButton("Click me!");
getContentPane().setLayout(new FlowLayout());
getContentPane().add(jb);
jb.addActionListener(this);
setSize(250,250);
setVisible(true);
}
public void actionPerformed(ActionEvent e){
JOptionPane.showMessageDialog(new
JFrame(),"","Event Fired !",
JOptionPane.PLAIN_MESSAGE);
}
public static void main(String arg[]){
JFrame jf=new jframe();
}
}

Folosirea meniurilor
Componentele unui meniu sunt derivate din
MenuComponent.
Meniuri fixe (vizibile permanent)
Meniuri de context (popup)
l

addMenuBar

Ierarhia claselor ce descriu


meniuri

Exemplu

Tratarea evenimentelor generate


de meniuri

Tratarea evenimentelor generate


de meniuri

Meniuri de context (popup)


PopupMenu popup = new PopupMenu("Options");
popup.add(new MenuItem("New"));
popup.add(new MenuItem("Edit"));
popup.addSeparator();
popup.add(new MenuItem("Exit"));
...
popup.show(Component origine, int x, int y)
fereastra.add(popup1);
...
fereastra.remove(popup1);
fereastra.add(popup2);
isPopupTrigger() :
l dac acest eveniment de mouse este evenimentul
care poate afia un meniu popup
l trebuie testat n ambele metode mousePressed i
mouseReleased pentru c depinde de platform

Folosirea unui meniu de context


(popup)

Folosirea unui meniu de context


(popup) (2)

Acceleratori
Clasa MenuShortcut
Ctrl + Tasta sau Ctrl + Shift + Tasta
// Ctrl+O
new MenuItem("Open",new MenuShortcut(
KeyEvent.VK_O));
// Ctrl+P
new MenuItem("Print",new MenuShortcut(p));
// Ctrl+Shift+P
new MenuItem("Preview",new MenuShortcut(p),
true);

Interfaa grafic cu
utilizatorul - Swing

Programare Orientat pe Obiecte

Swing
JFC (Java Foundation Classes)
Componentele Swing
Asemnri i deosebiri cu AWT
Folosirea ferestrelor
Ferestre interne
Folosirea componentelor
Containere
Look and Feel
Arhitectura modelului Swing
Folosirea modelelor
Tratarea evenimentelor

JFC (Java Foundation Classes)


Componente Swing
Sunt componente ce nlocuiesc i n acelai timp extind
vechiul set oferit de modelul AWT.
Look-and-Feel
Permite schimbarea nfirii i a modului de interaciune cu
aplicaia n funcie de preferine
Accessibility API
Permite dezvoltarea de aplicaii care s comunice cu
dispozitive utilizate de ctre persoane cu diverse tipuri de
handicap.
Java 2D API
Permite crearea de aplicaii care utilizeaz grafic la un nivel
avansat. Clasele puse la dispoziie permit crearea de desene
complexe, efectuarea de operaii geometrice (rotiri, scalri,
translaii, etc.), prelucrarea de imagini, tiprire, etc.
Drag-and-Drop
Ofer posibilitatea de a efectua operaii drag-and-drop ntre
aplicaii Java i aplicaii native.
Internaionalizare
Permite dezvoltarea de aplicaii care s poat fi configurate
pentru exploatarea lor n diverse zone ale globului, utiliznd
limba i particularitile legate de formatarea datei, numerelor
sau a monedei din zona respectiv.

Swing API
javax.accessibility
l javax.swing.plaf
l javax.swing.text.html
l javax.swing
l javax.swing.plaf.basic
l javax.swing.text.parser
l javax.swing.border
l javax.swing.plaf.metal
l javax.swing.text.rtf
l javax.swing.colorchooser
l javax.swing.plaf.multi
l javax.swing.tree
l javax.swing.event
l javax.swing.table
l javax.swing.undo
l javax.swing.filechooser
l javax.swing.text
Cel mai important: javax.swing
l

Componentele Swing
Componente atomice
JLabel, JButton, JToggleButton (JCheckBox,
JRadioButton), JScrollBar, JSlider, JProgressBar,
JSeparator
Componente complexe
JTable, JTree, JComboBox, JSpinner, JList,
JFileChooser, JColorChooser, JOptionPane
Componente pentru editare de text
JTextField, JFormattedTextField, JPasswordField,
JTextArea, JEditorPane, JTextPane
Meniuri
JMenuBar, JMenu, JPopupMenu, JMenuItem,
JCheckboxMenuItem, JRadioButtonMenuItem
Containere intermediare
JPanel, JScrollPane, JSplitPane, JTabbedPane,
JDesktopPane, JToolBar
Containere de nivel nalt
JFrame, JDialog, JWindow, JInternalFrame, JApplet

Asemnri i deosebiri cu AWT


Tehnologia Swing extinde AWT.
import javax.swing.*;
import java.awt.*; //Font, Color, ...
import java.awt.event.*;
l Convenia J
java.awt.Button - javax.swing.JButton
java.awt.Label - javax.swing.JLabel,etc.
l Noi gestionari de poziionare: BoxLayout,
SpringLayout
l Folosirea HTML
JButton simplu = new JButton("Text simplu");
JButton html = new JButton(
"<html><u>Text</u> <i>formatat</i></html>");
l

O aplicaie simpl AWT


import java . awt .*;
import java . awt. event .*;
public class ExempluAWT extends Frame implements
ActionListener {
public ExempluAWT ( String titlu ) {
super ( titlu );
setLayout (new FlowLayout ());
add (new Label (" Hello AWT "));
Button b = new Button (" Close ");
b. addActionListener ( this );
add (b);
pack ();
show ();
}
public void actionPerformed ( ActionEvent e) {
System . exit (0);
}
public static void main ( String args []) {
new ExempluAWT (" Hello ");
}
}

Aplicaia rescris folosind Swing1.4


import javax . swing .*;
import java . awt .*;
import java . awt. event .*;
class ExempluSwing extends JFrame implements ActionListener {
public ExempluSwing ( String titlu ) {
super ( titlu );
// Metoda setLayout nu se aplica direct ferestrei
getContentPane (). setLayout (new FlowLayout ());
// Componentele au denumiri ce incep cu litera J
getContentPane ().add( new JLabel ("Swing"));
JButton b = new JButton ("Close");
b. addActionListener ( this );
// Metoda add nu se aplica direct ferestrei
getContentPane ().add(b);
pack ();
show ();
}
public void actionPerformed ( ActionEvent e) {
// Tratarea evenimentelor se face ca in AWT
System . exit (0);
}
public static void main ( String args []) {
new ExempluSwing (" Hello ");
}
}

Aplicaia rescris folosind Swing1.5


import javax . swing .*;
import java . awt .*;
import java . awt. event .*;
class ExempluSwing extends JFrame implements ActionListener
{
public ExempluSwing ( String titlu ) {
super ( titlu );
setLayout (new FlowLayout ());
add( new JLabel ("Swing"));
JButton b = new JButton ("Close");
b. addActionListener ( this );
add(b);
pack ();
show ();
}
public void actionPerformed ( ActionEvent e) {
System . exit (0);
}
public static void main ( String args []) {
new ExempluSwing (" Hello ");
}
}

Folosirea ferestrelor

Frame f = new Frame();


f.setLayout(new FlowLayout());
f.add(new Button("OK"));
JFrame jf = new JFrame();
jf.getContentPane().setLayout(new FlowLayout());
jf.getContentPane().add(new JButton("OK"));
jf.setDefaultCloseOperation(WindowConstants.HIDE_ON_CLOSE);
l WindowConstants.DO_NOTHING_ON_CLOSE
l JFrame.EXIT_ON_CLOSE

Look and Feel


Modul n care sunt desenate componentele Swing i felul n
care acestea interacioneaz cu utilizatorul
l Acelai program poate utiliza diverse moduri Look-and-Feel,
cum ar fi cele standard Windows, Mac, Java, Motif sau altele
oferite de diveri dezvoltatori
javax.swing.plaf.metal.MetalLookAndFeel
Varianta implicit de L&F i are un aspect specific Java.
com.sun.java.swing.plaf.windows.WindowsLookAndFeel
Varianta specific sistemelor de operare Windows. Incepnd
cu versiunea 1.4.2 exist i implementarea pentru Windows
XP .
com.sun.java.swing.plaf.mac.MacLookAndFeel
Varianta specific sistemelor de operare Mac.
com.sun.java.swing.plaf.motif.MotifLookAndFeel
Specific interfaa CDE/Motif.
com.sun.java.swing.plaf.gtk.GTKLookAndFeel
GTK+ reprezint un standard de creare a interfeelor grafice
dezvoltat independent de limbajul Java. (GTK este acronimul
de la GNU ImageManipulation Program Toolkit).

Specificare unei anumite interfee


L&F
l

Folosirea clasei UIManager (metode statice):

getLookAndFeel - Obine varianta curent, returnnd un obiect


de tip LookAndFeel.
setLookAndFeel - Seteaz modul curet L&F. Metoda primete
ca argument un obiect dintr-o clas derivat din
LookAndFeel, fie un ir de caractere cu numele complet al
clasei L&F.
getSystemLookAndFeelClassName - Obine variant specific
sistemului de operare folosit. In cazul n care nu exist nici o
astfel de clas, returneaz varianta standard.
getCrossPlatformLookAndFeelClassName - Returneaz
interfaa grafic standard Java (JLF).
// Exemple:
UIManager.setLookAndFeel(
"com.sun.java.swing.plaf.motif.MotifLookAndFeel );
UIManager.setLookAndFeel (
UIManager.getSystemLookAndFeelClassName() );

Specificare unei anumite interfee


L&F
Setarea proprietii swing.defaultlaf
1. direct de la linia de comand prin setarea
proprietii swing.defaultlaf:
java -Dswing.defaultlaf =
com.sun.java.swing.plaf.gtk.GTKLookAndFeel App
2. n lib/swing.properties:
# Swing properties
swing.defaultlaf =
com.sun.java.swing.plaf.windows.WindowsLookAnd
Feel
l Exist posibilitatea de a schimba varianta de L&F
chiar i dup afiarea componentelor. Acesta este
un proces care trebuie s actualizeze ierarhiile de
componente:
UIManager.setLookAndFeel(numeClasaLF);
SwingUtilities.updateComponentTreeUI(f);
f.pack();

Interfaa grafic cu
utilizatorul - Swing

Programare Orientat pe Obiecte

Ferestre interne
Aplicaiile pot fi mprite n:
SDI (Single Document Interface)
MDI (Multiple Document Interface)
lClase:
JInternalFrame
DesktopPane container care va fi apoi plasat pe o
fereastr de tip JFrame. Folosirea clasei DesktopPane este
necesar deoarece aceasta tie cum s gestioneze
ferestrele interne, avnd n vedere c acestea se pot
suprapune i la un moment dat doar una singur este activ.
l

Folosirea ferestrelor interne


import javax . swing .*;
import java . awt .*;
class FereastraPrincipala extends JFrame {
public FereastraPrincipala ( String titlu ) {
super ( titlu ); setSize (300 , 200) ;
setDefaultCloseOperation ( JFrame . EXIT_ON_CLOSE );
FereastraInterna fin1 = new FereastraInterna (); fin1. setVisible ( true );
FereastraInterna fin2 = new FereastraInterna (); fin2 . setVisible ( true );
JDesktopPane desktop = new JDesktopPane ();
desktop .add( fin1 ); desktop .add( fin2 );
setContentPane ( desktop );
fin2 . moveToFront ();
}
}
class FereastraInterna extends JInternalFrame {
static int n = 0; // nr. de ferestre interne
static final int x = 30, y = 30;
public FereastraInterna () {
super (" Document #" + (++ n),
true , // resizable
true , // closable
true , // maximizable
true );// iconifiable
setLocation (x*n, y*n);
setSize ( new Dimension (200 , 100) );
}
}
class TestInternalFrame {
public static void main ( String args []) {
new FereastraPrincipala (" Test ferestre interne "). setVisible (true);
}
}

Clasa JComponent
JComponent este superclasa tuturor
componentelor Swing, mai puin JFrame,
JDialog, JApplet.
l JComponent extinde clasa Container.
Faciliti:
ToolTips - setToolTip
Chenare - setBorder
Suport pentru plasare i dimensionare
- setPreferredSize,
...
Controlul opacitii - setOpaque
Asocierea de aciuni tastelor
Double-Buffering
l

Faciliti oferite de clasa


JComponent (1)
import javax . swing .*;
import javax . swing . border .*;
import java . awt .*;
import java . awt. event .*;
class Fereastra extends JFrame {
public Fereastra ( String titlu ) {
super ( titlu );
setLayout (new FlowLayout ());
setDefaultCloseOperation ( JFrame . EXIT_ON_CLOSE );
// Folosirea chenarelor
Border lowered , raised ;
TitledBorder title ;
lowered = BorderFactory . createLoweredBevelBorder ();
raised = BorderFactory . createRaisedBevelBorder ();
title = BorderFactory . createTitledBorder (" Borders ");
final JPanel panel = new JPanel ();
panel . setPreferredSize (new Dimension (400 ,200) );
panel . setBackground ( Color . blue );
panel . setBorder ( title );
add( panel );
JLabel label1 = new JLabel (" Lowered ");
label1 . setBorder ( lowered );
panel .add( label1 );
JLabel label2 = new JLabel (" Raised ");
label2 . setBorder ( raised );
panel .add( label2 );

Faciliti oferite de clasa


JComponent (2)
// Controlul opacitatii
JButton btn1 = new JButton (" Opaque ");
btn1 . setOpaque ( true ); // implicit
panel .add( btn1 );
JButton btn2 = new JButton (" Transparent ");
btn2 . setOpaque ( false ); //dependent de Look&Feel !!
panel .add( btn2 );
// ToolTips
label1 . setToolTipText (" Eticheta coborata ");
label2 . setToolTipText (" Eticheta ridicata ");
btn1 . setToolTipText (" Buton opac ");
btn2 . setToolTipText ("<html><b> Apasati </b> <font color =red >F2</font> " +
" cand butonul are <u> focusul </u> </html>");
/* Asocierea unor actiuni ( KeyBindings ) - Apasarea tastei F2 cand focusul este pe
butonul al doilea va determina schimbarea culorii panelului */
btn2 . getInputMap ().put( KeyStroke . getKeyStroke ("F2")," schimbaCuloare ");
btn2 . getActionMap ().put(" schimbaCuloare ", new AbstractAction () {
private Color color = Color .red ;
public void actionPerformed ( ActionEvent e) {
panel . setBackground ( color );
color = ( color == Color . red ? Color . blue : Color .red);
}
});
pack ();
}
}
class TestJComponent {
public static void main ( String args []) throws Exception{
new Fereastra (" Facilitati JComponent "). show ();
UIManager.setLookAndFeel( "com.sun.java.swing.plaf.motif.MotifLookAndFeel");
}
}

Folosirea componentelor
Componente atomice
Etichete: JLabel
Butoane simple sau cu dou stri:
JButton, JCheckBox, JRadioButton;
Componente pentru progres i derulare:
JSlider, JProgressBar, JScrollBar
Separatori: JSeparator

Componente editare de text


Faciliti: undo i redo, tratarea evenimentelor generate
de cursor (caret), etc.
Arhitectura JTextComponent:
Model - Document
Reprezentare
Controller - editor kit, permite scrierea i citirea
textului i definirea de aciuni necesare editrii

Tratarea evenimentelor
ActionEvent
ActionListener :
- actionPerformed
CaretEvent: generat la deplasarea cursorului ce
gestioneaz poziia curent n text
CaretListener :
- caretUpdate
DocumentEvent: generat la orice schimbare a
textului
DocumentListener :
insertUpdate
removeUpdate
changedUpdate
PropertyChangeEvent: eveniment comun tuturor
componentelor de tip JavaBean, fiind generat la
orice schimbare a unei proprieti a componentei.
PropertyChangeListener:
- propertyChange

Containere
1. Containere de nivel nalt - JFrame, JDialog,
JApplet
2. Containere intermediare
JPanel
JScrollPane
JTabbedPane
JSplitPane
JDesktopPane
JRootPane: container utilizat n fundal de
JFrame, JDialog, JWindow, JApplet i
JInternalFrame
JLayeredPane: permite componentelor s se
suprapun una peste alta atunci cnd este
necesar

JPanel
l

Permite gruparea componentelor.

JPanel p = new JPanel(new BorderLayout());

p.add(new JLabel("Hello"));
p.add(new JButton("OK"));
...

JScrollPane
Ofer suport pentru derulare
String elemente[] = new String[100];
for(int i=0; i<100; i++)
elemente[i] = "Elementul " + i;
JList lista = new JList(elemente);
JScrollPane sp = new JScrollPane(lista);
frame.add(sp);
l

JTabbedPane
Permite suprapunerea mai multor containere.
JTabbedPane tabbedPane = new JTabbedPane();
ImageIcon icon = new ImageIcon("smiley.gif");
JComponent panel1 = new JPanel();
panel1.setOpaque(true);
panel1.add(new JLabel("Hello"));
tabbedPane.addTab("Tab 1", icon, panel1, "Aici avem
o eticheta");
tabbedPane.setMnemonicAt(0, KeyEvent.VK_1);
JComponent panel2 =
new JPanel();
panel2.setOpaque(true);
panel2.add(new JButton("OK"));
tabbedPane.addTab("Tab 2", icon,
panel2,"Aici avem un buton");
tabbedPane.setMnemonicAt(1,
KeyEvent.VK_2);
l

JSplitPane
lOfer

suport pentru separarea componentelor.

JList list;
JPanel panel;
JTextArea text;
...
JSplitPane sp1 = new JSplitPane(
JSplitPane.HORIZONTAL_SPLIT, list, panel);
JSplitPane sp2 = new JSplitPane(
JSplitPane.VERTICAL_SPLIT, sp1, text);
frame.add(sp2);

Dialoguri - Clasa JDialog


l

l
l
l

JOptionPane: Permite crearea unor dialoguri


simple, folosite pentru afiarea unor mesaje,
realizarea unor interogri de confirmare/renunare,
etc. sau chiar pentru introducerea unor valori
JOptionPane.showMessageDialog(frame,
"Eroare de sistem !", "Eroare",
JOptionPane.ERROR_MESSAGE);
JOptionPane.showConfirmDialog(frame,
"Doriti inchiderea aplicatiei ? ", "Intrebare",
JOptionPane.YES_NO_OPTION,
JOptionPane.QUESTION_MESSAGE);
JFileChooser
JColorChooser
ProgressMonitor: monitorizarea progresului unei
operaii consumatoare de timp

Arhitectura modelului Swing


MVC (model-view-controller):
Modelul - datele aplicaiei.
Prezentarea - reprezentare vizual
Controlul - transformarea aciunilor n evenimente
l Arhitectur cu model separabil: Model + (Prezentare,
Control)
l Fiecrui obiect corespunztor unei clase ce descrie o
component Swing i este asociat un obiect care
gestioneaz datele sale i care implementeaz o
interfa care reprezint modelul componentei
respective.
l Fiecare component are un model iniial implicit, ns
are posibilitatea de a-l nlocui cu unul nou atunci cnd
este cazul. Metodele care acceseaz modelul unui
obiect sunt: setModel, respectiv getModel, cu
argumente specifice fiecrei componente n parte.
l Crearea unui model = implementarea interfeei
JList - ListModel
DefaultListModel, AbstractListModel

Folosirea modelelor
Model
ButtonModel

Component

ComboBoxModel

JButton, JToggleButton, JCheckBox,


JRadioButton, JMenu, JMenuItem,
JCheckBoxMenuItem,
JRadioButtomMenuItem
JComboBox

BoundedRangeModel

JProgressBar, JScrollBarm, JSlider

SingleSelectionModel

JTabbedPane

ListModel

JList

ListSelectionModel

JList

TableModel

JTable

TableColumnModel

JTable

TreeModel

JTree

TreeSelectionModel

JTree

Document

JEditorPane, JTextPane, JTextArea,


JTextField, JPasswordField

Folosirea modelelor - exemplu


import javax . swing .*;
import javax . swing . border .*;
import java . awt .*;
import java . awt. event .*;
class Fereastra extends JFrame implements ActionListener {
String data1 [] = {" rosu ", " galben ", " albastru "};
String data2 [] = {"red", " yellow ", " blue "};
int tipModel = 1;
JList lst;
ListModel model1 , model2 ;
public Fereastra ( String titlu ) {
super ( titlu );
setDefaultCloseOperation ( JFrame . EXIT_ON_CLOSE );
// Lista initiala nu are nici un model
lst = new JList ();
add(lst , BorderLayout . CENTER );
// La apasara butonului schimbam modelul
JButton btn = new JButton (" Schimba modelul ");
add(btn , BorderLayout . SOUTH );
btn . addActionListener ( this );
// Cream obiectele corespunzatoare celor doua modele
model1 = new Model1 ();
model2 = new Model2 ();
lst . setModel ( model1 );
pack ();
}

Folosirea modelelor - exemplu


public void actionPerformed ( ActionEvent e) {
if ( tipModel == 1) {
lst . setModel ( model2 ); tipModel = 2;}
else {
lst . setModel ( model1 ); tipModel = 1;}
}
// Clasele corespunzatoare celor doua modele
class Model1 extends AbstractListModel {
public int getSize () {
return data1 . length ;
}
public Object getElementAt ( int index ) {
return data1 [ index ];
}
}
class Model2 extends AbstractListModel {
public int getSize () {
return data2 . length ;
}
public Object getElementAt ( int index ) {
return data2 [ index ];
}
}
}
public class TestModel {
public static void main ( String args []) {
new Fereastra (" Test Model "). show ();
}
}

Observaii
l

Multe componente Swing furnizeaz metode


care s obin starea obiectului fr a mai fi
nevoie s obinem instana modelului i s
apelm metodele acesteia. Un exemplu este
metoda getValue a clasei JSlider care este
de fapt un apel de genul:
getModel().getValue().
In multe situaii ns, mai ales pentru clase
cum ar fi JTable sau JTree, folosirea
modelelor aduce flexibilitate sporit
programului i este recomandat utilizarea
lor.

Tratarea evenimentelor:
informativ (lightweight)
l

Modelele trimit un eveniment prin care sunt informai


asculttorii c a survenit o anumit schimbare a datelor,
fr a include n eveniment detalii legate de schimbarea
survenit. Obiectele de tip listener vor trebui s apeleze
metode specifice componentelor pentru a afla ce anume
s-a schimbat.
ChangeListener - ChangeEvent
Modele: BoundedRangeModel, ButtonModel i
SingleSelectionModel

JSlider slider = new JSlider();


BoundedRangeModel model = slider.getModel();
model.addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e) {
// Sursa este de tip BoundedRangeModel
BoundedRangeModel m =(BoundedRangeModel)
e.getSource();
// Trebuie sa interogam sursa asupra schimbarii
System.out.println("Schimbare model: " + m.getValue());
}
});

Tratarea evenimentelor:
informativ (lightweight) (2)
l

Pentru uurina programrii, pentru a nu lucra direct


cu instana modelului, unele clase permit
nregistrarea asculttorilor direct pentru
componenta n sine, singura diferen fa de
varianta anterioar constnd n faptul c sursa
evenimentului este acum de tipul componentei i nu
de tipul modelului.

JSlider slider = new JSlider();


slider.addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e) {
// Sursa este de tip JSlider
JSlider s = (JSlider)e.getSource();
System.out.println("Valoare noua: " +
s.getValue());
}
});

Tratarea evenimentelor
2. Consistent(statefull): Modele pun la dispoziie
interfee specializate i tipuri de evenimente specifice
ce includ toate informaiile legate de schimbarea
datelor.
Model

Tip Eveniment

ListModel

ListDataEvent

ListSelectionModel

ListSelectionEvent

ComboBoxModel

ListDataEvent

TreeModel

TreeModelEvent

TreeSelectionModel

TreeSelectionEvent

TableModel

TableModelEvent

TableColumnModel

TableColumnModelEvent

Document

DocumentEvent

Document

UndoableEditEvent

Tratarea evenimentelor
String culori[] = {"rosu", "galben", "albastru");
JList list = new JList(culori);
ListSelectionModel sModel = list.getSelectionModel();
sModel.addListSelectionListener(new
ListSelectionListener() {
public void valueChanged (ListSelectionEvent e) {
// Schimbarea este continuta in eveniment
if (!e.getValueIsAdjusting()) {
System.out.println("Selectie curenta: " +
e.getFirstIndex());
}
}
});
Sau:
JList list = new JList(culori);
list.addListSelectionListener(new ListSelectionListener() {
public void valueChanged (ListSelectionEvent e) {

});

Componente pentru selectare


Clasa JList
Object elemente[] = {"Unu", new Integer(2)};
JList lista = new JList(elemente);
l Vector elemente = new Vector();
elemente.add( Unu); elemente.add( new Integer(2));
JList lista = new JList(elemente);
Obs: modificarea elementelor vectorului pe baza cruia
a fost creata iniial lista nu duce la modificarea
elementelor listei!! Pentru actualizarea elementelor
listei se va apela funcia setListData(vector) din clasa
JList.
l DefaultListModel model = new DefaultListModel();
model.addElement("Unu");
model.addElement(new Integer(2));
JList lista = new JList(model);
Obs: modificarea elementelor modelului pe baza cruia
a fost creata iniial lista se reflect automat n list!!
l

Clasa JList
lModelLista

model = new ModelLista();


JList lista = new JList(model);
...
class ModelLista extends AbstractListModel {
Object elemente[] = {"Unu", "Doi", new Integer(3),
new Double(4)};
public int getSize() {
return elemente.length;
}
public Object getElementAt(int index) {
return elemente[index];
}
}

Tratarea evenimentelor
class Test implements ListSelectionListener {
...
public Test() {
...
// Stabilim modul de selectie
list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
// sau SINGLE_INTERVAL_SELECTION
// MULTIPLE_INTERVAL_SELECTION
// Adaugam un ascultator
ListSelectionModel model = list.getSelectionModel();
model.addListSelectionListener(this);
// sau: list.addListSelectionListener(this);
...
}
public void valueChanged(ListSelectionEvent e) {
if (e.getValueIsAdjusting()) return;
int index = list.getSelectedIndex();
...
}
}

Obiecte de tip Renderer


Un renderer este responsabil cu afiarea articolelor unei
componente.
class MyCellRenderer extends JLabel implements
ListCellRenderer {
public MyCellRenderer() {
setOpaque(true);
}
public Component getListCellRendererComponent(JList list,
Object value, int index, boolean isSelected, boolean
cellHasFocus) {
setText(value.toString());
setBackground(isSelected ? Color.red :
Color.white);
setForeground(isSelected ?Color.white :
Color.black);
return this;
}
}
...
list.setCellRenderer(new MyCellRenderer());

Clasa JComboBox
lsimilar

cu JList, cu deosebirea c permite doar


selectarea unui singur articol, acesta fiind i singurul
permanent vizibil.
lIniializarea se face folosind fie un vector fie un model
de tipul ComboBoxModel
l fiecare element poate fi de asemenea reprezentat
diferit prin intermediul unui obiect ce implementeaz
aceeai intefa ca i n cazul listelor:ListCellRenderer.
lJComboBox permite i editarea explicit a valorii
elementului, acest lucru fiind controlat de metoda
setEditable.
lEvenimentele generate de obiectele
JComboBox sunt de tip ItemEvent generate
la navigarea prin list, respectiv
ActionEvent generate la selectarea efectiv
a unui articol.

Clasa JSpinner
ofer posibilitatea de a selecta o anumit valoare
(element) dintr-un domeniu prestabilit, lista elementelor
nefiind ns vizibil. Este folosit atunci cnd domeniul din
care poate fi fcut selecia este foarte mare sau chiar
nemrginit; de exemplu: numere intregi intre 1950 si 2050.
se bazeaz exclusiv pe folosirea unui model. Acesta este
un obiect de tip SpinnerModel (SpinnerListModel,
SpinnerNumberModel sau SpinnerDateModel)
permit i specificarea unui anumit tip de editor pentru
valorile elementelor sale. Acesta este instalat automat
pentru fiecare din modelele standard amintite mai sus
evenimentele generate de obiectele de tip JSpinner sunt
de tip ChangeEvent, generate la schimbarea strii
componentei.

Interfaa grafic cu
utilizatorul - Swing

Programare Orientat pe Obiecte

Tabele
Iniializarea
String[] coloane = {"Nume", "Varsta", "Student"};
Object[][] elemente = {
{"Ionescu", new Integer(20), Boolean.TRUE},
{"Popescu", new Integer(80), Boolean.FALSE}};
JTable tabel = new JTable(elemente, coloane);

Folosirea unui model


ModelTabel model = new ModelTabel();
JTable tabel = new JTable(model);
...
class ModelTabel extends AbstractTableModel {
String[] coloane = {"Nume", "Varsta", "Student"};
Object[][] elemente = {
{"Ionescu", new Integer(20), Boolean.TRUE},
{"Popescu", new Integer(80), Boolean.FALSE}};
public int getColumnCount() {return coloane.length;}
public int getRowCount() {return elemente.length;}
public Object getValueAt(int row, int col) {
return elemente[row][col];
}
public String getColumnName(int col) {
return coloane[col];
}
public boolean isCellEditable(int row, int col) {
// Doar numele este editabil
return (col == 0);
}
}

Tratarea evenimentelor
1. Generate de editarea celulelor
public class Listener implements TableModelListener {
public void tableChanged(TableModelEvent e) {
// Aflam celula care a fost modificata
int row = e.getFirstRow();
int col = e.getColumn();
TableModel model = (TableModel)e.getSource();
Object data = model.getValueAt(row, col);
...
}
}
...
tabel.getModel().addTableModelListener(new
Listener());

Tratarea evenimentelor
2. Generate de selectarea liniilor
class Listener implements ListSelectionListener {
public void valueChanged(ListSelectionEvent e) {
if (e.getValueIsAdjusting()) return;
ListSelectionModel model =
(ListSelectionModel)e.getSource();
int index = model.getMinSelectionIndex();
// Linia cu numarul index este prima selectata
...
}
}
}
...
tabel.setSelectionMode(ListSelectionModel.SINGLE_SE
LECTION);
ListSelectionModel model = tabel.getSelectionModel();
model.addListSelectionListener(new Listener());

Tratarea evenimentelor
3. Generate de selectarea coloanelor
class colSL implements ListSelectionListener {
public void valueChanged(ListSelectionEvent e) {
if (e.getValueIsAdjusting()) return;
ListSelectionModel model =
(ListSelectionModel)e.getSource();
int index = model.getMinSelectionIndex();
// coloana cu numarul index este prima selectata
...
}
}
}
...
ListSelectionModel colSM=
tab.getColumnModel().getSelectionModel();
colSM.addListSelectionListener(new colSL());

Folosirea unui renderer


public class MyRenderer extends JLabel
implements TableCellRenderer {
public Component
getTableCellRendererComponent(..) {
...
return this;
}
}

Folosirea unui editor


public class MyEditor extends AbstractCellEditor
implements TableCellEditor {
public Object getCellEditorValue() {
// Returneaza valoarea editata
...
}
public Component getTableCellEditorComponent(...) {
// Returneaza componenta de tip editor
...
}
}

Arbori
String text = "Radacina";
DefaultMutableTreeNode root = new DefaultMutableTreeNode(text);
DefaultMutableTreeNode numere = new DefaultMutableTreeNode
("Numere");
DefaultMutableTreeNode siruri = new DefaultMutableTreeNode
("Siruri");
for(int i=0; i<3; i++) {
numere.add(new DefaultMutableTreeNode(new Integer(i)));
siruri.add(new DefaultMutableTreeNode("Sirul " + i));
}
root.add(numere);
root.add(siruri);
JTree tree = new JTree(root);

Tratarea evenimentelor
class Listener implements TreeSelectionListener {
public void valueChanged(TreeSelectionEvent e) {
// Obtinem nodul selectat
DefaultMutableTreeNode node =
(DefaultMutableTreeNode)
tree.getLastSelectedPathComponent();
if (node == null) return;
// Obtinem informatia din nod
Object nodeInfo = node.getUserObject();
...
}
}
...
// Stabilim modul de selectie
tree.getSelectionModel().setSelectionMode(
TreeSelectionModel.SINGLE_TREE_SELECTION);
// Adaugam un ascultator
tree.addTreeSelectionListener(new Listener());

Personalizarea nodurilor
TreeCellRenderer
setRootVisible
setShowsRootHandles: dac nodurile de pe primul nivel au
simboluri care s permit expandarea sau restrngerea lor.
putClientProperty: stabilete diverse proprieti, cum ar fi modul
de reprezentare a relaiilor (liniilor) dintre nodurile printe i fiu:
tree.putClientProperty("JTree.lineStyle", "Angled");
// sau "Horizontal", "None"
Specificarea unei iconie
ImageIcon leaf = createImageIcon("img/leaf.gif");
ImageIcon open = createImageIcon("img/open.gif");
ImageIcon closed = createImageIcon("img/closed.gif");
DefaultTreeCellRenderer renderer =new
DefaultTreeCellRenderer();
renderer.setLeafIcon(leaf);
renderer.setOpenIcon(open);
renderer.setClosedIcon(closed);
tree.setCellRenderer(renderer);

Desenarea

Programare Orientat pe Obiecte

Desenarea
Conceptul de desenare
Metoda paint
Suprafee de desenare
Folosirea fonturilor
Folosirea culorilor
Folosirea imaginilor
Mecanismul de double-buffering
Tiprirea

Conceptul de desenare
Un program Java care are interfa grafic cu utilizatorul
trebuie s deseneze pe ecran toate componentele sale
care au o reprezentare vizual. Desenarea componentelor
se face automat:
1. la afiarea pentru prima dat;
2. la operaii de minimizare, maximizare, redimensionare a
suprafeei de afiare;
3. ca rspuns al unei solicitri explicite a programului.
l

Metode:
void paint(Graphics g) - Deseneaz o component.
void update(Graphics g) - Actualizeaz starea grafic a
unei componente.
a. terge componenta prin supradesenarea ei cu culoarea
fundalului;
b. stabilete culoarea (foreground) componentei;
c. apeleaz metoda paint pentru a redesena componenta.
void repaint() - Execut explicit un apel al metodei update
pentru a actualiza reprezentarea grafic a unei
componente.

Metoda paint
l
l

toate desenele care trebuie s apar pe o suprafa de afiare se


realizeaz n metoda paint
Responsabil cu desenarea unei componente

import java.awt .*;


Import javax.swing.*;
class Fereastra extends JFrame {
public Fereastra ( String titlu ) {
super ( titlu );
setSize (200 , 100) ;
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
public void paint ( Graphics g) {
super.paint(g);
g. setFont (new Font (" Arial ", Font .BOLD , 11));
g. setColor ( Color .red );
g. drawString (" Aplicatie DEMO ", 5, 35);
}
}
public class TestPaint {
public static void main ( String args []) {
Fereastra f = new Fereastra (" Test paint ");
f. show ();
}
}

Suprafee de desenare
Clasa Canvas:
- Este o clas generic din care se deriveaz subclase pentru
crearea suprafeelor de desenare (plane).
- Planele nu pot conine alte componente grafice, ele fiind
utilizate doar ca suprafee de desenat sau ca fundal pentru
animaie.
- Desenarea pe o plana se face prin supradefinirea metodei
paint a acesteia.
l

class Plansa extends Canvas implements ...Listener {


//Eventual, unul sau mai multi constructori
public Plansa() { ... }
// Metode de desenare a componentei
public void paint(Graphics g) { ... }
// Metodele folosite de gestionarii de pozitionare
public Dimension getPreferredSize() {
// Dimensiunea implicita a plansei
return ...; }
public Dimension getMinimumSize() { return ... }
public Dimension getMaximumSize() { return ... }
// Implementarea metodelor interfetelor de tip //Listener
...
}

Folosirea clasei Canvas


import java . awt .*;
import java . awt. event .*;
import javax . swing .*;
class Plansa extends Canvas {
Dimension dim = new Dimension (100 , 100) ;
private Color color [] = { Color .red , Color . blue };
private int index = 0;
public Plansa () {
this . addMouseListener (new MouseAdapter () {
public void mouseClicked ( MouseEvent e) {
index = 1 - index ;
repaint ();
}
});
}
public void paint ( Graphics g) {
g. setColor ( color [ index ]);
g. drawRect (0, 0, dim .width , dim. height );
g. setColor ( color [1 - index ]);
g. fillOval (0, 0, dim .width , dim. height );
}

Folosirea clasei Canvas


public Dimension getPreferredSize () {
return dim ;
}
}
class Fereastra extends JFrame {
public Fereastra ( String titlu ) {
super ( titlu );
setSize (200 , 200) ;
setDefaultCloseOperation(EXIT_ON_CLOSE);
add (new Plansa () , BorderLayout . CENTER );
}
}
public class TestCanvas {
public static void main ( String args []) {
new Fereastra (" Test Canvas "). show ();
}
}

Contextul grafic de desenare


Un context grafic este un obiect de tip
Graphics folosit pentru desenare:
pe o poriune de ecran
la imprimant
ntr-o zon virtual de memorie.
Metode:
primitive grafice: desenarea de figuri
geometrice, texte i imagini
stabilirea proprietilor contextului grafic:
culoare, font
originea coordonatelor
suprafaa vizibil
modul de desenare

Proprietile contextului grafic

Primitive grafice
Desenarea textelor - drawString
drawString("Hello", 10, 20);
l Desenarea figurilor geometrice
Linie: drawLine, drawPolyline
Dreptunghi simplu: drawRect, fillRect,
clearRect
Dreptunghi cu chenar: draw3DRect
Dreptunghi cu chenar ridicat sau adncit:
fill3DRect
Dreptunghi cu coluri: drawRoundRect
Dreptunghi cu coluri rotunjite: fillRoundRect
Poligon: drawPolygon, fillPolygon
Oval (Elips) drawOval, fillOval
Arc circular sau eliptic: drawArc, fillArc
l

Folosirea fonturilor
Parametrii unui font
Numele fontului: Helvetica Bold, Arial, Bold
Italic, etc.
Familia din care face parte fontul: Helvetica,
Arial, etc.
Dimensiunea fontului (nlimea sa)
Stilul fontului: ngroat (bold), nclinat (italic);
Metrica fontului.
Clase: Font, FontMetrics
Stabilirea unui font: setFont

Clasa Font
l
l

Incapsuleaz toate informaiile fontului, mai puin


metrica sa.
Font(String name, int style, int size)
new Font("Dialog", Font.PLAIN, 12);
new Font("Arial", Font.ITALIC, 14);
new Font("Courier", Font.BOLD, 10);
Pentru componente etichetate
Label label = new Label("Un text");
label.setFont(new Font("Dialog", Font.PLAIN, 12));
In metoda paint(Graphics g)
g.setFont(new Font("Courier", Font.BOLD, 10));
g.drawString("Alt text", 10, 20);
Lista fonturilor instalate:
Font[] fonturi = GraphicsEnvironment.
getLocalGraphicsEnvironment().getAllFonts();

Lucrul cu fonturi
import java . awt .*;
import javax.swing.*;
class Fonturi extends Canvas {
private Font [] fonturi ;
Dimension canvasSize = new Dimension (400 , 400) ;
public Fonturi () {
fonturi = GraphicsEnvironment .
getLocalGraphicsEnvironment (). getAllFonts ();
canvasSize . height = (1 + fonturi . length ) * 20;
}
public void paint ( Graphics g) {
String nume ;
for (int i=0; i < fonturi . length ; i ++) {
nume = fonturi [i]. getFontName ();
g. setFont (new Font (nume , Font .PLAIN , 14));
g. drawString (i + ". " + nume , 20, (i + 1) * 20);
}
}

Lucrul cu fonturi
public Dimension getPreferredSize () {
return canvasSize ;
}
}
class Fereastra extends JFrame {
public Fereastra ( String titlu ) {
super ( titlu );
setDefaultCloseOperation(EXIT_ON_CLOSE);
ScrollPane sp = new ScrollPane ();
sp.add(new Fonturi());
sp. setSize (200 , 200) ;
add (sp , BorderLayout . CENTER );
pack ();
}
}
class TestAllFonts {
public static void main ( String args []) {
new Fereastra ("All fonts "). show ();
}
}

Clasa FontMetrics
Informaii despre metrica unui font.
public void paint(Graphics g) {

FontMetrics fm = g.getFontMetrics();
}
Metode
getHeight
stringWidth
charWidth

Clasa FontMetrics
Metrica unui font const n urmtoarele atribute pe
care le au caracterele sale:
Linia de baz: este linia dup care sunt aliniate
caracterele unui font;
Linia de ascenden: linia superioara pe care nu o
depaseste nici un caracter din font
Linia de descenden: linia inferioar sub care nu
coboar nici un caracter din font;
Ascendentul: distana ntre linia de baz i linia de
ascenden;
Descendentul: distana ntre linia de baz i linia de
descenden;
Limea: limea unui anumit caracter din font;
Distana ntre linii (leading): distana optim ntre
dou linii de text scrise cu acelai font.
Inlimea: distana dintre liniile de baz
(leading+ascent+descent);
exemplu
l

Folosirea culorilor
Red Green Blue Alpha (0255,0.0 1.0)
l Clase: Color, SystemColor
l Constante
Color rosu = Color.red;
Color galben = Color.yellow;
Color fundal = SystemColor.desktop;
l Constructori
// Exemple de folosire a constructorilor:
Color alb = new Color(255, 255, 255);
Color negru = new Color(0, 0, 0);
Color rosuOpac = new Color(255, 0, 0);
Color rosuTransparent = new Color(255, 0, 0, 128);
l Metode
brighter, darker, getRed, etc
l

Folosirea culorilor
int r = rValue.getValue();
int g = gValue.getValue();
int b = bValue.getValue();
int a = aValue.getValue();
color = new Color(r, g, b, a);
repaint();
...
public void paint(Graphics g) {
g.setColor(Color.black);
g.setFont(new Font("Arial", Font.BOLD, 12));
String text = "";
text += " R=" + color.getRed();
text += " G=" + color.getGreen();
text += " B=" + color.getBlue();
text += " A=" + color.getAlpha();
g.drawString(text, 0, 30);
g.setColor(color);
g.fillRect(0, 0,canvasSize.width, canvasSize.height);
}

Folosirea imaginilor
Aceasta este o imagine:

Formate permise: gif sau jpeg


Clasa: Image
Afiarea unei imagini:
1. Crearea unui obiect de tip Image;
2. Afiarea propriu-zis ntr-un context grafic;

Folosirea imaginilor
Crearea unui obiect Image
Toolkit toolkit = Toolkit.getDefaultToolkit();
Image image1 = toolkit.getImage("poza.gif");
Image image2 = toolkit.getImage(
new URL("http://www.infoiasi.ro/~acf/poza.gif"));
l Afiarea unei imagini
Image img =
Toolkit.getDefaultToolkit().getImage("taz.gif");
g.drawImage(img, 0, 0, this);
g.drawImage(img, 0, 200, 100, 100, this);
g.drawImage(img, 200, 0, 200, 400, Color.yellow, this);
//Formatul cel mai general:
boolean drawImage(Image img, int x, int y, int width,
int height, Color bgcolor, ImageObserver observer)
l

Monitorizarea ncrcrii
imaginilor
l

Interfaa ImageObserver
boolean imageUpdate (Image img, int flags, int
x, int y, int w, int h )

flags:ABORT, ALLBITS, ERROR, HEIGHT, WIDTH,


PROPERTIES
// Imaginea este completa
(flags & ALLBITS) != 0
// Eroare sau transfer intrerupt
(flags & ERROR | ABORT ) != 0

public boolean imageUpdate(Image img, int flags,


int x, int y, int w, int h) {
// Desenam doar daca toti bitii sunt disponibili
if (( flags & ALLBITS) != 0) repaint();
// Daca sunt toti bitii nu mai sunt necesare
// noi update-uri
return ( (flags & (ALLBITS | ABORT)) == 0);

Mecanismul de double-buffering
l

implic realizarea unui desen n memorie i apoi transferul


su pe ecran, pentru a elimina efectul neplcut de clipire
(flickering) rezultat atunci cnd sunt efectuate redesenri
repetate la intervale mici de timp (crearea de animaii).

// Supradefinim update pentru a elimina stergerea desenului


public void update(Graphics g) {
paint( g );
}
public void paint(Graphics g) {
// Desenam in memorie pe un obiect de tip Image
// w si h sunt dimensiunile desenului
Image img = createImage(w, h);
Graphics gmem = img.getGraphics();
// Realizam desenul folosind gmem
gmem.setColor(...);
gmem.fillOval(...); ...
// Transferam desenul din memorie pe ecran
// desenand de fapt imaginea creata
g.drawImage(img, 0, 0, this);
gmem.dispose();
}

Tiprirea componentelor
java.awt.print
l Interfaa Printable
public int print(Graphics g, PageFormat pf, int pageIndex)
throws PrinterException {
// Descrierea imaginii obiectului
// Poate fi un apel la metoda paint: paint(g)
if (ceva nu este in regula) {
return Printable.NO_SUCH_PAGE;
}
return Printable.PAGE_EXISTS;
}
Etapele tipririi:
1. Crearea unei sesiuni de tiprire: PrinterJob.getPrinterJob
2. Specificarea obiectului care va fi tiprit: setPrintable;
3. Opional, iniierea unui dialog cu utilizatorul pentru
precizarea unor parametri legai de tiprire: printDialog;
4. Tiprirea efectiv: print.
l

Tiprirea unei componente


import java .io .*;
import java . awt .*;
import java . awt. event .*;
import java . awt. print .*;
import javax.swing.*;
class Plansa extends Canvas implements Printable {
Dimension d = new Dimension (400 , 400) ;
public Dimension getPreferredSize () {
return d; }
public void paint ( Graphics g) {
g. drawRect (200 , 200 , 100 , 100) ;
g. drawOval (200 , 200 , 100 , 100) ;
g. drawString (" Hello ", 200 , 200) ;
}
public int print ( Graphics g, PageFormat pf , int pi) throws
PrinterException {
if (pi >= 1) return Printable . NO_SUCH_PAGE ;
paint (g);
g. drawString (" Numai la imprimanta ", 200 , 300) ;
return Printable . PAGE_EXISTS ;
}
}

Tiprirea unei componente


class Fereastra extends JFrame implements ActionListener {
private Plansa plansa = new Plansa ();
private JButton print = new JButton (" Print ");
public Fereastra ( String titlu ) {
super ( titlu );
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
add (plansa , BorderLayout . CENTER );
JPanel south = new JPanel ();
south.setLayout(new FlowLayout());
south .add( print );
add (south , BorderLayout . SOUTH );
print . addActionListener ( this );
pack ();
}
public void actionPerformed ( ActionEvent e) {
// 1. Crearea unei sesiuni de tiparire
PrinterJob printJob = PrinterJob . getPrinterJob ();
// 2. Stabilirea obiectului ce va fi tiparit
printJob . setPrintable ( plansa );

Tiprirea unei componente


// 3. Initierea dialogului cu utilizatorul
if ( printJob . printDialog ()) {
try {
// 4. Tiparirea efectiva
printJob . print ();
} catch ( PrinterException ex) {
System . out. println (" Exceptie la tiparire !");
ex. printStackTrace ();}
}
}
}
class TestPrint {
public static void main ( String args []) throws
Exception {
Fereastra f = new Fereastra (" Test Print ");
f. show ();
}
}

Tiprirea textelor
Flux ctre lpt1 sau /dev/lp.
import java .io .*;
import java . awt .*;
class TestPrintText {
public static void main ( String args []) throws Exception{
// pentru Windows
PrintWriter imp = new PrintWriter ( new FileWriter
("lpt1"));
/* pentru UNIX
PrintWriter imp = new PrintWriter (new FileWriter (
"/dev/lp "));*/
imp . println (" Test imprimanta ");
imp . println (" ABCDE ");
imp . close ();
}
}

Appleturi

Programare Orientat pe Obiecte

Introducere
l

l
l
l

program Java de dimensiuni reduse ce


gestioneaz o suprafa de afiare (container)
care poate fi inclus ntr-o pagin Web.
miniaplicatie.
poate fi format din una sau mai multe clase
o clas principal ce extinde clasa Applet
(JApplet) - clasa ce trebuie specificat n
documentul HTML ce descrie pagina Web n
care dorim s includem appletul.
un applet nu poate fi executat independent, va
fi executat de browserul n care este ncrcat
pagina Web ce conine appletul respectiv.
ciclul de viat al unui applet: dictat de
evenimentele generate de ctre browser la
vizualizarea documentului HTML ce conine
appletul.

Ierarhia claselor din care deriv


appleturile
lPachetul

care ofer suport pentru crearea de


appleturi este java.applet. In pachetul javax.swing
exist i clasa JApplet, care extinde Applet, oferind
suport pentru crearea de appleturi pe arhitectura de
componente JFC/Swing.

Crearea unui applet simplu


1. Scrierea codului sursa
import java.awt.* ;
import javax.swing.* ;
public class FirstApplet extends JApplet {
Image img;
public void init() {
img = getImage(getCodeBase(), image.jpg");
}
public void paint (Graphics g) {
g.drawImage(img, 100, 0, this);
g.drawOval(0,0,120,50);
g.drawString(Ce ziceti de asta?", 0, 25);
}
}
l Pentru a putea fi executat de browser, clasa
principal a appletului trebuie s fie public.

Crearea unui applet simplu (2)


2. Salvarea fiierelor surs
- clasa principal a appletului va fi salvat
ntr-un fiier cu acelai nume i extensia
java
- FirstApplet.java.
3. Compilarea
- javac FirstApplet.java
- rezulta FirstApplet.class
4. Rularea appletului
Applet-urile nu ruleaza independent. Ele pot
fi rulate doar prin intermediul unui browser:
Internet Explorer, Netscape, Mozilla, Opera,
etc. sau printr-un program special cum ar fi
appletviewer din kitul de dezvoltare J2SDK.

Crearea unui applet simplu (3)


Pentru a executa un applet trebuie s facem dou
operaii:
Crearea unui fiier HTML n care vom include appletul.
fiierul simplu.html:
<html>
<head>
<title>Primul applet Java</title>
</head>
<body>
<applet code=FirstApplet.class width=400
height=400>
</applet>
</body>
</html>
Vizualizarea appletului: se deschide fisierul
simplu.html folosind unul din browser-ele amintite
sau efectund apelul: appletviewer simplu.html.

Ciclul de via al unui applet


Fiecare etap este strns legat de un eveniment
generat de ctre browser i determin apelarea
unei metode specifice din clasa ce implementeaz
appletul.
Incrcarea n memorie
Este creat o instana a clasei principale a
appletului i ncrcat n memorie.
Iniializarea
Este apelat metoda init ce permite iniializarea
diverselor variabile,citirea unor parametri de intrare,
etc.
Pornirea
Este apelat metoda start
Execuia propriu-zis
l

Interaciunea dintre utilizator i componentele afiate pe


suprafaa appletului
Executarea unui anumit cod ntr-un fir de execuie.
In unele situaii ntreaga execuie a appletului se consum
la etapele de iniializare i pornire.

Ciclul de via al unui applet


Oprirea temporar
- este apelat metoda stop ce oprete temporar
execuia pe perioada n care nu este vizibil, pentru
a nu consuma inutil din timpul procesorului.

n cazul n care utilizatorul prsete pagina Web n care


ruleaz appletul
dac fereastra browserului este minimizat. n momentul n
care pagina Web ce conine appletul devine din nou activ,
va fi reapelat metoda start.

Oprirea definitiv
- La nchiderea tuturor instanelor browserului folosit
pentru vizualizare, appletul va fi eliminat din
memorie i va fi apelat metoda destroy a acestuia,
pentru a-i permite s elibereze resursele deinute.
- Apelul metodei destroy este ntotdeauna precedat
de apelul lui stop.

Metodele specifice appleturilor


lAceste

metode sunt apelate automat la diverse evenimente


generate de ctre browser i nu trebuie apelate explicit din
program
lsunt definite n clasa Applet

Metoda

Situaia n care este apelat

init

La iniializarea appletului. Teoretic, aceast metod


ar trebui s se apeleze o singur dat, la prima
afiare a appletului n pagin, ns, la unele
browsere, este posibil ca ea s se apeleze de mai
multe ori.

start

Imediat dup iniializare i de fiecare dat


cnd appletul redevine activ, dup o oprire
temporar.

stop

De fiecare dat cnd appletul nu mai este vizibil


(pagina Web nu mai este vizibil, fereastra
browserului este minimizat, etc) i nainte de
destroy.

destroy

La nchiderea ultimei instane a browserului


care a ncrcat n memorie clasa principal a
appletului.

Structura general a unui applet


import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class StructuraApplet extends JApplet {
public void init() {
}
public void start() {
}
public void stop() {
}
public void destroy() {
}
}

Interfaa grafic cu utilizatorul


l

Clasa Applet este o extensie a superclasei


Container, ceea ce nseamn c appleturile
sunt, nainte de toate, suprafee de afiare.
Plasarea componentelor, gestionarea
poziionrii lor i tratarea evenimentelor
generate se realizeaz la fel ca i n cazul
aplicaiilor.
Uzual, adugarea componentelor pe
suprafaa appletului precum i stabilirea
obiectelor responsabile cu tratarea
evenimentelor generate sunt operaiuni ce
vor fi realizate n metoda init.
Gestionarul de poziionare implicit este
FlowLayout, ns acesta poate fi schimbat
prin metoda setLayout.

Definirea i folosirea parametrilor


Parametrii sunt pentru appleturi ceea ce argumentele de
la linia de comand sunt pentru aplicaiile independente.
l Permit utilizatorului s personalizeze aspectul sau
comportarea unui applet fr a-i schimba codul i
recompila clasele.
l Definirea: n cadrul tagului APPLET din documentul
HTML ce conine appletul prin atributul PARAM.
l Fiecare parametru are un nume, specificat prin NAME i
o valoare, specificat prin VALUE:
<APPLET CODE="TestParametri.class" WIDTH=100
HEIGHT=50>
<PARAM NAME=textAfisat VALUE="Salut">
<PARAM NAME=numeFont VALUE="Times New Roman">
<PARAM NAME=dimFont VALUE=20>
</APPLET>
l tipul parametrilor este ntotdeauna ir de caractere,
indiferent dac valoarea este ntre ghilimele sau nu.
l Fiecare applet are i un set de parametri prestabilii ale
cror nume nu vor putea fi folosite pentru definirea de
noi parametri
l

Definirea i folosirea parametrilor


l

getParameter: primete ca argument numele unui


parametru i returneaz valoarea acestuia. In cazul
n care nu exist nici un parametru cu numele
specificat, metoda ntoarce null, caz n care
programul trebuie s atribuie o valoare implicit
variabilei n care se dorea citirea respectivului
parametru.
Orice applet poate pune la dispoziie o
documentaie referitoare la parametrii pe care i
suport
Aceasta se realizeaz prin supradefinirea metodei
getParameterInfo, care returneaz un vector format
din triplete de iruri (numele parametrului, tipul su
i o descriere a sa).
Informaiile furnizate de un applet pot fi citite din
browserul folosit pentru vizualizare prin metode
specifice acestuia.
De exemplu, n appletviewer informaiile despre
parametri pot fi vizualizate la rubrica Info din meniul
Applet, n Netscape se folosete opiunea Page info
din meniul View, etc.

Folosirea parametrilor
un applet care s afieaz un text primit ca parametru,
folosind un font cu numele i dimensiunea specificate de
asemenea ca parametri.
import javax . swing.* ;
import java . awt .*;
public class TestParametri extends JApplet {
String text , numeFont ;
int dimFont ;
public void init () {
text = getParameter ("textAfisat");
if ( text == null ) text = " Hello "; // valoare implicita
numeFont = getParameter ("numeFont");
if ( numeFont == null ) numeFont = " Arial ";
try {
dimFont = Integer . parseInt ( getParameter
("dimFont"));
} catch ( NumberFormatException e) {
dimFont = 16;
}
}
l

Folosirea parametrilor
public void paint ( Graphics g) {
g. setFont (new Font ( numeFont , Font .BOLD ,
dimFont ));
g. drawString (text , 20, 20);
}
public String [][] getParameterInfo () {
String [][] info = {
// Nume Tip Descriere
{" textAfisat ", " String ", " Sirul ce va fi afisat "},
{" numeFont ", " String ", " Numele fontului "},
{" dimFont ", "int ", " Dimensiunea fontului "}
};
return info ;
}
}

Tag-ul APPLET
Sintaxa complet a tagului APPLET, cu ajutorul cruia pot fi
incluse appleturi n cadrul paginilor Web este:
<APPLET
CODE = clasaApplet
WIDTH = latimeInPixeli
HEIGHT = inaltimeInPixeli
[ARCHIVE = arhiva.jar]
[CODEBASE = URLApplet]
[ALT = textAlternativ]
[NAME = numeInstantaApplet]
[ALIGN = aliniere]
[VSPACE = spatiuVertical]
[HSPACE = spatiuOrizontal] >
[< PARAM NAME = parametru1 VALUE = valoare1 >]
[< PARAM NAME = parametru2 VALUE = valoare2 >]
...
[text HTML alternativ]
</APPLET>
Atributele puse ntre paranteze ptrate sunt opionale.
l

Tag-ul APPLET
CODE = clasaApplet
Numele fiierului ce conine clasa principal a
appletului. Acesta va fi cutat n directorul specificat
de CODEBASE. Extensia .class poate sau nu s
apar.
WIDTH =latimeInPixeli, HEIGHT =inaltimeInPixeli
Specific limea i nlimea suprafeei n care va fi
afiat appletul. Sunt obligatorii.
ARCHIVE = arhiva.jar
Specific arhiva n care se gsesc clasele appletului.
CODEBASE = directorApplet
Specific URL-ul la care se gsete clasa appletului.
Uzual se exprim relativ la directorul documentului
HTML. In cazul n care lipsete, se consider implicit
URL-ul documentului.
ALT = textAlternativ
Specific textul ce trebuie afiat dac browserul
nelege tagul APPLET dar nu poate rula appleturi
Java.

Tag-ul APPLET
NAME =numeInstantaApplet
Ofer posibilitatea de a da un nume respectivei instane
a appletului, astfel nct mai multe appleturi aflate pe
aceeai pagin s poat comunica ntre ele folosindu-se
de numele lor.
ALIGN =aliniere
Semnific modalitatea de aliniere a appletului n pagina
Web. Acest atribut poate primi una din urmtoarele
valori: left, right, top, texttop, middle, absmiddle,
baseline, bottom, absbottom
VSPACE =spatiuVertical, HSPACE = spatiuOrizontal
Specific numarul de pixeli dintre applet i marginile
suprafetei de afiare.
PARAM
Tag-urile PARAM sunt folosite pentru specificarea
parametrilor unui applet
text HTML alternativ
Este textul ce va fi afiat n cazul n care browserul nu
ntelege tagul APPLET. Browserele Java-enabled vor
ignora acest text.

Alte metode oferite de clasa


Applet
Punerea la dispozitie a unor informaii despre applet
- getAppletInfo: permite specificarea unor informaii
legate de applet cum ar fi numele, autorul,
versiunea, etc. Metoda returneaz un sir de
caractere continnd informaiile respective.
public String getAppletInfo() {
return "Applet simplist, autor necunoscut, ver 1.0";
}
l Aflarea adreselor URL referitoare la applet
getCodeBase - returneaz URL-ul directorului ce
conine clasa appletului;
getDocumentBase - returneaz URL-ul directorului
ce conine documentul HTML n care este inclus
appletul respectiv.
Aceste metode sunt foarte utile deoarece permit
specificarea relativ a unor fiiere folosite de un
applet, cum ar fi imagini sau sunete.
l

Alte metode oferite de clasa


Applet
Afiarea unor mesaje n bara de stare a browserului
public void init() {
showStatus("Initializare applet...");
}
l Afiarea imaginilor
l prin intermediul unei componente ce permite acest
lucru (Canvas), fie direct n metoda paint a appletului, folosind metoda drawImage a clasei Graphics.
l obinerea unei referine la imaginea respectiv se
va face cu ajutorul metodei getImage din clasa
Applet.
l argument:
adresa URL absolut a fiierului ce reprezint
imaginea
calea relativ la o anumit adres URL
l cea a directorului n care se gsete
documentul HTML ce conine appletul
(getDocumentBase)
l cea a directorului n care se gsete clasa
appletului (getCodeBase).
l

Afiarea imaginilor
import javax . swing . *;
import java . awt .*;
public class Imagini extends JApplet {
Image img = null ;
public void init () {
img = getImage ( getCodeBase () ,
"taz.gif");
}
public void paint ( Graphics g) {
g. drawImage (img , 0, 0, this );
}
}

Alte metode oferite de clasa


Applet
l

Aflarea contextului de execuie:


pagina n care acesta ruleaz, eventual mpreun cu
alte appleturi
este descris de interfaa AppletContext.
Crearea unui obiect ce implementeaz aceast
interfa se realizeaz de ctre browser, la apelul
metodei getAppletContext a clasei Applet.
Prin intermediul acestei interfee un applet poate
vedea n jurul sau, putnd comunica cu alte appleturi aflate pe aceeasi pagin sau cere browser-ului s
deschid diverse documente
AppletContext context = getAppletContext();
Afiarea unor documente n browser
showDocument: primete adresa URL a fiierului ce
conine documentul pe care dorim sa-l deschidem (text,
html, imagine, etc). Aceast metod este accesat prin
intermediul contextului de execuie al appletului.

try {
URL doc = new URL("http://www.pub.ro");
getAppletContext().showDocument(doc);
}
catch(MalformedURLException e) {
System.err.println("URL invalid! \n" + e);}

Arhivarea appleturilor
pentru ca un applet aflat pe o pagin Web s poat fi executat
codul su va fi transferat de pe serverul care gzduiete
pagina Web solicitat pe maina clientului.
l dimensiunea fiierelor care formeaz appletul trebuie s fie
ct mai redus
l dac appletul conine i alte clase n afar de cea principal
sau diverse resurse (imagini, sunete, etc), acestea vor fi
transferate prin reea abia n momentul n care va fi nevoie de
ele, oprind astfel temporar activitatea appletului pn la
ncrcarea lor.
l cea mai eficient modalitate de a distribui un applet este s
arhivm toate fiierele necesare acestuia.
l Arhivarea fiierelor unui applet se face cu utilitarul jar, oferit n
distribuia J2SDK.
// Exemplu
jar cvf arhiva.jar ClasaPrincipala.class AltaClasa.class
imagine.jpg sunet.au
// sau
jar cvf arhiva.jar *.class *.jpg *.au
l Includerea unui applet arhivat ntr-o pagin Web se realizeaz
specificnd pe lng numele clasei principale i numele
arhivei care o conine:
<applet archive=arhiva.jar code=ClasaPrincipala width=400
height=200 />
l

Restricii de securitate
un applet se execut pe maina utilizatorului care a solicitat
pagina Web ce conine appletul respectiv
l este foarte important s existe anumite restricii de securitate
care s controleze activitatea acestuia, pentru a preveni
aciuni ru intenionate, cum ar fi tergeri de fiiere, etc., care
s aduc prejudicii utilizatorului.
l procesul care ruleaz appleturi instaleaz un manager de
securitate, un obiect de tip SecurityManager care va
superviza activitatea metodelor appletului, aruncnd excepii
de tip SecurityException n cazul n care una din acestea
ncearc s efectueze o operaie nepermis.
Un applet nu poate s:
Citeasc sau s scrie fiiere de pe calculatorul pe care a fost
ncarcat (client).
Deschid conexiuni cu alte maini n afar de cea de pe care
provine (host).
Porneasc programe pe maina client.
Citeasc diverse proprieti ale sistemului de operare al
clientului.
Ferestrele folosite de un applet, altele dect cea a browserului,
vor arta altfel dect ntr-o aplicaie obinuit, indicnd faptul
c au fost create de un applet.
l

Appleturi care sunt i aplicaii


Deoarece clasa Applet este derivat din
Container, deci i din Component, ea
descrie o suprafa de afiare care poate fi
inclus ca orice alt component ntr-un alt
container, cum ar fi o fereastr.
l Un applet poate funciona i ca o aplicaie
independent astfel:
Adugm metoda main clasei care descrie
appletul, n care vom face operaiunile
urmtoare.
Crem o instan a appletului i o adugm
pe suprafaa unei ferestre.
Apelm metodele init i start, care ar fi fost
apelate automat de ctre browser.
Facem fereastra vizibil.

Applet i aplicaie
import java . applet . Applet ;
import java . awt .*;
public class AppletAplicatie extends Applet {
public void init () {
add (new Label (" Applet si aplicatie "));
}
public static void main ( String args []) {
AppletAplicatie applet = new AppletAplicatie ();
Frame f = new Frame (" Applet si aplicatie ");
f. setSize (200 , 200) ;
f.add(applet , BorderLayout . CENTER );
applet . init ();
applet . start ();
f. show ();
}
}

Fire de execuie

Programare Orientat pe Obiecte

Fire de execuie
Ce este un fir de execuie ?
Crearea unui fir de execuie
Ciclul de via
Terminarea firelor de execuie
Sincronizarea firelor de execuie
Monitoare
Semafoare
Probleme legate de sincronizare
Gruparea firelor de execuie
Fluxuri de tip pipe
Clasele Timer i TimerTask

Ce este un fir de execuie ?


lProgramare

concurent
lFirele de execuie fac trecerea de la programarea
secvenial la programarea concurent.
lUn fir de execuie este o succesiune secvenial de
instruciuni care se execut n cadrul unui proces.
Program (proces)

Program (proces)

Proces - mai multe fire de execuie

Asemnri / Deosebiri
Asemnri:
Concuren
Planificare la execuie
Deosebiri:
Un fir de execuie poate exista doar ntr-un proces
Proces uor, Context de execuie
Proces nou: cod + date
Fir nou: la crearea unui fir nu este copiat dect codul
procesului printe, toate firele de execuie avnd
acces la aceleai date, datele procesului original.
Utilitatea:
calcule matematice
ateptarea eliberrii unei resurse
desenarea componentelor unei aplicaii GUI

Crearea unui fir de execuie


Orice fir de execuie este o instan a clasei
Thread
Crearea unui fir de execuie:
extinderea clasei Thread
implementarea interfeei Runnable
Clasa Thread:
l implementeaz un fir de execuie generic
care, implicit, nu face nimic
Interfaa Runnable
Definete un protocol comun pentru obiecte
active
Conine metoda run
Este implementat de clasa Thread

Extinderea clasei Thread


public class FirExecutie extends Thread {
public FirExecutie(String nume) {
// Apelam constructorul superclasei
super(nume);
}
public void run() {
//Codul firului de executie
...
}
}
l Lansarea unui fir
// Cream firul de executie
FirExecutie fir = new FirExecutie("simplu");
// Lansam in executie
fir.start();

Folosirea clasei Thread


class AfisareNumere extends Thread {
private int a, b, pas;
public AfisareNumere (int a, int b, int pas ) {
this .a = a;
this .b = b;
this .pas = pas;
}
public void run () {
for (int i = a; i <= b; i += pas)
System . out. print (i + " " );
}
}
public class TestThread {
public static void main ( String args []) {
AfisareNumere fir1 , fir2 ;
fir1 = new AfisareNumere (0, 100 , 5);
// Numara de la 0 la 100 cu pasul 5
fir2 = new AfisareNumere (100 , 200 , 10);
// Numara de la 100 la 200 cu pasul 10
fir1 . start ();
fir2 . start ();
// Pornim firele de executie, ele vor fi distruse automat la
// terminarea lor
}
}
//Secvential...
0 5 10 15 20 25 30 35 40 45 50 55 ...
//Un posibil rezultat
0 100 110 5 10 15 120 130 20 140 25 ...

Implementarea interfeei
Runnable
class Fir extends Parinte, Thread // Incorect
public class ClasaActiva implements Runnable {
public void run() {
//Codul firului de executie
...
}
}
...
ClasaActiva obiectActiv = new ClasaActiva();
Thread fir = new Thread(obiectActiv);
fir.start();
// Sau
public class FirExecutie implements Runnable {
private Thread fir = null;
public FirExecutie() {
fir = new Thread(this);
}
public void run() { ... }
}
...
FirExecutie fir = new FirExecutie();

Ciclul de via
Starea New Thread
Thread fir = new Thread(obiectActiv);
// fir se gaseste in starea "New Thread"
Nu are alocate resurse
Putem apela start
IllegalThreadStateException

Ciclul de via (2)


Starea Runnable
fir.start();
//fir se gaseste in starea "Runnable"
Alocare resurse
Planificare la procesor
Apel run
Starea Not Runnable
Este adormit prin apelul metodei sleep;
try {
// Facem pauza de o secunda
Thread.sleep(1000);
} catch (InterruptedException e) { ...}
A apelat metoda wait, ateptnd ca o anumit
condiie s fie satisfacut (notify);
Este blocat ntr-o operaie de intrare/ieire.

Starea Dead
Firele de execuie trebuie s se termine natural.
l Nu mai exist metoda stop.
public void run() {
for(int i = a; i <= b; i += pas)
System.out.print(i + " " );
}
l Variabile de terminare
public boolean executie = true;
public void run() {
while (executie) {
...
}
}
System.exit termin forat toate firele de execuie.

Metoda isAlive
true - Runnable sau Not Runnable
false - New Thread sau Dead
NumaraSecunde fir = new NumaraSecunde();
// isAlive retuneaza false
// (starea este New Thread)
fir.start();
// isAlive retuneaza true
// (starea este Runnable)
fir.executie = false;
// isAlive retuneaza false
// (starea este Dead)

Prioriti de execuie
Modele de lucru:
Modelul cooperativ - n care firele de execuie decid
cnd s cedeze procesorul; dezavantajul este c
unele fire pot acapara procesorul, nepermind i
execuia altora pn la terminarea lor.
Modelul preemptiv - cuante de timp -partajare
resurse, dezavantajul fiind nevoia de a sincroniza
accesul firelor la resursele comune.
Metoda setPriority:
MAX_PRIORITY = 10;
MIN_PRIORITY = 1;
NORM_PRIORITY= 5;
Un fir de execuie cedeaz procesorul:
prioritate mai mare
metoda sa run se termin
yield
timpul alocat a expirat

Sincronizarea firelor de execuie


Partajarea resurselor comune
Ateptarea ndeplinirii unor condiii
Scenariul productor / consumator
class Buffer {
private int number = -1;
public int get() {
return number;
}
public void put(int number) {
this.number = number;
}
}

Clasa Producator
class Producator extends Thread {
private Buffer buffer;
public Producator(Buffer b) {
buffer = b;
}
public void run() {
for (int i = 0; i < 10; i++) {
buffer.put(i);
System.out.println("Producatorul a pus:\t" + i);
try {
sleep((int)(Math.random() * 100));
} catch (InterruptedException e) { }
}
}
}

Clasa Consumator
class Consumator extends Thread {
private Buffer buffer;
public Consumator(Buffer b) {
buffer = b;
}
public void run() {
int value = 0;
for (int i = 0; i < 10; i++) {
value = buffer.get();
System.out.println("Consumatorul
a primit:\t" + value);
}
}
}

Mecanisme de sincronizare
Activitile productorului i consumatorului trebuie
sincronizate la nivelul resursei comune n dou
privine:
1. Cele dou fire de execuie nu trebuie s acceseze
simultan buffer-ul; acest lucru se realizeaz prin
blocarea obiectului Buffer atunci cnd este accesat
de un fir de execuie, astfel nct nici nu alt fir de
execuie s nu-l mai poat accesa (Monitoare).
2. Cele dou fire de execuie trebuie s se
coordoneze, adic productorul trebuie s
gseasc o modalitate de a spune consumatorului
c a plasat o valoare n buffer, iar consumatorul
trebuie s comunice productorului c a preluat
aceast valoare, pentru ca acesta s poat genera
o alta. Pentru a realiza aceasta comunicare, clasa
Thread pune la dispoziie metodele wait, notify,
notifyAll. (Semafoare).

Monitoare
Seciune critic = segment de cod ce gestioneaz o
resurs comun
Monitor = monitorizeaz accesul la o seciune critic;
lact asociat fiecrui obiect
l Controlul accesului ntr-o seciune critic se face
prin cuvntul cheie synchronized
public synchronized void put(int number) {
// buffer blocat de producator
...
// buffer deblocat de producator
}
public synchronized int get() {
// buffer blocat de consumator
...
// buffer deblocat de consumator
}

Semafoare
Metodele wait - notify
class Buffer {
private int number = -1;
private boolean available = false;
public synchronized int get() {
while (!available) {
try {
wait();
// Asteapta producatorul sa puna o valoare
} catch (InterruptedException e) {
e.printStackTrace();
}
}
available = false;
notifyAll();
return number;
}
l

Semafoare
public synchronized void put(int number) {
while (available) {
try {
wait();
// Asteapta consumatorul sa preia valoarea
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.number = number;
available = true;
notifyAll();
}
}

Probleme legate de sincronizare


Deadlock - Problema filozofilor:
Solicitarea resursele n aceeai ordine
Monitoare care s controleze accesul la un
grup de resurse
Variabile care s informeze disponibilitatea
resurselor fr a bloca monitoarele
Arhitectura sistemului
l

Fire de execuie inaccesibile


Operaiile blocante IO nu trebuie fcute n
metode sincronizate.

Variabile volatile
class TestVolatile {
boolean test;
public void metoda() {
test = false;
//
if (test) {
// Aici se poate ajunge...
}
}
l Modificatorul volatile informeaz
compilatorul s nu optimizeze codul n care
aceasta apare, previzionnd valoarea pe
care variabila o are la un moment dat.

Gruparea firelor de execuie


pune la dispoziie un mecanism pentru manipularea
firelor ca un tot i nu individual (putem s pornim sau s
suspendm toate firele dintr-un grup cu un singur apel
de metod)
l Clasa ThreadGroup
l Fiecare fir de execuie Java este membru al unui grup,
afilierea fiind permanent.
//Exemplu
ThreadGroup grup1 = new ThreadGroup("Producatori");
Thread p1 = new Thread(grup1, "Producator 1");
Thread p2 = new Thread(grup1, "Producator 2");
ThreadGroup grup2 = new ThreadGroup("Consumatori");
Thread c1 = new Thread(grup2, "Consumator 1");
Thread c2 = new Thread(grup2, "Consumator 2");
Thread c3 = new Thread(grup2, "Consumator 3");
l Un grup poate avea ca printe un alt grup - ierarhie de
grupuri, cu rdcina grupul implicit main
l

Comunicarea prin fluxuri de tip


pipe
PipedReader, PipedWriter
PipedOutputStream, PipedInputStream
Conectarea fluxurilor
PipedWriter pw1 = new PipedWriter();
PipedReader pr1 = new PipedReader(pw1);
// sau
PipedReader pr2 = new PipedReader();
PipedWriter pw2 = new PipedWriter(pr2);
// sau
PipedReader pr = new PipedReader();
PipedWriter pw = new PipedWirter();
pr.connect(pw) //echivalent cu
pw.connect(pr);

Exemplu
class Producator extends Thread {
private DataOutputStream out;
public void run() {
...
out.writeInt(i);
}
}
class Consumator extends Thread {
private DataInputStream in;
public void run() {
...
value = in.readInt();
}
}
...
PipedOutputStream pipeOut = new PipedOutputStream();
PipedInputStream pipeIn = new PipedInputStream(pipeOut);
DataOutputStream out = new DataOutputStream(pipeOut);
DataInputStream in = new DataInputStream(pipeIn);
Producator p1 = new Producator(out);
Consumator c1 = new Consumator(in);
p1.start();
c1.start();

Clasele Timer i TimerTask


Planificare unor aciuni pentru o singur
execuie sau pentru execuii repetate la
intervale regulate.
l Etape:
Crearea unei subclase Actiune a lui
TimerTask i supradefinirea metodei run
Crearea unui fir de execuie prin instanierea
clasei Timer;
Crearea unui obiect de tip Actiune;
Planificarea la execuie a obiectului de tip
Actiune, folosind metoda schedule din clasa
Timer;

Folosirea claselor Timer i


TimerTask
import java . util .*;
import java . awt .*;
class Atentie extends TimerTask {
public void run () {
Toolkit . getDefaultToolkit (). beep ();
System . out. print (".");
}
}
class Alarma extends TimerTask {
public String mesaj ;
public Alarma ( String mesaj ) {
this . mesaj = mesaj ;
}
public void run () {
System . out. println ( mesaj );
}
}
public class TestTimer {
public static void main ( String args []) {
// Setam o actiune repetitiva , cu rata fixa
final Timer t1 = new Timer ();
t1. scheduleAtFixedRate ( new Atentie () , 0, 1*1000) ;
// Folosim o clasa anonima pentru o alta actiune
Timer t2 = new Timer ();

Folosirea claselor Timer i


TimerTask
t2. schedule ( new TimerTask () {
public void run () {
System . out. println ("S-au scurs 10 sec .");
// Oprim primul timer
t1. cancel ();
}
}, 10*1000) ;
// Setam o actiune pentru ora 22:30
Calendar calendar = Calendar . getInstance ();
calendar .set( Calendar . HOUR_OF_DAY , 22);
calendar .set( Calendar .MINUTE , 30);
calendar .set( Calendar .SECOND , 0);
Date ora = calendar . getTime ();
Timer t3 = new Timer ();
t3. schedule(new Alarma("Toti copiii la culcare!"),
ora);
}
}