Php, Mysql Si Java Utilizate Pentru O Aplicatie Didactica
PHP, MySQL și Java
utilizate pentru o aplicație didactică
Introducere
Scopul aplicației
Fizica a fost mereu privitã ca o materie grea, aproape inteligibilã, uneori demodatã sau chiar inutilã. Motivele acestui fapt sunt multe, dar unul dintre cele mai importante este acela cã nu se asigurã un suport interactiv, corespunzãtor cu cerințele începutului de secol XXI. Tocmai de aceea a luat ființã acest site web, care își propune sã facã mai ușoarã învãțarea materiei și sã încerce sã readucã popularitatea fizicii în rândul tinerilor de astãzi. Nu în ultimul rând, aduce resurse și informații pasionaților sau profesorilor.
Site-ul își propune să prezinte materia din programa școlară, mai întâi pe cea pentru clasa a IX-a. În momentul de față sunt expuse doar câteva capitole exemplificative, important în acest caz nefiind conținutul în sine, ci produsul software care publică și gestionează informațiile. Sunt prezente și elemente care nu se mai cer în ziua de astăzi, dar care pot trezi interesul pasionaților sau care pot explica mai bine anumite fenomene.
Vom (re)explora misterele și minunãțiile fizicii, dar într-un mod mai plãcut și interactiv. Scopul NU este de a înlocui cursurile de la școalã și nici de a micșora rolul profesorului. Acesta este doar un loc în care elevii pot gãsi mai multe resurse sau le pot citi din altã perspetivã. Pe lângã imaginile care însoțesc teoria, site-ul dispune și de appleturi interactive, cu scopul de a facilita înțelegerea diferitelor concepte. Acestea au fundalul gri și pot fi pornite/oprite cu un singur click. Motivul pentru care nu sunt pornite în mod automat este acela cã dacã sunt pornite mai multe appleturi pe aceeași paginã, pot influența în mod negativ performanțele unui calculator mai slab.
În ziua de astãzi, fizica nu primește din partea elevilor respectul cuvenit. Foarte mulți considerã cã nu mai folosește la nimic sã ai cunoștințe elementare de fizicã, nerealizând cã atunci când vorbesc despre ultimele mașini de pe piațã, vorbesc și despre cai-putere, capacitate cilindrica, viteze sau accelerații, iar toate acestea își au locul în fizicã. În plus, fiecare dintre noi interacționeazã cu rezultate ale studierii fizicii, atunci când deschide telefonul mobil, când aprinde un bec sau când se urcã în tramvai.
Proiectul exemplică posibilitățile limbajelor și uneltelor de programare Open Source, folosind un server de web Apache cu modul PhP, un server de baze de date MySQL, appleturi Java dezvoltate cu ajutorul mediului de programare NetBeans și imagini creeate cu utilitarul GiMP. Este așadar demonstrat că pentru a creea un proiect web nu este necesară o tehnologie proprietară scumpă.
Ideea aplicației este simplă: cu ajutorul unei secțiuni de administrare, în care se poate intra doar pe bază de parolă, sunt adăugate și editate capitole și subcapitole. Atât conținutul cât și numele capitolelor sunt stocate într-o bază de date. În conținut sunt prezente taguri HTML, ce fac lectura mai ușoară și fac referință la imagini și appleturi. Pentru ușurința editării, în secțiunea de administrare este prezent și un editor de texte implementat în javascript. Acesta adaugă elementele de HTML și poate fi folosit chiar de o persoană care are doar cunoștințe minime de HTML.
În paginile ce urmează voi demonstra că acest site este un produs software modern, competitiv, ce necesită tehnologii gratuite și eficiente și care poate satisface cerințele erei prezentului, era informației. Cu ajutorul cadrului creeat, se pot expune informații și din alte domenii, cum ar fi informatică, biologie, matematică etc. Se pot chiar face lecții online și intr-o versiune viitoare va putea chiar avea teste care vor monitoriza gradul de înțelegere al materiei. Oricum, profesorii de fizică pot include anumite pagini din site în prezentări de lecție.
World Wide Web
WORLD WIDE WEB ( WEB sau WWW) reprezintă un context arhitectural pentru accesul la documente stocate pe mașini între care există legături, pe Internet. În ultimii ani a evoluat de la o aplicație pentru transmiterea de date utile, la o aplicație despre care milioane de oameni cred că este Internetul. Popularitatea sa se datorează faptului că are o interfață grafică dinamică, ușor de accesat de către utilizatori și în același timp oferă o cantitate imensă de informație din orice domeniu.
WEB-ul a fost realizat din nevoia de a permite cercetătorilor din toata lumea să țină legătura, utilizând colecții de rapoarte, planuri, desene, fotografii și alte tipuri de documente necesare aflate într-o continuă modificare. Propunerea inițială pentru conceperea unei “arhive” de documente și informații ce au legături între ele (WEB) a fost făcută de catre Tim Berners-Lee, fizician la CERN, în martie 1989. Primul prototip (bazat pe text) a fost operational la scurt timp, 18 luni mai târziu. În decembrie 1991 s-a făcut o demonstrație publică la conferința Hypertext '91, în San Antonio, Texas. Acțiunea a continuat în anul următor, fiind încununată cu realizarea primei interfețe grafice, Mosaic, în februarie 1993.
Există mai multe tipuri de tehnologii care sunt folosite pentru sprijinirea World Wide Web și mai multe sunt în curs de dezvoltare . There are several groups involved in the development and coordination of these technologies. Există mai multe grupuri implicate în dezvoltarea și coordonarea acestor tehnologii. Enumerăm cateva :
IAB – Internet Architecture Board. Web site: . The IAB websites states that "The IAB does not aim to produce polished technical proposals on such topics. Rather, the intention is to stimulate action by the IESG or within the IETF community that will lead to proposals that meet general consensus." Afirmă IAB site-uri care "CEI nu are ca scop să prezinte propuneri tehnice lustruit pe asemenea teme. Mai degrabă, intenția este de a stimula acțiuni de către IESG sau în cadrul comunității IETF care va duce la propuneri care îndeplinesc consens general."
IANA – Internet Assigned Numbers Authority. IANA – Internet Assigned Numbers Authority: They control the assignment of internet addresses and domain names. Ei controlează alocarea adreselor de internet și a numelor de domenii.
IESG – The Internet Engineering Steering Group. IESG – Internet Engineering Group directorWeb site: .: According to RFC 2418, the IESG "has responsibility for developing and reviewing specifications intended as Internet Standards." În conformitate cu RFC 2418, IESG "are responsabilitatea pentru dezvoltarea și revizuirea specificațiilor destinate ca standardele Internet."
IETF – The Internet Engineering Task Force. IETF – Internet Engineering Task Force. Their web site says "The Internet Engineering Task Force (IETF) is a large open international community of network designers, operators, vendors, and researchers concerned with the evolution of the Internet architecture and the smooth operation of the Internet."Site-ul lor web spune: "Internet Engineering Task Force (IETF) este o comunitate mare deschisă internațională de designeri de rețea, operatori, vânzători și cercetători preocupați de evoluția arhitecturii Internet și buna funcționare a Internetului."
InterNIC – Internet Network Information Center, the authority for allocating internet addresses. InterNIC – rețea de Internet Centrul de Informare, autoritatea de alocare a adreselor de internet. .
Tehnologii Folosite
HTML
HTML este un acronim care provine de la HyperText Markup Language și reprezintă un limbaj declarativ ce permite crearea de documente hipertext, pentru paginile Web, documente care pot fi vizualizate cu ajutorul navigatoarelor Web (în mediul Internet cel mai folosit este browserul Internet Explorer).
Web reprezintă un spațiu abstract de informație, fiind practic un serviciu de informare care face apel la conceptul de hipermedia. În contextul unui document dat, există o deosebire conceptuală între noțiunile de hipermedia și multimedia.
Un document multimedia este un document care poate să conțină atât informații de natură statică (text, imagini, grafice sau diagrame), cât și informații dinamice (sunet, animație, film). Dacă la acest conținut informațional se adaugă și capabilități de realizare a unor legături între părțile componente ale unui document multimedia, ceea ce rezultă reprezintă un document hipertext sau document hipermedia. În practică, termenii hipertext și hipermedia tind să fie considerați similari, deosebirea structurala fiind data de elementele multimedia (prin formatele grafice, audio și video) conținute de un document hipermedia.
La modul general, un document hipermedia poate fi identificat prin următoarele caracteristici fundamentale:
Forma de vizualizare este dependentă de programul de afișare a informațiilor conținute de documentul respectiv, în speță, de navigatorul Web;
Structura și conținutul documentului trebuie să respecte un format general de reprezentare pentru a se asigura portabilitatea și independența de platformă (cele doua atribute se referă la necesitatea recunoașterii documentului HTML, indiferent de componenta software și de echipamentele hardware cu care este dotat sistemul). Acest format de reprezentare este asigurat și furnizat de limbajul de marcare hipertext HTML. HTML are la bază limbajul Generalizat Standard de Marcare (Standard Generalized Markup Language – SGML).
Tehnicile hipertext (hipermedia) pot fi utilizate în diverse aplicații, precum cărțile electronice, enciclopediile, sistemele on-line de ajutor, sistemele de învățare asistată de calculator ( – Computer-Aided Learning), scrierea colaborativă de documente, chioșcurile informaționale interactive, sistemele decizionale etc.
Hipertextul reprezintă o forma neliniară de document electronic, fiind considerat o metodă de organizare complexă a informațiilor, prin care datele sunt memorate într-o rețea de noduri și legături. Nodurile sunt identificate, în mod unic, prin adresă. De exemplu, dacă dorim să obținem o anumită adresă sau capitol dintr-o carte, în loc să facem acest lucru fizic se poate atinge o anumită zonă a paginii ca să obținem informația dorită. Această rețea poate fi parcursă prin intermediul navigatoarelor interactive și manipulată de un editor structural. Conceptual, hipertextul poate fi definit ca o metodă de prezentare a informației, prin care anumite secvențe ale textului, numite cuvinte de legătură, sunt evidențiate în mod special, ca prin accesarea lor să se obțină informații suplimentare în legătură cu subiectul ales. Aceasta denotă o tehnica pentru organizarea informației textuale într-o manieră sofisticată, neliniară, în vederea facilitării exploatării rapide a unei cantități mari de cunoștințe.
Cuvintele de legătură prin care se realizează link-urile reprezintă secvențe text formatate într-o manieră deosebita, prin aplicarea unei anumite culori, dar și prin sublinierea textului. De asemenea, o legătură hipertext este evidențiata și prin modificarea aspectului de afișare a cursorului, în momentul în care utilizatorul îl plasează pe secvența de text respectivă.
Astfel, pentru explicitarea unei noțiuni, prin aceste cuvinte de legătură, se pot obține mai multe nivele de detaliere a conceptului asupra căruia utilizatorul dorește să se informeze.
Termenul tehnic pentru textul marcat este acela de element, acesta fiind văzut ca o componentă structurală a unui document. Limbajul HTML conține o mare diversitate de astfel de elemente, care poartă denumirea specifică de tag-uri sau marcatori.
Numele unui tag HTML se încadrează întotdeauna între delimitatorii „<” și „>”, nu poate începe cu o cifră și nu admite caracterul spațiu. Plecând de la caracterul opțional al tag-ului de sfârșit (plasarea acestuia între paranteze drepte), se pot deosebi două tipuri de tag-uri HTML, și anume:
Tag singular care conține numai tag-ul de început (Exemplu: <HR> permite trasarea unei linii orizontale în pagina Web);
Tag pereche care are în structura să, atât tag-ul de început, cât și cel de sfârșit (Exemplu: <B> Text </B> aceste cuvinte de legătură, se pot obține mai multe nivele de detaliere a conceptului asupra căruia utilizatorul dorește să se informeze.
Termenul tehnic pentru textul marcat este acela de element, acesta fiind văzut ca o componentă structurală a unui document. Limbajul HTML conține o mare diversitate de astfel de elemente, care poartă denumirea specifică de tag-uri sau marcatori.
Numele unui tag HTML se încadrează întotdeauna între delimitatorii „<” și „>”, nu poate începe cu o cifră și nu admite caracterul spațiu. Plecând de la caracterul opțional al tag-ului de sfârșit (plasarea acestuia între paranteze drepte), se pot deosebi două tipuri de tag-uri HTML, și anume:
Tag singular care conține numai tag-ul de început (Exemplu: <HR> permite trasarea unei linii orizontale în pagina Web);
Tag pereche care are în structura să, atât tag-ul de început, cât și cel de sfârșit (Exemplu: <B> Text </B> permite aplicarea caracterelor aldine asupra textului cuprins între cei doi marcatori).
În anumite situații se pot utiliza o serie atribute (parametri) ale tag-urilor HTML. Atunci când un tag HTML prezintă unul sau mai multe atribute, acestea sunt specificate întotdeauna în tagul de început al liniei de comandă.
Numele de tag-uri și de atribute pot fi editate cu caractere majuscule, cu minuscule sau combinația dintre acestea, HTML nefiind un limbaj case-sensitive. Însă, în anumite situații, se recomandă folosirea literelor mici, pentru ca elementele de cod să fie recunoscute de orice program de vizualizare a documentelor Web.
Fișierele HTML sunt fișiere text obișnuite, divizate în două părți: antetul (HEAD) și corpul de text (BODY).
Pentru introducerea unui program HTML se poate utiliza orice editor de texte, dar se recomandă editorul Notepad, pornind de la considerentul că un fișier HTML este practic un fișier ASCII (conținând caractere neformatate). După ce a fost editat întregul program, utilizatorul procedează la salvarea fișierului care conține documentul respectiv. Notepad va propune automat extensia ., specifică fișierelor de tip text, extensie care trebuie modificată cu HTML sau HTM, pentru ca în momentul accesării, navigatorul să recunoască acel fișier ca pe un document Web.
Fișierul HTML poate fi accesat din orice program de gestionare a fișierelor (Windows Explorer sau My Computer) sau chiar direct din browser, prin comanda Open.
Cele mai importante tag-uri HTML utilizate pentru acest tip de operații sunt:
<! Text> permite introducerea în program a unui comentariu, care nu va fi afișat în momentul accesării paginii Web, dar care poate permite parcurgerea cu ușurință a codurilor din programul HTML;
<B>Text</B> pentru editarea textului cu caractere aldine (îngroșate);
<I>Text</I> pentru editarea textului cu caractere italice (caractere cursive);
<Hi Align= Left|Center|Right|Justify>Text</Hi> unde „i” specifică dimensiunea caracterelor, în număr puncte tipografice1 (H6 – dimensiunea minima, H1- dimensiunea maxima, un punct tipografic reprezintă 1/72 inch);
<BIG>Text</BIG> editarea textului cu o dimensiune mai mare decât cea curentă;
<SMALL>Text</SMALL> aplică o dimensiune mai mică decât cea curentă;
<U>Text</U> aplică asupra textului operația de subliniere;
<P Align=Left|Center|Right> asigură editarea unui paragraf, cu posibilitatea de aliniere a textului (Stânga|Centrat|Dreapta), prin atributul Align;
<BR> permite trecerea pe rândul următor sau inserarea în pagină a unor linii vide;
<DIV Align=Left|Center|Right|Justify> permite alinierea unui text sau a unei imagini, cu valorile: Stânga|Centrat|Dreapta|Justificat;
<CENTER> Text (Imagine)</CENTER> centrează un text sau o imagine;
<HR Size=s Color=denumire/cod_culoare Width=n% Align=Left|Center| Right Noshade> HR permite trasarea unei linii orizontale, ca o linie de demarcație între diferitele informații conținute de documentele HTML. Prezintă următoarele atribute:
Size – dimensiunea (grosimea liniei – în puncte tipografice);
Color – culoarea liniei, folosind codurile de culoare;
Width – reprezintă cât la suta din lățimea ferestrei ocupa linia orizontală;
Align – alinierea liniei, în situația în care aceasta nu ocupă întreaga lățime a paginii;
Noshade – inhibă aplicarea unui efect de umbrire asupra liniei orizontale;
Bgcolor – în cazul în care comanda se aplica unui sir de caractere, se poate stabili o culoare de fundal pentru acestea.
Tag-ul BODY care asigură editarea corpului de text, prezintă următoarea serie de atribute ce permit realizarea unor setări generale, la nivelul întregului document HTML:
Bgcolor – setează culoarea pentru fundalul paginii Web;
Text – stabilește culoarea caracterelor;
Link – culoarea legăturilor care nu au fost accesate sau vizitate;
Vlink – culoarea legăturilor care au fost vizitate;
Alink – culoarea legăturilor în momentul activării lor.
În situația în care utilizatorul introduce tag-ul BODY, fără atributele sale, există anumite setări implicite, aplicate acestor elemente ale paginii Web (culoarea de fundal-alb, culoarea caracterelor-negru, culoarea legăturilor neaccesate-albastru, a legăturilor vizitate-indigo, culoarea în momentul accesării-roșu).
Toate setările din tag-ul BODY sunt operaționale la nivelul întregului document HTML. Există însă situații în care designer-ul documentului Web dorește aplicarea unor formatări, numai la nivelul unei secvențe de text din pagina respectivă, situație în care folosește tag-ul FONT, cu următoarele atribute de formatare:
Face – stabilește tipul de font ce se dorește a fi aplicat; în plus, există posibilitatea de a specifica mai multe tipuri de fonturi (separate prin virgula), urmând ca la procesare, navigatorul Web să execute fontul pe care îl recunoaște din lista respectiva;
Color – stabilește culoarea caracterelor, prin nume sau prin coduri hexazecimale;
Size – setează dimensiunea caracterelor, măsurată în număr puncte tipografice.
Pe lângă tag-urile prezentate anterior, într-un document HTML se pot introduce și o serie de entități, utilitatea majoră a acestora fiind posibilitatea de generare a unor simboluri sau a unor caractere speciale. Pentru a concepe documente HTML conținând diacritice, se vor utiliza în programul sursa entitățile-caracter.
De asemenea, într-un document HTML se pot defini trei tipuri de liste: liste ordonate (Ordered List), liste nenumerotate (Unnumbered List) și liste de definitii (Definition List). În funcție de necesitățile designer-ului Web în ceea ce privește modalitatea de prezentare a informației, într-un document HTML există și posibilitatea generării de liste imbricate pe mai multe nivele de ierarhizare a informațiilor prezentate în structurile respective.
Hipertextul (hyperlink-ul) reprezintă cea mai importantă facilitate în proiectarea paginilor Web, prin faptul că realizează delimitarea funcțională între un document obișnuit și un document hipermedia. Hipertextul permite ca, prin „activarea” (executarea unui clic) unui sir de caractere sau a unei imagini, să se vizualizeze conținutul informațional al altor fișiere HTML sau al altor zone aparținând fișierului curent. În raport de locația fișierului destinație, către care se generează legătura, exista mai multe tipuri funcționale de legături hipertext:
legături interne stabilite între zone diferite aparținând aceluiași document;
legături locale stabilite între fișiere diferite, plasate pe același server;
legături externe generate între fișiere plasate pe servere diferite.
Pentru realizarea legăturilor hipertext se folosește tag-ul ANCHOR (ancora), care se introduce, în mod diferențiat, în raport de natura documentului implicat în realizarea hyperlink-ului. Astfel, la sursa, în fișierul din care se va genera conexiunea, tag-ul Anchor va conține atributul HREF (Hypertext Reference) care permite specificarea URL-ului (Uniform Resource Locator) fișierului destinație, în speță, adresa acestuia. În ceea ce privește specificarea destinației se va utiliza atributul NAME, prin care se precizează locația către care se generează legătura respectiva.
O formă particulară de legătură hipertext o reprezintă transmiterea unui mesaj prin poșta electronică (e-mail). Adresa e-mail cuprinde în structura să următoarele elemente: nume_cont@furnizor_servicii_Internet.domeniu.
Eticheta "Mailto" va deschide un program de e-mail cu ajutorul căruia utilizatorul poate trimite un mesaj către destinatarul a cărui adresa este furnizată în linia de comandă.
În funcție de modul în care se comporta în timpul vizualizării în fereastra navigatorului Web, în speță, de dinamismul lor, se poate vorbi despre mai multe tipuri de imagini, și anume:
imagini statice, simple sau purtătoare de hyperlink-uri;
imagini care asigură fundalul paginilor Web;
imagini dinamice (animate – filme sau clipuri);
imagini reactive ce conțin zone generatoare de legături hipertext.
Pentru a introduce în pagina Web o imagine statică se utilizează tag-ul (Image).
Atributele tag-ului de setare a unei imagini au următoarea semnificație funcțională:
Src – specifică numele fișierului care furnizează imaginea grafica sau, după caz, specificatorul de fișier al acestuia (adresa completă a fișierului); există anumite tipuri specializate de fișiere ce conțin imagini, de exemplu: fișiere de tip BMP, GIF, TIFF, JPEG, , WMF etc.;
Height și Width – sunt elemente ce permit stabilirea dimensiunii imaginii din pagina Web, respective înălțimea și lățimea acesteia (se măsoară în pixeli);
Align – stabilește modalitatea de aliniere a imaginii în pagina (Stânga|Dreapta); în cazul în care utilizatorul dorește alinierea imaginii pe mijlocul paginii Web, se poate apela, fie la tag-ul DIV, cu valoarea Center a atributului Align, fie la posibilitatea de centrare pe pagină, prin tag-ul CENTER;
Border – permite definirea unui chenar de încadrare a imaginii, valoarea „n” stabilind grosimea liniei respective (se măsoară în puncte tipografice);
Alt – permite afișarea unei etichete explicative în momentul plasării indicatorului mouse-ului pe suprafața imaginii.
Pentru ca o imagine simplă să se transforme într-o imagine generatoare de hyperlink-uri, este necesar ca aceasta să funcționeze cu tag-ul ANCHOR (ANCORA) care permite realizarea de legături hipertext.
Prin atributul Href din ancora se specifică fișierul HTML către care se va genera legătura hipertext, plecând de la imaginea setată prin tag-ul (activarea hyperlink-ului se realizează prin executarea unui clic în orice locație a imaginii).
În afara de stabilirea unei culori de fundal, un utilizator are posibilitatea de a seta o imagine pe fundalul paginii pe care o proiectează. Este de preferat ca această imagine să fie cât mai simplă și monocromă, pentru a permite o vizualizare facilă a conținutului informațional al paginii respective. Pentru această operație se va utiliza tag-ul BODY, cu atributul BACKGROUND, prin care se va introduce numele sau, după caz, adresa completă a fișierului care furnizează imaginea de fundal.
Includerea în pagină Web a imaginilor dinamice, presupune utilizarea tag-ului Image (), dar cu atributul Dynsrc, care specifică sursa formatului video (fișiere de tip MPEG, , MOV etc.).
O altă categorie de imagini ce pot fi definite într-o pagina Web o constituie imaginile reactive, care prezintă facilitatea de a genera legături hipertext cu alte resurse (de regulă, documente HTML), prin activarea unor locații speciale ale acestei imagini, cunoscute sub accepțiunea de zone reactive.
În mod obișnuit, utilizatorul poate vizualiza pe ecran un singur document HTML, încărcat în fereastra asignată de navigator acelui document. Pentru a spori atractivitatea paginilor Web și a organiza mai eficient informațiile conținute de acestea, Web designerii pot recurge la tehnica „subferestrelor”, reprezentând un set de secțiuni în fereastra navigatorului, cunoscute sub accepțiunea de cadre.
Conceptul de cadru (frame) consta în divizarea ecranului în mai multe zone, ce pot fi asimilate unor ferestre, fiecare dintre acestea putând găzdui un document HTML; practic, aceste ferestre pot fi tratate într-o maniera independentă (fiecare zonă este identificată printr-un nume), ceea ce îi permite utilizatorului modificări punctuale la nivelul unei ferestre, fără a le afecta pe celelalte, fapt ce mărește considerabil posibilitățile de informare ale acestuia, pe domenii de interes.
În funcție de conținutul informațional al documentelor găzduite de aceste ferestre, ele vor fi prevăzute cu bare de defilare care să permită deplasarea pe orizontală și/sau pe verticală în interiorul cadrului, utilizatorul putând astfel interveni, la modul punctual, asupra unui cadru sau al altuia.
Formularul Web sau formularul electronic reprezintă o interfață care permite interacțiunea cu utilizatorii paginilor Web, prin introducerea unor date de natură diversă, date ce vor fi prelucrate ulterior pe serverul Web de către anumite programe specializate, cunoscute sub denumirea de scripturi (Common Gateway Interface – interfața sau standardul „porții” comune).
Interfața (scriptul ) reprezintă, practic, o specificație care extinde Protocolul de Transfer Hypertext (HTTP) pentru a permite serverelor Web să interacționeze dinamic cu stațiile de lucru client. În acest mod, se asigură interacțiunea server-navigator Web, în sensul personalizării rezultatelor, prin diverse prelucrări asupra elementelor conținute de paginile Web.
CSS
CSS este un acronim provenind din Cascading Style Sheets, care înseamnă “foi de stil în cascadă”. Proiectarea limbajului CSS a urmărit, îndeosebi, separarea dintre conținutului paginii (textul destinat vizitatorului și imaginile din pagină) și codul-sursă, scris pentru realizarea paginii Web.
Folosind limbajul CSS, se poate ajunge la:
un control mai fin asupra paginii Web;
scăderea dimensiunii în octeți a paginilor Web, în cazul în care codul CSS este conținut într-un fișier extern;
comoditatea editării paginii Web (modificând fișierul CSS extern, se modifică simultan toate paginile Web în care acesta este inclus);
efecte mai sofisticate decât cele produse de codul HTML, cum ar fi: suprapunerea unei imagini peste altă imagine;
suprapunerea unui text peste un alt text;
impresia de relief;
efectul hover;
afișarea unor fonturi mai mari decât fontul afișat de eticheta <h1> etc.
Principalul dezavantaj al limbajului CSS este reprezentat de faptul că pagina conținând cod CSS poate să arate diferit în aplicații de navigare diferite, deoarece nu toate browser-ele interpretează codul CSS corect și complet. Internet Explorer este singurul navigator care citește complet și corect codul CSS.
Definirea stilurilor
În limbajul CSS, stilurile se pot defini în mai multe moduri, de aici și următoarea clasificare:
stiluri dedicate;
clase de stiluri;
stiluri in-line;
stiluri definite în fișiere externe.
Deoarece într-o pagină Web putem avea mai multe tipuri de stiluri definite, este firesc ca acestea să fie aplicate conform anumitor reguli de prioritate. Numai pentru atributele care pot intra în conflict, vor avea prioritate, în ordinea descrescătoare a priorității, următoarele tipuri:
Stilurile in-line;
Stilurile din blocul <style> – prioritate are stilul cel mai recent definit;
Stilurile definite în fișiere externe – prioritate are stilul cel mai recent definit;
Stilul default.
În paragrafele ce urmează, vom prezenta, pe scurt, modalitățile de definire a tuturor tipurilor de stiluri enumerate mai sus.
Stilurile dedicate se aplică numai blocurilor de text pentru care sunt definite. Definirea lor se face în interiorul blocului <head> … </head>, după următoarea sintaxă de definire:
<style>
selector {atribut1: valoare1; …}
</style>
unde selector reprezintă un nume de element.
Un exemplu de definire este:
h2 {text-align:right; color:yellow}
Clasele de stiluri permit definirea unui stil general și folosirea lui doar la cerere, oriunde este necesar. Declararea lor se face după sintaxa:
.nume_stil { … }
sau
tip.nume_stil { … }
Pentru ca un element să folosească acest stil, el trebuie să aibă un atribut class a cărui valoare să fie nume_stil, iar în al doilea caz trebuie și să aibă denumirea (tag-ul) tip.
Un exemplu de utilizare pentru acest tip de stil ar fi:
definirea stilului:
h2.ry {text-align:right; color:yellow}
utilizarea stilului:
<h2 class = ry> Textul nostru </h2>
Stilurile in-line sunt acele stiluri definite chiar în cadrul etichetei elementului care le folosește, cu ajutorul atributului style. Valoarea atributului style este aceeași cu definiția stilului, așa cum s-a specificat mai sus, cu deosebirea că în loc de { … } se pun caracterele “ … ”.
Stilurile definite în fișiere externe se pun într-un fișier cu extensia “.css”. Definirea stilului se face întocmai ca în blocul <style>, cu mențiunea că nu se mai pun etichetele <style> … </style>. Pentru a avea acces la stilul definit în acest fișier, în blocul <head> … </head> vom pune eticheta <link> cu atributele rel, href și type, conform sintaxei de mai jos:
<link rel = “stylesheet” href = “adresă_fișier” type = “text/css” />
Atribute pentru stiluri
Pentru exprimarea valorilor unui atribut, pot fi utilizate diverse denumiri prestabilite, precum și diverse unitați de măsură:
pt – puncte tipografice;
pc – pica;
px – pixeli;
in – inch;
mm – milimetri;
cm – centimetri.
Sintaxa limbajului CSS pune la dispoziție programatorilor o multitudine de atribute și de valori specifice acestor atribute. Avem, astfel, atribute specifice pentru:
definirea fonturilor (Tabelul 2);
modelarea textului (Tabelul 3);
formatarea blocurilor de text (Tabelul 4);
configurarea straturilor (Tabelul 5).
Tabelul 2
Atribute pentru fonturi
Tabelul 3
Atribute pentru text
Tabelul 4
Atribute pentru blocurile de text
Tabelul 5
Atribute pentru straturi
JavaScript
JavaScript este cel mai des întâlnit limbaj de scriptare folosit în crearea paginilor web, dar nu numai. Este un limbaj lejer, care nu are reguli foarte stricte, și care oferă, astfel, destul de multă libertate programatorilor, fiind, astfel, un limbaj destul de ușor de folosit chiar și de începători.
În același timp, însă, JavaScript poate fi folosit și în moduri complexe, fiind de fapt, un limbaj de programare orientat de obiecte.
De cele mai multe ori, JavaScript este folosit pentru a adăuga dinamism paginilor web, acesta făcând posibilă modificarea elementelor fără reactualizarea paginilor, sau crearea de animații și handlere pentru evenimente.
Inserarea de cod JavaScript în interiorul unei pagini HTML se face cu ajutorul tag-ului <script>, astfel:
<script type=”text/javascript”>
– cod JavaScript –
</script>
Acesta poate fi plasat atât în secțiunea head a documetului html, cât și în interiorul sectiunii body.
Se poate, de asemenea, include un fisier extern javascript, setând proprietatea src a elementului script ca fiind adresa la care se regăsește acest fisier extern.
<head>
…
<script type=”text/javascript”>
…cod javascript…
</script>
…
</head>
<head>
…
<script type=”text/javascript” src=”javascript-extern.js”></script>
…
</head>
<body>
…
<script type=”text/javascript”>
…cod javascript…
</script>
…
</body>
<body>
…
<script type=”text/javascript” src=”javascript-extern.js”></script>
…
</body>
Codul JavaScript poate fi executat de browser, adică pe partea de client. Astfel, având și caracteristicile unui limbaj de progarmare, acesta este utilizat pentru a adăuga noi functionalități și conținut dinamic paginilor HTML. Acest lucru este posibil deoarece browser-ul reține în memorie structura documentelor/paginilor web sub forma unui arbore de obiecte și pune la dispoziție aceste obiecte script-urilor JavaScript, care le pot citi și manipula. Acest arborele de obiecte poartă numele de Document Object Model sau DOM.
Ce posibilități oferă JavaScript?
Construirea unor aplicații web dinamice;
Interacțiunea cu utilizatorul (afișare căsuțe de eroare/avertizare, validarea datelor din formulare înainte de a fi trimise la server, afișarea de mesaje când mouse-ul trece peste un obiect din pagina web, etc);
Realizarea de animații;
Reacționarea la diverse evenimente (acțiuni ale mouse-ului/tastaturii, etc);
Crearea unor formulare interactive;
Efectuarea unor calcule (care nu se doresc a fi efectuate pe server pentru a nu-l încărca);
Interacțiunea cu elementele de DOM (citirea/modificare conținutului unui element HTML);
Crearea de cookie-uri.
Deși JavaScript este un instrument mult mai puternic decât HTML și CSS, acesta are și câteva restricții în ceea ce privește operațiunile pe care le poate face:
Nu poate scrie fișiere pe calculatorul utilizatorului;
Nu poate citi fișiere de pe calculatorul utilizatorului (doar cookie-uri);
Nu poate executa instrucțiuni pe server.
O primă observație importantă este aceea că JavaScript este un limbaj case sensitive. Sintaxa JavaScript este foarte asemănătoare cu cea C sau Java. Instrucțiunile funcționează în același mod (ex: if, while, for, switch etc.).
În general, regulile de sintaxă nu sunt foarte stricte. Însă atunci când există o eroare, de cele mai multe ori, codul pur și simplu nu funcționează, dar nu se observa nici o eroare. Pentru identificarea erorilor se recomandă folosirea instrucțiunilor try și catch:
try
{
//cod JavaScript
}
catch(error)
{
alert(error);
}
Aceasta furnizează erori la executare, de exemplu dacă se încearcă modificarea unui element care nu există sau există conflicte de tipuri de date. Erorile de sintaxă nu genereaza nici un fel de eroare, astfel încât, de cele mai multe ori, dacă nu se găsește o eroare cu try/catch, dar codul nu funcționează, probabil există erori de sintaxă.
Fiind un limbaj de programare, JavaScript permite declararea variabilelor, respectiv definirea funcțiilor:
Declararea variabilelor: În JavaScript variabilele nu au un tip anume. Ele se declară cu ajutorul cuvântului cheie var, astfel:
var nume_variabila ;
Tipul va fi dat de valoarea lor. De asemenea, nu este necesar ca variabilele să fie declarate:
var x;
…
x=5*3;
sau
x=5*3;
ambele sunt corecte.
Definirea funcțiilor: În JavaScript funcțiile se definesc cu ajutorul cuvântului cheie function:
function nume_functie(param_1, param_2, …., param_n){
– corpul functiei, instructiuni –
}
Funcțiile din JavaScript, la rândul lor, nu au tip, nici pentru argumente, nici pentru valorile returnate.
Funcțiile JavaScript pot fi apelate fie din cadrul altor funcții sau pur și simplu dintr-o secțiune de cod JavaScript, fie ca handlere de evenimente asupra elementelor HTML.
Una dintre cele mai importante funcționalități ale JavaScript este posibilitatea de a accesa și modifica elementele HTML, prin HTML DOM. Astfel se pot crea pagini web dinamice, elementele putând fi modificate în timp real, fără a necesita reîncărcarea paginii.
O modalitate frecvent utilizataă de accesare în interiorul codului JavaScript a unui element HTML din document este invocarea metodei DOM getElementById(), care accesează elementul care are id-ul specificat (dat ca parametru).
Spre exemplu se poate apela o funcție JavaScript care, la încărcarea paginii/element din pagină sau la apăsarea unui buton, modifică conținutul unui paragraf anume din pagină. Acest lucru se face în felul următor:
<script type=”javascript”>
function modifica_text(){
document.getElementById(„prg1”).innerHtml=”Acesta este noul continut”;
}
</script>
–––––––
<body>
<p id=”prg1”> Acesta este paragraful initial </p>
<input type=”button” onclick=modifica_text() > Apasa aici </input>
</body>
Se observă în codul de mai sus atributul onclick al butonului. Acesta este un eveniment care declanșează execuția funcției JavaScript modifica_text(). În corpul acestei funcții se accesează elementul de DOM care are id-ul „prg1” (în cazul de față este vorba despre un paragraf) și i se modifică conținutul cu ajutorul metodei innerHTML.
În concluzie, JavaScript oferă un conținut dinamic și interactiv paginilor HTML, dar fără să încarce server-ul web cu mai multe operațiuni, întrucât instrucțiunile sale sunt client-side. De asemenea, preia unele dintre operațiunile făcute până acum de server (unele calcule, validari, etc) și le execută la client, mărind astfel viteza de răspuns a paginii web.
În JavaScript, există câteva obiecte predefinite, precum String, Array, Date, Boolean, Math. Fiecare dintre ele are proprietățile și metodele proprii, care sunt prezentate mai în detaliu în secțiunea de referințe a site-ului w3school.com, http://w3schools.com/jsref/default.asp.
Există funcții legate de timp, foarte folositoare pentru animații:
setTimeout(Milisecunde, 'CodDeExecuatDupaMilisecunde()');
setInterval(Milisecunde, 'CodDeExecuatRepetatLa IntervalulMilisecunde()');
PHP
În acest capitol este prezentată o descriere a principalelor noțiuni legate de acest limbaj. Sunt prezentate tipurile de date pe care acest limaj le suportă, tipurile de variabile care pot fi utilizate, precum si modul de includere a codului PHP in cadrul codului HTML.
Ce este PHP?
PHP este un limbaj de tip scripting pe partea de server, proiectat special pentru Web. Într-o pagina HTML poate fi încapsulat cod PHP care va fi executat de fiecare dată când pagina este vizitată. Codul PHP este interpretat pe serverul web și generează cod HTML(sau un alt output) care va fi văzut de către vizitator.
PHP a fost proiectat în 1994 și la origine, a fost contribuția unui singur on, Rasmus Lendorf. Apoi, limbajul a fost adoptat și de către alți specialiști și a treuct prin 4 rescrieri majore care l-au adus la versiunea complexă de astăzi. În noiembrie 2007, era instalat pe mai mult de 21 milioane de domenii din lumea întreagă, numar aflat în continuă creștere.
PHP este un proiect open source, ceea ce înseamnă ca avem acces la codul sursă și îl putem utiliza, modifica si redistribui gratuit.
La început, acronimul PHP reprezenta Personal Home Page, dar a fost modificat conform convenției recursive de numire GNU și acum reprezintă PHP Hypertext Processor.
Versiunea 5 este versiunea curentă majoră a limbajului PHP.
Caracteristici ale PHP
Principalii concurenți ai PHP sunt Perl, Microsoft ASP.NET, Ruby, Java Server Pages(JSP) si ColdFusion.
Comparativ cu aceste produse, PHP are multe avantaje, inclusiv :
Performanță;
Scalabilitate;
Interfețe cu multe SGBD-uri;
Bibliotecti predefinite pentru multe task-uri web comune;
Cost redus;
Facilitatea învățării si utilizării;
Support pentru orientarea pe obiecte;
Portabilitate;
Flixibilitate în dezvoltare;
Disponibilitatea codului sursă;
Disponibilitatea suportului și a documentației.
Performanță
PHP este foarte rapid. Utilizând un singur server, necostisitor, putem
servi milioane de accesări pe zi.
Scalabilitate
Așa cum Rasmus Lendorf a spus, PHP are o arhitectură “shared
nothing”. Aceasta presupune că se poate implementa scalarea orizontală cu un număr mare de servere, în mod eficient și ieftin.
Integrarea bazelor de date
PHP are posibilităti native de conectare la multe sisteme de baze de date. Pe lângă MySQL, se poate conecta direct la PostgreSQL, Oracle, DB2, Informix, InterBase, Sybase etc. Utilizând standardul ODBC(Open Database Connectivity) ne putem conecta la orice bază de date care furnizează un driver ODBC.
Biblioteci predefinite
Deoarece PHP a fost proiectat pentru Web, deține multe funcții built-in pentru efectuarea multor task-uri referitoare la web. Se pot genera imagini, realiza conexiuni la servicii web si alte servicii în rețea, parsa cod XML, trimite email-uri, lucra cu cookie-uri si genera documente PDF, toate acestea scriind doar câteva linii de cod.
Ușurința învățării PHP
Sintaxa PHP se bazează pe cea a altor limbaje de programare, în principiu C si Pearl.
Suport pentru orientarea pe obiecte
Versiunea 5 a PHP are caracteristici OO bine proiectate: moștenire, atribute și metode private si protected, clase abstracte și metode, interfețe, constructori si destructori. De asemenea, există și câteva trăsături mai puțin comune, cum ar fi iteratorul.
Portabilitate
PHP este disponibil pentru multe sisteme de operare : sisteme gratuite Unix-like(Linux, FreeBSD), versiuni Unix comerciale(Solaris, IRIX, OS X) sau pe diferite versiuni de Microsoft Windows. Un cod PHP bine scris va rula fără modificări pe un sistem diferit, care rulează PHP.
Flexibilitate în dezvoltare
PHP permite implementarea task-urilor simple cu ușurință, și în egală măsură se adaptează la implementarea aplicațiilor mari care utilizează un framework bazat pe modele de proiectare cum ar fi Model-View-Controller(MVC).
Elemente de bază ale sintaxei
Ieșirea din modul HTML
Tag-urile PHP sunt <?php și ?>. Acestea anuntă serverul web unde începe și se termina codul PHP, iar orice text dintre aceste 2 tag-uri este interpretat ca PHP. Textul din afara tag-urilor PHP este tratat ca HTML normal.
Există 4 stiluri diferite de tag-uri PHP. Următoarele fragmente de cod sunt echivalente :
Stilul XML:
<?php echo ' Acesta este un mesaj'; ?>
Acesta este stilul de tag PHP recomandat. Administratorul serverului nu îl poate dezactiva, deci se poate garanta că va fi disponibil pe toate serverele. Acest stil de tag poate fi utilizat în documentele XML.
Stilul prescurta :
<?echo ' Acesta este un mesaj'; ?>
Pentru a utiliza acest stil, este nevoie fie să activăm setarea short_open_tag în fisierul de configurare, fie să compilăm PHP cu short_tag-urile activate. Stilul nu este activat implicit.
Stilul script:
<script language= 'php'>
echo 'Acesta este un mesaj';
</script>
Stilul este familiar celor care au utilizat JavaScript sau VBScript. Poate fi folosit dacă editorul HTML are probleme cu celălalte stiluri.
Stilul ASP:
<% echo 'Acesta este un mesaj'; %>
Poate fi folosit dacă a fost activată setarea de configurare asp_tags. Implicit stilul este dezactivat.
Separarea instrucțiunilor
Instrucțiunile sunt separate la fel ca în Pearl sau C, fiecare instrucțiune este terminată cu un semn punct și virgulă.
Tag-ul de închidere implică și sfârșitul instrucțiunii, deci următoarele două exemple sunt echivalente:
<?php
echo "Acesta este un mesaj";
?>
<?php echo "Acesta este un mesaj" ?>
Comentariile
PHP suportă comentarii de tip ’C++’,’C’ și Unix shell. De exemplu:
<?php
echo "Acesta este un mesaj"; // Acesta este un comentariu pe o linie
/* Acesta este un alt comentariu
pe mai multe linii */
echo "Acesta este un nou mesaj";
echo "Acesta este ultimul mesaj"; # Acesta este un comentariu pe o linie tip shell
?>
Comentariul pe o singură linie, de fapt realizează comentarea codului până la sfârșitul liniei curente sau până la terminarea blocului curent PHP.
Tipuri de date
PHP oferă următoarele tipuri de date de bază:
Integer – numere întregi;
Float – numere reale;
String – șiruri de caractere;
Boolean – valori logice;
Array – stochează date multiple;
Object – stochează instanțe ale claselor.
De asemenea, sunt disponibile două tipuri speciale : NULL si resource .
Variabilele cărora nu le-a fost atribuită o valoare sau care au primit valoarea specific NULL sunt de tip NULL.
Anumite funcții predefinite(de exemplu, funcțiile referitoare la baza de date) returnează variabile al căror tip este resource. Acestea reprezintă resurse externe (cum ar fi conexiunile la baza de date). O astfel de variabilă nu va fi prelucrată direct; de obicei, acestea sunt returnate de anumite funcții si trebuie transmise ca parametri altor funcții.
Variabile
Noțiuni de bază
Reprezentarea variabilelor in PHP se realizeaza utilizând un semn dolar, $, urmat de numele variabilei, ex: $variabila.
Numele variabilelor satisfac aceași regula ca și alte date din PHP. Un nume de variabilă valid trebuie sa înceapă cu o litera sau '_' , urmat de oricâte litere sau numere .
Prin definiție, variabilele sunt mereu atribuite prin valoare. Prin urmare, când îi este asociată o expresie unei variabile, întreaga valoare a expresiei este copiată în variabilă. Asta înseamnă , de exemplu, ca după ce îi atribuim unei variabile valoarea altei variabile, schimbarea uneia dintre variabile nu va avea nici un efect asupra celeilalte.
PHP mai oferă și un alt tip de atribuire valori unor variabile, atribuirea prin referința. Asta înseamnă ca noua variabilă indică catre, sau devine un alias pentru, variabila originală. Modificarile aduse noii variabilei afectează si variabila originală.
PHP Superglobals
Câteva variabile predefinite in PHP sunt „superglobale”, ceea ce înseamnă ca pot fi folosite oriunde in script. Nu este necesar sa scriem „global $variable;” sa le accesăm in funcții sau metode.
$GLOBALS
Reprezintă un vector ce conține referințe la toate variabilele care sunt definite in scopul global al script-ului. Numele variabilele reprezinta cheile vectorului.
$_SERVER
Reprezintă un vector ce conține informații cum ar fi headere, căi de acces și locațiile scriptului. Intrările in acest vector sunt create de serverul web.
$_GET
Reprezintă un vector asociativ ce conține variabile pasate script-ului curent cu ajutorul parametrilor URL. $HTTP_GET_VARS conține aceleași informații inițiale, însă nu este un superglobal.
$_POST
Reprezintă un vector asociativ ce conține variabile pasate script-ului curent prin intermediul metodei HTTP POST. $HTTP_POST_VARS conține aceleași informații inițiale, însă nu este variabilă superglobală.
$_COOKIE
Reprezintă un vector asociativ ce conține variabile pasate script-ului curent prin intermediul metodei HTTP Cookies. $HTTP_COOKIE_VARS conține aceleași informații inițiale, însă nu este o variabilă superglobală.
$_FILES
Reprezină un vector asociativ ce conține fișiere uploadate în script-ul curent cu ajutorul metodei HTTP POST. $HTTP_POST_FILES conține aceleași informații inițiale, însă nu este o variabilă superglobală.
$_ENV
Reprezintă un vector asociativ ce conține variabile pasate script-ului curent prin intermediul metodelor din cadrul script-ului. $HTTP_ENV_VARS conține aceleași informații inițiale, însă nu este o variabilă superglobală.
$_REQUEST
Reprezintă un vector asociativ, care prin definiție, conține variabile oferite script-ului de către variabilele superglobale $_GET, $_POST, $_COOKIE.
$_SESSION
Reprezintă un vector asociativ ce conține variabilele din sesiunea valabilă script-ului curent. $HTTP_SESSION_VARS conține aceleași informații inițiale, însă nu este o variabilă superglobală.
Folosirea variabilelor statice
O variabilă statică, ce există in scope-ul funcției locale, nu își pierde valoarea când programul parasește acest scope. Fie următorul exemplu :
<?php
function Functie ()
{
$var = 0;
echo $var;
$var++;
}
?>
După cum putem observa, această funcție este destul de inutilă deoarecere de fiecare dată când este apelată variabila $var primeste valoarea 0 si se printează valoarea „0”.
Instrucțiunea $var++ este nefolositoare deoarece, de îndată ce funcția se termină, variabila $var dispare. Pentru a realiza o funcție de numărare care să nu piardă număratoarea curentă, variabila $var trebuie declarată statică.
<?php
function Functie()
{
static $var = 0;
echo $var;
$var++;
}
?>
De fiecare dată când funcția Functie() este apelată, aceasta va afișa valoarea lui $var și apoi o va incrementa.
Variabile din afara mediului PHP
În momentul în care un formular este transmis unui script PHP,toate informațiile din acel formular sunt transmite automat scriptului PHP.
<form action="pagina.php" method="POST">
Nume: <input type="text" name="nume"><br>
Parola: <input type="password" name="parola"><br>
<input type="submit" name="submit" value="Log In!">
</form>
În funcție de versiunea de PHP și de configurare, datele din formular pot fi accesate in 3 moduri. Pentru a accesa conținutul câmpului Nume, aceste modalități sunt:
$nume;
$_POST['nume'];
HTTP_POST_VARS['nume'].
Pentru a alege una dintre cele 3 modalități, trebuie avute în vedere următoarele considerente:
Stilul scurt($nume) este convenabil, însă necesită ca setarea de configurare register_globals să fie activată. Din motive de securitate, această setare este implicit dezactivată. Acest stil facilitează introducerea unor erori care determină insecuritatea codului, motiv pentru care nu este o abordare recomandată.
Stilul mediu($_POST['nume']) constituie abordarea recomandată. Dacă vom crea versiuni scurte ale numelor variabilelor, pe baza stilului mediu nu mai apare o problem de securitate.
Stilul lung($_HTTP_POST_VARS['nume']) oferă cele mai multe informaț Oricum, acest stil este depreciate și probabil că va fi eliminate ulterior. Acest stil a fost cel mai portabil, însă acum poate fi dezactivat prin intermediul directive de configurare register_long_arrays, care îmbunătățește performanța.
Utilizarea unui formular de tip GET este asemănătoarea, singura diferentă este folosirea variabilei predefinită GET. GET mai poate fi folosit si pentru a extrage informații din QUERY_STRING, reprezentând informațiile de după semnul ’?’ din URL. De exemplu, URL-ul http://www.exemplu.ro/index.php?id=1 contine date GET care sunt accesibile prin $_GET['id'].
Cookie-uri HTTP
Cookie-urile reprezintă un mecanism pentu stocarea datelor in browser. Cu ajutorul lor putem indentifica utilizatorii care revin pe o anumita pagină.
Pentru setarea unui cookie se folosește funcția setcookie(). Deorecere cookie-urile aparțin header-ului HTTP, functia setcookie() trebuie apelată prima, înainte de trimiterea oricărui conținut către browser.
Informațiile de tip cookie sunt stocate in variabilele superglobale prezentate mai sus: $_COOKIE, $HTTP_COOKIE_VARS dar și in $_REQUEST.
O variabilă de tip Cookie poate fi tratată și ca un vector, dacă se dorește atribuirea unor valori multiple. De exemplu:
<?php
setcookie("MyCookie[var1]", "Mesaj 1", time()+3600);
setcookie("MyCookie[var2]", "Mesaj 2", time()+3600);
?>
Aceasta va crea două variabile cookie separate, cu toate că MyCookie va fi un singur array.
MySQL
Baza de date este un ansamblu structurat de date coerente astfel încât acestea pot fi prelucrate eficient de mai mulți utilizatori în mod concurent.
Caracteristica principală a aplicațiilor de baze de date constă în faptul că accentul este pus pe operațiile de memorare și regăsire efectuate asupra unor volume mari de date, și mai puțin asupra operațiilor de prelucrare a acestora.
Un sistem de gestiune a bazelor de date (SGBD – Data Base Management System) este un produs software care asigură interacțiunea cu o bază de date, permițând definirea, consultarea și actualizarea datelor din baza de date. Toate cererile de acces la baza de date sunt tratate și controlate de SGBD.
Conceptele bazelor de date relaționale
Bazele de date relaționale sunt de departe cel mai folosit tip de baze de date.
Tabele
Bazele de date relaționale sunt formate din relații, numite de obicei tabele de date. Tabela are un nume, una sau mai multe coloane, fiecare coloană corespunzând unui alt tip de date, și linii care corespund fiecare câte unei înregistrări.
Coloane
Fiecare coloană din tabelă are un nume unic și conține date diferite.
Linii
Fiecare linie din tabelă reprezintă o altă înregistrare .
Valori
Fiecare linie este formată dintr-un set de valori individuale care corespund coloanelor. Fiecare valoare trebuie să aibă tipul de dată specificat de coloana ei.
Chei
Coloana de identificare dintr-o tabelă se numește cheie sau cheie primară. De obicei, bazele de date sunt formate din mai multe tabele și folosesc o cheie ca referința între aceste tabele. În bazele de date relaționale, termenul folosit pentru această relație este cel de cheie externă. De exemplu: ClientID este cheia primară în tabelul Clienți, dar atunci când apare într-o altă tabelă, cum este tabelul Comenzi, ea este referită ca și cheie externă.
Scheme
Setul complet de proiecte pentru tabelele dintr-o bază de date se numește schema bazei de date. O schemă trebuie să prezinte tabelele și coloanele acestora, tipurile de date din coloane și trebuie să indice cheia primară a fiecărei tabele și toate cheile externe. Schema poate fi reprezentată în diagrame ale relațiilor dintre entități sau sub formă de text.
Relații
Cheile externe reprezintă o relație între datele din două tabele. De exemplu, legătura de la Comenzi la Clienti reprezintă o relație dintre o linie din tabela Comenzi și o linie din tabela Clienti.
Relațiile pot fi de trei tipuri:
Unu la unu – o linie dintr-o tabelă se află într-o relație cu o altă linie dintr-o altă tabelă
Unu la mai mulți – o linie dintr-o tabelă se află într-o relație cu mai multe linii dintr-o altă tabelă
Mai mulți la mai mulți – mai multe linii dintr-o tabelă se afla în relație cu mai multe linii dintr-o altă tabelă
Proiectarea unei baze de date pentru Web
Pentru a proiecta o bază de date, vom folosi un procedeu numit modelare entitate-relație. Adică, entitățile reprezintă tabele și relațiile sunt legăturile care se stabilesc între tabele. Un model entitate-relație poate fi cu ușurință modelat și va genera o structură a unei baze de date.
Etapele acestui procedeu sunt următoarele:
identifici coloanele;
grupezi coloanele în tabele;
identifici cheile primare;
identifici cheile externe.
Identificarea coloanelor
Pentru a identifica coloanele, trebuie sa ne punem întrebarea: „Care sunt datele pe care le voi stoca?”. Pe măsură ce identificam coloanele, le vom pune pe o listă, astfel ne va fi ușor să le modificăm pe parcursul operațiunii. Când am terminat de identificat coloanele începem sa le grupăm în tabele.
Gruparea coloanelor în tabele
Majoritatea coloanelor sunt corelate între ele. Aceste corelații ajută la gruparea lor în tabele. De exemplu, dacă avem coloane ca nume client, adresă, telefon, acestea se pot corela și forma tabela clienți. O coloană însă poate apărea de mai multe ori pe listă, deci se poate corela cu mai multe entități.
După ce am determinat și tabelele, trebuie să le denumim. Trebuie să avem grijă atunci când facem acest lucru, deoarece limbajul SQL impune anumite restricții la denumirile tabelelor și ale coloanelor. Acestea sunt:
primul caracter trebuie să fie o literă;
să aibă în componență numai litere, cifre și caracterul _;
lungimea să fie de maximum 64 de caractere;
sunt case-insensitive.
Identificarea cheilor primare
Fiecare tabelă va trebui să aibă o cheie primară. Cheia primară o alegem uitându-ne cu atenție la fiecare coloană și determinând dacă conțin sau nu valori unice. S-ar putea să fim nevoiți să alocăm mai multe coloane unei chei primare, dacă nicio coloană nu îndeplinește această condiție.
Dacă nu am găsit nici o coloană și nici o combinație de coloane care să poată fi trecute drept cheie primară, atunci vom crea noi o coloană care să îndeplinească acest rol. La un client, dacă avem nume, adresă, telefon, se poate crea o coloană clientid care va identifica fiecare client după un număr unic.
Identificarea cheilor externe
Aceasta este etapa cea mai dificilă pe care va trebui s-o parcurgem. Vom compara coloanele cu cheile primare și pentru fiecare combinație posibilă verificăm dacă există o relație între valoarea acestei coloane și valoarea cheii primare.
Pentru aceasta putem folosi diagramă entitate-relație. Aceasta prezintă tabelele sub formă de dreptunghiuri și relațiile dintre ele sub formă de romburi. Relația apare oriunde a fost găsită o cheie externă.
Dar această etapă nu presupune numai identificarea cheii externe, ci și clasificarea relației găsite în relație unu la unu, unu la mai mulți sau mai mulți la mai mulți.
De exemplu, un client poate avea mai multe comenzi, deci apare o relație de unul la mai mulți, o comandă poate avea mai multe produse și fiecare produs poate aparține mai multor comenzi, deci apare o relație de mai mulți la mai mulți.
Uneori la relațiile mai mulți la mai mulți, lipsește o tabelă care să facă legătura între combinații și va trebui creată.
De exemplu, fiecare client comandă mai multe produse. Fiecare produs poate fi comandat de mai mulți clienți. Vei crea tabela comenzi care va face legătura între tabelele clienți și produse-comandate. În ea vei plasa coloana comandaid care va fi cheie primară în tabela comenzi și va fi cheie externă în tabela produse-comandate. De asemenea, coloana clientid este cheie primară în tabela clienți și cheie externă în tabela comenzi.
Figura 2.1 – O diagramă entitate-relație
Normalizarea bazei de date
Există o serie de reguli care descriu ce înseamnă o structură corectă a unei tabele și care definesc așa numitele forme normale. Normalizarea bazei de date înseamnă că vom transforma baza de date astfel încât să satisfacă niște reguli. Regulile de normalizare sunt atribute pe care o bază de date le are pentru a respecta aceste reguli.
Regulile cele mai importante pentru o bază de date normalizată pe care nu trebuie să le omitem sunt:
trebuie să utilizăm doar valori atomice – adică nici o coloană nu trebuie să aiba valori compuse, nici să reprezinte o repetiție. De exemplu, coloana nume trebuie împărțită în nume, prenume și inițială. Această regulă este deseori încălcată și asta duce la o îngreunare a utilizării SQL pentru datele tabelei.
pe cheia primară trebuie să ne bazăm în totalitatea ei – un exemplu: dacă comanda id și clientid sunt o cheie primară compusă, numele este asociat unui client, nu și unei comenzi.
Arhitectura bazelor de date pentru Web
În continuare va fi prezentat modul cum funcționează un server web. Un browser face o cerere către un server web și acesta îi trimite înapoi un răspuns ca în figura de mai jos:
Figura 2.2 – O relatie browser – server
Dacă avem și o bază de date, deci un server de baze de date, vom adauga și un server de baze de date, astfel:
Figura 2.3 – O relație browser – server web – server baze de date
Utilizarea bazei de date în MySQL
SQL
SQL este acronimul de la Structured Query Language și este limbajul standard pentru acesarea sistemelor de gestiune a bazelor de date relaționale (SGBDR). SQL este folosit pentru a stoca și regasi datele în și dintr-o bază de date.
Inserarea datelor în baze de date
Pentru a insera date în baza de date folosim instrucțiunea INSERT.
Structura:
INSERT INTO obiect [AS alias] [ (nume_coloana [, nume_coloana …] ) ]
{VALUES ( {expr | DEFAULT} [, {expr | DEFAULT} …] )
| subcerere}
Regăsirea datelor din bazele de date
Instrumentul de bază al SQL este instrucțiunea SELECT. Este folosită pentru a regasi datele dintr-o bază de date prin selectarea acelor linii din tabelă care corespund criteriului specificat. Există multe opțiuni și mai multe moduri în care puteți utiliza instrucțiunea SELECT.
Structura:
SELECT { [ {DISTINCT | UNIQUE} | ALL] lista_campuri | *}
FROM [nume_schema.]nume_obiect ]
[, [nume_schema.]nume_obiect …]
[WHERE conditie_clauza_where]
[START WITH conditie_clauza_start_with
CONNECT BY conditie_clauza_connect_by]
[GROUP BY expresie [, expresie …]
[HAVING conditie_clauza_having] ]
[ORDER BY {expresie | pozitie} [, {expresie | pozitie} …] ]
[FOR UPDATE
[OF [ [nume_schema.]nume_obiect.]nume_coloana
[, [ [nume_schema.]nume_obiect.]nume_coloana] …]
[NOWAIT | WAIT numar_intreg] ];
ORDER BY se folosesște dacă dorim să afișăm liniile returnate de o interogare într-o anumită ordine.
Un element din lista_câmpuri are forma: expresie [AS] alias.
Cele mai simple interogări SELECT sunt și cele mai folosite:
select * from tabel; – regăsește toate coloanele din tabelă sau tabelele specificate
select *
from tabel
where ClientID= 3;
Clauza where specifică criteriul folosit pentru a selecta anumite linii.
În afară de egalitate, MySQL acceptă un set complet de operatori de comparație și expresii regulate.
Regăsirea de date din mai multe tabele
Join-ul este operația de regăsire a datelor din două sau mai multe tabele, pe baza valorilor comune ale unor coloane. De obicei, aceste coloane reprezintă cheia primară, respectiv cheia externă a tabelelor.
Condiția de join se scrie în clauza WHERE a instrucțiunii SELECT. Într-o instrucțiune SELECT care unește tabele prin operația de join, se recomandă ca numele coloanelor să fie precedate de numele sau alias-urile tabelelor. Dacă același nume de coloană apare în mai mult de două tabele, atunci numele coloanei se prefixează obligatoriu cu numele sau alias-ul tabelului corespunzător. Pentru a realiza un join între n tabele, va fi nevoie de cel puțin n – 1 condiții de join.
Inner join (equijoin, join simplu) – corespunde situației în care valorile de pe coloanele ce apar în condiția de join trebuie să fie egale.
Actualizarea înregistrărilor din baza de date
Pentru a modifică datele din bazele de date se folosește instrucțiunea UPDATE.
Structura:
UPDATE nume_tabel [alias]
SET col1 = expr1[, col2=expr2]
[WHERE condiție];
sau
UPDATE nume_tabel [alias]
SET (col1,col2,…) = (subcerere)
[WHERE condiție];
Ștergerea de înregistrări din baza de date
Ștergerea de linii dintr-o bază de date se poate face cu instrucțiunea DELETE.
Structura:
DELETE FROM nume_tabel
[WHERE condiție];
Dacă nu se specifică nici o condiție, vor fi șterse toate liniile din tabel.
Conectarea la o bază de date cu ajutorul PHP
PHP permite conectarea la diferite baze de date printre care:
dbase
FrontBase
Interbase
SQL Server
MySQL
Oracle
MySQL reprezintă o bază de date relațională oferită gratuit, disponibilă atît pentru Windows, cît și pentru Linux. Este folosită în realizarea aplicațiilor mici și medii.
Ideea pe care se bazează interacțiunea PHP – MySQL sau în general interacțiunea dintre PHP și o bază de date este aceea că permite ca informațiile care vor apărea pe site să fie prezente în baza de date. În acest fel informațiile pot fi actualizate ușor și prezentate într-o formă "dinamică" în cadrul site-ului.
Vom începe prin a ne conecta la o bază de date MySQL. mysql_connect(adresa, utilizator, parola);
Ca și parametri vom folosi adresa care reprezintă IP-ul sau hostname-ul calculatorului pe care am instalat baza de date MySQL. Acesta poate fi același cu cel pe care rulează serverul de web (de obicei Apache sau IIS) sau un alt calculator. În cazul în care se găsește pe același calculator cu serverul de web, putem folosi la adresa și localhost. Numele de utilizator și parola vor fi cele setate pentru MySQL. Implicit acestea sunt nume de utilizator: root și fără parolă.
Este recomandat ca aceste setări implicite să fie modificate.
Funcția mysql_connect returnează un număr de identificare al conexiunilor în caz de succes sau false în caz de eroare
<?php
$id = mysql_connect("localhost", "root", "")
or die("Nu ma pot conecta la MySQL!");
print ("Conectare reusita");
mysql_close($id);
?>
Atenție: o conexiune la baza de date trebuie deschisă întotdeauna înainte de a o folosi!
În cazul în care nu ne putem conecta la baza de date functia mysql_connect va returna fals, iar în acest caz se va trece la executarea funcției die care va afișa mesajul din paranteză și va termina execuția scriptului.
Următorul pas îl reprezintă alegerea bazei de date:
mysql_select_db(baza_de_date, identificatorul_conexiunii);
Parametrii folosiți în acest caz vor fi numele bazei de date ales și identificatorul returnat de către mysql_connect.
<?php
$id = mysql_connect("localhost", "root", "")
or die("Nu ma pot conecta la MySQL!");
$db = mysql_select_db("shop", $id)
or die("Nu gasesc o baza de date cu numele curs!");
mysql_close($id);
?>
In exemplul de mai sus am selectat baza de date shop. Ca și în exemplul anterior, în cazul în care nu putem selecta baza de date shop se va trece la execuția funcției die a cărui comportament a fost explicat mai sus.
Inserarea si selectarea unor înregistrări
În exemplul următor vom însera într-o bază de date o înregistrare. Pentru aceasta vom folosi funcția mysql_query cu ajutorul căreia vom executa o instrucțiune SQL.
mysql_query(instructiune_SQL, identificatorul_conexiunii);
Această instrucțiune (în cazul nostru <<INSERT INTO cursanti(nume) VALUES('$nume')>>) va fi transmisă serverului MySQL care îl va executa și va returna rezultatul. În cazul mysql_query rezultatul va fi true, în caz de succes, sau false.
Pentru a testa exemplul următor va trebui să creați un fișier cu numele "adauga_nume.php". Acest fișier va afișa în browser un formular cu o linie în care vă puteți introduce numele și un buton care în momentul în care este apăsat va transmite numele mai departe. După cum se observa am setat formularului la actiune valoarea "adauga_nume.php", ceea ce înseamnă că valoarea va fi transmisă spre același fișier.
După ce valoarea este transmisă, execuția va continua și în interiorul instrucțiunii if, execuție care inițial a fost ignorată, deoarece variabila $nume nu exista în cazul primei execuții.
<?
if($nume) {
$idSQL = mysql_connect("localhost", "root", "");
mysql_select_db("shop", $idSQL);
$query = "INSERT INTO cursanti(nume) VALUES('$nume')";
mysql_query($query, $idSQL);
print("Numele dvs a fost introdus in baza de date!");
}
?>
<form method="POST" action="adauga_nume.php">
Numele dvs:
<input type="text" name="nume" size="30">
<input type="submit" value="Adauga"></form>
Atenție: În unele cazuri este necesar să se folosească variabila $HTTP_POST_VARS['nume'] în momentul în care se dorește preluarea variabilei nume transmisă prin metoda POST prin intermediul formularului.
Selectarea înregistrărilor :
După ce am înserat o înregistrare în baza de date dorim să o afișam în browser. De aceea vom încerca să vedem dacă în tabela cursanți există un utilizator cu numele Cristi. Pentru aceasta construim o instrucțiune sql de tipul celei de mai jos. Instrucțiunea mysql_num_rows returnează numărul de rezultate returnate de execuția instrucțiunii. Se poate observa că în cazul în care se folosește instrucțiunea mysql_query cu o instrucțiune SELECT, acesta nu va returna true sau false, ci va returna o listă de rezultate false în caz de eroare.
$query = "SELECT * FROM cursanti WHERE nume='Cristi'";
$result = mysql_query($query, $idSQL);
if(mysql_num_rows($result))
{ print("<strong>Numele Cristi exista in tabela cursanti</strong>");}
else
{ print("<strong>Numele Cristi nu exista in tabela cursanti</strong>");}
Atenție: Trebuie să fiți conectați la baza de date înainte de a executa instrucțiunea SQL.
În următorul exemplu dorim să afișăm toate înregistrările din tabelul cursanți. Vom proceda ca și în exemplul anterior. Însă în cazul în care găsim rezultate în tabelul cursanți vom parcurge fiecare din aceste rezultate și îl vom afișa pe ecran.
mysql_fetch_row(rezultatul_returnat_de_mysql_query);
Instrucțiunea mysql_fetch_row va parcurge rezultatul returnat de instrucțiunea mysql_query și va returna pentru fiecare înregistrare un tablou care conține fiecare câmp returnat. Indexarea tablourilor începe de la valoare 0. Instrucțiunea while va avea ca efect returnarea pentru fiecare linie a unui tablou. În cazul nostru vom avea în $row[0], numele cursantului.
$query = "SELECT nume FROM cursanti";
$result = mysql_query($query, $idSQL);
if(mysql_num_rows($result)) {
while($row = mysql_fetch_row($result))
{
print("$row[0]<br>");
}
} else {
print "Tabela cursanți este goala !";
}
Atenție: Trebuie să fiți conectați la baza de date înainte de a executa instrucțiunea SQL.
În următorul exemplu vom selecta dintr-un tabel toți cursanții a căror nume încep cu litera c. Pentru aceasta vom folosi o instrucțiune SQL mai complexa. Porțiunea <nume LIKE 'c%'> din interiorul instrucțiunii SQL se traduce prin toate înregistrările a căror cîmp nume începe cu litera c. Semnul % înseamnă orice număr de caractere chiar și nici unul.
În acest exemplu am selectat pe lângă nume și câmpul email, pe care îl afișam prin intermediul lui $row[1].
$query = "SELECT nume,email FROM cursanti WHERE nume LIKE 'c%'";
$result = mysql_query($query, $idSQL);
if(mysql_num_rows($result)) {
while($row = mysql_fetch_row($result))
{
print("$row[0]");
print("$row[1]<br>");
}
} else {
print "Tabela cursanti este goala !";
}
JAVA
Java este un limbaj de programare orientat pe obiecte care a fost inițial dezvoltat de către institutul Sun Microsystems și care la ora actuală este deținut de către Corporația Oracle. Limbajul a fost lansat în anul 1995 și are foarte multe componente asemănătoare cu limbajele C și C++. Sintaxa este unul din elementele care fac ca Java să fie considerat asemănator cu limbajele mai sus menționate însă spre deosebire de acestea, Java are un model orientat pe obiecte mult mai simplu și mai ușor de înțeles și utilizat, acesta fiind unul din motivele care a făcut ca Java să fie un limbaj așa de cunoscut.
Inițial a fost proiectat pentru dispozitivele mobile inteligente insă din considerente economice, de marketing (piața dispozitivelor inteligente nu era încă suficient dezvoltată, deci neprofitabilă la acea vreme), limbajul a fost reproiectat pentru a crea pagini web cu conținut dinamic.
Spre deosebire de alte limbaje de programare, java a fost proiectat din considerente comerciale pentru a răspunde unor cereri precise ale noii piețe, în expansiune (WWW).
Patru ani mai târziu, java a devenit limbajul de programare preferat pentru aplicațiile la nivel de întreprindere bazate pe World Wide Web.
În prezent, limbajul de programare Java aree mai multe versiuni. Versiunea cea mai răspândită este Java 2 Standard Edition (J2SE). Mai există și versiunea recomandată dezvoltării aplicaților pentru corporații (Java 2 Enterprise Edition, J2EE) și o versiune pentru dezvoltarea aplicațiilor pentru telefoanele mobile și device-uri inteligente (Java 2 Micro Edition, J2ME).
Ca majoritatea limbajelor de programare orientate pe obiecte, și în Java aplicațiile sunt compilate spre a se obține fișiere în cod binar. Mai exact există fișiere sursă a căror extensie este .java și care sunt scrise utilizându-se sintaxa Java.
Java functionează însă altfel decât C++ si alte limbaje de programare de nivel înalt. Codul scris în limbajele de nivel înalt – altele decât java – trebuie compilat în cod obiect , care apoi este editat cu un editor de legături (linker), pentru a forma programul în limbaj masină rulat pe calculator.
Codul sursă Java nu este compilat în cod obiect, ci în cod de octeți , salvat într-un fișier cu extensia .class utilizând un compilator java.
Compilatorul Java este o componentă a pachetului Java 2 Software Development Kit (J2SDK).
Întrucât Java este un limbaj independent de platforma pe care rulează, codul sursă al unei aplicații scrise în limbaj Java este compilat și se obține un fișier rezultat cunoscut sub denumirea de fișier binar care este stocat într-un fișier de tip .class. În cazul în care un fișier sursă conține mai multe clase declarate de tip Java, atunci pentru fiecare din aceste clase se va genera câte un fișier de tip .class care va conține informațiile acestor clase în cod binar.
Aceste fișiere scrise în cod binar și obținute în urma compilării fișierelor sursă sunt apoi rulate folosindu-se o mașină virtuală Java (JVM). Rularea acestor fișiere binare de către o mașină virtuală Java este independentă de sistemul de operare pe care mașina virtuală Java este instalată și prin urmare portabilitatea acestor aplicații de pe o mașină pe alta sau de pe un sistem de operare pe altul este relativ ușor de realizat. Scopul principal al acestor aplicații scrise în limbaj Java este acela de a fi scrise o dată și apoi de a fi rulate oriunde fără a mai fi nevoie de ajustări sau modificări de cod. Acesta este prin urmare poate unul din principalele motive care a făcut ca Java să fie atât de mult folosit în realizarea de aplicații dar mai ales în realizarea de aplicații de tip web-based.
Java este un limbaj de programare orientat pe obiecte. La baza acestui limbaj stă noțiunea de clasă al cărei scop este de a pune la un loc cât mai multe caracteristici ca și comportamentul pe care o entitate le deține. Toate aceste clase pot interacționa între ele și se pot defini între acestea atât relații de compunere cât și relații de moștenire. Mai exact o clasă definită în limbaj Java poate conține la rândul ei alte clase definite în limbaj Java, și poate de asemenea extinde o altă clasă scrisă în limbaj Java, moștenind în acest fel atributele și comportamentul clasei părinte. Java dispune și de alte caracteristi ce fac din acest limbaj unul puternic și stabil. Spre deosebire de limbajele cu care se aseamănă mult C și C++ și în care o clasă poate să extindă mai multe clase, lucru care de multe ori poate cauza probleme mari de control, în Java o clasă nu poate extinde decât o singură clasă, însă poate implementa mai multe interfețe, dovedindu-se a fi în acest fel un limbaj mult mai clar și mai simplu.
O interfață în limbaj Java este un concept menit să definească un comportament al unei viitoare clase Java. Este o abstractizare ce nu poate defini decât comportament și care nu oferă detalii despre implementare. O clasă poate implementa o astfel de interfață fiind implicit nevoită să ofere implementări pentru fiecare din metodele conținute de interfața implementată.
O altă caracteristică care face ca Java să difere de limbajul C++ este managementul propriu al memoriei. În C++ orice clasă trebuie gestionată de la creeare până la distrugere. În Java, partea de distrugere a obiectelor de clase este realizată de către mașina virtuala Java și nu de către dezvoltatori. Există un colector de obiecte neutilizate al carui scop este de curăța memoria de obiectele care nu mai sunt implicate în nici un proces. Chiar și așa riscul apariției de scurgeri de memorie (memory leaks) este încă prezent, întrucât un cod scris necorespunzator poate face ca obiecte Java care nu mai sunt deloc necesare să mai fie încă referite de către referințe active din cadrul unei aplicații Java. Scopul principal al acestui management propriu de memorie este acela de a scuti utilizatorii limbajului Java de a se ocupa de întreg ciclul de viață al unui obiect Java. Un dezvoltator nu va trebui decât să decidă când un obiect Java trebuie creeat și să cunoască contextele în care un obiect Java poate fi încă activ și nu poate constitui un obiectiv a colectorului de obiecte neutilizate.
Un alt avantaj al limbajului de progrmare Java este sintaxa care, așa cum a mai fost spus, este asemănătoare cu ceea a limbajelor C și C++. Mai exact sintaxa limbajului Java este derivată din ceea a limbajului C++ însă s-a căutat să se obțină un limbaj exclusiv dedicat ideii de orientare pe obiecte. Tot codul care este scris în cadrul limbajului Java este scris în interiorul unei clase, și orice în Java este un obiect de clasă, mai puțin datale de tip primitive cum sunt: numerele întregi și cele în virgulă fixă, caracterele, variabilele de tip Boolean (true/false). Un obiect Java este o instanță, o matriță a unei clase Java. Sintaxa limbajului Java suportă comentarii de cod care pot face codul mult mai inteligibil și mai ușor de urmărit.
Mai jos este prezentat codul unui fișier sursă Java ce rezolva tradiționala problema Hello World:
class HelloWorld {
public static void main(String[] args) {
// Display the string.
System.out.println("Hello World!");
}
}
În continuare se face o scurtă prezentare prin exemple concludente de cod Java a câtorva din cele mai utilizate și des întalnite caracteristici care fac din limbajul Java unul puternic, stabil și mereu deschis schimbărilor oportune.
O caracteristică de bază a acestui limbaj de programare este moștenirea sau în terminologie tehnică Înheritance. Această caracteristică este foarte apropiată de o altă caracteristică de bază a limbajului Java și anume compunerea sau Composition. Aceastea se pot transpune într-o formă tehnică mai simplă și mai ușor de înțeles ca:
Înheritance Is-A, Composition Has-A
sau în traducere: Moștenirea implică ‘este un’, Compunerea implică ‘are un’
Moștenirea este prezentă pretutindeni în limbajul Java, se poate chiar spune că este aproape imposibil să se scrie o aplicație în Java fără să se folosească chiar deloc moștenirea. Scopul principal al acestei caracteristici este acela de a reutiliza cod ce a fost deja scris. Acest lucru poate parea nesemnificativ la prima vedere însă dacă se acordă un pic de atenție acestui detaliu se poate observa cât de puternică este această unealtă și cât de ușor poate fi adaptat codul deja existent unor cerințe noi. Există cum e poate de așteptat o serie de teorii legate de moștenire în Java. Chiar dacă este o unealtă puternică ce poate aduce o serie de beneficii, este în același timp și un lucru periculos care dacă nu este utilizat cu atenție și în cunostință de cauză, poate cauza efecte destul de grave și de greu de îndepărtat în timp.
În lumea Java se vorbește despre două tipuri de moșteniri, este o dată vorba despre moștenirea de interfață (Înterface Înheritance), și aceasta este realizată atunci când o clasă Java implementează metodele pe care o interfață ce este implementată de această clasă Java le conține, și apoi este vorba despre moștenirea de implementare (Implementation Înheritance), care se obține atunci când o clasă Java extinde o altă clasă Java. De obicei marile probleme sunt cauzate de către cel de-al doilea tip de moștenire, atunci când o clasă Java extinde în mod nesigur și iresponsabil o altă clasă Java. De obicei cel de-al doilea tip de moștenire trebuie să se realizeze între clase Java care sunt într-un fel înrudite și grupate în același pachet. Prin extinderea unei clase dintr-un pachet străin, față de care nu există nici o legatură clară și sigură, se realizează o violare a conceptului de moștenire prin implementare.
Motivul pentru care trebuie să se acorde o atenție mai mare acetui tip de moștenire este faptul că o implementare greșită poate avea efecte negative mari și de lungă durată . Astfel de greșeli au fost realizate și atunci când platforma Java a fost dezvoltată în procesul ei de creeare, iar aceste greșeli își fac încă simțită prezența și cel mai probabil își vor face simțită prezența și în viitor.
Acesta este felul în care se realizează o moștenire de interfață (Înterface Înheritance)
interface Car {
public abstract void drive();
}
class Dacia implements Car {
public void drive() {
System.out.println("You are driving a Dacia car!");
}
}
Acesta este modul în care se realizează o moștenire de implementare (Implementation Înheritance)
class Dacia implements Car {
public void drive() {
System.out.println("You are driving a Dacia car!");
}
}
class DaciaBreak extends Car {
@Override
public void drive() {
System.out.println("You are driving a DaciaBreak car!");
}
}
Acesta este modul în care se poate realiza o moștenire de implementare greșită.
class MyHashSet extends HashSet {
@Override
public boolean addAll(Collection c) {
addCount += c.size();
return super.addAll(c);
}
}
class TestMySet {
public static void main() {
MyHashSet s = new MyHashSet ();
s.addAll(Arrays.asList("Snap", "Crackle", "Pop"));
}
}
Problema în exemplul de mai sus este faptul că există un detaliu de implementare al clasei HashSet care nu este cunoscut la prima vedere. Metoda suprascrisă addAll intern apelează la rândul ei o altă metodă ce va adăuga pe rând fiecare element din colecția primită ca argument și care de asemenea va incrementa dimensiunea set-ului rezultat. Prin urmare, în urma rulării acestui program se va obține un set ce va avea dimensiunea de 6 și nu de 3.
Tocmai pentru că este o unealtă atat de puternică dar care dacă este folosită incorect poate cauza probleme atât de mari, s-au adoptat în timp strategii alternative, prin care s-a căutat să se evite situațiile neplacute pe care moștenirea le poate cauza. Una din aceste alternative este Compunerea sau în terminologie tehnică Composition.
Compunerea este tehnica prin care se evită procesul de moștenire însă se obține în final același rezultat pe care moștenirea îl oferă. În loc ca o clasă să extindă, să moștenească caracteristicile și comportamentul unei alte clase parinte, această clasă o va conține pe clasa parinte, dar va oferi în continuare și comportamentul pe care clasa conținută îl deține. Acest lucru se realizează prin combinarea tehnicii de moștenire prin interfață și cel al composiției, mai exact va exista o interfață Java ce va define un comportament, o clasă Java ce va implementa comportamentul definit de această interfață și în cele din urmă o clasă o altă clasă Java ce va conține clasa Java mai sus definite și pe care o va folosi pentru a oferi în conținuare comportamentul definit de interfața inițială.
Mai jos se va exemplifică printr-un exemplu de cod ceea ce a fost descris până acuma ca fiind compunere.
interface Car {
public abstract void drive();
public abstract Boolean hasAutomatedPilot();
}
class Dacia implements Car {
public void drive() {
System.out.println("You are driving a Dacia car!");
}
public Boolean hasAutomatedPilot() {
return false;
}
}
class Logan implements Car {
private Car dacia = new Dacia();
public void drive() {
System.out.println("You are driving a Logan car!");
}
public Boolean hasAutomatedPilot() {
return dacia.hasAutomatedPilot();
}
}
Se poate observa din exemplul prezentat mai sus cum clasa Logan refolosește comportamentul clasei Dacia, însă nu prin moștenire ci prin compunere. În felul acesta se realizează o implementare mult mai flexibilă și mai ușor adaptabilă schimbărilor întrucât clasa finală nu va fi dependentă de detaliile de implementare ale clasei pe care o conține. De asemenea este o clasă care este oricând posibil să fie modificată întrucât comportamentul afișat este un detaliu de implementare intern, la care se poate oricând renunța, utilizându-se poate o altă implementare, lucru de care utilizatorul clasei finale nu va fi afectat.
Tot în cadrul acestei categorii de caracteristici merită să fie menționate și clasele abstracte. O clasă abstractă este o clasă Java ce nu poate fi instanțiate întrucât nu are tot comportamentul definit în totalitate. Mai exact clasa poate conține atat comportament definit cât și comportament ce nu este definit, implementat, și el urmează să fie definit de către clase ce vor extinde aceste clase abstracte. Scopul unei clase abstracte este de a oferi cât mai multă implementare comportamentului unei clase, lasând posibilitatea unor clase ce vor extinde această clasă de a da anumite implementări anumitor comportamente ce vor avea de obicei efecte în modul în care clasa rezultantă se va prezenta.
Chiar dacă par o unealtă atrăgatoare și deosebit de puternică, clasele abstracte trebuiesc utilizate cu precauție întrucât pot avea aceleași efecte negative ca și cele cauzate de moștenirea de implementare, și se preferă în programarea Java modernă să fie ușor înlocuite de interfețele Java care sunt mult mai puternice și mai stabile.
Ca o concluzie clasele abstracte sunt de obicei utilizate în implementări interne ce nu ajung să fie utilizate de către utilizatori ai claselor ce extind aceste clase abstracte.
abstract class Shape {
public String color;
public Shape() {
}
public void setColor(String c) {
color = c;
}
public String getColor() {
return color;
}
abstract public double area();
}
public class Point extends Shape {
public int x, y;
public Point() {
x = 0;
y = 0;
}
public double area() {
return 0;
}
public double perimeter() {
return 0;
}
}
public class TestPoint {
public static void print(Point p) {
System.out.println("point: " + p.x + "," + p.y);
}
public static void main(String args[]) {
Point p = new Point();
p.print();
System.out.println("Area is: " + p.area());
}
}
O altă caracteristică puternică a limbajului de programare Java este polimorfismul. Polimorfismul este capacitatea unor metode sau acțiuni de a realize lucruri diferite bazându-se pe obiectul asupra caruia se realizează aceste metode sau acțiuni. Concret există mai multe clase Java care impartasesc toate același comportament, însă acesta diferea ca rezultat de la o clasă la alta. Important aici nu este cum se comportă fiecare clasă în ceea ce priveste un comportament ci faptul că asupra oricarui obiect al oricarei clase se poate apela acest comportament, ce va diferi de la o clasă la alta.
Pentru a se obține acest rezultat limbajul Java folosește o altă caracteristică de bază și anume suprascrierea sau în exprimare tehnică Overriding. Suprascrierea se realizează atunci când există o clasă de bază, parinte, ce defineste un anumit comportament, și se defineste o altă clasă fiu ce va extinde această clasă parinte, dar va modifica comportamentul acesteia prin redefinirea acestuia în anumite situații (se pot redefini doar anumite metode care oferă interes).
Mai jos se va exemplifica printr-un exemplu ceea ce reprezintă în Java polimorfismul.
interface GeometricFigure {
public abstract double area();
}
class Linie implements GeometricFigure {
public double area () {
return 1;
}
}
class Circle implements GeometricFigure {
private double r;
public double area () {
return Math.pi*Math.pow(r,2);
}
}
public class TestGeometricFigure {
public static void main(String args[]) {
List<GeometricFigure> figures = new ArrayList<GeometricFigure >();
figures.add(new Linie());
figures.add(new Circle());
// !!! Aici se folosete polimorfismul
foreach(GeometricFigure figure : figures) {
System.out.println("Area is: " + figure.area());
}
}
}
Toate acestea precum și multe alte caracteristici fac ca limbajul de programare Java să fie un limbaj puternic și ușor de utilizat, care este capabil să rezolve cu ușurință majoritatea problemelor ce pot aparea în cazul realizarea unei aplicații de orice natură, inclusiv al celor de tip web-based. Java a mizat și mizează în continuare pe următoarele principii de bază:
trebuie să fie un limbaj simplu, familiar și orientat pe obiecte;
trebuie să fie robust și securizat;
trebuie să aibă o arhitectură neutră;
trebuie să fie ușor portabil în orice sistem de operare;
trebuie să se execute cu o performanță ridicată;
trebuie să fie dinamic, să poată suporta execuția pe baza de threaduri;
trebuie să fie interpretabil.
O caracteristică de bază a limbajului Java este portabilitatea. Acest lucru înseamnă că un program o dată scris în limbaj Java el poate fi executat oriunde și în orice sistem de operare ce suportă limbajul Java. Utilizatori de rând pot ajunge să utilizeze suportul oferit de un program scris în limbaj Java prin utilizarea unui Java Runtime Environment (JRE) care trebuie să fie instalat.
Tipuri de programe Java
Ideea execuției în calculatorul local a programelor descărcate din rețea a stat la baza conceperii limbajului Java, evoluția lui ulterioară fiind puternic influențat de succesul pe care l-a repurtat, fiind utilizat ca un limbaj de programare tradițional. De aici a rezultat și o diversificare a programelor java în mai multe categorii.
În Java, programele se împart în trei tipuri principale:
Aplicații;
Apleți (applets);
Servleți (servlets).
Cele trei tipuri de programe, deși utilizează același limbaj de programare, sunt folosite în scopuri diferite și au o structură diferită.
Platforme Java
Limbajul de programare Java a fost folosit la dezvoltarea unor tehnologii dedicate rezolvării unor probleme din cele mai diverse domenii. Aceste tehnologii au fost grupate în așa numitele platforme de lucru, ce reprezintă seturi de librării scrise în limbajul Java, precum și diverse programe utilitare, folosite pentru dezvoltarea de aplicații sau componente destinate unei anumite categorii de utilizatori.
J2SE (Standard Edition)
Este platforma standard de lucru ce oferă suport pentru crearea de aplicații independente și appleturi. De asemenea aici este inclusă și tehnologia Java Web Start ce furnizează o modalitate extrem de facilă pentru lansarea și instalarea locală a programelor scrise în Java direct de pe Web, oferind cea mai comodă soluție pentru distribuția și actualizarea aplicațiilor Java.
J2ME (Micro Edition)
Folosind Java, programarea dispozitivelor mobile este extrem de simplă, platforma de lucru J2ME oferind suportul necesar scrierii de programe dedicate acestui scop.
J2EE (Enterprise Edition)
Această platformă oferă API-ul necesar dezvoltării de aplicații complexe, formate din componente ce trebuie să ruleze în sisteme eterogene, cu informații memorate în baze de date distribuite. Tot aici găsim și suportul necesar pentru crearea de aplcații și servicii web , bazate pe componente cum ar fi servleții și paginile JSP.
Diversitatea și continua dezvoltare a acestei platforme spune foarte mult despre ceea ce înseamnă să utilizezi o tehnologie de programare avansată precum este Java. În spatele acestei vaste platforme stă cum era de așteptat platforma mamă, Java Platform, Standard Edition (Java SE) care oferă întreg suportul pentru detaliile tehnice gen threaduri,rețea, fișiere xml, etc.
Lucrul cu Thread-uri
Computerele sunt multitask, adică pot raspunde la mai multe cereri ȋn același timp. Pentru a profita la maxim de această capacitate a computerelor, un programator trebuie să scrie un program care să execute mai multe task-uri simultan. Acest concept poartă numele de programare paralelă.
Ȋn Java, un task se numește ”thread”, care inseamna ”fir de execuție” și reprezintă o secvență de instrucțiuni care sunt executate una după alta.
Capacitatea unui program de a executa mai multe secvențe de cod în același timp se numește ”Multithreading”.
Conceptul de thread reprezintă cea mai mică unitate de procesare ce poate fi programată spre execuție de către sistemul de operare. Sunt utile deoarece eficentizează timpul de execuție al unui program.
Un proces conține mai multe thread-uri, fiecare executând porțiunea lui de cod. Totuși, se întâmplă ca aceste porțiuni de cod pe care thread-urile le execută să nu fie independente.
“Regula de aur” a sincronizării ȋn Java este: Două thread-uri nu pot fi sincronizate simultan, pe același obiect. Dacă un thread este sincronizat pe un obiect și un al doilea thread ȋncearcă să se sincronizeze cu același obiect, el va fi forțat să aștepte până când primul a terminat lucrul cu obiectul respectiv. Aceasta tehnică prin care un thread asteaptă execuția altor thread-uri înainte de a continua propria execuție, se numește sincronizarea thread-urilor. Se marchează prin incadrarea codului cu synchronized { }.
Fiecare obiect are un ”lock”, care poate să fie la un singur thread ȋntr-un anumit moment dat. Pentru a declara o sincronizare, un thread trebuie să obțină mai ȋntât lock-ul obiectului respectiv. Dacă el este valabil, atunci thread-ul obține imediat lock-ul și ȋncepe să-și execute codul. În momentul finalizării execuției codului, el va elibera lock-ul. Un thread care nu poate să obțină un lock-ul, va intra ȋn modul ”sleep” și va ieși ȋn momentul ȋn care lock-ul este disponibil.
Sincronizarea are rolul de a preveni conflictele. Totuși aceasta poate produce erori precum deadlock-ul. Un deadlock apare atunci când un thread așteaptă o resursă pe care nu o va primi nicioadată.
Java oferă următoarele facilități pentru sincronizarea threadurilor: mecanismul synchronized și metodele: wait, notify și notifyAll.
Pentru ca programatorul Java să poată dezvolta programe care folosesc mai multe fire de execuție, cei de la Java propun pachetul java.lang. În acest pachet există două clase, Thread și ThreadGroup, respectiv o interfață, Runnable.
Clasa Thread și interfața Runnable oferă suport pentru lucrul cu thread-uri ca entități separate. În schimb, clasa ThreadGroup permite crearea unor grupuri de thread, lucru care se înțelege încă din numele acestei clase. Acest grup de fire de execuție este perceput ca un tot unitar. ThreadGroup conține mai multe obiecte de tip Thread.
Scopul unui obiect de tip Thread este acela de a executa o singură metodă. Metoda este executată ȋn firul de execuție, care poate rula ȋn paralel cu alte thread-uri. Oprirea din execuție este cauzată de două tipuri de scenarii: thread-ul se oprește din execuție pe fondul terminării normale a metodei sau din cauza terminării soldate cu o excepție. Oprirea este iremediabilă deoarece thread-ul nu se mai poate reporni și nu se mai poate folosi același obiect.
Există două moduri de a programa un thread:
primul mod este acela de a defini o subclasă a clasei Thread;
cel de-al doilea mod este acela de a defini o clasă care implementează interfața:
java.lang.Runnable.
Interfața Runnable definește o singură metodă public void run(). Un obiect care implementează interfața Runnable poate fi considerat ca parametru ȋn contructorul unui obiect de tip Thread. Când este apelată metoda start() a thread-ului, acesta va executa metoda run() din obiectul Runnable.
Vom descrie ambele metode în cele ce urmează.
Descrierea clasei Thread
Clasa Thread implementează interfața Runnable, de aceea programatorul, pentru a lucra cu thread-uri trebuie să creeze o clasă care extinde Thread sau una care implementează interfata Runnable. Pentru acest lucru, vom folosi operatorul extends respectiv implements.
Pentru a crea un fir de execuție, trebuie să cream un obiect de tipul Thread, folosind operatorul new:
Thread fir=new Thread();
După ce obiectul este creat, el poate fi configurat și apoi se poate trece la execuția sa. Configurarea cuprinde elemente ca de exemplu precizarea unui nume, a unei priorități etc.
Când firul este gata de execuție, se invocă metoda sa start(). Metoda start cere JVM-ul să creeze un thread. JVM-ul creează astfel un context favorabil unui thread. Apelul acestei metode face posibilă executarea metodei run(). Toate instrucțiunile pe care vrem ca thread-ul să le execute le vom specifica în metoda run(), pe care o vom suprascrie. Când metoda run() se încheie, firul de execuție se termină.
Putem vedea o legatură între felul cum funcționează un thread și felul cum metoda main este apelată de Java Runtime System în momentul în care rulează o aplicație Java normală. O dată cu pornirea mașinii virtuale JVM, se lansează și firul de execuție care apelează metoda main. Acestea pot fi închise brusc prin apelarea metodei exit() al clasei System – System.out.exit(1).
Principalii constructori ai clasei Thread:
Thread(): Inițializează un nou obiect de tip Thread;
Thread (Runnable target): Inițializează un nou obiect de tip Thread căruia i se specifică un obiect țintă dintr-o clasă care implementează interfața Runnable;
Thread (Runnable target, String name): Inițializează un nou obiect de tip Thread căruia i se specifică un obiect țintă dintr-o clasă care implementează interfața Runnable și un nume name;
Thread (String name): Inițializează un nou obiect de tip Thread căruia i se specifică un nume name.
Thread (ThreadGroup group, Runnable target): Inițializează un nou obiect de tip Thread căruia i se specifică un obiect țintă dintr-o clasă care implementeaza interfața Runnable, grupul de fire de care aparține group;
Thread (ThreadGroup group, Runnable target, String name): Inițializează un nou obiect de tip Thread căruia i se specifică un obiect țintă dintr-o clasă care implementeaza interfața Runnable, grupul de fire de care aparține group și un nume;
Thread (ThreadGroup group, Runnable target, String name, long stack_size):
Inițializează un nou obiect de tip Thread căruia i se specifică un obiect țintă dintr-o clasă care implementează interfața Runnable, grupul de fire de care aparține, un nume și dimensiunea stivei care îi va fi alocată pentru execuție (stack_size).
Thread(ThreadGroup group, String name): Inițializează un nou obiect de tip Thread căruia i se specifică grupul de fire de care aparține group și un nume name.
Tabelul 6
Declarațiile și descrierea câtorva metode ale clasei Thread:
Interfața Runnable
Ca orice alt obiect Java, un fir de execuție este o instanță a unei clase. Firele de execuție definite de o clasă vor avea același cod și prin urmare, aceeași secvență de instrucțiuni.
Crearea unei clase care să definească fire de execuție poate fi făcută prin două modalități:
prin extinderea clasei Thread;
prin implementarea interfeței Runnable.
Cea mai importantă clasă care implementează interfața Runnable este Thread.
Una din cele mai folosite interfețe din Java este interfața Runnable. Este foarte importantă deoarece este implementată de clasa Thread (fir de execuție, în sensul pe care îl are și în C++).
Interfața Runnable asigură un protocol comun obiectelor care doresc să-și execute codul, atâta timp cât sunt active. Un obiect este activ dacă a fost lansat în execuție și nu a fost oprit.
”Motorul” unui obiect care implementează clasa Runnable, este metoda run(). Această metodă trebuie suprascrisă de obiectul de tip Runnable.
Interfața se numește Runnable și nu Running, deoarece ea nu se execută chiar tot timpul. Pe marea majoritate a mașinilor se află un singur procesor care este ocupat și cu alte sarcini. Doar o parte din timpul de lucru al procesorului este alocată obiectului de tip Runnable.
Importanța interfeței Runnable se vede în momentul în care avem, de exemplu, o clasă care extinde clasa JPanel. Cum clasele în Java nu pot extinde decât o singură clasă, acest lucru subliniază importanța acestei interfețe, mai ales în domeniul grafic, unde adesea sunt folosite thread-uri. Este nevoie să moștenim clase din pachetul java.awt sau javax.swing dar este nevoie și de thread-uri, așa că suntem obligați să extindem clasele ce țin de grafica 2D în detrimentul clasei Thread.
O clasă ce implementează o interfață trebuie să suprascrie toate metodele acestei interfețe. Acest lucru se aplică, bineințeles și interfeței Runnable.
Un thread se creează folosind interfața Runnable în modul următor: se creează un obiect de tipul clasei care implementează interfața Runnable, apoi se creează un obiect de tip Thread, folosind un constructor ce are ca parametru chiar pe obiectul de tipul clasei care implementează pe Runnable. În final, se pornește obiectul de tip thread folosind metoda start, cu aceleași efecte ca și un thread creeat prin metoda clasei derivate din Thread.
Clasa Timer
Pe lângă componente grafice, pachetul swing vine și cu o serie de utilitare. Un astfel de utilitar este clasa Timer.
Clasa Timer aparține pachetului javax.swing.Timer. Acesta lansează unul sau mai multe evenimente (action events) după un anumit delay. Timer-ul din pachetul Swing oferă facilități diferite față de cel din pachetul java.util.
În general, se recomandă folosirea timerelor de tip Swing, în dauna celor cu scop general folosite pentru sarcinile legate de GUI, deoarece timer-ele Swing împart același preexistent timer de tip thread.
Totuși, s-ar putea folosi un timer cu scop general dacă programatorul nu plănuiește să influențeze cumva timer-ul de la GUI sau dacă vrea cumva să execute o prelucrare de lungă durată.
Timer-ul din pachetul Swing se poate folosi într-una dintre cele două posibile metode:
să execute o singură instrucțiune, o singură dată, după un anumit delay
să execute o instrucțiune în mod repetat
Timer-ul este ușor de folosit. Atunci când creăm un obiect de tip Timer, vom specifica un action listener care ne va informa dacă timerul s-a oprit sau nu. Vom mai avea nevoie de metoda Action Performed. Aceasta va conține codul pentru sarcina pe care o vrem executată, bineințeles, după un anumit delay. Întârzierea va fi dată din timer, ea fiind contorizată în milisecunde. Dacă dorim ca timer-ul să se oprească doar o dată, vom apela metoda setRepeats (false).
Există și o altă posibilitate de a utiliza un timer și anume prin:
Crearea unei subclase Action a lui TimerTask și supradefinirea metodei run ce va conține Action pe care vrem să o planificăm.
Crearea unui fir de execuție prin instanțierea clasei Timer;
Crearea unui obiect de tip Acțiune;
Planificarea la execuție a obiectului de tip Acțiune, folosind metoda schedule din clasa Timer;
Metodele de planificare pe care le avem la dispoziție au următoarele formate:
schedule(TimerTask task, Date time);
schedule(TimerTask task, long delay, long period);
schedule(TimerTask task, Date time, long period);
scheduleAtFixedRate(TimerTask task, long delay, long period);
scheduleAtFixedRate(TimerTask task, Date time, long period);
unde task descrie acțiunea ce se va executa, delay reprezintă întârzierea fața de momentul curent după care va începe execuția, time momentul exact la care va începe execuția iar period intervalul de timp între două execuții.
Metodele de planificare se împart în două categorii:
schedule – planificare cu întârziere fixă: dacă dintr-un anumit motiv acțiunea este întârziată, următoarele acțiuni vor fi și ele întârziate;
scheduleAtFixedRate – planificare cu număr fix de rate: dacă dintr-un anumit motiv acțiunea este întârziată, următoarele acțiuni vor fi executate mai repede, astfel încât numărul total de acțiuni dintr-o perioadă de timp să fie tot timpul același.
Un timer se va opri natural la terminarea metodei sale run sau poate fi oprit forțat folosind metoda cancel. După oprirea sa el nu va mai putea fi folosit pentru planificarea altor acțiuni.
În caz că vrem să oprim forțat toate firele de execuție, vom apela System.exit(int status). Aplicația curentă imediat se va opri. Practic System.exit face ca rularea lui Java Virtual Machine să se încheie.
Clasa Applet
Un java applet este o mică aplicație scrisă în Java, trimisă userilor în format bytecode. Userul lansează în execuție programul cu ajutorul unui browser web. Apoi applet-ul este executat cu ajutorul lui Java Virtual Machine (JVM), într-un proces separat de cel al browser-ului. Aplicația poate să fie redată sub forma unui frame al paginii web, dar și sub forma unei ferestre (application window). Mai poate fi deschisă cu ajutorul lui AppletViewer, program realizat de compania Sun, folosit tocmai pentru testarea applet-urilor. Acestea au fost introduse în prima versiune a limbajului Java, apărut în anul 1995.
Applet-ul se poate insera în alte aplicații. Pentru ca o clasă să devină applet, aceasta trebuie să extindă clasa Applet (extends Applet).
Clasa Applet face parte din pachetul java.applet și extinde clasa Panel.
Un applet este introdus într-o pagina web cu ajutorul tag-urilor <applet> </applet>. Acest tag poate avea următoarele atribute:
archive: conține arhiva de tip ”.jar” a aplicației;
code: conține numele clasei alături de extensia “.class”;
codebase: URL-ul în care se află fisierul “nume_clasa”.class corespunzator appletului;
object: indică fișierul în care se află un applet serializat;
alt: specifică un text care va fi afișat în browserele care nu suportă applet-ul respectiv;
name: numele applet-ului;
height si width: lățimea applet-ului. Sunt opționale aceste două setări. Dimensiunile frame-ului pentru applet se pot seta din cod;
vspace și hspace indică distanța pe verticală lăsată între și după applet, respective lățimea pe orizontală.
Un applet are următoarele metode de baza : init(), start(), stop() si destroy().
Metoda init() se va apela de către browser înaintea metodei start(). Metoda stop() se apelează când s-a dorit stoparea execuției applet-ului. Destroy() este folosită pentru a distruge aplicația de tip applet.
Pentru a desena pe suprafața applet-ului, va trebui să folosim metoda paint(), care aparține clasei Container. Metoda paint are ca parametru un obiect de tip Graphics.
Similară cu metoda getParameterInfo ce oferea o ”documentație” despre parametrii pe care îi acceptă un applet, există metoda getAppletInfo. Putem primii informații despre applet, utilizând metoda getAppletInfo(). Lungimea și lățimea unui applet pot fi modificate cu ajutorul metodei resize(int lungime, int latime).
Comunicarea applet-urilor se poate realiza doar dacă acestea au același server comun și dacă aparțin aceleiași pagini web. Un applet va fi emițătorul iar celălalt va fi receptorul. Pentru a vedea dacă două applet-uri fac parte din aceeași pagină web, acestea vor trebui să-și afle contextul, apelând metoda getApplet(String nume_applet). Această metodă va returna o referință pentru applet-ul specificat cu ajutorul string-ului nume_applet. În caz de eșec, se va returna valoarea null.
Execuția unui applet începe în momentul în care un browser afișează pagina web care conține applet-ul. Această execuție trece prin mai multe etape. Fiecare etapă este strâns legată de un eveniment generat de către browser și determină apelarea unei metode specifice din clasa ce implementează applet-ul.
load() – incărcarea în memorie – se creează o instanță a clasei principale a applet-ului și se încarcă în memorie;
init() – inițializarea – se apelează această metodă ce permite inițializarea unor variabile, citirea unor parametri de intrare, etc. Metoda init este responsabilă și pentru așezarea tuturor componentelor pe formă;
start() – Pornirea – această metodă reprezintă execuția propriu-zisă;
stop() – Oprirea temporară – În cazul în care utilizatorul părăsește pagina Web în care rulează applet-ul se apelează metoda stop() a acestuia, dându-i astfel posibilitatea să se oprească temporar cât timp nu este vizibil, pentru a nu consuma inutil din timpul procesorului. Metoda stop() este apelată și dacă fereastra browser-ului este minimizată. În momentul când pagina Web ce conține applet-ul devine din nou activă, va fi reapelată metoda start();
destroy() – Oprirea definitivă – La închiderea browser-ului, applet-ul va fi eliminat din memorie și va fi apelată metoda destroy a acestuia, pentru a-i permite să elibereze resursele deținute. Bineinteles, înaintea apelării metodei destroy(), se va apela metoda stop();
Clasa Applet oferă și posibilitatea redării de sunete în formatul ”.au”. Acestea sunt descrise prin intermediul unor obiecte ce implementează interfața AudioClip din pachetul java.applet.
Un sunet aflat într-un fișier ”.au” la un anumit URL se poate reda în două feluri:
Folosirea metodei play() a clasei Applet care primește ca argument URL-ul la care se află sunetul. Acesta poate fi specificat absolut sau relativ la URL-ul applet-ului;
Crearea unui obiect de tip AudioClip, urmată de apelarea metodei getAudioClip(), urmând ca în final să se redea sunetul prin apelarea metodei start(). Acesta se poate opri cu ajutorul metodei stop();
În cazul în care applet-ul folosește mai multe tipuri de sunete, este recomandată încărcarea acestora cu ajutorul unui fir de execuție separat (thread), pentru a nu bloca temporar activitatea programului.
De remarcat este faptul că applet-ul se execută pe mașina utilizatorului care a solicitat pagina web respectivă, pagină ce conține applet-ul. Este important ca să existe anumite restricții de securitate pentru ca să se evite acțiuni rău intenționate, activități precum ștergerea de fișiere, introducerea unor virusi, cât și alte prejudicii.
Pentru a realiza un control asupra activității applet-urilor, procesul care pornește applet-ul va instala un manager de securitate, acesta fiind un obiect de tip SecurityManager care va ”superviza” activitatea metodelor applet-ului. Acesta va arunca diferite excepții de tip Security Exception în cazul în care vreo metodă a applet-ului va încerca să realizeze o operație nepermisă.
Printre aceste operații nepermise, amintim:
Citirea sau scrierea de fișiere pe calculatorul pe care a fost încărcat (client);
Deschiderea de conexiuni cu alte mașini în afară de cea de pe care provine (host);
Pornirea de programe pe mașina client;
Citirea de diverse proprietăți ale sistemului de operare care aparțin clientului.
Java.AWT. Scurtă introducere în contextul grafic
Atât C++ cât și JAVA oferă facilități la nivelul graficii.
Spre deosebire de JAVA, unde componenta grafică vine la pachet, în C++ se poate realiza o grafică destul de bună, chiar și 3D cu diverse efecte de lumină, dar doar dacă se îmbină cu un alt limbaj de programare, OpenGL.
Pe lângă componenta grafică, JAVA oferă facilități și la nivelul sunetului. Îmbinarea eficientă a imaginii și a sunetului poate garanta succesul unei aplicații.
JAVA pune la dispoziție utilizatorului o serie de componente grafice în vederea creării unei interfețe. Aceste componente fac parte din pachetul java.awt.
Clasa Component este superclasa abstractă a tuturor claselor ce se găsesc în pachetul java.awt.
Button – butoane cu eticheta formată dintr-un text pe o singură linie;
Canvas – este o suprafață pentru desenare;
Checkbox – componentă ce poate avea două stări (true și false),
CheckBoxGroup – o grupare de mai multe checkbox-uri;
Choice – liste în care doar elementul selectat este vizibil;
Container – superclasa tuturor suprafețelor de afișare;
Label – etichete simple ce pot conține o singură linie de text needitabil;
List – liste cu selecție simplă sau multiplă;
Scrollbar – bare de defilare de două tipuri (orizontale sau verticale);
TextComponent – superclasa componentelor pentru editarea textului: TextField (pe osingură linie) și TextArea (pe mai multe linii).
Componenta AWT are peste 100 de metode comune, moștenite din clasa Component. Deobicei ele servesc pentru aflarea sau setarea atributelor obiectelor, atribute legate de dimensiune, poziție, culoare, font, etc. și au formatul general getProprietate, respectiv setProprietate.
Cele mai folosite metode sunt acelea legate de :
Poziție: getLocation, getX, getY, getLocationOnScreen, setLocation, setX, setY;
Dimensiuni: getSize, getHeight, getWidth, setSize, setHeight, setWidth;
Dimensiuni și poziție: getBounds, setBounds;
Culoare (text și fundal): getForeground, getBackground, setForeground, setBackground;
Font: getFont, setFont;
Vizibilitate: setVisible, isVisible;
Interactivitate setEnabled, isEnabled.
Utilizând aceste componente, programatorul poate construi interfața cu utilizatorul. O dată cu trecerea anilor, pachetul java.awt nu a mai reușit să satisfacă cerințele actuale de dezvoltare, astfel încât echipa de programatori de la compania Sun au lansat pe piață un nou pachet, javax.swing.
Pentru început, pachetul java.awt este util pentru un programator care își creează primele interfețe grafice. Din punctul de vedere al utilizatorului, componentele grafice awt se caracterizează prin formă (ceea ce se observă pe ecran) și prin răspunsuri la interacțiunea cu utilizatorul (interacțiuni ale mouse-ului, respectiv ale tastaturii).
Conceptul de desenare
Biblioteca AWT conține toate clasele necesare pentru crearea interfețelor cu utilizatorul, desenarea graficelor și a imaginilor.
Clasa Graphics este o clasă de tip abstract, care face parte din pachetul java.awt. Grafica din JAVA se bazează pe lucrul cu pixeli și pe un sistem ortogonal XOY.
Coordonata (0,0) se află în colțul din stânga sus al interfeței grafice. Dimensiunile suprafeței grafice sunt stabilite direct de programator/dezvoltator.
Tabelul 7
Clasa Graphics conține o serie de metode foarte utile.
Acestea au și niște funcții de umplere și anume:
fillRect(int x, int y, int width, int height)
fillArc(int x, int y, int width, int height, int startAngle, int arcAngle)
fillOval(int x, int y, int width, int height)
Pentru a schimba culorile de desenare, vom lucra cu obiecte din clasa java.awt.Color. Culoarea implicită de desenare este cea neagră. Pentru a o schimba, va trebui să scriem g.SetColor(Color.culoarea_aleasa) unde g este un obiect de tip Graphics. De exemplu g.SetColor(Color.red).
Dacă programatorul dorește să aibă o altă nuanță de culoare decât cele implicite, va trebui să utilizeze constructorul: public Color (int r, int g, int b) care are ca parametrii codul RGB (red-green-blue). Aceștia pot lua valori între 0 și 255.
Putem creea și o culoare transparentă folosind constructorul public Color (int r, int g, int b, int transparenta). Toți cei 4 parametrii iau valori între 0 si 255. Ultimul parametru, în caz că va avea valoarea 0, obiectul va avea o transparență totală, iar dacă va lua valoarea 255, atunci culoarea acestuia va fi una opacă.
O componentă este un obiect care are o reprezentare grafică. Din clasa Component fac parte, indirect sau direct, mai toate componentele, mai puțin meniurile.
Public abstract class Component extends Object implements ImageObserver, MenuContainer, Serializable.
Metodele acestei clase vor avea stabilite caracteristicile componentei.
Ierarhia componentelor în AWT: button, checkbox, container (panel si window), label, list, scrollbar, textcomponent (text area, text field).
Metodele cele mai importante ale clasei Component sunt :
public Color getBackground() = obține culoarea de fundal;
public void setBackground(Color c) = setează culoarea de fundal;
public void getForeground() = întoarce culoarea de scriere;
public void getForeground(Color c) = seteză culoarea de scriere;
public Component getComponentAt (int x, int y) = întoarce componenta de la coordonatele (x,y) dacă aceasta este componenta curentă sau subcomponenta acestuia, Null în caz contrar;
public int getHeight() = obține inălțimea componentei;
public int getWidth() = obține lățimea componentei;
public void setSize(int width, int height) = setezi lățimea respectiv lungimea componentei;
public void setBounds (int x, int y, int width, int height) = stabilește poziția și dimensiunile componentei;
public int getX() = determină coordonata pe axa OX a componentei;
public int getY() = determină coordonata pe axa OY a componentei;
public String getName() = obține numele componentei;
public void setName (String nume) = setează numele componentei;
public Component getParent () = întoarce componenta părinte;
public boolean isEnable() = testează dacă componenta e disponibilă;
public boolean setEnable (boolean b) = stabilește dacă componenta e disponibilă;
public void paint (Graphics g) = desenează componenta, g fiind contextul grafic pentru desenare. Este una dintre cele mai importante metode;
public void repaint () = redesenează componenta;
public boolean isVisible() = verifică proprietatea de vizibilitate a unei componente;
public Cursor getCursor()/public void setCursor(Cursor cursor) = returneaza/setează forma cursorului în Java. Există câteva tipuri predefinite de cursoare și anume default_cursor, crosshair_cursor, text_cursor, wait_cursor;
Public void list();
Public void list (PrintStream out);
Public void list(PrintStream out, int indent);
Public void list(PrintWriter out);
Public void list(PrintWriter out, int indent).
Metoda paint
Java oferă posibilitatea controlului la nivel de pixel pe dispozitivul grafic, respectiv desenarea a diferite forme grafice direct pe suprafața unei componente.
Desenarea componentelor se face automat și este un proces care se execută în urmatoarele situații:
la afișarea pentru prima dată a unei componente;
ca răspuns al unei solicitări a programului;
la operații de redimensionare a suprafeței de afișare pe care este plasată o componentă, Java pune la dispoziție 3 metode de desenare, aflate în clasa Component.
Prima metodă este void paint(Graphics g). Aceasta va desena componenta.
Este o metodă supraîncarcată de fiecare componentă în parte pentru a furniza modul său de reprezentare grafică specifică. Metoda este apelată de fiecare dată când conținutul componentei trebuie desenat.
A doua metodă enumerată este void update(Graphics g). Este utilizată pentru a actualiza starea grafică a unei componente.
Metoda update funcționează în 3 pași. Inițial șterge componenta prin redesenarea ei folosind culoarea fundalului, apoi stabilește culoarea (foreground) componentei, ca la final să apeleze metoda paint pentru a desena componenta actuală. De reținut este că aceasta nu se apelează explicit.
A treia metodă este void repaint(). Ea execută explicit un apel al metodei update pentru a actualiza reprezentarea grafică a componentei, desenul.
Desenarea în Java trebuie făcută doar în interiorul metodei paint(). Interfața grafică se poate realiza pe un tip special de componentă, numită Canvas.
Canvas este o clasă din care se derivează mai multe subclase, fiecare având rolul său în creearea interfeței grafice. Constructorul clasei Canvas realizează o ”planșa” în interiorul căruia se desenează. Ea nu poate conține mai multe componente grafice, fiind folosită doar ca suprafață de desenare a diferitelor decoruri sau fundale pentru animații.
Pe lângă clasa Canvas, în grafică se mai folosește și clasa Graphics.
Pentru a desena, programatorul trebuie să obțină contextul grafic pentru fereastra în care se va efectua desenarea. Acesta se obține printr-un obiect de tip Graphics, pe care îl vom pune ca parametru la metoda paint().
Clasa Graphics oferă posibilitatea de a desena forme geometrice precum linii, dreptunghiuri, arce de cerc și poligoane. Mai pot fi afișate imagini, desena pixeli și șiruri de caractere.
Metodele clasei Graphics:
clearRect (int x, int y, int width, int height);
clipRect(int x, int y, int width, int height);
copyArea(int x, int y, int width, int height, int dx, int dy);
create() = creaza un nou obiect de tip Graphics care este o copie a obiectului Graphics curent;
create(int x, int y, int width, int height) = creeaza un nou obiect de tip Graphics bazat pe obiectul grafic curent, dar cu o nouă translatare și o nouă zonă clip;
dispose() = șterge contextul grafic curent și eliberează toate resursele din sistem care îl foloseau;
draw3DRect(int x, int y, int width, int height, boolean raised);
drawArc(int x1,int y1, int width, int height,int startAngle, int arcAngle);
drawBytes(byte[] data, int offset, int length, int x, int y);
drawChars(char[] data, int offset, int length, int x, int y);
drawImage(Image img, int x, int y, ImageObserver observer);
drawImage(Image img,int x,int y,int width,int height, Color bgcolor, ImageObserver observer)
drawImage(Image img, int x, int y, int width, int height, ImageObserver observer);
drawImage(Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, Color bgcolor, ImageObserver observer) ;
drawImage(Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, ImageObserver observer) ;
drawLine(int x1, int y1, int x2, int y2;
drawOval(int x, int y, int width, int height);
drawPolygon(int[] xPoints, int[] yPoints, int nPoints);
drawPolygon(Polygon p);
drawPolyline(int[] xPoints, int[] yPoints, int nPoints);
drawRect(int x, int y, int width, int height);
drawRoundRect(int, int, int, int, int, int);
drawString(String str, int x, int y);
fill3DRect(int x, int y, int width, int height, boolean raised);
fillArc(int x, int y, int width, int height, int startAngle, int arcAngle);
fillOval(int x, int y, int width, int height);
fillPolygon(int[] xPoints, int[] yPoints, int nPoints);
fillPolygon(Polygon p);
fillRect(int x, int y, int width, int height);
fillRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight);
finalize() = sterge contextul grafic curent, atata timp cat nu mai e actual;
getClipRect() ;
getColor();
getFont();
getFontMetrics();
getFontMetrics(Font);
setColor(Color);
setFont(Font);
setPaintMode();
setXORMode(Color) = setează modul de desenare a contextului grafic, acesta alternând între culoarea curentă a contextului grafic actual și noua culoare specificată;
toString() = returnează un obiect de tip String care reprezintă valoarea obiectului de tip Graphics curent;
translate(int xn, int yn) = mută centrul axei de coordonate x si y din origine în punctul dat de parametrii xn și yn;
Prin dreptunghi de decupare (clip area) se înțelege zona din suprafața componentei de afișare în care sunt vizibile operațiile efectuate. Orice operație efectuată în afara acestui dreptunghi nu are nici un efect.
Stabilirea unui dreptunghi de decupare se realizează prin : clipRect(int x, int y, int width, int height).
Proprietățile contextului grafic:
culoarea de desenare
Color getColor()
void setColor(Color)
originea coordonatelor – poate fi modificată prin : translate(int x, int y)
modul de desenare
void setXorMode() – scriere "sau exclusiv"
void setPaintMode() – suprascriere
fontul curent pentru desenarea caracterelor
Font getFont()
void setFont(Font)
zona de decupare (în care sunt vizibile modificarile)
Shape getClip()
void setClip(Shape)
void setClip(int x, int y, int w, int h)
Pentru a scrie un text pe ecran avem două posibilități:
să folosim o componentă Label;
să apelăm la metodele clasei Graphics de desenare a textelor, cum ar fi drawString.
Indiferent de ce dorim să alegem, putem să specificăm prin intermediul fonturilor cum să arate textul respectiv, folosind metoda setFont fie din clasa Component, fie din Graphics.
Cei mai importanți parametri ce caracterizează un font sunt :
Tipul fontului: Helvetica Bold, Arial Bold Italic, etc;
Familia din care face parte fontul: Helvetica, Arial, etc;
Dimensiunea fontului: înălțimea și lățimea sa;
Stilul fontului: îngroșat (bold), înclinat (italic).
Clasele care oferă suport pentru lucrul cu fonturi sunt Font și FontMetrics.
Desenarea fonturilor
La afișarea unui șir cu metoda drawString trebuie să specificăm poziția la care să apară șirul pe ecran (coordonata x si y). În momentul în care avem de afișat mai multe șiruri trebuie să calculăm pozițiile lor de afișare în funcție de lungimea și înălțimea în pixeli a textului fiecărui șir.
Utilizarea imaginilor
Lucrul cu imagini in Java este posibil doar folosind următoarele formate de imagini: jpg, gif și png. Orice imagine este o instanță a clasei Image. Aceasta nu este o clasă de componente (nu extinde clasa Component).
Metoda getImage nu verifică dacă fișierul sau adresa specificată reprezintă o imagine valida și nici nu încarcă efectiv imaginea în memorie, aceste operațiuni fiind făcute abia în momentul în care se va realiza afișarea imaginii pentru prima dată.
Metoda nu face decât să creeze un obiect de tip Image care face referință la o anumită imagine externă.
Dintre metodele clasei Image cele mai des folosite sunt cele pentru determinarea dimensiunilor unei imagini:
int getHeight(ImageObserver observer);
int getWidth(ImageObserver observer) unde parametrul observer este uzual this.
Afișarea imaginilor
Afișarea imaginilor într-un applet se face fie prin intermediul unei componente ce permite acest lucru. Există 3 metode pentru a realiza suprafața de desenare și anume: componenta de tip Canvas, fie direct prin metoda paint a applet-ului și nu în ultimul rând folosind metoda drawImage a clasei Graphics.
În ambele cazuri, obținerea unei referințe la imaginea respectivă se va face prin intermediul metodei getImage din clasa Applet. Aceasta poate primi ca argument fie adresa URL absolută a fișierului ce reprezintă imaginea, fie calea relativă la o anumită adresă URL, de exemplu cea a directorului în care se găsește documentul HTML ce conține applet-ul. Aici vom folosi metoda getDocumentBase. Se mai poate da calea relativa a directorului în care se găsește clasa applet-ului și atunci folosim getCodeBase.
Afișarea unei imagini într-un context grafic se realizează prin intermediul metodei drawImage care aparține clasei Graphics. În general se realizează în metoda paint a unui obiect de tip Canvas.
Cele mai uzuale formate ale metodei prin care se afișează o imagine pe suprafața de desenare sunt:
boolean drawImage(Image img, int x, int y, ImageObserver observer);
boolean drawImage(Image img, int x, int y, Color bgcolor, ImageObserver observer);
boolean drawImage(Image img, int x, int y, int width, int height, ImageObserver observer);
boolean drawImage(Image img, int x, int y, int width, int height, Color bgcolor, ImageObserver observer);
unde:
img este obiectul ce reprezintă imaginea;
x si y sunt coordonatele la care va fi afișată imaginea pe suprafața de desenare;
observer este un obiect care "observă" încărcarea imaginii. Acesta va fi informat în legătura cu incărcarea imaginii, starea ei;
width, heigth reprezintă înalțimea și lățimea la care trebuie scalată imaginea;
bgColor reprezintă culoarea cu care vor fi colorați pixelii transparenți ai imaginii.
Metoda drawImage returnează true dacă imaginea a fost afișată în întregime și false în caz contrar, cu alte cuvinte metoda nu asteptă ca o imagine să fie complet afișată ci se termină imediat ce procesul de afișare a început. În cazul în care se afișează o imagine care se găsește pe Internet sau imaginea afișată este de dimensiuni mari se va observa că aceasta nu apare complet de la început ci este desenată treptat fără intervenția programatorului.
Acest lucru se întâmplă deoarece metoda drawImage nu face decât să declanșeze procesul de încărcare/afișare a imaginii, după care redă imediat controlul apelantului, lucru deosebit de util întrucât procesul de încărcare a unei imagini poate dura mult și nu este de dorit ca în acest interval de timp (până la încărcarea completă a imaginii) aplicația să fie blocată. Ca urmare, la apelul metodei drawImage va fi desenată numai porțiunea de imagine care este disponibilă la un moment dat și care poate fi incompletă. De aceea trebuie să existe un mecanism prin care componenta să fie redesenată în momentul în care au mai sosit informații legate de imagine.
Lucrul cu evenimente în contextul grafic (Java.awt.event)
Un pachet este o colecție de clase și interfețe înrudite din punctul de vedere al functionalității lor.
Sunt folosite pentru găsirea și utilizarea mai ușoară a claselor, pentru a evita conflictele de nume și pentru a controla accesul la anumite clase. În alte limbaje de programare pachetele se mai numesc librării sau bibilioteci.
Platforma standard de lucru Java se bazeaza pe o serie de pachete cu ajutorul cărora se pot construi într-o manieră simplificată aplicațiile.
Există un set de clase deja implementate care modelează structuri de date, algoritmi sau diverse noțiuni esențiale în dezvoltarea unui program.
Cele mai importante pachete și suportul oferit de ele sunt:
java.lang – clasele de baza ale limbajului Java;
java.io – intrari/iesiri, lucrul cu fișiere;
java.util – clase și interfețe utile;
java.applet – dezvoltarea de applet-uri;
java.awt – interfața grafică cu utilizatorul;
java.awt.event – mecanismele de tratare e evenimentelor generate de utilizator;
java.beans – scrierea de componente reutilizabile;
java.net – programare de rețea;
java.sql – lucrul cu baze de date;
java.rmi – execuție la distanta Remote Message Interface;
java.security – mecanisme de securitate: criptare, autentificare;
java.math – operații matematice cu numere mari;
java.text – lucrul cu texte, date si numere independent de limbă;
java.lang.reflect – introspecție;
javax.swing – interfața grafică cu utilizatorul, mult îmbogățită față de AWT.
Java pune la dispoziția programatorilor pachetul java.awt.event pentru a ști cum să mânuiască diferite evenimente ce au apărut în urma interacționării componetelor awt.
Există o serie de interfețe în acest pachet. Acestea sunt :
ActionListener : acesta este folosit pentru a primi semnalele evenimentor noi apărute;
AWTEventListener : este folosit pentru a primi notificări în legatură cu event-urile trimise obiectelor care sunt instanțe ale lui Component, MenuComponent sau ale subclaselor acestora;
ComponentListener : sunt folosite pentru a recepționa evenimente de tip Component;
ContainerListener : sunt folosite pentru a recepționa evenimente de tip Container;
FocusListener : se folosește pentru a primi evenimente ale tastaturii concéntrate asupra unei componente;
KeyListener : este folosit pentru a recepționa evenimente legate de tastatura și anume dacă s-a apăsat pe un anumit buton al tastaturii;
MouseListener : este folosit pentru a primi diferite acțiuni ale mouse-ului. Conține diferite metode axate pe câte un eveniment și anume:
mouseClicked(MouseEvent e)
mouseEntered(MouseEvent e)
mouseExited(MouseEvent e)
mousePressed(MouseEvent e)
mouseReleased(MouseEvent e)
Descrierea aplicației
Modul de utilizare
Figura 3.1 – Prima pagină a site-ului
Site-ul își întâmpină oaspeții cu un aspect plăcut, cu un meniu în partea stângă și cu conținutul central. Lecțiile (subcapitolele) se regăsesc în meniu, fiind afișate numai lecțiile capitolului ales.
Figura 3.2 – Conținut al site-ului
Fiecare lecție conține atât teorie, cât și imagini sugestive și appleturi care fac mai ușoară înțelegerea materiei. Appleturile pot fi pornite sau oprite cu un singur click. La încărcarea paginii, acestea sunt oprite, pentru a nu scădea performanța calculatoarelor mai slabe.
Pentru a adăuga un capitol nou, administratorul trebuie mai întâi să se autentifice în secțiunea de administrare. De la opțiunea "Adaugă (Sub)Capitol", se introduce noul nume, apoi se editează opțional conținutul. Pentru a simplifica lucrurile, există un editor de texte simplu, scris în JavaScript, care conține cele mai uzuale marcaje HTML, cum ar fi introducerea unei imagini sau a unui applet, schimbarea fontului, introducerea tabelelor sau a diacriticelor. Pentru ca noua lecție să devină un subcapitol, se pote alege dintr-o listă de meniu doar capitolele de sine stătătoare. Altfel, se poate lăsa această opțiune nemarcată.
Figura 3.3 – Interfața de modificare dinamică a conținutului site-ului
Rezultatul se poate vedea imediat în pagină, efectuând o reîncărcare. Conținutul lecției va fi interpretat drept cod HTML și va fi afișat ca atare. Formatarea textului este posibilă datorită legării paginii de un document css. Astfel, dacă mai târziu se hotărăște schimbarea aspectului, nu mai trebuie să se schimbe conținutul lecțiilor.
Figura 3.4 – Noua pagină creată a site-ului
Pentru a efectua modificări la o lecție, în secțiunea "Modifică (Sub)Capitol" se poate alege capitolul sau lecția de modificat, apoi va apărea o componentă textarea cu conținutul capitolului ales. Se pot schimba și numele, dar și capitolul părinte, existând posibilitatea de a transforma o lecție într-un capitol de sine stătător.
Figura 3.5 – Exemplu de adăugare de conținut
Ștergerea unei lecții este deosebit de simplă. Nu trebuie decât să se selecteze un capitol și lecția dorită, apoi apăsarea pe "Șterge Capitol" sau "Șterge SubCapitol". Este important de menționat că un capitol de sine stătător poate fi șters numai dacă nu mai conține vreun subcapitol. Această măsură a fost luată pentru a micșora efectele unei ștergeri accidentale.
Secțiunea de administrare mai conține și opțiunea de ieșire din cont, ceea ce va asigura închiderea sesiunii. Astfel, dacă o altă persoană va avea acces la același calculator, nu va putea intra în zona de administrare dacă nu cunoaște vreo parolă.
După cum se poate observa, modul de utilizare este foarte simplu și nu ridică probleme de administrare unei persoane cu cunoștințe minime de html.
Implementarea
La fel ca în majoritatea aplicațiilor web moderne, site-ul este bazat pe o bază de date, în care sunt memorate capitolele, subcapitolele și conținutul lor.
Baza de date MySQL conține doar două tabele. Unul dintre ele ("admin") este folosit pentru a reține numele și parolele utilizatorilor cu drepturi de administrare. Acestea din urmă sunt criptate cu ajutorul algoritmului md5, pentru a preveni aflarea parolei în cazul în care cineva străin are acces la baza de date.
Al doilea tabel ("capitole") conține capitolele și conținutul lor. La fiecare dată în parte avem o coloană de identificare, un nume, id-ul unui capitol părinte (unde este cazul) și o coloană care are ca valoare sursa HTML care descrie conținutul capitolului (de tipul longtext, care poate conține până la aproximativ 65 000 de caractere). Capitolele se împart astfel în două categorii: capitole care nu au un capitol părinte (numite în pagina web "capitole") și capitole care au un capitol părinte dintre cele din prima categorie (numite în pagina web "subcapitole").
Modulul PHP se conectează la baza de date atunci când pagina este deschisă și extrage numele și id-ul capitolelor de sine stătătoare, scriind apoi numele în meniul din stânga. Când un astfel de capitol de sine stătător este deschis, se transmite paginii id-ul capitolului respectiv, apoi modulul PhP va selecta din baza de date toate subcapitolele ce au la partea de capitol părinte id-ul transmis prin metoda GET.
Implicit, se va afișa conținutul capitolului respectiv. Sub numele capitolului selectat vor fi afișate toate subcapitolele sale. Codul pentru această parte este următorul:
<?php
$comanda="select nume_capitol, id_capitol from capitole where capitol_parinte is null";
$sql=mysql_query($comanda) or die('Cererea nu a fost executată: '.mysql_error()); ?>
<table>
<tr><td><a class="altlink" href ="index.php">
Acasă </a></td></tr>
<?php
while($r=mysql_fetch_array($sql)){ ?>
<tr><td><a class="altlink"
href="capitol.php?cap=<?=$r['id_capitol']?>"><?=$r['nume_capitol']?>
</a></td></tr>
<?php
if($r['id_capitol']==$_GET['cap']){
$comanda_sub="select nume_capitol, id_capitol, capitol_parinte from capitole where capitol_parinte=" .$r['id_capitol'];
$sql_sub=mysql_query($comanda_sub) or die('Cererea nu a fost executată: '.mysql_error());
if(mysql_num_rows($sql_sub)!=0){
while($r_sub=mysql_fetch_array($sql_sub))
print("<tr><td><p class=\"sub\"><img src = \" arrow.gif\" /><a class=\"submeniu\"href=\"capitol.php?cap="
.$r_sub['capitol_parinte']."&sub=".$r_sub['id_capitol']."\">".$r_sub['nume_capitol']."</a></td></tr></p>\n");
}
}
}
?>
Fișierul "capitol.php" preia un parametru GET, care este de fapt id-ul capitolului de afișat, apoi extrage din baza de date conținutul respectiv. Este o procedură simplă, care asigură rezultate bune.
Însă în secțiunea de administrare, lucrurile se complică un pic. În primul rând, este important de știut că avem mai multe fișiere care îndeplinesc funcțiile mai sus menționate: adăugarea, modificarea și ștergerea de capitole. Este un lucru vital să nu oferim accesul la aceste fișiere decât dacă mai întâi utilitatorul s-a autentificat. Pentru aceasta ne folosim de sesiuni, cu ajutorul cărora vom seta anumite variabile la logare, fără de care nu se oferă accesul.
În fiecare fișier sensibil vom include fișierul "autorizare.php". Acesta va verifica dacă a avut loc autentificarea, în caz contrar afișând un mesaj de eroare și o legătură spre pagina de logare. Conținutul fișierului este următorul:
<?php
session_start();
if($_SESSION['key_admin']!=session_id()){
print("<h1>Acces neautorizat!</h1><br>");
print("<a href=\"index.php\">Autentificare</a>");
exit();
}
include("../conectare.php");
$sql="select * from admin where nume= '".$_SESSION ['utilizator']."' and parola='".$_SESSION ['parola']."'";
$res=mysql_query($sql);
if(mysql_num_rows($res)!=1){
print("<h1>Nume sau parolă greșită!</h1><br>");
print("<a href=\"index.php\">Autentificare</a>");
exit();
}
?>
Pentru a verifica dacă numele de utilizator și parola introduse sunt corecte, verificăm baza de date, dar bineîțeles, după ce criptăm mai întâi parola folosind algoritmul md5. Conținutul fișierului "login.php" este următorul:
<?php
if(($_POST['nume']=="")||($_POST['parola']=="")){
print("<h1>Trebuie completate ambele câmpuri!</h1>");
print("<br><a href=\"index.php\">Înapoi</a>");
exit();
}
include("../conectare.php");
$parolaEncriptata=md5($_POST['parola']);
$sql="select * from admin where nume='".$_POST['nume']."' and parola='".$parolaEncriptata."'";
$res=mysql_query($sql);
if(mysql_num_rows($res)!=1){
print("<h1>Nume sau parolă greșită!</h1><br>");
print("<a href=\"index.php\">Înapoi</a>");
exit();
}
session_start();
$_SESSION['utilizator']=$_POST['nume'];
$_SESSION['parola']=$parolaEncriptata;
$_SESSION['key_admin']=session_id();
header("location: admin.php");
?>
Verificăm dacă în tabel există o singură înregistrare cu numele de utilizator și parola specificate, caz în care setăm variabilele de sesiune "utilizator", "parola" și "key_admin" cu valorile introduse, respectiv cu id-ul sesiunii. Dacă cererea SQL nu returnează o singură înregistrare, afișăm un mesaj de eroare și o legătură către pagina de logare ("index.php").
Fișierul "capitol_adauga" verifică dacă există variabila POST "capitol_nou", inițializată în momentul în care se apasă pe butonul "Adaugă". Dacă aceasta există, atunci introduce în baza de date toate variabilele POST necesare. Secvența de cod este următoarea:
if(isset($_POST['capitol_nou'])){
if($_POST['capitol_nou']==""){
print("<h1>Trebuie introdus un nume de capitol!</h1><br> ");
print("<a href=\"capitol_adauga.php\">Înapoi</a>");
exit();
}
if($_POST['capitol_parinte']=="0")
$parinte="null";
else
$parinte=$_POST['capitol_parinte'];
$sql="insert into capitole(nume_capitol, capitol_parinte, continut_capitol) values(\"".$_POST['capitol_nou']."\",". $parinte. ",\"".$_POST['continut']."\")";
print($sql);
$res=mysql_query($sql) or die('Cererea nu a fost executată:'. mysql_error());
print("<h3>Capitolul ".$_POST['capitol_nou']." a fost adăugat cu succes!</h3>");
}
Se observă că se testează dacă a fost specificat un capitol părinte, în caz contrar punându-se în textul de inserare cuvântul "null", astfel încât SGBD-ul să înțeleagă că înregistrarea nu are capitol părinte. Oicum, se afișează în continuare câmpurile pentru inserarea unor noi lecții.
Ar mai trebui menționat la acest fișier și editorul de texte din javascript, care atunci când este apelat de o componentă de tip imagine, adaugă la componenta de tip textarea codul HTML respectiv:
<script type="text/javascript">
<!–
function adauga(v){
document.getElementById('continut').value+=v;
document.getElementById('continut').focus();
}
//–>
</script>
Un exemplu de utilizare ar fi următorul, care adaugă în zona de editare codul HTML pentru scris îngroșat:
<img src="../img/bold.gif" alt="Îngroșat" id="bold" onclick= "adauga('<b></b>')" />
Acest sistem permite să se pună de-a lungul timpului mai multe imagini cu cod HTML aferent, fără să se facă modificări în codul precedent.
Fișierul "capitol_modifica" are exact aceeași structură, numai că oferă un sistem de alegere al capitolelor și subcapitolelor existente și atunci când este selectat un capitol, afișează în zona de editare conținutul. Sistemul de algere al capitolelor și subcapilelor presupune folosirea a două liste derulante (combo-box) și are următorul cod:
<table>
<tr>
<td>Capitole:</td>
<td><select name="capitol_mod">
<?php
while($r=mysql_fetch_array($res)){
?>
<option<?php if($_POST['capitol_mod']==$r['id_capitol']) print(" selected=\"true\" ")?> value="<?=$r['id_capitol']?>"> <?=$r['nume_capitol']?></option>
<?php
}
?>
</select></td>
</tr>
<?php
if((isset($_POST['alege_capitol']))||(isset($_POST['alege_subcapitol']))||(isset($_POST['capitol_mod']))||(isset($_POST['subcapitol_mod']))){
$subsql="select id_capitol, nume_capitol from capitole where capitol_parinte=".$_POST['capitol_mod'];
$subres=mysql_query($subsql);
?>
<tr>
<td>Subcapitole:</td>
<td><select name="subcapitol_mod"><?php
while($r=mysql_fetch_array($subres)){
$selectat=null;
if($r['id_capitol']==$_POST['subcapitol_mod'])
$selectat=' selected=true';
print("<option value=\"".$r['id_capitol']."\"".$selectat. ">".$r['nume_capitol']."</option>");
}
?>
</select></td>
</tr>
<?php
}
?>
</table>
Fișierul "sterge.php" este cel responsabil cu ștergerea (sub)capitolelor. Acesta are și el o secțiune care permite selectarea lecției de șters, plus încă o secțiune care verifică dacă în capitolul ce urmează să fie eliminat mai există și alte subcapitole. Codul în cauză este următorul:
if(isset($_POST['sterge_capitol'])){
$sql="select nume_capitol from capitole where capitol_parinte= '".$_POST['capitol_mod']."'";
$res=mysql_query($sql);
$r=mysql_fetch_array($res);
if(mysql_num_rows($res)!=0){
print("<font size=\"5\" color=\"red\">Capitolul ".$r ['nume_capitol']." are cel puțin un subcapitol! Sunteți sigur că doriți sa îl ștergeți?</font>");
print("<form action=\"sterge.php\" method=\"post\"><input type=\"hidden\" name=\"capitol_mod\" value=\"". $_POST['capitol_mod']."\"><input type=\"submit\" name= \"sterge\" value=\"Confirmă ștergerea\"></form>");
}
else{
$sql="delete from capitole where id_capitol= '".$_POST['capitol_mod']."'";
$res=mysql_query($sql) or die ("Capitolul ".$_POST ['capitol_mod']." nu a putut fi șters: ".mysql_error());
print("Capitolul a fost șters!");
}
}
if(isset($_POST['sterge_subcapitol'])){
$sql="delete from capitole where id_capitol='".$_POST ['subcapitol_mod']."'";
$res=mysql_query($sql) or die ("Subcapitolul ".$_POST ['subcapitol_mod']." nu a putut fi șters: ".mysql_error());
print("Subcapitolul a fost șters!");
}
if(isset($_POST['sterge'])){
$sql="delete from capitole where id_capitol='". $_POST['capitol_mod']."' or capitol_parinte='".$_POST ['capitol_mod']."'";
$res=mysql_query($sql) or die ("Capitolul ".$_POST ['capitol_mod']." nu a putut fi șters: ".mysql_error());
print("Capitolul a fost șters!");
Codul pentru alegerea lecției de șters este asemănător cu cel de la modificarea capitolelor și este următorul:
<form action="sterge.php" method="post">
<table>
<tr>
<td>
Capitol:
</td>
<td>
<select name="capitol_mod">
<?php
while($r=mysql_fetch_array($res)){
$selectat=null;
if($_POST['capitol_mod']==$r['id_capitol'])
$selectat=" selected=\"true\"";
?>
<option value="<?=$r['id_capitol']?>"<?=$selectat?>> <?=$r['nume_capitol']?></option>
<?php
}
?>
</select>
</td>
<td>
<input type="submit" name="sterge_capitol" value="Șterge Capitol">
</td>
<td>
<input type="submit" name="alege_capitol" value="Arată Subcapitole">
</td>
</tr>
<?php
if(isset($_POST['alege_capitol'])){
$sql="select nume_capitol, id_capitol from capitole where capitol_parinte='".$_POST['capitol_mod']."'";
$res=mysql_query($sql);
?>
<tr>
<td>
Subcapitol:
</td>
<td>
<select name="subcapitol_mod">
<?php
while($r=mysql_fetch_array($res)){
?>
<option value="<?=$r['id_capitol']?>"><?=$r['nume_capitol']?></option>
<?php
}
?>
</select>
</td>
<td>
<input type="submit" name="sterge_subcapitol" value= "Șterge Subcapitol">
</td>
</tr>
<?php
}
?>
</table>
</form>
Mai există și fișierul "sfarsit_sesiune.php", care termină sesiunea și dă posibilitatea altui utilizator să se autentifice. În plus, se mărește gradul de securitate, pentru că se elimină riscul ca altcineva să folosească același calculator și să intre în aceeași sesiune. Codul fșierului este următorul:
<?
include ("autorizare.php");
session_unset();
session_destroy();
print("La revedere!");
print ("<a href=\"index.php\">Către pagina de logare</a>");
?>
Site-ul se folosește de un document css pentru formatarea textului. Cu ajutorul lui se definesc culori, mărimi, poziționări (în special capitolele care formează meniul în partea din stânga). Atunci când este nevoie, stilul luat din documentul css este suprascris cu ajutorul proprietății "style", pe care majoritatea tagurilor HTML o au.
body {background-color: white;
color: black}
h1 {color: blue;}
h2 {color: blue;}
h3 {background-color: #7a5ada;
padding-top: 0.4em;
padding-bottom: 0.4em;
padding-left: 1.0em;
padding-right: 1.0em;
color: white;
text-align: left;
clear:both;}
h4 {color: blue;}
h5 {color: blue;}
h6 {color: blue;}
a.altlink:link { color: #7a5ada; text-decoration: none; }
a.altlink:visited { color: #5a3aba; text-decoration: none; }
a.altlink:hover { color: #7a5ada; text-decoration: underline; }
a.altlink:active { color: #7a5ada; text-decoration: underline; }
a.submeniu:link { color: #7a5ada; text-decoration: none;}
a.submeniu:visited { color: #5a3aba; text-decoration: none;}
a.submeniu:hover { color: #7a5ada; text-decoration: underline;}
a.submeniu:active { color: #7a5ada; text-decoration: underline;}
p.sub { margin-left: 15px;}
Pentru o gesionare bună a fișierelor folosite în site, împărțirea lor în directoare este următoarea: fișierele folosite direct la pagina principală (index.php, capitol.php etc.) sunt în directorul aplicației; imaginile sunt în subdirectorul "img", care are la rândul său un director pentru diacritice; appleturile sunt în directorul "applet"; fișierele necesare pentru secțiunea de administrare se regăsesc în subdirectorul "admin".
Appleturile constituie o importanta parte a site-ului. Acestea ajută prin animații la o mai bună înțelegere a materiei și reprezintă pasul în secolul XXI al învâțământului. Beneficiind de robustețea, eficiența și mai ales portabilitatea limbajului Java, appleturile sunt de fapt mici programe care excută diverse lucruri într-o pagină de internet.
În cazul de față, sunt desenate anumite figuri geometrice simple și afișate doar pentru o anumită perioadă de timp, variind de la câteva secunde la miimi de secundă. În acest fel se obțin efecte uneori spectaculoase, cum ar fi mișcarea bilei de-a lungul unor vectori, într-un mod destul de simplu.
Pachetele folosite în appleturile acestui site sunt:
java.applet – pachetul standard pentru appleturi, contine clasa java.applet.Applet, care este o superclasă pentru toate programele de acest fel. Oferă toate instrumentele pentru creearea unui applet și moștenește metodele care se apelează la inițializare, pornire, oprire și distrugere;
java.awt – Advanced Window Toolkit, contine obiecte și metode pentru desenarea textului sau a altor figuri geometrice. Deasemenea, conține obiecte cum ar fi culori, gradiente, pensule, fonturi etc;
java.awt.geom – conține obiecte și metode pentru creearea și prelucrarea figurilor geometrice simple, cum ar fi Point (pentru puncte), Line (pentru linii), Rectangle (pentru dreptunghiuri), QuadCurve2D (pentru curbe simple), CubeCurve2D (pentru curbe compuse), Ellipse (pentru elipse și cercuri), Arc (pentru porțiuni din elipse), GeneralPath pentru poligoane închise sau deschise etc. Deasemenea, există obiecte pentru astfel de figuri geometrice care au marginile rotunde, sau metode care nu numai că desenează conturul figurilor, dar și umplu conținutul cu o culoare (sau gradient);
java.awt.event.MouseListener – clasă pentru monitorizarea acțiunilor mouse-ului;
java.awt.event.MouseEvent – este o clasă standard pentru interfețe și evenimente care implică acțiuni ale mouse-ului.
Este foarte important de înțeles cum desenează metodele din pachetul java.awt. Acestea sunt executate la apelarea metodei paint(), adică după ce a pornit appletul. Ele se folosesc de coordonatele carteziene, dar cu originea în colțul din stânga sus, coordonatele crescând spre dreapta și în jos.
Mai jos este prezentat o secvență din codul programului "VectorDefinitie", care arată componentele unui vector, cum ar fi direcția, sensul, dreapta suport sau modulul. Fiecare cadru va sta pe ecran 2 secunde, iar când mica secvență se va termina, ultima va rămâne pe ecran 5 secunde, după care o va lua de la capăt:
public void paint(Graphics g){
Graphics2D g2 = (Graphics2D) g;
int x,y;
metrica = g2.getFontMetrics();
y = inaltime – metrica.getHeight();
if(stadiu>=0){
g2.setColor(Color.blue);
g2.draw(linie);
}
if(stadiu>=1){
g2.draw(linieStanga);
g2.draw(linieDreapta);
}
if(stadiu>=4){
g2.setColor(Color.red);
g2.draw(semiacolada1);
g2.draw(semiacolada2);
g2.drawString("10", latime/2+16, inaltime/2);
}
if(stadiu>=2){
g2.setStroke(dashed);
g2.setColor(Color.black);
g2.drawLine(latime/2, y-metrica.getHeight(), latime/2, 0);
}
if(stadiu>=3){
g2.drawLine(latime/4, 0, latime/4,
y-metrica.getHeight());
g2.drawLine((latime*9)/10, 0, (latime*9)/10,
y-metrica.getHeight());
}
if((stadiu==0)&&(continua)){
g2.setColor(Color.black);
String text = "Directia vectorului";
x = latime/2 – metrica.stringWidth(text)/2;
g2.drawString(text, x, y);
stadiu++;
dormi(2000);
}
else if((stadiu==1)&&(continua)){
String text = "Sensul vectorului";
x = latime/2 – metrica.stringWidth(text)/2;
g2.setColor(Color.black);
g2.drawString(text, x, y);
stadiu++;
dormi(2000);
}
else if((stadiu == 2)&&(continua)){
String text = "Dreapta suport";
x = latime/2 – metrica.stringWidth(text)/2;
g2.setColor(Color.black);
g2.drawString(text, x, y);
stadiu++;
dormi(2000);
}
else if((stadiu == 3)&&(continua)){
String text = "Alte drepte suport cu aceeasi directie";
x = latime/2 – metrica.stringWidth(text)/2;
g2.setColor(Color.black);
g2.drawString(text, x, y);
dormi(2000);
stadiu++;
}
else if((stadiu==4)&&(continua)){
String text = "Modulul vectorului";
x = latime/2 – metrica.stringWidth(text)/2;
g2.setColor(Color.black);
g2.drawString(text, x, y);
stadiu = 0;
dormi(5000);
}
}
private void dormi(int sec){
try{
Thread.sleep(sec);
repaint();
}
catch(InterruptedException e){
}
}
Funcția dormi() "îngheață" threadul appletului pentru un anumit interval de secunde, care este transmis prin argument ca un întreg multiplu de 1000. Motivul este că funcția Thread.sleep() accepta ca parametru miimi de secundă. În metoda init(), care este prima apelată, sunt inițializate mai multe câmpuri, printre care stadiu, inaltime, latime, semiacolada1, semiacolada2 etc, care sunt calculate astfel încât să deseneze în mijlocul spațiului de desenat, indiferent de dimensiunea appletului în pagină.
Câmpul stadiu este mai întâi inițializat cu 0 și este folosit ca marcaj pentru a ști ce figuri și text trebuie desenate. După ce sunt puse pe ecran, threadul appletului este înghețat pentru 2 secunde, astfel încât utilizatorul are posibilitatea să citească și să observe imaginea. Apoi este incrementată valoarea variabilei stadiu, pentru a desena secvența următore și este apelată metoda repaint(), care execută din nou metoda paint() a appletului. Când se ajunge la ultima secvență, câmpul stadiu ia valoarea 0 (deci o luăm de la capăt) și de data aceasta așteptăm 5 secunde, pentru a diferenția repetările cadrelor.
Pentru a arăta cum sunt calculate valorile inițiale, mai jos este afișat conținutul metodei init():
public void init(){
addMouseListener(this);
latime = getSize().width;
inaltime = getSize().height;
stadiu = 0;
Color fundal = new Color(224, 224, 224);
setBackground(fundal);
continua=false;
origineVector = new Point2D.Float(latime/2,
(inaltime*3)/4);
varfVector=new Point2D.Float(latime/2,inaltime/4);
varfStanga=new Point2D.Float(latime/2-10,inaltime/4+ 10);
varfDreapta=new Point2D.Float(latime/2+10,
inaltime/4+10);
linie = new Line2D.Float(origineVector,varfVector);
linieStanga = new Line2D.Float(varfVector,varfStanga);
linieDreapta = new Line2D.Float(varfVector,varfDreapta);
this.semiacolada1 = new CubicCurve2D.Float(varfVector.x, varfVector.y, varfVector.x+15, varfVector.y+15, varfVector.x -10, varfVector.y+20, varfVector.x+15, inaltime/2);
semiacolada2 = new CubicCurve2D.Float(origineVector.x, origineVector.y, origineVector.x+15, origineVector.y – 15,
origineVector.x-10, origineVector.y-20, origineVector.x+15,
inaltime/2);
float dash1[] = {5.0f};
dashed = new BasicStroke(1.0f,
BasicStroke.CAP_BUTT,
BasicStroke.JOIN_MITER,
10.0f, dash1, 0.0f);
}
Metoda paint() desenează numai dacă variabila continua este adevărată. Dar la început ea este falsă, schimbându-și valoarea atunci când se execută un click, evenimentul fiind prins de un obiect din clasa MouseEvent.
Se observă din procedura de mai sus că punctul de origine al vectorului desenat este la jumătatea lățimii, și la un sfert de marginea de jos, iar vârful este tot la jumătatea lățimii și la un sfert de marginea de sus. Așadar linia desenată va fi verticală, va fi jumătate cât lungimea appletului în pagină și va fi situată la mijlocul lățimii. Pentru a desena vârful de săgeată, aleg două puncte, vârfStânga și vârfDreapta la o distanță de 10 pixeli la stânga (respectiv dreapta) și 10 pixeli mai jos față de vârful vectorului.
Pentru a marca modulul vectorului, folosesc două obiecte din clasa CubicCurve, care cer pentru inițializare un punct de origine, două puncte intermediare care deformează curba și un punct destinație. Cele doua obiecte, semiacolada1 și semiacolada2 au ca puncte de plecare originea și vârful vectorului, iar punctul terminus este comun pentru amândouă, un punct aflat la mijlocul segmentului și mai spre dreapta cu 15 pixeli. Punctele intermediare sunt alese astfel încât să formeze două curbe compuse cu aspect de semiacoladă.
Mai jos se află un screenshot cu appletul în funcțiune:
Figura 3.6 – Appletul modulului unui vector
Conținutul appletului "TipuriVectori" este asemănător. Folosește aceeași funcție dormi(), aceeași idee cu câmpul stadiu care este incrementat și cu un cadru care este desenat în funcție de valoarea variabilei stadiu și este lăsat pe ecran 2 secunde. Singura diferență ar fi ca în loc să avem un singur vector, și deci o singură origine și un singur vârf, va trebui să recalculăm pozițiile acestor puncte pentru că trebuie să deplasăm segmente, pentru a arăta diferența dintre vectorii liberi, alunecători și ficși.
Mai jos este un screenshot al acestui applet:
,
Figura 3.7 – Appletul vectorilor liberi
Appletul "SumaVectori", care arată însumarea vectorilor folosind Metoda Triunghiului prin mișcarea unei bile de-a lungul a două trasee, este diferit de appleturile de mai sus prin faptul că nu se bazează atât de mult pe incrementarea unei valori, ci și pe incrementarea poziției bilei și a timpului foarte scăzut de "înghețare" a threadului (15 milisecunde).
Mai jos este prezentat conținutul acestui program:
public void paint(Graphics g){
Graphics2D g2 = (Graphics2D) g;
g2.draw(vector1);
g2.drawLine((int)varf1.x, (int)varf1.y, (int)varfStanga1.x,
(int)varfStanga1.y);
g2.drawLine((int)varf1.x, (int)varf1.y, (int)varfDreapta1.x,
(int)varfDreapta1.y);
g2.draw(vector2);
g2.drawLine((int)varf2.x, (int)varf2.y, (int)varfStanga2.x,
(int)varfStanga2.y);
g2.drawLine((int)varf2.x, (int)varf2.y, (int)varfDreapta2.x,
(int)varfDreapta2.y);
g2.setColor(Color.red);
g2.fillOval(xBila, yBila, 16, 16);
if((xBila+8<(int)varf1.x)&&(stadiu == 0)&&(continua)){
xBila++;
dormi(15);
}
else if((yBila+8>(int)varf2.y)&&(stadiu == 0)&&
(continua)){
yBila–;
dormi(15);
}
else if((stadiu == 0)&&(continua)){
stadiu++;
xBila = latime/10-8;
yBila = (inaltime*9)/10-8;
} if((xBila+8<(int)varf2.x)&&(yBila+8>(int)varf2.y)&&(stadiu==
1)&&(continua)){
xBila++;
yBila–;
g2.setColor(Color.blue);
g2.drawLine((int)origine1.x, (int)origine1.y,
(int)varf2.x, (int)varf2.y);
g2.drawLine((int)varf2.x, (int)varf2.y, (int)varf2.x-10,
(int)varf2.y+15);
g2.drawLine((int)varf2.x, (int)varf2.y, (int)varf2.x-15,
(int)varf2.y+10);
dormi(15);
}
else if((stadiu == 1)&&(continua)){
stadiu++;
repaint();
}
if ((stadiu == 2)&&(continua)){
g2.setColor(Color.blue);
g2.drawLine((int)origine1.x, (int)origine1.y,
(int)varf2.x, (int)varf2.y);
g2.drawLine((int)varf2.x, (int)varf2.y, (int)varf2.x-10,
(int)varf2.y+15);
g2.drawLine((int)varf2.x, (int)varf2.y, (int)varf2.x-15,
(int)varf2.y+10);
stadiu = 0;
xBila = latime/10-8;
yBila = (inaltime*9)/10-8;
dormi(2000);
}
}
Deși pare mai complicat la prima vedere, ideea este simplă: mai întâi, cand câmpul stadiu are valoarea 0, desenăm cei doi vectori de însumat și poziționăm originea bilei cu 8 pixeli mai în stânga și mai sus decât originea primului vector, iar bila va avea o rază de 16 pixeli. Cât timp coordonata x + 8 va fi mai mică decât coordonata x a vârfului primului vector, vom incrementa valoarea x a bilei, apoi vom "îngheța" threadul appletului pentru 15 milisecunde. În acest fel se produce iluzia deplasării bilei spre dreapta de-a lungul primului vector. Cand am ajuns cu 8 pixeli în stânga vârfului primului vector, incrementăm valoarea câmpului stadiu.
Când câmpul stadiu are valoarea 1, desenăm cei doi vectori de însumat și poziționăm originea bilei cu 8 pixeli mai în stânga și mai sus decât originea celui de-al doilea vector. Cât timp coordonata y + 8 este mai mare decât coordonata y a vârfului celui de-al doilea vector (să nu uităm ca atunci când mergem în sus, coordonata y scade), decrementăm valoarea y a bilei și vom apela funcția dormi() pentru 15 milisecunde. Când am ajuns cu 8 pixeli deasupra vârfului celui de-al doilea vector, incrementăm valoarea câmpului stadiu.
Când câmpul stadiu are valoarea 2, desenăm cei doi vectori de însumat, dar și vectorul sumă, care are originea în originea primului vector și vârful în vârful celui de-al doilea vector. Desenăm apoi bila cu originea cu 8 pixeli în stânga și 8 pixeli mai sus decât originea vectorului sumă. Cât timp coordonata x + 8 a bilei este mai mică decît coordonata x a vârfului și coordonata y + 8 este mai mare decât coordonata y a vârfului vectorului sumă, incrementam valoarea coordonatei x și decrementăm valoarea coordonatei y. Când am ajuns cu centrul bilei în vârful vectorului sumă, apelăm funcția dormi() pentru 2, astfel încât să se facă diferența între două succesiuni de secvențe. Apoi reinițializăm valoarea câmpului stadiu cu 0, repetând primul pas.
Se observă că pentru ușurința calculului, cei doi vectori de însumat au fost așezați perpedicular și s-a ales o lungime egală pentru amândoi. În acest fel, știm că vectorul sumă va fi pe o diagonală de 45o. Deplasarea bilei este ușor de calculat, pentru că se va mișca mai întâi orizontal, apoi vertical și în cele din urmă oblic.
La fel ca la celelalte două appleturi, există un eveniment de tip MousEvent care schimbă valoarea variabilei booleene continua, pornind și oprind appletul.
Mai jos este un screenshot al appletului "SumaVectori":
Figura 3.8 – Appletul de calcul a sumei a doi vectori
Secvența de cod comună tuturor appleturilor folosite în site responsabilă cu pornirea și oprirea cadrelor este următoarea:
public void mouseClicked(MouseEvent event){
if(continua)
continua = false;
else
continua = true;
repaint();
}
Pentru a ne folosi de evenimentele generate de mouse, trebuie ca appletul să implementeze interfața MouseListener. Aceasta conține metode pentru tratarea acțiunilor mouse-ului, cum ar fi mouseEntered, mouse Exited, mousePressed, mouseReleased sau mouseClicked. Este important de remarcat că un click înseamnă producerea altor două evenimente: apăsarea butonului de la mouse (mousePressed) și eliberarea lui în spațiul ocupat de applet (mouseReleased). Se poate așadar apăsa butonul și elibera, dar fără să se facă click. Pentru ca appletul să "asculte" evenimentele generate de mouse, trebuie ca obiectul instanțiat să fie înregistrat ca listener, cu ajutorul metodei statice addMouseListener(this);. Apelarea aceastei funcții se va face în metoda init(), asigurându-se astfel că va "asculta" evenimentele încă de la bun început.
Concluzii
Site-ul de față este un produs software modern, care folosește tehnologii gratuite, eficiente și moderne. Pe lângă ponțialul economic evident, poate deveni o unealtă importantă în procesul de învățământ, ajutând la fixarea unor cunoștințe sau făcând mai interesantă materia, cu ajutorul unor animații sau jocuri.
Spre deosebire de programele Desktop, la un proiect web accesul la informație este deosebit de simplu, utilizatorul având nevoie doar de o conexiune la internet și în cazul de față și de Mașina Virtuală Java (JVM), necesară pentru executarea appleturilor. Dar o mare parte a populației are acces la internet, dacă nu de acasă cel puțin de la școală sau internet café, iar instrumentele software necesare sunt ușor de procurat și instalat. Depinde numai de noi să rezolvăm anumite probleme ale societății oferind informațiile necesare.
Ca orice produs software, i se pot aduce continuu îmbunătățiri și elemente noi. De exemplu, ar fi foarte util pentru un volum mare de date să existe posibilitatea de căutare a unor informații în site. Dar pentru acest lucru trebuie implementat un mecanism care să înlocuiască unele caractere (a, i, s, t) cu diacritice și codul lor HTML (de exemplu cu codul ã pentru caracterul ă). O altă îmbunătățire importantă ar fi modificarea editorului de texte din secțiunea de administrare, astfel încât să deschidă un marcaj HTML la un click, și apoi să îl închidă mai târziu cu alt click pe același buton.
Un applet care ar ușura mult adăugarea de lecții noi ar putea primi ca parametri niște locații sau nume de imagini și apoi să le afișeze pe ecran în ordinea primită, la un anumit interval de timp, primit deasemenea ca parametru al appletului. Acest lucru ar elimina necesitatea unui programator care să creeze noi appleturi și apoi să le compileze, sau ar putea cel puțin să îi reducă semnificativ munca.
Se observă ușor un alt avantaj al aplicației web față de un program Desktop: este întotdeauna versiunea la zi, nu trebuie reinstalată sau descărcată.
Spre deosebire de alte tehnologii web, PhP-ul asigură o instalare ușoară pe un server nou, sau modificări facile când este cazul. Fișierele nu trebuie compilate în nici un fel (în afară de appleturile java, bineînțeles), ci doar copiate în directorul de web al serverului Apache. Nu este nevoie decât de un editor de texte și de un program care să efectueze transferul de date între calculatorul dezvoltatorului și server.
Bibliografie
Andrei Baranga "Programare WEB utilizând Java", Editura Albastră, 2007
Baron Schwartz , Peter Zaitsev, Vadim Tkachenko , Jeremy Zawodny , Arjen Lentz , Derek J. Balling “High Performance MySQL: Optimization, Backups, Replication, and More”, 3rd Edition, O'Reilly Media, 2008
Bruce Eckel "Thinking in Java", 4th edition, Prentice Hall, 2006
Eugenia Lucia Stamate “Crearea si publicarea unui site web. Limbajul HTML si elemente de web design”, Paralela 45, 2005
Horia Georgescu "Introducere în universul Java", Editura Tehnică, 2002
Jon Duckett “HTML and CSS: Design and Build Websites”, Wiley, 2011
Joshua Bloch “Effective Java”, 2nd Edition, Addison-Wesley, 2008
Larry Ullman “PHP și MySQL pentru site-uri web dinamice”, Editura Teora, 2014
Luke Welling, Laura Thomson – "PHP and MySQL WebDevelopment (4th Edition) ", Sams Publishing, 2008
Kevin Tatroe, Peter MacIntyre , Rasmus Lerdorf “Programming PHP”, 3rd Edition, O'Reilly Media, 2013
Marijn Haverbeke “Eloquent JavaScript: A Modern Introduction to Programming” 2nd Edition, No Starch Press, 2014
Paul DuBois “MySQL”, 5th Edition, Developer's Library, 2013
Rasmus Lerdorf, Kevin Tatroe – "Programming PHP", O’Reilly, 2007
Stuart Reges, Marty Stepp “Building Java Programs: A Back to Basics Approach”, 2nd Edition, Addison-Wesley, 2010
Traian Anghel – "Dezvoltarea aplicațiilor WEB folosind XHTML, PHP și MySQL", Polirom, 2005
Traian Anghel – "Programarea în PHP. Ghid practic", Polirom, 2005
W. Jason Gilmore – "Beginning PHP and MySQL 5: from noviceto professional, Third Edition", Apress, 2008
http://www.w3schools.com
http://www.php.net
http://java.sun.com
http://www.mysql.com
http://www.apache.org
Bibliografie
Andrei Baranga "Programare WEB utilizând Java", Editura Albastră, 2007
Baron Schwartz , Peter Zaitsev, Vadim Tkachenko , Jeremy Zawodny , Arjen Lentz , Derek J. Balling “High Performance MySQL: Optimization, Backups, Replication, and More”, 3rd Edition, O'Reilly Media, 2008
Bruce Eckel "Thinking in Java", 4th edition, Prentice Hall, 2006
Eugenia Lucia Stamate “Crearea si publicarea unui site web. Limbajul HTML si elemente de web design”, Paralela 45, 2005
Horia Georgescu "Introducere în universul Java", Editura Tehnică, 2002
Jon Duckett “HTML and CSS: Design and Build Websites”, Wiley, 2011
Joshua Bloch “Effective Java”, 2nd Edition, Addison-Wesley, 2008
Larry Ullman “PHP și MySQL pentru site-uri web dinamice”, Editura Teora, 2014
Luke Welling, Laura Thomson – "PHP and MySQL WebDevelopment (4th Edition) ", Sams Publishing, 2008
Kevin Tatroe, Peter MacIntyre , Rasmus Lerdorf “Programming PHP”, 3rd Edition, O'Reilly Media, 2013
Marijn Haverbeke “Eloquent JavaScript: A Modern Introduction to Programming” 2nd Edition, No Starch Press, 2014
Paul DuBois “MySQL”, 5th Edition, Developer's Library, 2013
Rasmus Lerdorf, Kevin Tatroe – "Programming PHP", O’Reilly, 2007
Stuart Reges, Marty Stepp “Building Java Programs: A Back to Basics Approach”, 2nd Edition, Addison-Wesley, 2010
Traian Anghel – "Dezvoltarea aplicațiilor WEB folosind XHTML, PHP și MySQL", Polirom, 2005
Traian Anghel – "Programarea în PHP. Ghid practic", Polirom, 2005
W. Jason Gilmore – "Beginning PHP and MySQL 5: from noviceto professional, Third Edition", Apress, 2008
http://www.w3schools.com
http://www.php.net
http://java.sun.com
http://www.mysql.com
http://www.apache.org
Copyright Notice
© Licențiada.org respectă drepturile de proprietate intelectuală și așteaptă ca toți utilizatorii să facă același lucru. Dacă consideri că un conținut de pe site încalcă drepturile tale de autor, te rugăm să trimiți o notificare DMCA.
Acest articol: Php, Mysql Si Java Utilizate Pentru O Aplicatie Didactica (ID: 160233)
Dacă considerați că acest conținut vă încalcă drepturile de autor, vă rugăm să depuneți o cerere pe pagina noastră Copyright Takedown.
