Un nou limbaj de programare nu are șanse să se impună fără să ofere, pe lângă
sintaxa propriu-zisă un set de biblioteci sau o ierarhie de clase coerentă și cât mai
generală. Atunci când limbajul C a fost prezentat pentru prima dată, împreună cu el a
fost prezentată și biblioteca standard de intrare ieșire. Primul program C pe care l-am
învățat conținea deja apelul:
printf( "hello, world!" );
Limbajul Java nu numai că nu face excepție de la această regulă dar chiar o extinde
cu ambiția de a oferi totul. Interfața Java pentru programarea aplicațiilor (API)
oferă o ierarhie de clase care include funcționalitate pentru lucrul cu mai multe fire
de execuție, lucrul în rețea, crearea interfețelor utilizator complexe, grafică, etc.
Acest capitol va prezenta o parte a acestei ierarhii împreună cu câteva tehnici
uzuale de scriere a aplicațiilor Java.
Există mai multe moduri de a aborda scrierea unui program. Unul dintre acestea este
scrierea unui program care are inițiativa pe toată perioada rulării. Acest tip de
programe execută în permanență o secvență de cod, fie și numai o buclă de
așteptare a cărei condiție depinde de elemente exterioare precum ar fi o apăsare de
tastă sau sosirea unui pachet de date din rețea.
Alternativa este aceea de a scrie programe care intră în execuție doar atunci când
sunt generate anumite evenimente în sistem. În clipa în care apar aceste evenimente,
programul le analizează și execută o secvență de cod specifică evenimentului
respectiv. După execuția codului, programul se oprește din nou până la apariția unui
nou eveniment.
Aceste două alternative diferite de a aborda scrierea unui program își au
rădăcinile în moduri diferite de lucru ale sistemelor de operare și în moduri
diferite de a gândi interfața cu utilizatorul.
Java implementează ambele stiluri de programe discutate mai sus. În primul caz, avem
o clasă de pornire care conține o funcție publică principală și care va fi
lansată în execuție la apelarea programului. În acest caz programul își controlează
complet execuția ulterioară. În termenii limbajului Java, aceasta este o aplicație.
În al doilea caz, codul rulează în interiorul unui navigator Internet. Clasa de
pornire trebuie să aibă implementate metode de răspuns la anumite evenimente pe care le
generează navigatorul, precum ar fi inițializare, pornire, oprire, desenare, etc. Acest
al doilea tip de programe Java le vom numi apleturi.
Distincția dintre cele două moduri de organizare a codului este destul de vagă, din
cauză că cele două moduri de lucru se pot amesteca în
realitate, un obiect aplet putând fi în același timp lansat ca aplicație
independentă și invers. Totul depinde de metodele care au fost definite în interiorul
clasei de pornire a programului. 
7.1 Aplicații Java
Cea mai simplă aplicație Java este declarația unei clase de pornire conținând o
singură metodă, main , ca în exemplul următor:
public class HelloWorld {
public static void main( String args[] ) {
System.out.println( "Hello, world!" );
}
}
Acest exemplu definește o funcție principală care afișează un simplu mesaj pe
consola aplicației. Afișarea este lăsată în sarcina clasei java.lang.System
care conține în interior implementarea ieșirii și intrării standard precum și a
ieșirii standard de eroare sub forma unor referințe către obiecte de tip InputStream
pentru in (intrarea standard) respectiv PrintStream pentru
out și err (ieșirea standard și ieșirea standard de
eroare).
Numele metodei main este obligatoriu, la fel și parametrul acesteia.
Atunci când lansăm interpretorul Java împreună cu numele unei clase care reprezintă
clasa de pornire, interpretorul caută în interiorul acestei clase definiția unei metode
numite main . Această metodă trebuie să fie obligatoriu publică și
statică. În același timp, metoda main trebuie să nu întoarcă nici un
rezultat și să accepte un singur parametru de tip tablou de șiruri de caractere.
Dacă interpretorul găsește această metodă în interiorul clasei apelate, el
lansează în execuție metoda main . Atenție, metoda main
fiind de tip static, nu poate apela decât variabile statice. De obicei însă, metoda main
nu face nimic altceva decât să-și prelucreze parametrul după care să creeze o serie
de obiecte care vor controla execuția ulterioară a aplicației.
Singurul parametru al metodei main este un tablou care conține
argumentele aflate pe linia de comandă în momentul apelului. Nu este necesară
transmiterea numărului de argumente care au fost găsite pe linia de comandă pentru că
tablourile Java conțin în interior informații relative la numărul de elemente. Acest
număr de elemente se poate obține prin accesarea variabilei length din
interiorul tabloului ca în exemplul următor care listează parametrii de pe linia de
comandă la lansarea unei clase:
public class Arguments {
public static void main( String args[] ) {
for( int i = 0; i < args.length; i++ ) {
System.out.println( args[i] );
}
}
}
Iată un exemplu de rulare a acestei aplicații:
>java Arguments unu doi trei
unu
doi
trei
> ^
Apleturile Java rulează într-un document HTML. În acest document, fiecare aplet are
rezervată o fereastră dreptunghiulară prin care comunică cu utilizatorul. Dreptunghiul
de încadrare al ferestrei este definit într-un tag HTML numit APPLET. Această
fereastră este în exclusivitate la dispoziția apletului care este responsabil de
desenarea ei și de tratarea eventualelor evenimente care se referă la ea.
Noul tag HTML este recunoscut deocamdată doar de anumite navigatoare WWW precum
HotJava și Netscape 2.0. Este foarte probabil
ca în viitor majoritatea navigatoarelor să ofere compatibilitate Java.
Împreună cu definirea interfeței dintre apleturi și navigator, Sun a definit și o
sintaxă specifică noului tag HTML care permite poziționarea și dimensionarea ferestrei
apletului în document precum și specificarea unor parametri care să poată altera modul
de lucru al apletului.
Iată un prim exemplu de aplet:
import java.awt.Graphics;
public class HelloWorldApplet extends java.applet.Applet {
public void init() {
resize( 150,25 );
}
public void paint( Graphics g ) {
g.drawString( "Hello world!", 50, 25 );
}
}
În mod minimal, apletul nostru nu definește decât două metode și anume una de
inițializare, necesară pentru organizarea mediului în care rulează apletul și una de
desenare a spațiului destinat apletului în interiorul documentului HTML. Metoda de
inițializare nu face în acest caz decât să redimensioneze spațiul alocat în mod
corespunzător necesităților sale în timp ce metoda de desenare afișează în acest
spațiu un mesaj de salut.
Pentru a vedea rezultatele rulării acestui aplet trebuie să construim un document
minimal HTML, care poate să arate în felul următor:
<HTML>
<HEAD>
<TITLE> Hello World Applet </TITLE>
</HEAD>
<BODY>
Iata iesirea programului:
<APPLET CODE="HelloWorldApplet.class" WIDTH=150 HEIGHT=25>
</APPLET>
</BODY>
</HTML>
Spre deosebire de o aplicație normală Java, apleturile nu pot primi parametri pe
linia de comandă pentru că nu există linie de comandă. Din acest motiv, trebuie să
introducem parametrii apletului în fișierul HTML. De exemplu am putea introduce, imediat
după linia de declarație a apletului o linie de forma:
<PARAM NAME=mesaj VALUE="Salutare, lume!">
Și să modificăm codul apletului după cum urmează:
import java.awt.Graphics;
public class HelloWorldApplet extends java.applet.Applet {
private String sir;
public void init() {
sir=getParameter( "mesaj" );
if( sir == null ) {
sir = "Hello, World!";
}
resize( 150,25 );
}
public void paint( Graphics g ) {
g.drawString( sir, 50, 25 );
}
}
În acest mod putem să controlăm la lansare inițializarea apletului. În definiția
clasei Applet există și două funcții care permit navigatorului
regăsirea unui minim de informații despre aplet. Aceste informații reprezintă
descrierea apletului și a parametrilor acestuia. Funcțiile care trebuiesc definite în
noua clasă derivată din Applet sunt getAppletInfo și getParameterInfo
. De exemplu, putem introduce în clasa HelloWorldApplet două noi funcții:
public String getAppletInfo() {
return "Applet scris de Eugen Rotariu";
}
public String [][] getParameterInfo() {
String info[][] = {
{ "Parametru", "String", "Textul de afisat" }
};
return info;
}
Execuția unui aplet este marcată de câteva evenimente importante generate de către
navigator. Atunci când navigatorul întâlnește o etichetă APPLET, pornește în primul
rând încărcarea codului necesar rulării apletului. Până când acest cod nu a ajuns
pe calculatorul client, apletul nu poate fi pornit.
După încărcarea codului, apletul este apelat pentru inițializare. Acesta este
momentul în care apletul își pregătește parametrii și obține de la sistem resursele
necesare rulării. După ce inițializarea a fost terminată, navigatorul trimite către
aplet o comandă de pornire. Aceasta este comanda care pune efectiv apletul în funcțiune
deschizând interacțiunea cu utilizatorul.
Un aplet rulează atâta timp cât navigatorul este activ. La schimbarea paginii
curente, apleturile din vechea pagină nu sunt distruse, dar primesc o comandă de oprire
temporară (pe care de altfel pot să o ignore). La reîncărcarea paginii, o altă
comandă de pornire este lansată spre aplet și acest ciclu se poate relua. În
sfârșit, la oprirea navigatorului, apletul primește o comandă de oprire definitivă,
caz în care el trebuie să elibereze toate resursele pe care le blochează.
Orice aplet Java reprezintă, din punctul de vedere al limbajului un nou tip de obiect,
derivat din obiectul standard Applet . Atunci când navigatorul lansează
un nou aplet el nu face altceva decât să instanțieze un nou obiect din această clasă.
Subrutinele care tratează evenimentele descrise anterior trebuiesc definite ca metode în
interiorul acestui nou tip de obiecte.
În continuare, între două evenimente de pornire și respectiv de oprire temporară a
apletului navigatorul transmite către aplet evenimente specifice oricărei interfețe
grafice cum ar fi evenimentul care provoacă redesenarea spațiului destinat apletului,
evenimente legate de apăsarea unor taste sau a unor butoane ale mausului, etc. Ca
răspuns la aceste evenimente, apletul trebuie să reacționeze schimbând conținutul
ferestrei, lansând mesaje sonore, etc. Iată și un exemplu de aplet care ne arată
fazele prin care trece un aplet în timpul existenței sale:
import java.applet.Applet;
import java.awt.*;
public class EventTutor extends Applet {
public void init() {
// metoda de inițializare
// este apelată la construcția noii instanțe de aplet
System.out.println("init");
}
public void paint(Graphics g) {
// metoda de desenare
// este apelată ori de câte ori este necesară
// redesenarea ferestrei apletului
System.out.println("paint");
}
public void start() {
// metoda de lansare in execuție
// este apelată la pornire
//sau la reîntoarcerea în pagina apletului
System.out.println("start");
}
public void stop() {
// metoda de oprire temporară a execuției
System.out.println( "stop" );
}
public void destroy() {
// metoda de oprire definitivă
System.out.println("destroy");
}
public void update(Graphics g) {
// metoda de actualizare a ferestrei apletului
// este apelata atunci când nu este necesară redesenarea
// întregii ferestre. În mod implicit,
// metoda apelează metoda paint.
System.out.println("update");
}
public boolean mouseUp(Event e, int x, int y) {
// S-a ridicat butonul mausului în fereastra apletului.
System.out.println("mouseUp");
return false;
}
public boolean mouseDown(Event e, int x, int y) {
// S-a apăsat butonul mausului în fereastra apletului
System.out.println("mouseDown");
return false;
}
public boolean mouseDrag(Event e, int x, int y) {
// S-a mișcat mausul în fereastra apletului
// cu butonul apăsat
System.out.println("mouseDrag");
return false;
}
public boolean mouseMove(Event e, int x, int y) {
// S-a mișcat mausul în fereastra apletului
System.out.println("mouseMove");
return false;
}
public boolean mouseEnter(Event e, int x, int y) {
// Mausul a pătruns în fereastra apletului
System.out.println("mouseEnter");
return false;
}
public boolean mouseExit(Event e, int x, int y) {
// mausul a ieșit din fereastra apletului
System.out.println("mouseExit");
return false;
}
public void gotFocus() {
// Fereastra apletului a devenit fereastra activă
System.out.println("gotFocus");
}
public void lostFocus() {
// Fereastra apletului nu mai este fereastra activa
System.out.println("lostFocus");
}
public boolean keyDown(Event e, int x) {
// S-a apăsat o tasta și aceasta
// este destinata apletului
System.out.println("keyDown");
return true;
}
}
Puteți rula apletul de mai sus pentru a vedea care este ordinea în care sunt apelate
aceste metode de către navigator. Apletul de mai sus produce ieșiri la consolă (o
fereastră text) și nu în fereastra apletului. Dacă nu vedeți consola, încercați să
căutați prin meniurile navigatorului opțiunea de afișare a consolei Java. Netscape de
exemplu are o astfel de opțiune în meniul Options-Show Java console.
Din cele spuse până acum se poate deduce că apleturile Java nu au o viață proprie,
ele fiind doar apelate din când în când de navigator. Ceea ce nu este întocmai
adevărat pentru că biblioteca standard de clase Java oferă suport pentru aplicații
care folosesc mai multe fire de execuție. Apleturile pot astfel crea fire de execuție
care să lucreze independent față de navigator. 
Iată descrierea DTD tagului pe care Sun l-a definit pentru introducerea unui aplet
într-un document HTML.
<!ELEMENT APPLET - - (PARAM*, (%text;)*)>
<!ATTLIST APPLET
CODEBASE CDATA #IMPLIED-- code base --
CODE CDATA #REQUIRED-- code file --
NAME CDATA #IMPLIED-- applet name --
WIDTH NUMBER #REQUIRED
HEIGHT NUMBER #REQUIRED
ALIGN (left|right|top|texttop|middle|absmiddle|
baseline|bottom|absbottom) baseline
VSPACE NUMBER #IMPLIED
HSPACE NUMBER #IMPLIED
>
<!ELEMENT PARAM - 0 EMPTY>
<!ATTLIST PARAM
NAME NAME #REQUIRED-- The name of the parameter --
VALUE CDATA #IMPLIED-- The value of the parameter --
>
Atributele obligatorii ale acestei definiții sunt numele fișierului în care este
memorat codul și dimensiunea spațiului rezervat apletului. Minimal, tag APPLET arată
în felul următor:
<APPLET CODE="HelloWorldApplet.class" WIDTH=200 HEIGHT=150>
Text care apare dacă navigatorul nu știe Java
</APPLET>
Atributele opționale ale tagului descriu locația de bază a codului apletului, modul
de aliniere în pagină, spațierea și eventualii parametrii care pot fi transmiși
apletului din interiorul documentului HTML.
Dacă codul clasei este în același director cu documentul HTML este suficient să fie
specificat atributul CODE cu numele fișierului unde este acesta memorat. Dacă este
nevoie de un director diferit, trebuie completat și atributul CODEBASE în care se
menționează directorul. De exemplu, dacă fișierele .class sunt
într-un subdirector numit /clase al directorului care conține documentul
HTML, atunci exemplul de mai sus devine:
<APPLET CODE="HelloWorldApplet.class" CODEBASE="clase"
WIDTH=200 HEIGHT=150>
Text care apare dacă navigatorul nu știe Java
</APPLET>
Atributul ALIGN specifică modul în care fereastra destinată apletului va fi
aliniată în pagină. Valorile sale posibile sunt: LEFT, RIGHT, TOP, TEXTTOP, MIDDLE,
ABSMIDDLE, BASELINE, BOTTOM și ABSBOTTOM. Valoarea implicită este BASELINE.
- LEFT, RIGHT - alinierea va fi în stânga, respectiv dreapta, textului din linie.
- TOP - alinierea se va face cu elementul cel mai înalt din linie, fie el un alt aplet, o
imagine sau textul însuși.
- TEXTTOP - alinierea se face cu cea mai înaltă poziție ocupată de textul liniei.
- ABSMIDDLE - mijlocul apletului va fi aliniat cu mijlocul elementului cel mai mare din
linie.
- MIDDLE - mijlocul apletului se va alinia cu mijlocul liniei de bază a textului.
- BASELINE, BOTTOM - baza apletului se va alinia cu linia de bază a textului.
- ABSBOTTOM - baza apletului va fi aliniată cu elementul cel mai de jos din linie.
Atributele VSPACE și HSPACE specifică, în pixeli, spațiul care desparte apletul de
textul care îl înconjoară.
Pentru a transmite parametrii unui aplet, puteți folosi tagul PARAM așa cum am
arătat mai sus.  |