Programare Java
Programare Java
Curs 8FOLOSIREA IMAGINILOR , ANIMATIEI SI SUNETULUIAnimatia 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 animatiei 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 cadru de animatie . Dupa cum am mai spus : apelul metodei repaint() duce automat la un apel al metodei paint() .De fapt mai exista inca o metoda intermediara 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;i105)|(pozX