Sunteți pe pagina 1din 14

Programare Java

Curs – 8

FOLOSIREA IMAGINILOR , ANIMATIEI SI SUNETULUI

Animatia in Java se realizeaza prin folosirea AWT - mai precis a unor componente ale
sale . Putem crea animatie si folosind instructiunile de desenare invatate in cursurile
anterioare dar la acest moment vom trece la folosirea unor imagini deja create - sub
forma de fisiere grafice cu diverse extensii .

Avem de facut practic doi pasi conceptuali pentru a realiza o animatie :

- desenarea
- comandarea sistemului de ferestre pentru a afisa desenul realizat anterior

Daca repetam acesti pasi se reuseste crearea teoretica a unei miscari .

DESENAREA SI REIMPROSPATAREA DESENULUI

In mod normal metoda paint() care deseneaza fereastra unui applet este apelata
automat de Java ; pentru un control mai bun al afisarii avem si posibilitatea de a apela
chiar noi redesenarea prin metoda repaint() .
Deci pentru a modifica o fereastra applet trebuie sa desenam ceva apoi sa apelam
repaint() pentru a vedea rezultatul .
Operatiile acestea de desenare nu vor fi create in metoda paint() deoarece s-ar executa
toate direct de la inceputul afisarii ferestrei .

PORNIREA SI OPRIREA EXECUTIEI APPLETULUI

Pentru aceste lucruri exista metodele start() si stop() ale clasei Applet . Aceste metode
sunt vide si va trebui sa le suprascriem atunci cand incepem sau finalizam programul .
Desi la desenarea unor lucruri simple aceste metode nu erau necesare , pentru
animatie situatia se schimba .

CONTROLUL PRIN FIRE DE EXECUTIE

Firele de executie , numite si thread-uri , sunt un lucru foarte important pentru


animatie - ele dau posibilitatea tratarii in paralel de Java a mai multor activitati .
Un fir de executie este o parte a unui program care este configurata sa ruleze in timp
ce restul programului executa altceva .
Prin separarea ainmatiei pe un fir de executie restul aplicatiei poate rula altceva .

Odata cu utilizarea firelor de executie trebuie sa facem unele modificari in fisierul


nostru clasa :
- adaugam la declarare "implements Runnable"
- se creaza un obiect Thread in care pastram firul
- suprascriem metoda start() a applet-ului pentru a crea si lansa firul de executie
- suprascriem metoda stop() pentru a seta firul care se executa la null
- cream metoda run() care contine instructiunile ce fac appletul sa ruleze
continuu animatia

Runnable este o interfata ; ea reprezinta sistemul prin care o clasa poate mosteni
metode pe care altfel nu le-ar fi mostenit de la superclasele sale . Aceste metode pot fi
astfel disponibile oricarei metode care are nevoie de ele . Runnable contine o metode
run() de care avem nevoie pentru a porni un fir de executie si de aceea trebuie
implementata aceasta interfata in cazul nostru .
Thread este o clasa din pachetul java.lang - asa incat nu avem nevoie de o instructiune
import pentru a o utiliza . De obicei obiectul de tip Thread se creaza in metoda start()
si va avea o valoare null pana la crearea efectiva a obiectului - creare care se face tot
in metoda start() . Pentru a rula un fir de executie creat avem nevoie de metoda sa
start() :

obiect_thread.start();

Apelarea acestei metode duce la apelarea metodei run() - mostenita prin interfata
Runnable .
Metoda run() este cea mai importanta a appletului devenit fir de executie . Ea este
folosita pentru a controla secventele animatiei prin stabilirea tuturor operatiilor legate
de desenare si de modificarile intre secventele de animatie .
Dupa definirea in metoda run() a comportamentului necesar firului de executie trebuie
sa definim si metoda stop() - pentru oprirea appletului .
Acest lucru - oprirea - il putem face prin atribuirea valorii null obiectului Thread ; de
fapt acest lucru nu duce la oprirea automata a executie firului dar problema se rezolva
prin metoda run() care va fi creata astfel incat sa permita rularea doar daca obiectul
Thread nu este null .

Pentru a clarifica problematica firelor de executie vom prezenta un applet care creaza
un ceas - o animatie simpla - cu actualizari constante .

In cadrul appletului vom folosi un ciclu while care ar putea fi periculos in conditii
normale : acest ciclu ar monopoliza resursele si practic nu am vedea nimic pe ecran
deoarece Java ar astepta la infinit oprirea ciclului .
Appletul va defini un anumit font pentru afisare si un obiect de tip Date care pastreaza
data curenta . Metodele start() si stop() au rolul de a porni si respectiv opri firul de
executie .
Metoda run() este cea mai importanta - cea care realizeaza de fapt toata animatia .
Aici vom avea si buclucasul ciclu while de mai sus ; primul lucru facut in ciclu este
apelarea repaint() pentru redesenarea ferestrei . Tot aici vom intalni si o noua metoda :
sleep() . Aceasta metoda a clasei Thread determina o pauza in executie . Daca nu s-ar
folosi aceasta metoda appletul ar rula la viteza maxima , lucru care poate sa nu fie
conform cu dorinta programatorului . Instructiunile try si catch vor apare aici pentru
tratarea erorilor si pentru moment le putem ignora .
Metoda paint() a appletului creaza o noua instanta a clasei Date - pentru folosirea
acestei clase trebuie sa o importam , ea fiind inclusa in java.util . De asemenea apare
si metoda toString() a clasei Date , necesara pentru afisarea ca sir a datei si orei . La
fiecare apelare a metodei paint() vom avea astfel un nou obiect Date care va tine ora si
data curente .
Sa vedem in continuare codul sursa al appletului descris anterior :

import java.awt.*;
import java.util.*;

public class CeasDigital extends java.applet.Applet implements Runnable {


Font fontul=new Font ("TimesRoman",Font.BOLD,24);
Date data;
Thread executabil;

public void start() {


if (executabil==null) {
executabil=new Thread(this);
executabil.start();
}
}

public void stop() {


if (executabil!=null) {
executabil=null;
}
}

public void run() {


Thread firExecutie=Thread.currentThread();
while (executabil==firExecutie) {
repaint();
try{
Thread.sleep(1000);
} catch (InterruptedException e) {}
}
}

public void paint(Graphics ecran) {


data=new Date();
ecran.setFont(fontul);
ecran.drawString(""+data.toString(),10,50);
}
}

EFECTUL DE FLICKERING AL ANIMATIE

Acest efect - cu denumirea in limba engleza , traducerea fiind palpaire - este cauzat de
modul de reimprospatare a fiecarui caddru de animatie . Dupa cum am mai spus :
apelul metodei repaint() duce automat la un apel al metodei repaint() .De fapt mai
exista inca o metoda intermadiara pe care Java o foloseste pentru a redesena ecranul
aplicatiei ; metoda update() - care sterge ecranul prin umplerea cu culoarea de fundal a
ferestrei appletului si abia apoi se apeleaza paint() .
Din cauza umplerii ecranului efectuata de metoda update() apare si acest efect de
flickering .
In practica exista doua moduri de a evita acest eveniment suparator :

- suprascrierea metodei update() astfel incat aceasta sa nu mai stearga ecranul


sau sa nu stearga partile de fereastra care nu se vor modifica .
- suprascrierea metodelor paint() si update() impreuna cu folosirea dublei
memorari ( double buffering ).

Vom prezenta mai intai prima metoda , suprascrierea lui update() - aceasta fiind cea
mai simpla ; in multe cazuri insa ea nu este aplicabila la programe mai complexe si va
trebui utilizata cea de a doua tehnica de mai sus .

SUPRASCRIEREA METODEI UPDATE()

Implicit aceasta metoda are urmatorul cod sursa :

public void update(Graphics g) {


g.setColor(getBackground());
g.fillRect(0,0,size().width,size().height);
g.setColor(getForeground());
paint(g);
}

Putem alege o versiune de rezolvare a problemei palpairii prin anularea totala a


stergerii ecranului . Aceasta solutie nu poate fi aplicata pe scara larga dar in cazurile in
care se poate aplica este cea mai simpla solutie .
Sa luam ca exemplu codul sursa de mai jos :

import java.awt.*;

public class AlternareCulori extends java.applet.Applet implements Runnable {


Font f=new Font("TimesRoman",Font.BOLD,50);
Color culori[]=new Color[50];
Thread executabil;

public void start() {


if (executabil==null) {
executabil=new Thread(this);
executabil.start();
}
}

public void stop() {


executabil=null;
}
public void run() {
float c=0;
for (int i=0;i<culori.length;i++) {
culori[i]=Color.getHSBColor(c,(float)1.0,(float)1.0);
c+=.02;
}
int i=0;
Thread firExecutie=Thread.currentThread();
while (executabil==firExecutie) {
setForeground(culori[i]);
repaint();
i++;
try {
Thread.sleep(200);
} catch (InterruptedException e) {}
if (i==culori.length) i=0;
}
}

public void paint(Graphics ecran) {


ecran.setFont(f);
ecran.drawString("Priviti textul !",20,50);
}
}

Pentru a intelege cat mai bine appletul sa incercam un comentariu aproape linie cu
linie al codului sursa :

Linia 5 defineste o variabila "culori" care desemneaza un tablou cu 50 de elemente .


La pornirea appletului metoda run() umple acest tablou cu obiecte Color . Crearea
tabloului de culori poate fi realizata si in metoda paint() dar nu ar avea logica , el
creandu-se astfel la fiecare apelare a metodei paint() . In realitate este de ajuns crearea
sa o singura data , astfel incat e mai bine sa cream tabloul de culori in metoda init() .
Pentru a crea obiecte de culori diferite s-a folosit metoda getHSBColor() ; aceasta este
parte a clasei Color si creaza un obiect Color pe baza combinatiei intre nuanta ( hue ) ,
saturatie ( saturation ) si luminozitate ( brightness ) . Prin incrementarea valorii
nuantei putem astfel crea un obiect cu o culoare noua - avantajul crearii in acest fel a
obiectelor Color fiind rapiditatea mai mare a limbajului la implementarea acestei
metode .
Pentru a se obtine animatia - adica modificarea continua a culorii textului afisat de
applet - se utilizeaza un ciclu care strabate tabloul de culori stabilind pe rand fiecare
culoare din tablou drept culoare de desenare si apoi reapeleaza metoda repaint() .
Datorita conditiei din ciclul while procesul descris mai sus se va relua la infinit pana
la oprirea fortata a appletului .

La rularea appletului - e adevarat ca si in functie de hardware-ul disponibil - apare


efectul de flicker ; acesta se datoreaza aici faptului ca la fiecare desenare a sirului cu o
noua culoare exista si o operatie de stergere totala a ecranului .
Acum vom opera modificarea metodei update() pentru a reduce acest efect suparator .
Vom inlatura din metoda partea responsabila cu stergerea ecranului , obtinand o
metoda update() cu urmatorul cod sursa :

public void update(Graphics ecran) {


paint(ecran);
}

Cea de a doua metoda de evitare a flickerului este dubla memorare . Aceasta consta in
procesul de a desena un cadru intreg de animatie intr-o zona invizibila inainte de a-l
copia in zona vizibila de pe ecran . Zona invizibila in care lucram se numeste buffer
( sau memorie tampon ) .

Prin aceasta tehnica se creaza practic inca o suprafata de desenare , se fac toate
operatiunile de desenare pe ea dupa care se deseneaza dintr-o data intreaga suprafata
in fereastra principala a appletului - toate acestea in loc sa se deseneze direct in
fereastra appletului , pe rand fiecare element .
Tehnica dublei memorari este destulde performanta , ea reusind sa elimine practic
flickerul dar aduce dezavantajul unei folosiri intensive a memoriei sistemului de
calcul . Pentru a crea un applet bazat pe aceasta tehnica trebuie sa avem o imagine pe
care o desenam in buffer si un context grafic pentru acea imagine . Acestea vor simula
efectul desenarii pe suprafata appletului : contextul grafic ( de fapt o instanta a clasei
Graphics ) care ofera metodele de desen si obiectul Image , care memoreaza ceea ce
se va desena .
Ca sa reusim implementarea corect a tehnicii de mai sus trebuie sa parcurgem patru
etape .
Mai intai imaginea invizibila si contextul grafic trebuie stocate in variabile de instanta
care vor putea apoi fi trimise metodei paint() . Acest lucru se face sintactic la modul
urmator :

Image imagineInvizibila;
Graphics invizibil;

In al doilea rand pe parcursul initializarii appletului vom crea obiecte Image si


Graphics pe care le vom atribui acestor variabile . Metoda createImage() returneaza o
instanta a clasei Image , pe care apoi o putem transmite metodei getGraphics() pentru
a obtine un nou context pentru imaginea respectiva :

imagineInvizibila = createImage(size().width , size().height);


invizibil=imagineInvizibila.getGraphics();

In acest moment , ori de cate ori va trebui sa desenam pe ecran - cu metoda paint() -
vom desena in contextul grafic invizibil ; ca exemplu , pentru a desena o imagine
numita img la pozitia 100,100 folosim linia de cod :

invizibil.drawImage(img,100,100,this);

In ceea ce priveste cuvantul cheie this folosit aici nu va faceti probleme pentru ceea ce
reprezinta - va fi prezentat mai detaliat in paginile urmatoare .
Ultima etapa , dupa ce s-a terminat de desenat totul in contextul invizibil ,
instructiunea urmatoare copiaza zona tampon invizibila pe ecran :

ecran.drawImage(imagineInvizibila,0,0,this);

Pentru a elimina si umplerea ecranului cu culoarea de fond ( operatia default a


metodei update() ) este indicat sa suprascriem si metoda update() la modul urmator :

public void update(Graphics g) {


paint(g);
}

Pentru a realiza in practica implementarea dublei memorari vom prezenta un exemplu


de applet care deseneaza si misca un cer intre doua patrate colorate diferit - appletul se
numeste "Dame" , dupa asemanarea rezultatului vizual cu o piesa din acest joc :

import java.awt.*;

public class Dame extends java.applet.Applet implements Runnable {


Thread executabil;
int pozX=5;
int deplasareX=4;
Image imgInvizibila;
Graphics invizibil;

public void init() {


imgInvizibila=createImage(size().width,size().height);
invizibil=imgInvizibila.getGraphics();
}

public void start() {


if (executabil==null) {
executabil=new Thread(this);
executabil.start();
}
}

public void stop() {


executabil=null;
}

public void run() {


Thread firExecutie=Thread.currentThread();
while (executabil==firExecutie) {
pozX+=deplasareX;
if ((pozX>105)|(pozX<5)) {
deplasareX*=-1; }
repaint();
try {
Thread.sleep(100);
} catch (InterruptedException e) { }
}
}

public void update(Graphics ecran) {


paint(ecran);
}

public void paint(Graphics ecran) {

invizibil.setColor(Color.black);
invizibil.fillRect(0,0,100,100);
invizibil.setColor(Color.white);
invizibil.fillRect(100,0,100,100);

invizibil.setColor(Color.red);
invizibil.fillOval(pozX,5,90,90);
ecran.drawImage(imgInvizibila,0,0,this);
}

public void destroy() {


invizibil.dispose();
}
}

Sa comentam putin programul de mai sus :

- variabila pozX este folosita pentru a muta cercul dintr-un loc in altul , ea
pastrand coordonatele unde se afla piesa la un moment dat . Valoarea variabilei
se modifica continuu in metoda run() .
- primul pas pentru dubla memorare consta in crearea unui obiect Image care sa
pastreze cadrul invizibil pana cand acesta este complet si a unui obiect
Graphics care sa permita desenarea in aceasta zona invizibila . Acest lucru il
fac liniile :

Image imgInvizibila;
Graphics invizibil;

- celor doua variabile amintite in randurile precedente li se atribuie obiecte


create in metoda init() a appletului :

public void init() {


imgInvizibila=createImage(size().width,size().height);
invizibil=imgInvizibila.getGraphics();
}
- metoda paint() este modificata pentru a scrie zona tampon invizibila in locul
obiectului principal Graphics ; practic , doar ultima linie a metodei paint()
afiseaza in fereastra appletului . Aceasta instructiune afiseaza cadrul de
animatie complet la coordonatele 0,0 . Deoarece obiectul imgInvizibil a fost
creat de aceeasi dimensiune ca zona de ecran el va acoperi complet fereastra
appletului .

DISTRUGEREA CONTEXTELOR GRAPHICS

Ati remarcat in finalul exemplului de mai sus o metoda pe care nu am detaliat-o :

public void destroy() {


invizibil.dispose();
}

Pe scurt , aceasta metoda distruge obiectul invizibil .

Sa detaliem totusi putin problema !


Chiar daca recuperatorul de memorie Java functioneaza automat si distruge obiectele
atunci cand nu mai este nevoie de ele in program acest lucru nu este valabil si pentru
obiectele Java care sunt create pentru a gestiona memoriile tampon din afara ecranului
.Obiectele ramase orfane si nefolosite ocupa astfel memorie si inrautatesc
performantele Java ; pentru a rezolva acest neajuns ar trebui sa folosim explicit
metoda dispose() a clasei Graphics pentru a distruge aceste obiecte atunci cand am
terminat treaba cu ele .
Locul cel mai potrivit pentru a face acest lucru este metoda destroy() a appletului -
metoda introdusa sporadic pe parcursul unui curs anterior .
Metoda destroy() este apelata fara argumente , dupa modelul sintactic de mai jos :

public void destroy() {


graficaTampon.dispose();
}

INCARCAREA SI FOLOSIREA IMAGINILOR

Lucrul cu imagini in Java se realizeaza in principal prin intermediul clasei Image ,


inclusa in pachetul java.awt . Cand lucram cu un applet vom folosi pentru incarcare si
afisare a imaginilor metode ale claselor Applet si Graphics .

Pentru a afisa o imagine in appletul nostru trebuie intai sa o incarca in program din
World Wide Web . Imaginile se vor pastra in fisiere grafice separate de fisierele sursa
si compilate Java , asa ca trebuie specificat clar locul in care le putem gasi . Cand
folosim clasa Image fisierele grafice pe care le utilizam trebuie sa fie de tip .GIF sau
.JPG .

O adresa web este reprezentata printr-un obiect URL . Clasa URL face parte din
pachetul java.net care va trebui deci importat pentru a-l pune la dispozitia programului
nostru .
Obiectul URL este creat prin transmiterea adresei paginii web ca argument pentru
metoda constructor a clasei URL , ca in exemplul de mai jos :

URL u=new URL (http://www.site.com/imagini/imagine1.gif);

Dupa ce am creat obiectul URL il putem folosi pentru a crea un obiect Image care
reprezinta propriu-zis fisierul grafic .
Pentru a incarca o imagine noua intr-un obiect Image clasa Applet contine o metoda
numita getImage() , care poate fi folosita in doua moduri :

- cu un singur argument - obiect URL , localizandu-se imaginea de la adresa


exacta
- cu doua argumente : adresa URL de baza ca obiect URL si un sir care
reprezinta calea relativa sau denumirea fisierului care contine imaginea .

Ultima metoda este putin mai complicata dar ofera o mai mare flexibilitate .
Clasa Applet poseda doua metode care pot fi folosite pentru a crea o adresa URL de
baza fara a folosi in program o adresa fixa explicita ( lucru care ar face ca la orice
modificare a adresei necesitate de applet sa fie necesara si o recompilare a appletului )
:

- metoda getDocumentbase() returneaza obiectul URL care reprezinta directorul


ce contine pagina web care prezinta appletul
- metoda getCodeBase() care returneaza obiectul URL care reprezinta directorul
unde se afla fisierul cu clasa principala a appletului .

Calea relativa catre o resursa se foloseste ca al doilea argument pentru metoda


getImage() si se modifica in functie de ce s-a folosit in primul argument .
Sa luam un exemplu cu o pagina web cu adresa : http://www.site.com/index.html ,
care incarca o imagine din acelasi director , imagine numita imagine1.gif . Pentru a
folosi aceasta imagine in appletul nostru ne trebuie o instructiune de genul :

Image imagine=getImage(getDocumentBase(),"imagine1.gif");

Practic , folosirea metodelor getDocumentBase() si getCodeBase() depinde de locul in


care avem fisierele grafice : in subdirectoarele appletului Java sau in subdirectoarele
paginii web care apeleaza appletul . Datorita folosirii acestor metode putem reloca
pagina web cu tot cu applet fara a aparea probleme legate de eventuala necesitate de a
recompila clasele Java .

DESENAREA IMAGINILOR

Dupa ce am pus o imagine intr-un obiect Image aceasta poat fi afisata in applet cu
metoda drawImage() a clasei Graphics . Pentru a afisa o imagine la dimensiunile reale
vom apela metoda cu patru argumente :

- obiectul Image pentru afisare


- coordonatele x si y ale coltului din stanga sus ale locului unde vrem sa afisam
imaginea
- cuvantul cheie this
Daca fisierul grafic trebuie afisat la o alta scara decat originalul trebuie sa folosim
sase argumente pentru metoda drawImage() :

- obiectul Image de afisat


- coordonatele x si y ale imaginii
- latime imaginii in pixeli
- inaltimea imaginii in pixeli
- cuvantul cheie this

Scalarea imaginii are efect doar pentru afisarea in applet , obiectul propriu-zis nefiind
alterat de aceste apeluri de metoda .

Pentru a afla dimensiunile unei imagini afisate avem la dipsozitie metodele


getHeight() si getWidth() care returneaza inaltimea si respectiv latimea imaginii
afisate .

Ultiimul argument al metodei drawImage este cuvantul cheie this - element folosit in
general intr-un obiect pentru a face o referinta la el insusi .
Folosirea sa in acest context este necesara pentru a identifica un applet care poate
urmari incarcarea imaginii de pe web . Incarcarea imaginii este urmarita prin
intermediul unei interfete ImageObserver . Clasele care implementeaza aceasta
interfata - printre care si Applet - pot observa gradul de incarcare al unei imagini .
Acest lucru poate fi folositor de exemplu pentru un program care sa afiseze altceva in
timpul incarcarii unor imagini ( procese care uneori pot dura destul de mult ) .

In continuare vom prezenta un exemplu de afisare a unor imagini la scara originala si


cu dimensiuni marite :

import java.awt.*;

public class Imagine extends java.applet.Applet {


Image poza;

public void init() {


poza=getImage(getCodeBase(),"poza1.gif");
}

public void paint(Graphics ecran) {


int latime=poza.getWidth(this);
int inaltime=poza.getHeight(this);
int xPoz=10;

setBackground(Color.pink);
ecran.drawImage(poza,10,10,latime,inaltime,this);
xPoz+=latime+5;
ecran.drawImage(poza,xPoz,10,latime*4,inaltime*4,this);
}
}
Appletul de mai sus presupune ca dispunem de un fisier grafic numit poza1.gif , pe
care dorim sa-l afisam mai intai la dimensiunile sale reale si apoi cu latime si
inaltimea de patru ori mai mari .
Variabila xPoz contine valoarea coordonatei x a locului unde se doreste inceperea
afisarii imaginii .

FOLOSIREA SUNETULUI

Clasa Applet are posibilitatea de a reda si sunet . De la versiunea 2 a limbajului Java


putem folosi fisiere audio in mai multe formate : AIFF , AU , MIDI si WAV .

Cea mai simpla metoda de incarcare si redare a unui sunet este prin utilizarea metodei
play() a clasei Applet . Aceasta metoda are doua forme de apelare :

- cu un argument - obiect URL , va incarca si reda fisierul audio de la adresa


servita ca argument
- cu doua argumente - a adresa URL de baza si o cale directoare . Primul
argument este de cele mai multe ori un apel al metodei getDocumentBase()
sau getCodeBase() .

Instructiunea de mai jos incarca si reda un fisier audio numit sunet.wav , aflat in
acelasi director cu appletul :

play(getCodeBase(),"sunet.wav");

Metoda play() incarca si reda sunetul cat mai repede posibil . In cazul in care fisierul
de sunet nu este disponibil la adresa servita metodei play() nu vom obtine nici un
mesaj de eroare - pur si simplu nu se va auzi nici un sunet !

Avem posibilitatea de a reda continuu un sunet , de a-l porni si a-l opri la dorinta .
Acesta lucru se poate face incarcand fisierul audio intr-un obiect AudioClip , folosind
metoda getAudioClip a acestuia . Clasa AudioClip este inclusa in pachetul java.awt .

Metoda getAudioClip() primeste unul sau doua argumente . Primul argument ( care
poate fi si unic ) este un obiect URL care identifica fisierul de sunet iar al doilea poate
fi o referinta la cale .
In exemplul de mai jos putem vedea cum se incarca un fisier audio - "sunet.wav" ,
aflat intr subdirectorul "audio" al appletului - intr-un obiect AudioClip :

AudioClip clip=getAudioClip(getCodeBase(),"audio/sunet.wav");

Metoda getAudioClip() poate fi apelata numai in cadrul unui applet . Pentru


incarcarea unui fisier audio intr-o aplicatie independenta Java trebuie sa folosim
metoda newAudioClip() a clasei Applet :

AudioClip clip=newAudioClip("audio/sunet.wav");
Odata creat obiectul AudioClip putem apela si metodele play() , stop() sau loop() ale
acestuia . Play() reda sunetul , stop() opreste redarea sunetului iar loop() provoaca
redarea continuu a fisierului audio .
Spre deosebire de apelarea simpla play() pentru un anumit fisier de sunet ( caz in care
inexistenta fisierului audio nu provoaca nici o eroare ) folosirea metodelor
getAudioClip() sau newAudioClip() poate duce la erori in cazul in care fisierul de
sunet indicat de argumente nu exista ; acest lucru se datoreaza faptului ca obiectul
AudioClip creat de noi va avea valoarea null , iar redarea unui obiect null produce o
eroare .

In cazul in care vrem sa redam mai multe sunete simultan nu exista nici o problema -
vom folosi mai multe fire de executie .
Trebuie mentionata si o problema - in cazul in care utilizam o redare continuua a unui
sunet in appletul nostru oprirea firului de executie al appletului nu va duce si la
oprirea automata a sunetului . In practica daca un utilizator va trece in alta pagina web
sunetul va continua sa se auda ! Rezolvarea acestei probleme se face prin utilizarea
metodei stop() pentru sunetul redat in acelasi timp cu oprirea firului de executie al
appletului .

In continuare avem un exemplu care reda continuu un sunet - sunet1.wav - si o data la


fiecare 5 secunde reda si fisierul sunet2.wav :

import java.awt.*;
import java.applet.*;

public class CicluAudio extends java.applet.Applet implements Runnable {

AudioClip sunetFundal;
AudioClip bip;
Thread executabil;

public void start() {


if (executabil==null) {
executabil=new Thread(this);
executabil.start();
}
}

public void stop() {


if (executabil!=null) {
if (sunetFundal!=null)
sunetFundal.stop();
executabil=null;
}
}

public void init() {


sunetFundal=getAudioClip(getCodeBase(),"sunet1.wav");
bip=getAudioClip(getCodeBase(),"sunet2.wav");
}

public void run() {


if (sunetFundal!=null) sunetFundal.loop();
Thread firExecutie=Thread.currentThread();
while (executabil==firExecutie) {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {}
if (bip!=null) bip.play();
}
}

public void paint(Graphics ecran) {


ecran.drawString("Se aude sunet !",50,50);
}
}

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