Sunteți pe pagina 1din 89

1

i în sfârşit ... Java


Scurt istoric

Java este un limbaj de programare orientat pe obiecte asemănător limbajului


C++. El a fost dezvoltat de firma Sun, prima semnalare a apariţiei sale datând din
1991. Limbajul a fost dezvoltat în cadrul unui proiect denumit Green, obiectivul
acestuia fiind dezvoltarea unui limbaj pentru programarea echipamentelor electrice
şi electronice "inteligente" şi comunicarea cu acestea. Punctul de pornire a fost
limbajul C++, dar Java aduce acestuia un volum semnificativ de modificări, mai ales
în sensul simplificării, creşterii rigurozităţii şi a portabilităţii. Conducătorul proiectului,
Green James Gosling, este considerat părintele limbajului Java. Noului limbaj i s-a
dat la început numele Oak (eng. stejar) dar acesta a fost revendicat de o altă firmă şi
realizatorii l-au schimbat în Java, aluzie la sursa băuturii favorite a memrilor echipei -
cafeaua.

Caracteristicile noului limbaj au intrat însă şi în atenţia şi firmelor preocupate


de dezvoltarea Internetului. A realiza aplicaţii având un cod redus, uşor deci de
transportat prin reţele şi care pot fi rulate pe diferite tipuri de calculatoare şi de
sisteme de operare reprezenta o problemă dificilă. Dar nu şi pentru echipa care a
creat Java, care în 1994 a pus la punct o aplicaţie destinată navigării prin Internet
(denumită HotJava) care integra suportul necesar executării în pagina de web a
unor mici aplicaţii, denumite applet-uri. A mai trebuit un pic de sprijin din partea
firmei Netscape, al cărui program de navigare în Internet era deja larg răspândit şi
succesul imediat al limbajului Java a fost asigurat.

Tratarea programelor scrise în Java

Un program scris în limbajul Java este supus unei compilări în urma căreia se
obţine un cod intermediar (cod de octeţi) care este apoi interpretat şi executat de o
aplicaţie specializată, care poate fi asimilată unui procesor virtual. Această aplicaţie
2

poartă denumirea de "maşină virtuală java" (eng. Java Virtual Machine, JVM
denumită mai nou JRE – Java Runtime Environment). Codul rezultat în urma
compilării poate fi transferat şi apoi executat pe orice calculator pe care există
instalat JVM. Site-ul firmei Sun oferă spre descărcare, gratuit, aplicaţia JVM pentru
toate sistemele de operare majore.

Realizarea unei aplicaţii elementare în Java

Aplicaţiile Java pot fi realizate în mai multe moduri. Cel mai economic mod
este scrierea aplicaţiei într-un editor (Notepad este suficient) urmată de compilare şi
execuţie, ambele realizate prin comenzi în fereastra Command.
Exemplu:

Fişierul se salvează sub numele Grideala.java. Numele fişierului coincide cu


numele clasei conţinute în acesta.

compilare

executare
3

Aplicaţiile scrise în Java conţin una sau mai multe clase. De regulă clasele
sunt conţinute în fişiere distincte ale căror nume coincid cu numele claselor. Una
dintre clase va conţine metoda principală, main(), care defineşte punctul de început a
aplicaţiei.
Deşi iniţierea în Java folosind un editor simplu, compilatorul javac şi
procesorul virtual java poate fi o abordare în învăţarea limbajului, în cele ce urmează
aplicaţiile vor fi dezvoltate folosind unul dintre mediile integrate, NetBeans.

Netbeans şi JDK - instalare şi configurare

JDK (Java Development Kit) este un ansamblu de instrumente software


destinat dezvoltării de aplicaţii în Java oferit de firma Sun Microsystems. Pachetul
poate fi descărcat de pe site-ul firmei:
(http://java.sun.com/javase/downloads/index.jsp).
Site-ul firmei Sun oferă spre descărcare şi versiuni de JRE (Java Runtime
Environment, procesorul virtual Java necesar rulării aplicaţiilor) dar, pentru
dezvoltarea de aplicaţii cu NetBeans trebuie descărcat şi instalat JDK. De altfel în
kitul conţinând JDK există şi JRE.
Mediul integrat de dezvoltare NetBeans poate fi descărcat de la adresa
http://www.netbeans.info/downloads/index.php. El se instalează în mod obligatoriu
după instalarea JDK. Mediul face apel de altfel la instrumentele de dezvoltare de
aplicaţii integrate în JDK.

Realizarea unei aplicaţii simple în NetBeans


Aplicaţia deja realizată poate fi uşor refăcută folosind NetBeans. Înainte de a
realiza însă noua aplicaţie este bine să creaţi pe disc un director care să conţină
toate proiectele pe care le veţi realiza. La crearea unui nou proiect, NetBeans va
crea automat un director în care va plasa componentele acestuia.
Paşi necesari realizării unui proiect sunt următorii:

1. După pornirea mediului se selectează File / New project:


4

2. În fereastra New Project se selectează categoria (General) şi tipul

proiectului (Java Application)


5

În noua ferestră se indică numele proiectului (Greutate), directorul în care va


fi creat (D:\ProiecteJava) şi se deselectează caseta de validare Create Main Class
deoarece clasa principală va fi creată ulterior.
Rezultatul va fi crearea componentelor proiectului Greutate.

3. În meniul contextual afişat la selectarea proiectului Greutate (clic cu

butonul drept) se selectează New / Java Class:

În fereastra care se afişează se defineşte numele clasei - tot Greutate


deoarece va fi clasa principală a proiectului (va conţine main()) şi se indică numele
pachetului (Package, echivalentul în Java a spaţiului de nume din C++ introdus prin
directiva using) care va conţine clasa. Mediul NetBeans permite păstrarea claselor
aplicaţiei într-un pachet implicit, DefaultPackage, dar este bine ca într-un proiect
clasele să fie dispuse într-un pachet creat în acest scop şi nu în cel implicit. Odată
introdus numele pachetului, NetBeans va crea un director purtând numele acestuia.
6

Rezultat:

Clasa creată nu conţine deocamdată decât un constructor.

4. Se adaugă clasei metoda main():


7

Metoda main() trebuie în continuare completată:

5. Se salvează şi se execută aplicaţia:


8

Save All Run Main Project (F6)

În NetBeans consola este fereastra Output. În această fereastră vor fi scrise


atât mesajele mediului de programare generate în timpul procesării fişierelor
aplicaţiei (compilare, execuţie) cât şi şirurile de caractere afişate prin apelul
metodelor System.out.print() sau System.out.println().

Observaţie: Proiectele realizate cu NetBeans vor fi afişate sub forma unui

arbore în fereastra Projects. Butonul realizează construirea executabilului şi


executarea proiectului principal. Pentru a impune proiectul principal se selectează
File / Set Main Project sau se afişează meniul contextual aferent proiectului (clic cu
butonul drept pe numele proiectului) şi se selectează opţiunea Set Main Project.
9

Scurtă prezentare a limbajului Java

Fiind derivat din C++, limbajul Java nu pune probleme dificile celor care
cunosc acest limbaj. De aceea prezentarea elementelor fundamentale ale limbajului
va fi realizată foarte succint.

Comentarii

Programele Java conţin explicaţii sub forma unor comentarii. Acestea vor
asigura în timp înţelegerea diferitelor metode şi rolul funcţional al variabilelor folosite.
Exemplu de aplicaţie scrisă folosind comentarii:

class Greutate
{
/* Clasa Greutate permite calculul greutatii ideale.
Formula folosita determina greutatea pentru barbati, pentru femei rezultatul
trebuie inmultit cu 0.9.
*/
public static void main ( String[] args )
{
int h, v; // h - inaltimea in cm si v - varsta in ani
double g; // greutatea in kg
h = 178;
v = 36;
g = 50 + 0.75 * (h-150) + 0.25 * (v - 20);
System.out.println("Greutatea ideala (barbat) = " + g + " kg");
System.out.println("Greutatea ideala (femeie) = " + 0.9*g + " kg");
} // Sfarsit main
} // Sfarsit clasa Greutate

Într-un program scris în Java pot fi folosite două tipuri de comentarii:


• comentarii "în linie", introduse prin //. Un astfel de comentariu se încheie
la sfârşitul liniei curente;
• comentarii pe unul sau mai multe rânduri consecutive. Zona care conţine
comentariul este delimitată prin /* (comentariu) */.
10

De regulă se folosesc comentariile în linie, cel de-al doilea tip fiind folosit
frecvent în timpul depanării programelor mari şi complexe, pentru a suprima din
program anumite zone.
Comentariile care încep cu /** sunt prelucrate de aplicaţia javadoc pentru
realizarea automată a unei pagini web conţinând comentariile programatorului.
Această facilitate este folosită pentru documentarea rapidă a programelor mari,
compuse din mai multe clase.

Variabile

În Java numele unei variabile, metode sau clase poate fi orice combinaţie de
litere şi cifre, începând cu o literă. Caracterele '_' (underscore) şi '$' sunt
considerate litere şi pot intra în construcţia numelor. Nu pot fi folosite ca nume
cuvintele rezervate folosite la definirea limbajului.

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

true false null


11

Tipuri de date elementare

În Java, ca şi în alte limbaje evoluate, sunt definite 8 tipuri de date elementare


(primitive):

Cuvânt cheie
Descriere Mărime/Reprezentare internă
pt. declarare

(numere întregi)

byte Întreg reprezentat pe un octet 8-biţi, repr. in compl. faţă de 2

short Întreg scurt 16-biţi, repr. in compl. faţă de 2

int Intreg 32-biţi, repr. in compl. faţă de 2

long Întreg lung 64-biţi, repr. in compl. faţă de 2

(numere reale)

float Simplă precizie 32-biţi, IEEE 754

double Dublă precizie 64-biţi IEEE 754

(alte tipuri)

char Un caracter 16-biţi, repr. Unicode

boolean O valoare logică true sau false

Spre deosebire de alte limbaje, în Java informaţiile din tabelul precedent sunt
valabile indiferent de calculatorul pe care se execută programul.

Observaţii asupra tipului char:


În Java un caracter se reprezintă încadrat între apostroafe. Astfel 'C' sau '&'
sunt caractere. Unele caractere nu au simbol grafic. Cele mai uzuale se pot totuşi
introduce folosind o succesiune de două caractere (secvenţă escape) astfel: '\n'
(LF), '\a' (bell), '\b' (backspace), '\f' (pagină nouă, formfeed), '\r' (retur car, carriage
return), '\t' (tab orizontal), '\v' (tab vertical). Un exemplu în acest sens poate fi scris
12

pornind de la succesiunea de apeluri de metode care realizează afişarea pe ecran a


rezultatelor programului scris mai sus:
System.out.println("Gr. (barbat) = " + g + " kg");
System.out.println("Gr. (femeie) = " + 0.9*g + " kg");
System.out.println() asigură trecerea la linie nouă după afişarea şirului de
caractere introdus ca şi argument. Dacă însă folosim un singur apel, acelaşi rezultat
se obţine folosind secvenţa \n:
System.out.println("Gr. (barbat) = " + g + " kg\nGr. (femeie) = " + 0.9*g + " kg");

iruri

Pentru a utiliza un şir, în Java trebuie declarat şi apoi realizată alocarea


memoriei necesare.
Exemple fundamentale:
int a[]; // Se poate scrie si int [] a;
a = new int[7];
int b[] = {1, 3, 4, 6, 10};

Pentru şirul a se va rezerva în memorie o succesiune de 7 locaţii. Deoarece


elementele şirului a sunt de tip int, fiecare locaţie va avea lungimea de 4 octeţi.
irul b a fost declarat şi iniţializat în acelaşi timp. Pentru elementele şirului b
se vor rezerva 5 locaţii de memorie consecutive.
Pentru referirea elementelor şirurilor se folosesc indici. Astfel, după
declararea şirului a se va putea scrie:
a[0] = 12;
a[2] = 21;
a[3] = a[0] + a[2];

irurile pot avea două sau chiar mai multe dimensiuni. Exemplu:
int [ ] [ ] c;
c = new int [3] [4];
c[0] [2] = 17;
System.out.println("c(0,2) ="+c[0] [2]);

Lungimea unui şir, indiferent de conţinutul acestuia, poate fi obţinută folosind


proprietatea .length.
13

Exemplu:

for (i=0; i<a.length; i++)

Clasa String

În Java şirurile de caractere sunt obiecte aparţinând clasei String. Declararea


unui şir de caractere poate fi realizată fie scriind:

String unu="Thomas ";

fie ca şi în cazul declarării şi iniţializării obiectelor:


String doi;
doi = new String("Jerry");
Un şir de char (declarat char [ ]) poate fi transformat într-un obiect aparţinând
clasei String. Exemplu:
char data[] = {'a', 'b', 'c'};
String str = new String(data);

Unirea mai multor obiecte de tip String anterior definite se realizează folosind
operatorul '+', astfel:
String trei;
trei=unu+" & " + doi; // rezultat "Thomas & Jerry"

Se pot defini desigur şiruri de şiruri. Declaraţia String [ ] args care apare
sistematic în lista de parametri ai metodei main() este un bun exemplu.

Literali

În timpul scrierii unui program, programatorul foloseşte frecvent literali.


Literalii sunt valori aparţinând tipurilor primitive prezentate. Compilatorul analizează
aceste valori, le stabileşte tipul, le converteşte şi le memorează în locaţii din
memorie. De exemplu, în clasa Greutate apărea atribuirea:
h = 178;
14

Compilatorul va asocia literalului "178" tipul int., va face conversia în binar


corespunzătoare şi va memora rezultatul într-o zonă din memorie având o lungime
de 4 octeţi. La fel, în expresia greutăţii:
g = 50.0+0.75*(h-150)+0.25*(v-20);
compilatorul va considera că 50.0, 0.75 şi 0.25 sunt double (numere reale în dublă
precizie) iar 150 şi 20 sunt int (numere întregi).

Exemple fundamentale:

Literal Tipul de dată

178 int

8864L long

37.266 double

37.266D double

87.363F float

26.77e3 double

'c' char

true boolean

false boolean

Operatorii limbajului Java

În definirea unui limbaj, stabilirea operatorilor care pot fi folosiţi la scrierea


expresiilor şi a regulilor lor de utilizare reprezintă o etapă importantă. Limbajele de
nivel înalt folosesc un mare număr de operatori şi chiar permit extinderea setului de
operatori pentru a putea scrie expresii în care intervin variabile aparţinând tipurilor
structurate (obiecte).

Operatorii matematici din Java


+ - * / % (modulo)
x % y furnizează restul împărţirii întregi a lui x la y.
15

Exemplu de utilizare a operatorului '%':

if((an % 4 == 0 && an % 100 !=0) || an % 400 == 0)


System.out.println(an + " este bisect.");
Operatorul % nu se aplică tipurilor float şi double.

Operatorul "/" poate provoca trunchiere în cazul operanzilor întregi.

Evaluarea expresiilor aritmetice se efectuează de la stânga la dreapta


respectând ordinea de evaluare normală.

Operatorii de comparare şi logici


Operatorii de comparare (relaţionali) din Java sunt : > >= < <= == !=
Operatorii de comparare au o prioritate inferioară celor aritmetici :
i < lim + 1 se evaluează ca şi i < (lim + 1)
O expresiile în care intervine o succesiune de operatori logici && (şi) sau o
succesiune de operatori || (sau) sunt evaluate de la stânga la dreapta şi evaluarea
expresiei încetează când se ştie deja valoarea de adevăr a rezultatului.
&& e mai prioritar ca şi || iar ambele sunt mai puţin prioritare ca şi operatorii
de comparaţie.
Operatorul ! (negaţie)
if (!corect) . . . identic cu if (corect == false) . . .

Conversiile de tip
Când într-o expresie intervin operanzi de tipuri diferite, operanzii
corespunzând unui tip mai restrictiv se convertesc automat spre tipul mai general
astfel încât nu se produce pierdere de informaţie.

Dacă rezultatul unei expresii este float sau double şi este atribuit unei
variabile de tip întreg, compilatorul va sesiza posibila pierdere de informaţie şi va
semnala o eroare.

Operatorii de conversie de tip (transtipaj sau cast)


16

(nume-tip) expresie
expresie este convertită în tipul specificat :
x = Math.sqrt((double)n)
alfa = (float)a / j ;

Operatorii de incrementare şi de decrementare


++ şi --
În funcţie de poziţia operatorului faţă de variabila incrementată, se realizează
pre şi post incrementare (decrementare)

int n = 5 ;

x = n++ ; x = ++n ;
atribuie 5 lui x atribuie 6 lui x

Operatorii şi expresiile de atribuire


Expresia :
i = i + 3;
în care variabila din stânga egalului se repetă în dreapta acestuia se mai poate
scrie astfel :
i += 3 ;
+= este în acest caz un operator de atribuire.

În general în Java,
exp1 op= exp2 ; echivalează cu
exp1 = exp1 op (exp2) ;
unde op este + - * / %.

Exemplu fundamental:
x *= y + 1 ;
echivalează cu :
x = x * (y + 1) ;
şi nu cu
x=x*y+1;
17

Expresiile condiţionale
Pentru a calcula expresia z = max(a, b) ;
se poate scrie

if (a > b)
max = a ;
else
max = b ;

Limbajul Java oferă şi o altă cale :


max = (a > b) ? a : b ;

Instrucţiunile limbajului Java

Instrucţiunea de decidere - if

Ansamblul de instrucţiuni cuprinse între acolade formează o instrucţiune


compusă sau un bloc de instrucţiuni. Instrucţiunile din interiorul unui bloc de
instrucţiuni sunt executate în ordinea în care sunt scrise.

Variante de scriere a instrucţiunii if


if (expLogica )
{
if ( expLogica )
mai multe instrucţiuni
instrucţiune;
}
if (expLogica ) if (expLogica )
instrucţiune; {
else mai multe instrucţiuni
instrucţiune; }
else
{
mai multe instrucţiuni
}
if (expLogica ) if (expLogica )
instrucţiune; {
18

else mai multe instrucţiuni


{ }
mai multe instrucţiuni else
} instrucţiune;

Indentarea (scrierea decalată) instrucţiunilor sau a blocurilor de


instrucţiuni din if nu este obligatorie dar are mare importanţă în înţelegerea şi
depanarea programului.

Instrucţiunea while

Instrucţiunea while permite realizarea unei structuri repetitive (ciclu)


condiţionate anterior. Corpul ciclului poate fi executat o dată, de mai multe ori sau
de loc.
Exemplu fundamental:

int contor = 1;
while ( contor <= 3 )
{
System.out.println("Contor = "+contor);
contor = contor + 1; // sau mai bine contor++
}

System.out.println("La revedere!");

Sintaxa instrucţiunii while este:


while ( condiţie )
instrucţiune

Condiţia este o expresie logică.

Sintaxa instructiunii while


while ( condiţie )
while ( condiţie ) {
instrucţiune; una sau m.
m.instrucţiuni
}

Instrucţiunea do
19

Pentru programarea unui ciclu poate fi folosită întotdeauna instrucţiunea


while. Deoarece while începe prin executarea unui test, în cazul în care variabila
testată nu poate primi valori decât în interiorul ciclului, programatorul trebuie să-i dea
la început o valoare convenabilă pentru a determina intrarea în ciclu. Exacutarea
instrucţiunilor din corpul ciclului va corecta automat valoarea iniţială.
Pentru astfel de cazuri există însă şi o cale mai simplă, respectiv folosirea
instrucţiunii do.

Exemplu:

g = 9.81;
t = 0;
do
{
d = (g * t * t ) / 2;
System.out.println( t + " " + d);
t = t + 1;
}
while (d <= 500);

Instrucţiunea for

Instrucţiunea for este preferată ori de câte ori trebuie realizat un ciclu care
foloseşte un contor. Ea poate fi însă folosită însă în toate cazurile în care trebuie să
realizăm un ciclu, şi reprezintă o modalitate compactă şi elegantă de scriere a
acestora.
Dacă înaintea unui ciclu trebuie realizate mai multe iniţializări, acestea pot
scrise în for una după alta, despărţite prin virgule:

class Suma
{
public static void main ( String[] args )
{
int [] a = {1, 2, 3, 4, 5, 6, 7, 8, 9};
int i, sum;
for (i=0,sum = 0; i<a.length; i++)
sum = sum + a[i];
System.out.println("Suma elementelor sirului a este: "+sum);
}
}
20

Oricare dintre cele trei părţi ale instrucţiunii for pot lipsi. Lipsa condiţiei de
reluare este echivalentă cu a scrie o condiţie care este întotdeauna adevărată.
Ieşirea dintr-un astfel de ciclu se poate face folosind instrucţiunea break.
Exemplu:

for ( ; ; )
{
..
break;
..
}

Executarea instrucţiunii break provoacă o ieşire imediată din ciclul for. Ea


poate fi folosită şi pentru a ieşi din ciclurile while sau do.

Instrucţiunea switch

Instrucţiunile de ciclare prezentate, while, do şi for sunt folosite pentru


realizarea blocurilor de instrucţiuni a căror execuţie începe cu prima linie şi este
controlată de către programator. Instrucţiunea switch este folosită tot pentru a
construi un bloc de instrucţiuni dar punctul de unde începe execuţia depinde de
valoarea unei expresii având valori întregi.
Sintaxa instrucţiunii este:

switch (expresie)
{
case constanta_1 : instrucţiuni
case constanta_2 : instrucţiuni
...
default : instrucţiuni;
}

Fiecare dintre punctele de unde poate începe execuţia blocului este etichetat
printr-o constantă având valoare întreagă. Dacă expresia de testat corespunde
uneia dintre constante, execuţia blocului începe din punctul indicat de aceasta.
Cazul default este facultativ.
21

Exemplu :
switch (t)
{
case 's' :
rez = Math.sin(Math.PI * x / 180.);
System.out.println("rezultatul este : "+rez);
break;
case 'c' :
rez = Math.cos(Math.PI * x / 180.);
System.out.println("rezultatul este : "+rez);
break;
case 't' :
rez = Math.sin(Math.PI * x / 180.)/Math.cos(3.14159 * x / 180.);
System.out.println("rezultatul este : "+rez);
break;
default:
System.out.println("Caracter incorect!");
}

Ca şi în cazul ciclurilor, instrucţiunea break provoacă o ieşire imediată din


blocul realizat folosind switch.

Realizarea aplicaţiilor complexe

O aplicaţie scrisă în Java constă dintr-o clasă sau un ansamblu de clase. În


cazul în care aplicţia cuprinde mai multe clase, una dintre ele va fi clasa principală,
respectiv va conţine metoda statică main().
Divizarea unei aplicaţii în clase crează premisa lucrului pe secvenţe de cod
de dimensiuni reduse, uşor de realizat şi mai ales de depanat. Fiecare clasă este
specializată pe prelucrarea variabilelor clasei (membrii date ai clasei). Metodele
clasei sunt module de mici dimensiuni, fiecare având un rol funcţional elementar.
Practic dezvoltarea unei clase înseamnă două lucruri:
1. identificarea variabilelor (membrilor date) care vor păstra proprietăţile
obiectelor care vor fi declarate în continuare şi
2. scrierea unui ansamblu complet şi coerent de metode care să asigure
crearea şi evoluţia membrilor date ai clasei.
Pentru a se executa codul dintr-o metodă aceasta trebuie apelată. Apelul se
realizează de regulă din altă metodă a aceleiaşi clase sau a altei clase aparţinând
aplicaţiei. La scrierea apelului metodei, numele acesteia este precedat fie de
numele obiectului ale cărui date trebuie prelucrate fie de numele clasei căreia îi
22

aparţine metoda. Al doilea caz se referă la metode care prelucrează eventual


parametrii transmişi în momentul apelului, ca în cazul metodelor care
implementează funcţii matematice (sin, cos etc.).
Metodele de acest ultim fel sunt declarate folosind declaraţia static.
Structura lexicală folosită la apelul unei metode poate fi deci fie
obiect.metoda(); fie clasă.metodă();
Exemple:
p1.translatez(3, 10); // abscisa si ordonata punctului p1 sunt modificate
y = r * Math.sin(x); // sin() este o metodă statică a clasei Math
k = Integer.parseInt(args[1]); // parseInt() este o met. statică a clasei Integer

Vizibilitatea variabilelor

Vizibilitatea unei variabile se defineşte ca zona din program în care aceasta


este cunoscută deci poate fi accesată. Regulile privind vizibilitatea variabilelor în
Java pot fi reprezentate grafic.

class vizvar {
zona de vizib. a
var. clasei
declaraţii variabile membre

zona de vizib. a public void metoda_1( declaratii parametri)


param. metodei

declaraţii variabile locale


zona de vizib. a var.
locale catch (param. exceptie) {

zona de vizib. a
param. excepţiei

}
Din punct de vedere al locului declarării, o variabilă poate fi membră a clasei
(declarată în afara oricărei metode) sau locală (declarată în interiorul unei metode,
de obicei la la începutul acesteia sau la începutul unui bloc din interiorul acesteia).
Variabilele locale aparţinând unor blocuri separate sunt diferite, chiar dacă
poartă acelaşi nume. Se recomandă totuşi folosirea unor nume de variabile distincte
şi mai ales sugestive, care să ajute programatorul în urmărirea logicii programului.
Unei variabile membre a clasei i se alocă spaţiu în memorie în momentul
creării unei instanţe a clasei folosind operatorul new.
23

Variabilele locale există pe timpul execuţiei blocului în care au fost declarate


şi îşi încetează existenţa în momentul ieşirii din acesta.

Programarea în Java a aplicaţiilor Windows


Cunoştinţele de programare deja prezentate permit începerea scrierii de
aplicaţii care posedă o interfaţă grafică (în engleză GUI, Graphical User Interface).
Sarcina nu este dintre cele mai simple, dar pot fi evidenţiate două premise
favorabile:
a. există un număr important de clase specializate în rezolvarea diferitelor
aspecte care vor apărea şi
b. spectaculozitatea aplicaţiilor va face relativ uşoară depăşirea dificultăţilor.
Java Foundation Classes, prescurtat JFC este o colecţie de clase specializate
pe realizarea interfeţelor grafice ale aplicaţiilor Java. Folosind această colecţie de
clase, realizarea unei interfeţe grafice presupune:
1. adăugarea obiectelor grafice necesare;
2. realizarea adaptărilor care asigură reprezentarea corectă a fiecărui obiect
adăugat (poziţie, dimensiune) şi
3. adăugarea codului necesar implementării comportamentului fiecărui
obiect.

Crearea unei aplicaţii simple


În NetBeans se va selecta New / Project iar în fereastra următoare se va
impune ca tip de proiect General / Java Application.
24

În pasul următor se va impune numele şi directorul. Caseta de validare


Create Main Class nu va fi selectată.

În continuare va fi realizată interfaţa grafică a noii aplicaţii. În Java


componentele unei interfeţe grafice sunt obiecte aparţinând unei colecţii de clase
(cunoscută sub denumirea Swing). Obiectele grafice pot fi reprezentate sub forma
unei structuri arborescente, rădăcina acesteia fiind un container principal.
Containerul principal poate fi un obiect aparţinând uneia dintre clasele următoare:
1. JFrame - pentru aplicaţii Windows obişnuite,
2. JApplet pentru miniaplicaţii care pot fi integrate în pagini web sau
3. JDialog pentru ferestre de dialog.
Fiecare container conţine un panou (content pane) pe care sunt dispuse
obiecte grafice (controalele Windows) şi poate integra eventual o bară cu meniuri
derulante.

După crearea proiectului pasul următor este crearea ferestrei aplicaţiei. În


aplicaţiile Windows obişnuite fereastra principală este un obiect din clasa JFrame.
În meniul File se va selecta New File / Java GUI Forms./ JFrame Form.
25

În fereastra următoare i se va impune numele fişierului.


26

Informaţiile din ferestra anterioară indică faptul că mediul va creea o clasă


Exemplu, care va fi adăugată pachetului exemplu. În Java clasele sunt conţinute în
pachete (echivalentul spaţiilor de nume din .NET). Pentru clasele proprii aplicaţiei
NetBeans oferă varianta alternativă a includerii lor într-un pachet implicit (default-
package) dar se recomandă crearea unui pachet distinct. Pentru pachetul creat
mediul va adăuga pe disc un director nou purtând numele pachetului, facilitând astfel
accesul la fişierele conţinând clasele aplicaţiei şi arhivarea acestora.
În cazul claselor derivate din JFrame sau JDialog mediul de dezvoltare va
include în acestea în mod automat metoda main() acestea devenind astfel clase
principale. Pentru prima clasă a aplicaţiei, derivată de regulă din JFrame este
normal să se procedeze astfel dar în cazul următoarelor clase adăugate, de tip
JDialog sau JFrame metoda main() din componenţa acestora va trebui ştersă.
În exemplul considerat clasa realizată va fi derivată din JFrame şi va conţine
iniţial trei metode: constructorul, metoda initComponents() şi metoda principală,
main().
Rezultat:
27
28

Rezultatul va consta în afişarea zonei utile a ferestrei următoarei aplicaţii. Se


afişează de asemenea o bară cu instrumente care va permite comutarea din afişare
interfaţă grafică - afişare cod.

afişare cod sursă

Notă: Dacă tabul Design nu este vizibil, tracerea la afişarea ferestrei aplicaţiei
se poate realiza si din meniul aplicaţiei (Wiew / Editors / Design).

Selectarea şi plasarea controalelor Windows care compun interfaţa se


realizează folosind trei ferestre:
1. Palette., care conţine componentele Swing care pot fi adăugate,
2. Inspector, care afişeză structura ierarhică a componentelor incluse şi
3. Properties care afişează proprietăţile obiectului selectat în fereastra de
editare grafică sau în fereasra Inspector.
29

Dacă ferestrele necesare nu sunt afişate se va impune afişarea lor folosind


meniul Window. De exemplu pentru Palette se va selecta Window / Palette.
Pentru aplicaţia considerată s-au adăugat trei etichete (obiecte din clasa
JLabel), trei casete de text (obiecte din clasa JTextField) denumite h, v şi g, o casetă
de validare (obiect din clasa JCheckBox) denumită s şi două butoane (JButton).
Pentru schimbarea numelui unui control se selectează controlul şi se editează
numele afişat în fereastra Inspector.

schimbare nume implicit

Ferestrei i se schimbă titlul (proprietatea title = Greutatea ideala) şi i se


adaptează dimensiunile prin deplasarea frontierelor cu mouse-ul.
Pentru a adăuga metoda care tratează evenimentul declanşat de selectarea
cu mouse-ul a unui buton se selectează în meniul contextual afişat la selectarea
butonului opţiunea Events / Action / actionPerformed.
30

Pentru butonul Calcul codul metodei va fi:

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {


// TODO add your handling code here:
double gre;
gre = 50. + 0.75 * (Double.parseDouble(h.getText()) - 150.) +
0.25 * (Double.parseDouble(v.getText()) - 20.);
if(!s.isSelected()) // s neselectat
gre = gre * 0.9;
g.setText(String.valueOf(gre));
}

Pentru butonul Gata codul va fi:

private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {


// TODO add your handling code here:
System.exit(0);
}

Pentru controlul de tip JTextField g s-a modificat proprietatea editable


deoarece conţinutul său se stabileşte în metoda asociată butonului Calcul.

În acest moment se poate executa aplicaţia (butonul ):


31

Metode Java pentru conversia datelor

Datele necesare calculelor şi rezultatele obţinute sunt de regulă conţinute în


casete de text (obiecte din clasa JTextField). Perechea de metode ale clasei
JTextField care permit accesul la conţinutul casetei de text sunt getText() pentru
preluarea conţinutului şi setText() pentru impunerea acestuia.
Metoda getText() returnează un obiect de tip String care trebuie convertit în
vederea obţinerii unei valori numerice utilizabile în expresii matematice. Argumentul
metodei setText() este un obiect de tip String, rezultat din conversia unei valori
numerice. Pentru a realiza conversii, în Java sunt definite clase care mapează
tipurile simple, astfel:
Tip simplu Clasă de mapare
byte Byte
short Short
int Integer
long Long
char Character
float Float
double Double
boolean Boolean

Fiecare dintre clasele de mapare posedă o metodă statică de conversie din


String într-un tip simplu:

String sir = "1235";


int nr;
nr = Integer.parseInt(sir);

Pentru clasele din tabelul de mai sus metodele de conversie sunt


următoarele:
- byte - Byte.parseByte(aString)
- short - Short.parseShort(aString)
- int - Integer.parseInt(aString)
- long - Long.parseLong(aString)
32

- float - Float.parseFloat(aString)
- double - Double.parseDouble(aString)
- boolean - Boolean.valueOf(aString).booleanValue();
Conversia inversă, dintr-un tip numeric simplu în şir de caractere se poate fie
apelând metoda String.valueOf(variabila) fie mai simplu, exploatând modul în care
Java realizează concatenarea şirurilor de caractere.
Exemplu:

double v = 3.14;
String sir = "" + v;

Deoarece în expresia atribuită variabilei sir primul termen este şir, operatorul
+ va fi considerat ca fiind operator de concatenare iar variabila v va fi automat
convertită în String.
33

Utilizarea controalelor Windows

Casete de text
Casetele de text sunt obiecte aparţinând clasei JTextField. Coţinutul unei
casete de text este de regulă un obiect de tip String. În timpul executării programului
conţinutul casetei poate fi preluat folosind metoda getText() şi poate fi impus folosind
metoda setText(). Proprietăţile care sunt de obicei impuse sunt:
- horizontalAlignment, - mod de cadraj al şirului de caractere
- editable - dacă este posibilă scrierea în casetă sau nu. Opţiune
dezactivată pentru casetele al căror conţinut este determinat în
aplicaţie;
- font - fontul utilizat
- background - culoarea fundalului
- foreground - culoarea scrisului,
- text - conţinutul iniţial al controlului.
Proprietăţile pot fi modificate prin program, metodele cele mai frecvent
apelate fiind setBackground(), care permite impunerea culorii fundalului şi
setForeground(), care impune culoarea textului.

Butoane
Butoanele sunt controale Windows destinate declanşării unei acţiuni.
Înţelegerea modului în care se specifică acţiunea (metoda) care trebuie să fie
executată la declanşarea unui anumit eveniment este posibilă doar prin evidenţierea
unor particularităţi ale modului în care programarea obiectuală este implementată în
Java.

Interfeţe, clase incluse, clase anonime

Evenimentele declanşate de acţiunile operatorului şi la care o aplicaţie


Windows poate reacţiona sunt diverse. Pentru integrarea mai uşoară a
mecanismului de tratare a lor, creatorii limbajului Java au realizat o grupare a lor pe
categorii. Gruparea metodelor specializate pe tratarea unei categorii de evenimente
34

se realizează folosind conceptul de interfaţă (eng. interface). O interfaţă poate fi


privită ca fiind o clasă mai aparte, care conţine un număr de metode abstracte care
trebuie suprascrise în cadrul clasei care o foloseşte. Suprascrierea unei metode a
unei interfeţe presupune scrierea unei metode având acelaşi nume cu cel al metodei
corespunzătoare din definiţia interfeţei dar un conţinut adaptat aplicaţiei. Evident nu
se pot creea obiecte având ca tip o interfaţă în locul unei clase.

Declararea faptului că o clasă suprascrie metodele unei interfeţe (sau ale mai
multor interfeţe) se realizează printr-o directivă implements:
class nume_clasă implements interfaţă_1 [interfaţă_2 ...]

Notă. Limbajul Java nu admite moştenirea multiplă, respectiv o clasă nu poate


avea mai multe superclase. Prin interfeţe această constrângere este însă ocolită, o
clasă moştenind membrii unei clase şi a unui număr oarecare de interfeţe.

Exemplu :
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class CelsConv implements ActionListener


{
...

Într-o aplicaţie Java obişnuită începută ca în exemplul precedent vor exista


obligatoriu secvenţe de cod de tipul:
. . .
butonCalcul.addActionListener(this);
butonGata.addActionListener(this);
. . .

Aşa cum deja se ştie, obiectul referit prin this este obiectul curent care în
acest mod este indicat ca fiind listener (ascultător). Metoda apelată la producerea
evenimentului (clic pe buton) denumită în programare handler de eveniment, va fi
cea conţinută în clasa căreia îi aparţine obiectul declarat ca listener.
Aceasta este modalitatea prin care se "instituie" supravegherea şi
interceptarea apăsării butoanelor butonCalcul şi butonGata.
35

Interfaţa ActionListener, implementată în clasa CelsConv, conţine doar o


metodă, actionPerformed(). Ea trebuie suprascrisă în cadrul acestei clase.
Deoarece pot exista mai multe butoane ale căror selectări declanşează aceeaşi
metodă (în exemplul dat există două butoane), metoda actionPerformed() va
implementa un algoritm de identificare a sursei evenimentului.

public void actionPerformed(ActionEvent e)


{
if (e.getSource() == butonCalcul)
{
double tempData = Double.parseDouble(tempCelsius.getText());
int tempFahr = (int)(tempData * 1.8 + 32);
tempCelsius.setText(""+tempFahr);
}
else
System.exit(0);
}

Dacă se foloseşte NetBeans declararea obiectului listener se bazează pe


posibilitatea definirii claselor incluse (inner clases) într-o clasă dată.
În Java o aplicaţie care foloseşte clase incluse are structura:
class ClasaPrinc {
...
class ClasaInclusa {
...
}
...
}

Clasa inclusă poate fi declarată oriunde în cadrul clasei exterioare. Dacă


declararea clasei incluse s-a realizat în afara metodelor clasei exterioare, din
metodele clasei incluse pot fi accesate variabilele clasei exterioare şi invers.
Dacă o clasă inclusă implementează o interfaţă, numele ei poate fi omis
(clasa devine anonimă) ajungându-se la expresii de forma:

numele clasei lipseşte, apare doar numele


interfeţei (ActionListener)

În metoda suprascrisă actionPerformed() se apelează o


altă metodă, jRadioButton1ActionPerformed(evt)
36

Scrierea din exemplul precedent poate induce în eroare dar să ne amintim că


nu pot fi create obiecte aparţinând unei interfeţe, deci scriind:
new ActionListener() { ...
nu creem un obiect de tip ActionListener ci un obiect aparţinând unei clase interioare
anonime care la rândul ei implementează interfaţa ActionListener.
În NetBeans scrierea codului care asociază o metodă de tratare unui
eveniment se realizează automat. Utilizatorul poate edita practic doar metoda
apelată în cadrul metodei suprascrise a interfeţei implementate,
jRadioButton1ActionPerformed(evt) în exemplul anterior.
În concluzie se poate spune că, dacă un obiect al interfeţei trebuie să
răspundă la o acţiune (clic cu mouse-ul de exemplu) NetBeans generează pentru
listener un obiect aparţinând unei clase interioare anonime în care sunt suprascrise
metodele unei interfeţe pe care aceasta o implementează. Metoda aferentă
evenimentului interceptat conţine un apel la o metodă a clasei (handler) a cărui
nume este format din numele controlului + numele evenimentului interceptat.
Practic pentru a impune tratarea unui eveniment se selectează obiectul care
va declanşa evenimentul (sursa evenimentului, un buton de exemplu) şi folosind
interfaţa se va declanşa scrierea automată a metodei de tratare într-unul dintre
următoarele moduri:
a. Se foloseşte meniul contextual (pentru actionPerformed de exemplu)

b. Se selectează câmpul din fereastra de proprietăţi (tabul Events selectat)


din dreptul evenimentului a cărui tratare se doreşte.

clic

Dacă se doreşte apelarea altei metode sau se doreşte schimbarea numelui


predefinit, se editează numele implicit după care se apasă Enter.
37

În continuare se trece la editarea codului metodei, specific aplicaţiei.

Exemplu: Să se realizeze o aplicaţie care transformă gradele Celsius în grade


Farenheit şi invers.
Soluţie:
După adăugarea unei etichete (JLabel) conţinând şirul de caractere
Temperatura şi a unei casete de text (JTextField) pentru introducerea valorii şi
afişarea rezultatului, se va adăuga interfeţei un control de tip ButtonGroup şi două
butoane radio (JRadioButton). Controlul de tip buttonGroup va servi la gruparea
butoanelor radio. Pentru a realiza gruparea, se selectează succesiv, cu tasta
Control apăsată, cele două butoane radio şi apoi, în fereastra de proprietăţi, se
selectează pentru proprietatea buttonGroup valoarea buttonGroup1, respectiv
obiectul deja adăugat.

Proprietatea text a butoanelor radio se modifică în "Celsius -> Fahrenheit"


respectiv "Fahrenheit -> Celsius".
Se mai adaugă două butoane (JButton) având proprietatea label "Calculează"
respectiv "Gata".
Pentru a stabili sensul transformării se adaugă clasei aplicaţiei o variabilă
denumită sens de tip boolean având valoarea true pentru Celsius - Fahrenheit.
38

Folosind proprietatea selected a primului buton Radio se va impune ca la


pornirea aplicaţiei acesta să fie selectat.
39

Corespunzător se va interveni în constructorul clasei dând variabilei sens


valoarea true.

Mai urmează să se adauge metodele de tratare a evenimentelor declanşate la


selectarea butoanelor.
Pentru primul buton radio codul metodei va fi:

Pentru al doilea buton radio codul va fi:

Butonul "Calculează" va declanşa execuţia unei metode care va coţine


preluarea valorii din controlul de tip JTextfield, conversia sa din String în double,
calculul noii valori şi memorarea acesteia, după conversie în String, în controlul de
tip JTextField.
Pentru transformare se vor folosi formulele:
Celsius -> Fahrenheit: v = 9.0 / 5.0 * v + 32.0;
Fahrenheit -> Celsius v = 5.0 / 9.0 * (v - 32.0);
40

Pentru al doilea buton "Gata", funcţia de tratare a evenimentului declanşat la


acţionarea sa va opri aplicaţia.

Rezultat posibil:

Casete de validare (JCheckBox


CheckBox)
Box)

Un control de tip casetă de validare (JCheckBox) poate avea două stări:


selectat sau neselectat. Starea de selectare poate fi stabilită în momentul realizării
interfeţei grafice sau în timpul execuţiei aplicaţiei, prin apelul metodei setChecked();
Exemplu de utilizare:
Se consideră o aplicaţie care afişează trei controale, un control de tip JLabel
şi două de tip JCheckBox, ca în figură.
41

Selectarea butoanelor de tip JCheckBox trebuie să modifice aspectul fontului


folosit la scrierea şirului de caractere conţinut în JLabel.
Ambelor butoane li se va ataşa aceeaşi funcţie de tratare.
Pentru început se include metoda ataşată implicit primului buton:

Se revine în fereastra de proprietăţi şi i se modifică numele:

Apoi se editează textul metodei:

Pentru al doilea buton (italic) ataşarea aceleiaşi metode pentru evenimentul


actionPerformed se realizează astfel:
- se selecteasă câmpul din dreptul evenimentului actionPerformed:

Mediul de programare afişează automat numele metodei,


italicActionPerformed().
42

- fără a intra în fereastra de editare a clasei (fără a apăsa tasta Enter)


se modifică numele metodei (italicActionPerformed ->
cbActionPerformed) şi apoi se apasă tasta Enter.
43

Controale cu listă

Componentele Swing folosite limbajul Java începând cu versiunea 1.2


implementează arhitectura Model-View-Controller (MVC). Modelul MVC constă în
esenţă în separarea datelor de reperezentarea lor. Datele sunt conţinute într-un
obiect (model) asociat unui control Windows care realizează reprezentarea lor
(view). Cea de-a treia componentă, Controller realizează interceptarea şi
procesarea evenimentelor.

Controller

View Model

Această abordare stă de altfel la baza independenţei aplicaţiilor Java de


platforma pe care se execută aplicaţia.
Dacă pentru controale simple obiectul care conţine datele este realizat
automat pentru controale complexe, care pot conţine un număr mare şi variat de
obiecte (JComboBox, JList, JTable, JTree), programatorul poate opta între folosirea
unui obiect aparţinând unei clase implicite (DefaultListModel, DefaultTableModel,
DefaultTreeModel) şi definirea unei clase proprii, derivată de regulă dintr-o clasă
abstractă predefinită. Evident complextitatea programării creşte dacă nu se
foloseşte clasa implicită, dar în multe cazuri este singura soluţie.

JComboBox
Controlul de tip JComboBox permite selectarea unei valori dintr-o listă
predefinită. Definirea listei se realizează de obicei în etapa de proiectare a aplicaţiei,
conţinutul acesteia fiind accesibil prin intermediul proprietăţii model, Lista poate fi
construită şi editată şi dinamic, în timpul execuţiei, folosind metodele:
44

Tip
Metoda Acţiune
returnat
void addItem(Object obj) Adaugă un element în listă
void insertItemAt(Object obj, int index) Inserează un element în listă
Object getSelectedItem() Returnează ob. selectat
int getSelectedIndex() Returnează poz. elem. selectat
void removeAllItems() Goleşte lista
void removeItem(Object obj) Suprimă prima apariţie a obj.
void removeItemAt(int index) Suprimă el.. de la poziţia index
int getItemCount() Returnează nr. de elemente

Exemple:
Să se realizeze o aplicaţie care afişează în ferestră o imagine selectată
dintr-o listă de imagini.
Pentru rezolvarea problemei se realizează o nouă aplicaţie Windows în
fereastra căreia se adaugă trei controale: două de tip JLabel şi unul de tip
JComboBox.

Lista asociată controlului de tip JComboBox va fi adăugată acţionând butonul


din dreptul proprietăţii model.
45

Proprietatea selectedItem va fi "Pasare", deci prima intrare în listă.


În controlul imagine de tip JLabel va fi adăugată imaginea corespunzătoare
entităţii iniţial selectate ("Pasare"). Pentru aceasta va fi şters şirul de caractere din
dreptul proprietăţii text şi vor fi impuse dimensiunile controlului în corespondenţă cu
cele ale imaginilor care urmează să fie afişate (proprietăţile Horizontal Size şi
Vertical Size).

Pentru a adăuga imaginea care va fi iniţial afişată va fi acţionat butonul din


dreptul proprietăţii icon.
46

Pentru a putea funcţiona mai trebuie doar să se adauge clasei o metodă care
să fie apelată la schimbarea elementului din listă selectat. Evenimentul generat la
selectarea unui alt element din listă este actionPerformed.
47

Formarea numelui imaginii care va fi afişată în controlul imagine se realizează


prin alăturarea a trei şiruri de caractere: "Imagini/" + nume + ".gif". Variabila nume
primeşte ca valoarea şirul de caractere selctat. Rezultă deci că în directorul Imagini
trebuie să existe patru fişiere având denumirile Pasare.gif,

Pentru ca aplicaţia să poată funcţiona, directorul Imagini trebuie plasat în


directorul aplicaţiei.

Observaţie: Aplicaţia poate fi rescrisă, în noua variantă lista controlului de tip


JComboBox fiind generată în timpul execuţiei programului. În acest caz iniţializarea
el se va realiza în constructorul clasei.

După secvenţa de iniţializare s-a impus poziţia iniţial selectată (metoda


setSelectedIndex() din clasa JComboBox) şi s-a încărcat în controlul imagine de tip
JLabel imaginea corespunzătoare (metoda setIcon()).
48

JListBox
Controlul de tip JListBox permite să se selecteze o valoare sau mai multe
valori dintr-o listă predefinită. i în cazul acestui control, definirea listei poate fi
realizată în etapa de proiectare a aplicaţiei sau ulterior, în timpul execuţiei.
Dacă aplicaţia se dezvoltă folosind NetBeans, obiectul folosit ca model diferă
pentru cele două situaţii. În cazul în care lista este definită în momentul proiectării
aplicaţiei mediul va creea un obiect aparţinând unei clase interioare anonime care
implementează interfaţa AbstractListModel:

Metoda setModel(Object obj) realizează asocierea obiectului model, care


conţine datele care urmează să fie afişate de controlul listaStg din clasa JList.
Metodele getSize() şi getElementAt() sunt metode suprascrise ale interfeţei
AbstractListModel. Pentru a accesa conţinutul obiectului model se apelează metoda
getModel(). Astfel pentru a prelua elementul aflat în poziţia poz se scrie:

String sir;
sir = (String) listaStg.getModel().getElementAt(poz);

Pentru liste generate dinamic, în timpul execuţiei aplicaţiei, soluţia obişnuită


este adăugarea la variabilele clasei a unui obiect din clasa DefaultListModel:

private DefaultListModel model_lista;

În constructorul clasei, după iniţializarea tuturor componentelor se va creea


obiectul ldr şi apoi va fi asociat controlului prin apelul metodei setModel():

...
initComponents();
model_lista = new DefaultListModel();
lista.setModel(model_lista);
...
49

Principalele metode din clasa DefaultListModel care permit crearea şi editarea


listei sunt prezentate în tabelul următor.

Tip returnat Metoda Acţiune


void add(int index, Object obj) Adaugă obj în poz. index
void addElement(Object obj) Adauga obj în listă
void clear() sau Goleşte lista
removeAllElements()
boolean contains(Object obj) Ret. true daca obj este in lista
Object firstElement() Ret. primul element
Object getElementAt (int index) Returnează el. din poz. index
int[] getSelectedIndices() Returnează şirul poziţiilor el. selectate
int indexOf(Object obj) Ret. poz. în care apare prima dată obj
void insertElementAt(Object Inserează obj în poz. index
obj, int index)
boolean isEmpty() Return. true daca lista este vida
void removeElement(Object Suprimă elem. obj
obj)
void removeElementAt(int Suprimă elementul din poziţia index
index)

Exemplu:
Să se realizeze o aplicaţie care adaugă într-o listă elemente selectate într-o
altă listă.
Se presupune că prima listă, din stânga, conţine ingrediente pentru o prăitură.
Ingredientele selectate vor fi adăugate în lista din dreapta.
50

Pentru realizarea interfeţei s-au adăugat ferestrei iniţiale două panouri


(JPanel) având proprietatea border setată pe TitleBorder:

În continuare se adaugă două controale de tip JList, listaStg şi listaDr şi un


buton. Se va observa că fiecare control de tip JList va fi în mod automat inclus într-
un container de tip jScrollPanel. Dacă lungimea unei liste va fi aşa de mare încât nu
va încăpea în spaţiul iniţial alocat vor fi afişate automat bare de defilare (scroll).
Pentru a păstra elementele listei din dreapta, gestionată dinamic, se va
adăuga clasei variabila ldr aparţinând clasei DefaultListModel:
51

Se va modifica apoi constructorul clasei asfel încât ldr să fie asociat listei din
dreapta, listaDr.

Pentru ca aplicaţia să devină funcţională mai trebuie ataşată o metodă de


tratare a evenimentului clic pentru butonul jButton1.
52

Metoda conţine preluarea în şirul select[] de tip int a indicilor elementelor


selectate în listaStg. Apoi se goleşte listaDr (metoda clear()) şi se adaugă în
obiectul ldr elementele din lista din stânga ale căror poziţii au fost memorate în şirul
select[]. Pentru aceasta se apelează în ciclu metoda addElement(). Preluarea unui
element din lista din stânga se realizează apelând metoda getElement() pentru
obiectul model obţinut prin apelul metodei getModel().

JTable
Controlul de tip JTable este folosit pentru afişarea datelor într-o formă
tabelară. Un obiect de tip JTable realizează doar afişarea datelor, acestea fiind
conţinute într-un obiect asociat (TableModel, de regulă un tablou bidimensional).

JTable TableModel

Înaintea creării unui ibiect din clasa JTable este necesară crearea obiectului
care conţine datele. Acesta poate aparţine unei clase definite de programator, de
regulă derivată din AbstractTableModel (clasă abstractă) sau poate aparţine clasei
DefaultTableModel. În NetBeans a doua variantă este cea implicită.
În NetBeans adăugarea unui obiect din clasa JTable provoacă inserarea în
fapt a două obiecte, un jScrollPanel (container) şi un jTable conţinut în primul.

a. Utilizarea unei clase anonime derivată din AbstractTableModel


La crearea unei clase derivate din AbstractTableModel trebuie suprascrise
următoarele metodele abstracte :
public int getRowCount();
public int getColumnCount();
public Object getValueAt(int row, int column);
53

Evident pot fi suprascrise şi metodele care nu sunt abstracte dacă este


necesară specializarea modului lor de operare. În exemplul prezentat în continuare a
fost suprascrisă metoda getColumnName().
Folosirea acestei metode pentru popularea cu date a unui control JTable
presupune:
1. Declararea unui obiect din clasa Vector:

private Vector<String[]> data = new Vector();

2. Popularea cu date a structurii declarate. Liniile sunt adăugate în


constructorul clasei principale, după apelul initComponents().

data.add(new String[]{"", "Pop Grigore", "Cluj-Napoca"});


data.add(new String[]{"", "Ionescu Paul", "Oradea"});
data.add(new String[]{"", "Popescu Laura", "Bucuresti"});

3. Asocierea la obiectul tabel (JTable) a obiectului care conţine datele


tabelului. Obiectul folosit va aparţine unei clase anonime derivată din
AbstractTableModel :

tabel.setModel(new AbstractTableModel() {
String[] colum = new String[]{"Numar", "Nume", "Localitate"};

public int getRowCount() {


return data.size();
}

public int getColumnCount() {


return colum.length;
}

public Object getValueAt(int rowIndex, int columnIndex) {


return columnIndex == 0 ? "" + (rowIndex + 1) : data.get(rowIndex)[columnIndex];
}

public String getColumnName(int column) {


return colum[column];
}
});

Rezultat:
54

Notă: În Java clasa Vector este folosita pentru a creea şiruri de lungime
variabilă. Lungimea unui Vector poate creşte sau scade după nevoile aplicaţiei. În
examplul dat s-au adăugat elemente (data.add(...)) s-au extras elemente (data.get())
şi s-a folosit lungimea vectorului (data.size()).
În timpul execuţiei programului datele pe care acesta le conţine pot evolua.
Practic structurii de tip Vector care conţine datele i se adauga noi elemente sau i se
suprimă elemente. Pentru a determina punerea de acord a reprezentării grafice cu
modelul se va apela metoda updateUI(). Exemplu :

private void adaugaActionPerformed(java.awt.event.ActionEvent evt) {


// TODO add your handling code here:
data.add(new String[]{"", nume.getText(), oras.getText()});
tabel.updateUI();
nume.setText(""); oras.setText("");
}
55

b. Utilizarea clasei DefaultTableModel


În lipsa declaraţiei unei clase noi, ca în exemplul precedent, datele unui
control JTable vor fi păstrate într-un obiect aparţinând clasei DefaultTableModel.
Configurarea controlului şi popularea cu datele iniţiale se realizează folosind interfaţa
mediului de programare.
După inserare în fereastra aplicaţiei un control JTable este afişat cu un număr
de linii şi coloane care poate fi adaptat accesând proprietatea model.

După configurarea controlului din clasa JTable se adaugă interfeţei aplicaţiei


două controale necesare introducerii datelor : nume din clasa JTextField şi fumator
din clasa JCheckBox.
56

Rezultat :

Secvenţa de cod scrisă de mediul de programare în metoda initComponents()


este următoarea:

Asocierea obiectului care conţine valorile (model) s-a realizat prin apelul
metodei setModel(), care are ca parametru un obiect din clasa DefaultTableModel.
Constructorul folosit are doi parametri. Primul este un tablou bidimensional de
obiecte din clasa Object iar al doilea este un şir de obiecte din clasa String (şiruri de
caractere, denumirile înscrise în capul coloanelor). În celulele unui astfel de tablou
pot fi puse obiecte de diferite naturi deoarece în Java clasa Object este rădăcina
întregii ierarhii de clase.
Observaţie : În exemplul precedent obiectul folosit ca model nu are nume.
Pentru modificarea datelor din tabel pentru a obţine o referinţă la acest obiect se va
scrie tabel1.getModel().
57

În tabelul următor au fost incluse câteva dintre metodele folosite pentru


editarea obiectului model aparţinând clasei DefaultTableModel şi asociat unui
JTable.

Tip
Metoda Acţiune
returnat
void addRow(Object[] obj) Adaugă modelului o linie la sfârşit
Object getValueAt(int linie, int col) Preia valoarea din poz. (linie, col)
int getRowCount() Returnează nr. de linii
void insertRow(int linie, Object[] obj) Inserează un rând în poziţia linie
void removeRow(int linie) Suprimă rândul linie
void setValueAt(Object obj, int linie, Inserează elementul obj în poziţia
int col) (linie, coloană)
void setColumnIdentifiers(String []) impune numele scris în capul
coloanelor

Continuând exemplul inceput, constructorul clasei principale poate fi scris


astfel :

public Tabeleex2() {
initComponents();
tabel1.getColumn("Fumator").setCellRenderer(new AfisareBool());
tabel1.getColumn("Nr. Crt.").setCellRenderer(new AfisareInt());
tabel1.getColumn("Nr. Crt.").setPreferredWidth(40);
tabel1.getColumn("Numele si prenumele").setPreferredWidth(240);
nr = 1;
}

După apelul metodei initComponents() în care se crează controalele interfeţei,


în constructor se apelează pentru două coloane (Nr.Crt şi Fumator) metoda
setCellRenderer. Această metodă asociază acestor coloane două obiecte
aparţinând unor clase specializate în afişarea valorilor din coloanele respective.
Clasa AfisareBool reprezintă valoarea logică true sau false din coloana Fumator sub
forma unei casete de validare (JCheckBox):
58

class AfisareBool extends DefaultTableCellRenderer {


JCheckBox cb = new JCheckBox();
@Override
public Component getTableCellRendererComponent(
JTable table, Object value,
boolean isSelected, boolean hasFocus,
int row, int column) {
cb.setSelected(((Boolean)value).booleanValue()); // impun starea
cb.setHorizontalAlignment(JLabel.CENTER);
return cb;
}
}

Clasa AfisareInt reprezintă valoarea întreagă din coloana Nr. Crt. sub forma
unui control JLabel având textul centrat pe orizontală:

class AfisareInt extends DefaultTableCellRenderer {


JLabel nr = new JLabel();
@Override
public Component getTableCellRendererComponent(
JTable table, Object value,
boolean isSelected, boolean hasFocus,
int row, int column) {
nr.setText((String)value); // impun valoarea
nr.setHorizontalAlignment(JLabel.CENTER);
return nr;
}
}

Ultimele două linii din constructor apelează metoda setPreferredWidth()


pentru a impune lăţimile primelor două coloane. Lăţimea ultimei coloane se
determină automat.
Tot în constructor se iniţializează contorul de linii nr (declarat de tip int).
Metoda asociată butonului etichetat cu Adauga este următoarea :

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {


// TODO add your handling code here:
Object[] sir = new Object[] {""+nr, nume.getText(), fumator.isSelected()};
DefaultTableModel dt = (DefaultTableModel)tabel1.getModel();
dt.addRow(sir);
nr++;
nume.setText("");
fumator.setSelected(false);
nume.requestFocus();
}
59

Ea iniţializeaza variabila sir cu un şir de obiecte folosind valorile din


controalele nume si fumator precum şi valoarea contorului nr.
În continuare se preia obiectul model (prin apelul metodei getModel()) al
controlului tabel1 (JTable) şi se adaugă acestuia şirul de obiecte sir.
În final se incrementează contorul nr (nr++), şi se aduc controalele nume şi
fumator la starea iniţiala :

nume.setText("");
fumator.setSelected(false);

De asemenea se apelează nume.requestFocus(); pentru a specifica nume ca


fiind controlul căruia i se adresează următoarea intrare de la tastatură.
Rezultat :

Meniuri
Meniurile permit definirea unui set extins de acţiuni şi selectarea uneia dintre
ele. Pentru a defini meniul unei aplicaţii trebuie creată o bară de meniuri (obiect
aparţinând clasei JMenuBar), un ansamblu de meniuri derulante (obiecte de tip
JMenu) şi pentru fiecare meniu derulant, un ansamblu de opţiuni (obiecte aparţinând
clasei JMenuItem).
Exemplu:
60

Sa se realizeze proiectul DemoMeniu având interfaţa din imagine.

1. Se adaugă proiectului bara cu meniuri derulante:

clic
Se va selecta cu mouse-ul JMenubar şi se va realiza adăugarea sa printr-un
clic cu mouse-ul în fereastra aplicaţiei.
selectat
În continuare se va edita conţinutul barei cu meniuri folosind reprezentarea
arborescentă afişată prin selectarea tabului Inspector.
2. Se modifică numele primului meniu derulant (proprietatea text):

selectat modificare proprietate text


61

3. Se adaugă meniului Imagini opţiunile Pasare, Caine, Pisica, Iepure şi


Iesire. Efectul selectării primelor patru intrări va fi schimbarea imaginii afişate în
centrul ferestrei iar ultima opţiune va opri aplicaţia.

selectat
modificare proprietate text

4. Se adaugă barei cu meniuri un al doilea meniu derulant:


62

Rezultat:

Se modifică proprietatea text din Menu în Culori:

selectat

5. Celui de-al doilea meniu derulant i se adaugă trei opţiuni: Albastru, Rosu şi
Verde. Selactarea uneia dintre opţiuni va schimba culoarea textului cu care se
afişează denumirea imaginii.

6. Se adaugă aplicaţiei două controale din clasa JLabel. Acestea vor conţine
o imagine respectiv denumirea imaginii afişate. Denumirile controalelor vor fi
schimbate în poza şi denumire.

Pentru a afişa denumirea imaginii iniţiale, proprietatea text a controlului


denumire va fi modificată în "Pasare" şi culoarea fontului va fi modificată în albastru
(proprietatea foreground).
63

Pentru controlul poza se va impune un conţinut iniţial folosind proprietatea


icon , aşa cum se vede în continuare.
64

Rezultat:

7. În continuare vor fi definite secvenţele de cod care trebuie executate la


selectarea diferitelor opţiuni din meniuri. Pentru a creea metoda care trebuie
executată la selectarea unei opţiuni dintr-un meniu derulant se va selecta opţiunea
cu un dublu clic în fereastra Inspector:

dublu clic

Pentru ultima opţiune din primul meniu derulant (Iesire) se va adăuga apelul
metodei exit(0):
65

Pentru prima opţiune din meniul Imagini, metoda care trebuie executată este
următoarea:

private void jMenuItem1ActionPerformed(java.awt.event.ActionEvent evt) {


// TODO add your handling code here:
poza.setIcon(new ImageIcon("Imagini/Pasare.gif"));
denumire.setText("Pasare");
}

Pentru celelalte trei metode se va schimba doar numele imaginii referite


(Caine.gif, Pisica.gif şi Iepure.gif).

Pentru prima opţiune din meniul Culori metoda care trebuie executată este
următoarea:

Pentru celelalte două opţiuni culorile impuse vor fi Color.RED respectiv


Color.GREEN.

Ferestre de dialog
În Java ferestrele de dialog sunt controale Windows din clasa JDialog.
Controalele adăugate ulterior în fereastra de dialog se adaugă controalelor clasei de
bază.

Desenarea în Java
Interfeţele aplicaţiilor create până în prezent au inclus de regulă un container
din clasa JFrame în care au fost adăugate un ansamblu de controale Windows.
Conţinutul acestora a fost impus folosind proprietăţile lor.
Există însă cazuri în care conţinutul unui control Windows este o reprezentare
grafică a unor date ale aplicaţiei. Pentru a face acest lucru posibil este însă
66

necesară declararea unei noi clase, derivată de regulă din clasa JPanel în cadrul
căreia să fie suprascrisă metoda în care se realizează reprezentarea grafică a
obiectelor clasei. Fereastra unei astfel de aplicaţii ar putea deci conţine pe lângă
controale JPanel obişnuite, adăugate pentru a grupa controalele Windows destinate
interacţiunii cu aplicaţia, un obiect aparţinând noii clase şi care va conţine
reprezentarea grafică a datelor aplicaţiei.

Exemplu:
Să se realizeze o aplicaţie care permite desenarea în centrul unui panou
(control JPanel) a unui dreptunghi sau a unui oval având dimensiunile impuse într-o
fereastră de dialog.
1. Se crează proiectul nou denumit figuri (File / New Project / General / Java
Application):

2. Se adaugă proiectului un fişier nou care va conţine clasa principală,


derivată din JFrame (File / New File/ Java GUI Forms / JFrame Form) impunând
pentru Class Name : figuri şi pentru Package tot figuri.
3. Se adaugă interfeţei grafice un Layout Manager.
67

Pentru aplicaţia dată s-a ales ca pentru dispunerea componentelor să se


folosească Border Layout. Unui container căruia i s-a ataşat acest mod de
dispunere i se pot adăuga cinci obiecte grafice dispuse ca în figură.

Specific acestui mod de dispunere este de asemenea faptul că obiectul din


mijloc (Center) se extinde automat la redimensionarea containerului astfel încât să
ocupe tot spaţiul disponibil după ce s-au (re)desenat componentele plasat la nord,
sud, est şi vest. În cazul aplicaţiei curente în centru va fi plasat controlul care va
conţine reprezentarea grafică dorită iar la nord (North) se va plasa un panou
(JPanel) care va conţine un grup de două butoane Radio (etichetate Oval şi
Dreptunghi) şi două butoane având etichetele Date şi Grafic. Butonul Date
declanşează afişarea unei ferestre de dialog în care se vor introduce dimensiunile
dreptunghiului de încadrare a figurii dorite.
68

Adăugarea unei ferestre de dialog

Colecţia de clase destinată realizării interfeţei unei aplicaţii conţine două clase
care permit afişarea unei ferestre de dialog: JOptionPane şi JDialog.
JOptionPane permite afişarea a două tipuri de ferestre de dialog:
a. fereastră care conţine un şir de caractere (un mesaj) şi un buton
etichetat cu Ok sau
b. fereastră care conţine un control prin care utilizatorul poate
introduce o valoare şi două butoane, etichetate cu Ok şi Cancel.
Cel mai frecvent se foloseşte prima formă, afişarea unei astfel de ferestre fiind
realizată prin apelul metodei statice showMessage(). Exemplu:

JOptionPane.showMessageDialog(f, "Mesajul pentru Dv.: Apasati OK", "Click OK",


JOptionPane.INFORMATION_MESSAGE);

În exemplul dat f este fereastra în cadrul căreia va fi afişată caseta de dialog.


Dacă aceasta nu trebuie afişată în cadrul unei ferestre, primul argument va fi null.
Pentru aplicaţia curentă soluţia corectă este utilizarea unui obiect aparţinând
clasei JDialog. Conţinutul unei ferestre de dialog astfel adăugate poate fi creeat ca
şi cel al ferestrei principale (JFrame) folosind controalele Windows din fereastra
Palette.
După adăugarea unui control din clasa JDialog şi denumit jDialog1, mediul de
programare afişează suprafaţa utilă a ferestrei noului control. Pentru a putea
introduce datele necesare s-au adăugat două etichete (JLabel), două controale din
clasa JTextField redenumite h şi v şi un buton etichetat Ok care închide fereastra.
69

Metoda executată la apăsarea butonului Ok este:

Metoda setVisible() afişează sau ascunde o fereastră de dialog. Pentru


afişarea ferestrei de dialog de exemplu metoda jButton1ActionPerformed va apela
setVisible() cu parametrul true:

Desenarea în Java

Controalele Windows deja utilizate au o geometrie predefinită. Programatorul


poate interveni într-o oarecare măsură asupra aspectului acestora folosind fereastra
de proprietăţi (dimensiuni, plasare în cadrul containerului, etichete, fonturi etc) dar nu
le poate desena. Clasele cărora le aparţin aceste obiecte grafice suprascriu metoda
paint(), în cadrul căreia se realizează reprezentarea grafică a obiectului. Ori de câte
ori are loc un eveniment care impune redesenarea obiectului (obiectul devine vizibil,
70

containerul în care este dispus se modifică, etc.) metoda paint() este apelată în mod
automat.
Aplicaţiile care conţin reprezentări grafice care trebuie realizate prin program
necesită definirea unei clase noi, derivată de regulă din JPanel. În noua clasă se va
suprascrie metoda paint(), codul acesteia realizând reprezentarea dorită. Metoda
paint() va fi apelată automat, ca şi în cazul controalelor standard, ori de câte ori este
necesar. Apelul ei direct din program este interzis. Dacă este necesară refacerea
reprezentării grafice ca urmare a modificării datelor pe baza căreia este realizată
reprezentarea, va fi apelată metoda repaint() care va forţa redesenarea prin apelul
metodei paint().

Adăugarea unei noi clase

Structura unei aplicaţii Java presupune fie o alăturare de mai multe clase,
fiecare fiind conţinută într-un fişier distinct, fie realizarea unei singure clase. În a
doua variantă eventualele clase care trebuie adăugate sunt definite în interiorul
clasei aplicaţiei, fiind denumite clase interioare (inner classes).
Prima variantă prezintă avantajul portabilităţii claselor. O clasă poate fi uşor
încorporată într-o altă aplicaţie, de regulă fără a trebui modificată. Dacă totuşi se
impun unele adaptări, se va aplica soluţia clasică oferită de programarea obiectuală,
respectiv definirea unei clase derivate.
În varianta definirii unei clase interioare, metodele definite în noua clasă pot
accesa direct variabilele clasei principale. În exemplul considerat, clasa interioară va
putea accesa conţinutul controalelor h şi v.
În Java o clasă interioară poate fi teoretic inclusă oriunde. În aplicaţia
considerată clasa interioară va fi plasată înafara oricărei metode, în zona de
declaraţii a clasei figuri.
Clasa interioara se va numi panouDesen şi este definită astfel:
71

public class panouDesen extends JPanel {


public panouDesen() {
}

public void paint(Graphics g) {


int hh = Integer.parseInt(h.getText());
int vv = Integer.parseInt(v.getText());
g.clearRect(0, 0, getWidth(), getHeight());
int x = getWidth() / 2 - hh / 2;
int y = getHeight() / 2 - vv / 2;
if (jRadioButton1.isSelected()) {
g.drawOval(x, y, hh, vv);
} else {
g.drawRect(x, y, hh, vv);
}
}
}

Erorile privind referinţe nerezolvate vor fi eliminate selectând în meniul


contextual opţiunea Fix imports:

Mediul va include la începutul fişierului liniile:


import javax.swing.JPanel;
import java.awt.Graphics;

După definirea clasei, în clasa principală, figuri, se va adăuga un nou câmp,


supdes:

private panouDesen supdes;


...
72

Pentru crearea obiectului supdes în constructorul clasei figuri, va fi apelat


constructorul clasei panouDesen:

supdes = new panouDesen();

Deoarece la demararea aplicaţiei în controalele h şi v lipsesc valorile (conţin


şiruri de caractere vide) sau în timpul funcţionării operatorul poate introduce
caractere nepermise, este indicată cuprinderea liniilor care preiau valorile din
controale în interiorul unui bloc Try-Catch. Aceasta se realizează simplu, prin aplelul
opţiniii Surround With try-catch din meniul contextual. Practic se selectează liniile
care conţin apeluri la metoda parseInt() şi se selectează în meniul contextual
opţiunea Surround With try-catch :

Notă: În variantele recente ale mediului Netbeans, după selectarea liniilor


care conţin apeluri ale metodei parseInt(), mediul va afişa un simbol (un bec galben)
în dreptul ultimei linii din grup. Selectarea cu mouse-ul a simbolului determină
afişarea opţiunii Surround with...
73

După selectarea variantei Surround with try {... din lista propusă, metoda
paint() va începe astfel:

public void paint(Graphics g) {


int hh = 0;
int vv = 0;
try {
hh = Integer.parseInt(h.getText());
vv = Integer.parseInt(v.getText());
} catch (NumberFormatException numberFormatException) {
}
g.clearRect(0, 0, getWidth(), getHeight());
...

Mediul a adăugat două linii care iniţializează cu 0 variabilele locale hh şi vv,


astfel încât dacă excepţia specificată (numberFormatException) se produce,
variabilele hh şi vv vor avea totuşi valori acceptabile.

Metodele folosite la desenare precum şi alte metode ale clasei Graphics mai
frecvent utilizate sunt prezentate în tabelul următor.

Tip
Metodă Explicaţie
returnat
void clearRect(int x, int y, int width, Umple dreptunghiul indicat prin
coordonate cu culoarea fundalului
int height)
suprafeţei pe care se desenează (un
JPanel de regulă)
void drawArc(int x, int y, int width, int height, Desenează un arc de cerc sau de
elipsă în dreptunghiul dat prin primele
int startAngle, int arcAngle)
4 argumente. Centrul arcului este în
centrul dreptunghiului iar startAngle şi
arcAngle definesc poz. de start şi
mărimea unghiului, în grade.
void drawImage(Image img, int x, int y, Include cât se poate dintr-o imagine.
Valoarea ultimului parametru poate fi
ImageObserver observer)
null.
74

void drawLine(int x1, int y1, int x2, int y2) Desenează o linie din punctul (x1, y1)
în punctul (x2, y2) folosind culoarea
curentă
void setColor(Color c) Impune culoarea folosită pentru
desenare.
void drawRect(int x, int y, int width, Desenează un dreptunghi.

int height)

void drawOval(int x, int y, int width, Desenează un oval sau un cerc.

int height)

void drawString(String str, int x, int y) Scrie şirul de caractere str începand
cu punctul de coord. (x, y)
void setFont(Font font) Impune fontul folosit în continuare

Plasarea obiectului supdes în fereastra aplicaţiei în poziţia


BorderLayout.CENTER impune modificarea constructorului clasei de bază, figuri
astfel:

public figuri() {
initComponents();
supdes = new panouDesen();
supdes.setPreferredSize(new Dimension(500,300));
getContentPane().add(supdes,java.awt.BorderLayout.CENTER);
pack();
}

Secvenţa de cod executată la apăsarea butonului Grafic conţine apelul


metodei repaint() pentru obiectul supdes:

Desenarea pe obiectul adăugat impune deci rescrierea metodei paint() dar


apelarea ei va fi realizată fie automat, de către Windows, dacă fereastra a suferit
modificări care necesită redesenarea, fie prin apelul metodei repaint(), din program.
Pentru a evidenţia apelarea automată de către Windows a metodei paint() se poate
75

pune în comentariu apelul metodei repaint() şi, după introducerea unui set de
dimensuini valide se redimensionează fereastra aplicaţiei.

Applet-uri
Una dintre caracteristicile limbajului Java este faptul că permite realizarea de
miniaplicaţii care pot fi transferate prin Internet şi executate în fereastra unui browser
pentru Web. O astfel de miniaplicaţie poartă numele de applet java. Fişierul
conţinând miniaplicaţia are extensia .class şi este rezultatul compilării miniaplicaţiei.
Dacă miniaplicaţia constă din mai multe clase, în urma compilării vor rezulta mai
multe fişiere .class. Dacă la dezvoltarea miniaplicaţiei se utilizează NetBeans,
ansamblul de fişiere .class care constituie applet-ul va fi întegistrat într-un
subdirector având numele pachetului declarat la crearea aplicaţiei care trebuie inclus
în directorul site-ului (de regulă în directorul care conţine pagina web în care applet-
ul este inclus).
Includerea într-o pagină web a unui applet se realizează folosind marcajul
<applet> Exemplu:

<applet code="miniap/miniap.class" width=350 height=200></applet>

În exemplul dat subdirectorul miniap care conţine applet-ul miniap.class este


înregistrat pe discul serverului în acelaşi director în care este înregistrată şi pagina
web care include applet-ul.
Atributele width şi height din marcajul <applet> indică mărimea zonei din
pagină alocată miniaplicaţiei.
Exemplu:
Se doreşte realizarea sub formă de applet a aplicaţiei realizate anterior.
Paşii realizării miniaplicaţiei sunt următorii:
1. Se realizează o nouă aplicaţie selectând ca şi tip General / Java
Class Library, numele ei fiind mini.
2. Se adaugă aplicaţiei un prim fişier alegând ca tip Java GUI Forms /
JApplet Form.
Numele dat clasei conţinute în proiect este figuri.
76

Deoarece unui applet îi lipseşte metoda main(), pentru a-l rula în NetBeans
se va selecta în meniul contextual afişat la selectarea fişierului care conţine applet-ul
opţiunea Run File.

Ca şi în varianta anterioară, se va realiza interfaţa aplicaţiei şi clasei mini i se


va adăuga clasa interioară panouDesen. Apoi aplicaţiei i se va adăuga variabila
supdes şi metoda init, care în cazul unei miniaplicaţii Java conţine codul conţinut în
constructorul clasei aplicaţiei va fi modificată astfel:

public void init() {


try {
java.awt.EventQueue.invokeAndWait(new Runnable() {

public void run() {


initComponents();
supdes = new panouDesen();
supdes.setPreferredSize(new Dimension(500, 300));
getContentPane().add(supdes, java.awt.BorderLayout.CENTER);

}
});
} catch (Exception ex) {
ex.printStackTrace();
}
}
77

Pentru testarea applet-ului se poate încărca într-un browser fişierul creat de


NetBeans în directorul build. În exemplul considerat acesta poartă numele
figuri.html.

În fişierul figuri.html applet-ul este inclus prin linia:


<APPLET codebase="classes" code="mini/figuri.class" width=500 height=540></APPLET>
Atributul codebase indică numele directorului în care se află subdirectorul
care conţine applet-ul.
78

Conectarea unei aplicaţii Java la un server de baze de date

Conectarea unei aplicaţii Java la un server de baze de date presupune


copierea într-un director a unui driver JDBC (Java Database Connectivity) specific
serverului de baze de date care urmează să fie accesat.
În cele ce urmează se va presupune că s-a instalat şi lansat în execuţie
serverul de baze de date MySQL. Acesta poate fi descărcat prin Internet sub forma
pachetului de aplicaţii destinat dezvoltării de site-uri web xamplite, care conţine
printre altele serverul de web Apache şi serverul de baze de date MySQL.

Pentru pornirea serverului MySQL se lansează în execuţie mysql_start.bat din


directorul xamplite.

Fereastra afişată în urma lansării în execuţie a serverului MySQL nu trebuie


închisă pe toată durata rulării aplicaţiilor care vor accesa serverul deoarece la
închiderea ei este oprit şi procesul mysqld.exe specific serverului MySQL.
79

Pentru a realiza o aplicaţie în Java care accesează serverul MySQL trebuie


realizate următoarele adaptări:
• Se descarcă MySQL Connector/J de la adresa :
http://dev.mysql.com/downloads/connector/j/5.0.html.
Acesta este driverul JDBC oficial pentru MySQL. Se dezarhivează fişierul
descărcat şi din directorul rezultat se copiază arhiva mysql-connector-java-5.0.6-
bin.jar într-un director care va fi referit ulterior, la crearea aplicaţiei. O soluţie bună
este plasarea fişierului mysql-connector-java-5.0.6-bin.jar în directorul
xamplite/mysql sau în directorul aplicaţiei curente.
• Se crează proiectul noii aplicaţii şi se adaugă acestuia calea spre arhiva
mysql-connector-java-5.0.6-bin.jar folosind intrarea Libraries a arborelui
structural al proiectului :

Rezultat:
80

În continuare se poate scrie aplicaţia. Accesul la tabelele bazei de date


presupune în principiu următorii paşi:
a. Se încarcă driverul JDBC necesar comunicaţiei cu serverul MySQL
folosind apelul:
Class.forName("com.mysql.jdbc.Driver");
b. Se crează o conexiune (obiect din clasa Connection) folosind metoda
statică getConnection() din clasa DriverManager:
con = DriverManager.getConnection("jdbc:mysql//localhost/baza_date", "user", "password");

c. Se crează un obiect Statement folosind obiectul din clasa Connection creat


la pasul anterior.
cda = con.createStatement();
d. Se crează o frază SQL (obiect din clasa String)
e. Se crează un obiect din clasa ResultSet prin apelul metodei
executeQuery() sau se apelează metoda executeUpdate() din clasa Statement
folosind ca argument fraza SQL creată în pasul precedent. Prima metodă este
apelată pentru comenzile SELECT iar a doua pentru comenzi ca INSERT, UPDATE
sau DELETE.
ResultSet rs = stmt.executeQuery(fraza_SQL);
f. Dacă s-a trimis serverului o comandă SELECT se transferă datele din
rezultat (ResultSet) în controalele windows corespunzătoare: JTextField,
JComboBox, JTable sau JList.

Exemplu fundamental:
Să se realizeze o aplicaţie care permite introducerea într-o bază de date a
raselor de câini.
81

1. Se lansează în execuţie xampplite şi se crează baza de date rase :

2. În baza de date creată se adaugă tabelele :


a. Tabelul tari :

b. Tabelul talie :
82

c. Tabelul scop :

d. Tabelul caine :

Pentru testarea aplicaţiei se vor adăuga înregistrări în primele 3 tabele create.


Aceste tabele vor servi la crearea listelor unor controale din clasa JComboBox.

3. Se porneşte NetBeans, se realizează un nou proiect (RaseCaini de tip


General / Java Application) şi se realizează adaptările legate de conexiunea la
serverul MySQL.
83

4. Se adaugă proiectului un fişier conţinând clasa principală raseCaini


derivată din JFrame :
84

5. Clasei principale i se adaugă două variabile, conect din clasa


java.sql.Connection şi stm din clasa java.sql.Statement :

6. Se crează interfata aplicaţiei. Pentru introducerea datelor, aceasta


cuprinde controalele de tip JComboBox comboTara, comboTalia, comboDestinatia şi
controlul nume din clasa JtextField.
85

comboTara

comboTalia

comboDestinatia

nume

jButton1 jButton2

7. Se editeză constructorul clasei raseCaini pentru a realiza iniţializarea


tuturor variabilelor clasei.

Pentru scrierea corectă a structurilor try-catch se va scrie conţinutul blocului


try şi se va creea structura folosind opţiunea corespunzătoare din meniul contextual.
Exemplu :
86

8. Se adauga proiectului metodele destinate populării controalelor de tip


JComboBox . iniComboTara(), iniComboTalia(), şi iniComboDest().

a. iniComboTara() :
87

b. iniComboTalia() :

c. iniComboDest() :

9. Se adauga proiectului metodele declanşate la apăsarea butoanelor.


a. Butonul Înregistrează
88

b. Butonul Abandon

Executarea aplicaţiei

Aplicaţiile din exemplele prezentate au fost lansate în execuţie exclusiv din


mediul de programare NetBeans. În procesul de construire a proiectului (Build /
Build Main Project) mediul de programare crează în directorul \dist un fişier
executabil.

dublu clic
89

Acesta poate fi lansat în execuţie ca orice aplicaţie Windows, din Windows


Explorer, cu un dublu clic. Dacă lansarea în execuţie trebuie realizată dintr-o
fereastră Command, se va introduce comanda:

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