Capitolul VII
Modele de programare

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
> ^

7.2 Apleturi Java

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. ^

7.3 Tagul APPLET

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. ^

[cuprins]
(C) IntegraSoft 1996-1998