Curs 11 Java

15
Programare Java Curs – 11 TRATAREA EVENIMENTELOR DE TASTATURA Un astfel de eveniment apare ori de cate ori este apasata o tasta . Pentru ca un eveniment de tastatura sa fie receptionat de catre o componenta trebuie ca aceasta sa fie selectata , sau focalizata - focused . Pentru a indica explicit selectarea unei componente pentru a primi date de intrare putem apela metoda requestFocus() a componentei respective , ca in exemplul de mai jos care presupune ca avem un buton denumit "buton1" : buton1.requestFocus(); Putem selecta chiar intreaga fereastra Applet prin apelarea metodei sale requestFocus() . EVENIMENTELE keyDown si keyUp Metodele care asigura tratarea unui eveniment de tastatura sunt de urmatoarea factura : public boolean keyDown(Event evt, int tasta) { // ... } Valorile generate de evenimentele keyDown , care sunt transmise metodei ca argumentul tasta , sunt intregi care reprezinta valori Unicode ; pentru a putea sa le folosim drept caractere trebuie sa folosim o convertire : caracter=(char)tasta; In exemplul de mai jos avem o metoda care afiseaza exact tasta pe care am apasat , ca si caracter si ca valoare Unicode :

description

Curs 11 Java

Transcript of Curs 11 Java

Programare Java

Programare Java

Curs 11TRATAREA EVENIMENTELOR DE TASTATURAUn astfel de eveniment apare ori de cate ori este apasata o tasta . Pentru ca un eveniment de tastatura sa fie receptionat de catre o componenta trebuie ca aceasta sa fie selectata , sau focalizata - focused . Pentru a indica explicit selectarea unei componente pentru a primi date de intrare putem apela metoda requestFocus() a componentei respective , ca in exemplul de mai jos care presupune ca avem un buton denumit "buton1" :

buton1.requestFocus();

Putem selecta chiar intreaga fereastra Applet prin apelarea metodei sale requestFocus() .

EVENIMENTELE keyDown si keyUp

Metodele care asigura tratarea unui eveniment de tastatura sunt de urmatoarea factura :public boolean keyDown(Event evt, int tasta) {

// ...

}

Valorile generate de evenimentele keyDown , care sunt transmise metodei ca argumentul tasta , sunt intregi care reprezinta valori Unicode ; pentru a putea sa le folosim drept caractere trebuie sa folosim o convertire :

caracter=(char)tasta;

In exemplul de mai jos avem o metoda care afiseaza exact tasta pe care am apasat , ca si caracter si ca valoare Unicode :

public boolean keyDown(Event evt, int tasta) {

System.out.println("Valoare Unicode: "+tasta);

System.out.println("Caracter: "+(char)tasta);

return true;

}

Metoda inrudita keyUp() are o semnatura identica - exceptand bineinteles numele metodei .

TASTE PRESTABILITE

Clasa Event are un set de variabile de clasa care reprezinta unele taste nealfanumerice ca tastele functionale sau cele directionale . Daca interfata appletului nostru foloseste aceste taste putem testa folosirea lor in cadrul metodei keyDown() . Valorile acestor variabile de clasa sunt intregi , acest lucru fiind important mai ales pentru folosirea instructiunii switch in cadrul testarii acestor variabile . Mai jos este prezentat un tabel care arata variabilele de clasa amintite mai sus :Event.HOMEtasta HOME

Event.ENDtasta END

Event.PGUPtasta Page Up

Event.PGDNtasta Page Down

Event.UPsageata in sus

Event.DOWNsageata in jos

Event.LEFTsageata la stanga

Event.Rightsageata la dreapta

Event.F1tasta F1

Event.F2tasta F2

Event.F3tasta F3

Event.F4tasta F4

Event.F5tasta F5

Event.F6tasta F6

Event.F7tasta F7

Event.F8tasta F8

Event.F9tasta F9

Event.F10tasta F10

Event.F11tasta F11

Event.F12tasta F11

Pentru a exemplifica utilizarea evenimentelor de tastatura vom prezenta un scurt applet in cadrul carui vom tasta un caracter si apoi il vom misca cu ajutorul tastelor directionale ( sageti ) ; in orice moment putem schimba caracterul prin simpla tastare a unui alt caracter .

Pentru realizarea acestei operatii folosim de fapt doar trei metode : init() , keyDown() si paint() .

Metoda init() va stabili culoarea de fond , fontul si pozitia initiala a caracterului ; aceasta metoda va contine si un apel requestFocus() - care are ca scop asigurarea faptului ca respectivele caractere pe care le vom introduce vor fi tratate chiar de fereastra Applet .

Actuinile propriu-zise ale appletului se desfasoara in cadrul metodei keyDown() ; aceasta se bazeaza pe un switch pentru a testa evenimentele de tastatura iar in cazul in care apare un eveniment al unei taste directionale se vor face modificarile necesare modificarii pozitiei caracterului din fereastra Applet . Daca evenimentul este provocat de apasarea unei taste nedirectionale acest lucru va duce la schimbarea caracterului afisat in fereastra Applet .Metoda paint() afiseaza doar caracterul curent la pozitia curenta. Unicul lucru de mentionat este faptul ca la lansarea appletului nu se deseneaza nimic - inca nu s-a tastat nici un caracter ; variabila tastaCrt va fi initializata cu 0 iar desenarea se va face doar dupa testarea acestei variabile :

import java.awt.*;

public class Taste extends java.applet.Applet {

char tastaCrt;

int xCrt;

int yCrt;

public void init() {

xCrt=(size().width/2)-8;

yCrt=(size().height/2)-16;

setBackground(Color.red);

setFont(new Font("Helvetica",Font.BOLD,36));

requestFocus();

}

public boolean keyDown(Event evt, int tasta) {

switch (tasta) {

case Event.DOWN:

yCrt+=5;

break;

case Event.UP:

yCrt-=5;

break;

case Event.LEFT:

xCrt-=5;

break;

case Event.RIGHT:

xCrt+=5;

break;

default:

tastaCrt=(char)tasta;

}

repaint();

return true;

}

public void paint(Graphics g) {

if (tastaCrt!=0) {

g.drawString(String.valueOf(tastaCrt),xCrt,yCrt);

}

}

}

TESTAREA TASTELOR SHIFT , CONTROL SI ALT

Aceste taste nu genereaza evenimente proprii insa atunci cand tratam un eveniment obisnuit - de tastatura sau mouse - putem testa daca vreuna dintre aceste trei taste a fost apasata pe durata evenimentului .

Clasa Event ofera trei metode pentru a testa apasarea uneia dintre tastele amintite mai sus : shiftDown() , metaDown() si controlDown() . Toate aceste metode returneaza valori booleene in functie de starea de apasare a tastelor respective .

Tasta Meta este echivalentul tastei ALT pe PC si al tastei Command pe MacIntosh .

Putem apela la aceste metode in oricare dintre metodele de tratare a evenimentelor prin apelarea lor pentru obiectul eveniment transmis metodei :

public boolean mouseDown(Event evt, int x, int y) {

if (evt.shiftDown())

// trateaza evenimentul shift+clic

else if (evt.controlDown())

// trateaza evenimetul CTRL+clic

else // trateaza evenimentul clic

}

Aceste metode mai pot fi folosite si pentru a testa care dintre butoanele mouseului au generat un anumit eveniment de mouse in cazul sistemelor cu doua sau trei butoane ale mouseului . In mod prestabilit evenimentele de mouse sunt generate indiferent de butonul apasat . Totusi Java asociaza apasarile pe butonul din drepata sau din mijloc cu apasarile tastelor de modificare Meta si Control asa ca prin testarea acestor taste se poate afla butonul de mouse care a fost apasat . Prin testarea tastelor de modificare putem afla care buton de mouse a fost folosit executand alte actiuni diferite decat cele pe care le-am fi folosit in mod normal pentru butonul din stanga . Se poate folosi instructiunea if pentru a testa fiecare caz , ca in exemplul de mai jos :

public boolean mouseDown(Event evt, int x, int y) {

if (evt.metaDown())

// trateaza evenimentul clic pe butonul din dreapta al mouseului

else if (evt.controlDown())

// trateaza evenimentul clic pe butonul din mijloc al mouseuluielse // trateaza evenimentul clic normal

}

TRATAREA EVENIMENTELOR PRIN METODA GENERICA

Metodele prestabilite prezentate mai sus sunt apelate de o metoda generica de tratare a evenimentelor - handleEvent() . La folosirea ei , AWT trateaza in mod generic evenimentele care apar intre componentele aplicatiei sau evenimentele datorate actiunilor utilizatorului .

In metoda handleEvent() se proceseaza evenimentele de baza si se apeleaza metodele despre care am vorbit mai devreme . Pentru a trata si alte evenimente decat cele mentionate deja , pentru a modifica comportamentul implicit de tratare a evenimentelor sau pentru a crea si a transmite propriile evenimente va trebui sa suprascriem metoda handleEvent() . Ea are o semnatura de forma :

public boolean handleEvent(Event evt) {

/...

}

Pentru a testa anumite evenimente trebuie sa examinam variabila de instanta id a obiectului Event . Identificatorul de eveniment este un intreg dar clasa in clasa Event este definit un ansamblu de evenimente drept variabile de clasa , ale caror nume pot fi testate in metoda handleEvent() . Deoarece aceste variabile de clasa sunt constante intregi poate fi folosita cu succes instructiunea handleEvent() . Mai jos avem un exemplu de metoda handleEvent() in care sunt afisate informatii de depanare despre evenimentele de mouse :

public boolean handleEvent(Event evt) {

switch (evt.id) {

case Event.MOUSE_DOWN: System.out.println("MouseDown "+evt.x+","+evt.y);

return true;

case Event.MOUSE_UP: System.out.println("MouseUp "+evt.x+","+evt.y);

return true;

case Event.MOUSE_MOVE: System.out.println("MouseMove "+evt.x+","+evt.y);

return true;case Event.MOUSE_Drag: System.out.println("MouseDrag "+evt.x+","+evt.y);

return true;

default: return false;

}

}

Putem testa si urmatoarele evenimente de tastatura :

Event.KEY_PRESS - generat cand este apasata o tasta ( analog cu metoda keyDown() )

Event.KEY_RELEASE - generat la eliberarea unei taste

Event.KEY_ACTION si Event.KEY_ACTION_RELEASE - generate cand este apasata si respectiv eliberata o tasta functionala ( tastele F , directionale , Page Up , Page Down, Home , etc. )

In ceea ce priveste evenimentele de mouse putem testa si in cazul lor mai multe evenimente :

Event.MOUSE_DOWN - generat la apasarea butonului mouseului ( analog cu metoda mouseDown() )

Event.MOUSE_UP - generat cand butonul mouseului este eliberat ( analog cu metoda mouseUp() )

Event.MOUSE_MOVE - generat cand mouseul este deplasat ( analog cu metoda mouseMove() )

Event.MOUSE_DRAG - generat cand mouseul este deplasat tinandu-se apasat butonul acestuia ( analog cu metoda mouseDrag() )

Event.MOUSE_ENTER - generat la intrarea cursorului mouseului pe suprafata appletului sau a unei componente a acestuia ( analog cu metoda mouseEnter() )

Event.MOUSE_EXIT - generat cand cursorul mouseului paraseste appletul ( analog cu metoda mouseExit() )

Mentionam ca la suprascrierea metodei handleEvent() in clasa noastra nici una dintre metodele prestabilite de tratare a evenimentelor nu va mai fi apelata decat daca o vom apela explicit in corpul metodei handleEvent() . Cea mai buna modalitate de a rezolva aceasta problema este de a testa evenimentele de care suntem interesati iar daca acestea nu apara sa apelam metoda super.handleEvent() - pentru ca superclasa care defineste metoda sa poata procesa evenimentele . Pentru a exemplifica acest lucru prezentam listingul de mai jos :

public boolean handleEvent(Event evt) {

if (evt.id==Event.MOUSE_DOWN) {

// proceseaza evenimentul mouse down

return true;

} else

return super.handleEvent(evt);

}

Mai trebuie retinut ca metoda handleEvent() returneaza si ea o valoare booleana . Valoarea returnata va fi false daca transferam evenimentul unei alte metode ( care si ea la randul ei va returna un true sau false ) sau true daca tratam evenimentul in corpul metodei noastre . Daca transferam tratarea evenimentului unei superclase metoda respectiva va returna true sau false astfel ca nu trebuie sa mai returnam explicit o valoare .

TRATAREA EVENIMENTELOR COMPONENTELORAceste evenimente au loc pe componente de genul butoane , zone de text sau alte elemente ale interfetelor grafice utilizator . Spre exemplu butoanele folosesc evenimente declansate la apasarea lor ; nu mai conteaza evenimentele mouse down sau mouse up sau locul unde a aparut un clic - componenta se va ocupa de tratarea tuturor acestor evenimente .

Exista trei tipuri de evenimente ce pot fi generate prin interactiunea cu componentele interfetei :

evenimente de actiune ( action events ) - sunt principalele evenimente din aceasta categorie , ele indica faptul ca respctivele componente au fost activate . Evenimentele de actiune sunt generate cand se apasa un buton , se selecteaza o optiune sau se apasa tasta ENTER intr-un camp de text

evenimente de selectare/deselectare ( list select/deselect events ) - acestea sunt generate atunci cand se selecteaza o caseta de validare sau o optiune dintr-un meniu ; aceste evenimente declanseaza de asemenea si un eveniment de actiune

evenimente de primire/cedare a selectiei ( got/lost focus events ) - sunt generate de orice componenta , ca raspuns la un clic de mouse sau la selectionarea prin tasta TAB . Primirea selectiei ( got focus ) inseamna ca respectiva componenta este selectionata si poate fi activata sau poate primi date de intrare . Cedarea selectiei ( lost focus ) inseamna ca s-a selectat o alta componenta .

TRATAREA EVENIMENTELOR DE ACTIUNE

Pentru a intercepta un astfel de eveniment se defineste in applet o metoda action() , cu semnatura :

public boolean action(Event evt, Object arg) {

// ...

}

Aceasta metoda action() , ca si metodele de tratare a evenimentelor de mouse sau tastatura , primeste ca argument un obiect ce se refera la evenimentul respectiv ; ea primeste si un al doilea argument , un obiect ce poate fi de orice tip . Tipul acestui al doilea argument e dat de componenta interfetei care a generat actiunea . Mai jos avem prezentate argumentele suplimentare pentru fiecare tip de componenta :ComponentaTipul argumentuluisemnificatia

butoaneStringeticheta butonului

casete de validareBooleantotdeauna true

butoane radioBooleantotdeauna true

meniuri de optiuniStringeticheta elementului selectat

campuri de textStringtextul din cadrul campului

In metoda action() primul lucru facut este testarea componentei care a generat actiunea . Obiectul Event pe care il primim ca argument in apelul action() contine o variabila de instanta numita target , care contine o referinta catre obiectul ce a generat evenimentul . Putem folosi operatorul instanceof pentru a afla ce componenta a generat evenimentul , ca in exemplul de mai jos :

public boolean action(Event evt, Object arg) {

if (evt.target instanceof textField)

return trateazaText(evt.target);

else if (evt.target instanceof Choice);

return trateazaChoice(arg);

// ...

return false;

}

In exemplul anterior metoda action putea fi generata de o componenta TextField sau de un meniu de optiuni .Metoda action() returneaza o valoare booleana , true daca va trata evenimentul si false in caz contrar .

In cazul in care avem mai multe componente din aceeasi clasa - de exemplu butoane - pot apare unele probleme . Toate pot genera actiuni si toate sunt instante ale aceleiasi clase Button . Aici apare utilizarea argumentului suplimentar : folosind comparatii simple de siruri , putem folosi etichete , elemente sau continutul componentei pentru a determina care dintre ele a generat evenimentul .

Un exemplu de astfel de solutie apare in continuare :

public boolean action(Event evt, Object obj) {

if (evt.target instanceof Button) {

String eticheta=(String)arg;

if (eticheta.equals("OK"))

// trateaza butonul OK

else if (eticheta.equals("EXIT"))

// trateaza butonul EXIT

else if (eticheta.equals("STOP"))

// trateaza butonul STOP

...

}

}

In cazul casetelor de validare sau al butoanelor radio argumentul suplimentar este totdeauna true si nu ne ajuta la diferentiere componentelor . In general nu se prea reactioneaza direct la activarea unei casete de validare sau la apasarea unui buton radio , acestea fiind de obicei selectate si abia apoi valorile lor sunt testate in alt loc , de obicei dupa apasarea unui buton . Daca vrem totusi ca programul sa reactioneze direct la evenimentele amintite putem folosi in locul argumentului suplimentar metoda getLabel() pentru a extrage eticheta casetei de validare si a diferentia astfel intre ele componentele de acest tip .TRATAREA EVENIMENTELOR DE SELECTARE

Intre aceste evenimente avem : list select , list deselect , got focus si lost focus . Pentru ultimele doua evenimente putem folosi metodele gotFocus() si lostFocus() - care se folosesc la fel ca metoda action() , cu urmatoarele semnaturi :

public bolean gotFocus(Event evt, Object arg) {

//...

}

public boolean lostFocus(Event evt, Object arg) {

//...

}

Pentru tratarea primelor doua evenimente trebuie folosita metoda handleEvent() , ca in exemplul de mai jos :

public boolean handleEvent(Event evt) {

if (evt.id==Event.LIST_SELECT)

handleSelect(Event);

else if (evt.id==Event.LIST_DESELECT)

handleDeselect(Event);

else return super.handleEvent(evt);

}

Event.LIST_SELECT si Event.LIST_DESELECT reprezinta identificatorii evenimentelor de selectare/deselectare iar controlul lor este transferat catre doua metode ajutatoare - handleSelect() si handleDeselect() . Apelul super.handleEvent() permite celorlalte evenimente sa fie transferate fara probleme catre metoda handleEvent() originala .

EVENIMENTELE ZONELOR DE TEXT

Zonele de text au aceleasi evenimente ca si campurile de text . Putem folosi metodele gotFocus() si lostFocus() pentru a intercepta evenimentele de primire/cedare a selectiei la fel ca in exemplele de mai sus ale acelorasi metode .

EVENIMENTE ALE LISTELOR DERULANTE

Aceste liste genereaza trei tipuri de evenimente ; selectarea sau deselectarea unui element din lista are ca efect un eveniment de selectare/deselectare din lista iar dublul clic executat pe un element al listei are ca efect un eveniment de actiune .

Putem suprascrie metoda action() pentru a trata elementul din lista pe care s-a efectuat dublu clic . Pentru selectiile si deselectiile din lista putem suprascrie metoda handleEvent() si apoi sa testam identificatorii de evenimente LIST_SELECT si LIST_DESELECT .

EVENIMENTE ALE BARELOR DE SCROLL

Pentru a trata evenimentele acestea trebuie folosita metoda handleEvent() . In continuare avem identificatorii de evenimente relevanti si miscarile care declanseaza aceste evenimente .Identificatorul evenimentuluiSemnificatia

SCROLL_ABSOLUTEgenerat la deplasarea casetei barei de scroll

SCROLL_LINE_DOWNgenerat la selectarea butonului din capatul de jos sau din stanga al barei de csroll

SCROLL_LINE_UPgenerat la selectarea butonului din capatul de sus sau din dreapta al barei de csroll

SCROLL_PAGE_DOWNgenerat la selectarea spatiului de sub sau din stanga casetei barei de scroll

SCROLL_PAGE_UPgenerat la selectarea spatiului de deasupra sau din dreapta casetei barei de scroll

Toate detaliile teoretice de pana acum s-ar putea sa para greu de inteles fara o exemplificare practica . Tocmai pentru a arata utilizarea diferitelor evenimente si tratarea lor vom prezenta un applet care va avea cinci butoane cu denumirea a cinci culori ; la executarea unui clic pe oricare buton fondul appletului se va modifica la culoarea inscrisa pe buton si va apare un text care ne va anunta culoarea pe care am selectat-o .Intr-o prima etapa a construirii appletului nostru vom crea componentele si se va stabili modul lor de dispunere in fereastra . In exemplul nostru vom folosi un administrator de dispunere de tip FlowLayout pe care il vom aplica apoi containerului nostru .

Odata cu apasarea butoanelor noastre se vor genera evenimente de actiune . Pentru tratarea lor vom folosi metoda action() care in practica va realiza mai multe lucruri :

testeaza daca initiatorul evenimentului este un buton

afla care este butonul initiator

schimba culoarea fondului

apeleaza metoda paint() pentru aplicare in fapt a culorii noii pe ecran

Pentru a modulariza cat mai corect codul sursa vom crea o metoda action() care va apela in fapt o alta metoda schimbaCuloare() ; aceasta metoda primeste ca argument chiar obiectul buton care a initiat evenimentul .Folosind faptul ca argumentul suplimentar al metodei action() este eticheta ( in cazul butoanelor ) putem afla care dintre butoane a fost apasat . In cazul de fata nu vom mai folosi solutia comparatiei etichetei butonului cu un anumit text . Obiectul transmis ca argument metodei schimbaCuloare() este o instanta a clasei Button iar una dintre variabilele de instanta este o referinta la acelasi obiect . In metoda noastra vom compara cele doua variabile pentru a testa daca este vorba de acelasi obiect , dupa care vom stabili culoarea de fond si apelam metoda repaint() .

In continuare avem si listingul complet al aplicatiei comentate in randurile anterioare :

import java.awt.*;

public class CuloareFundal extends java.applet.Applet {

String sir="Apasa un buton pentru a schimba culoarea de fond";

Button butonRosu,butonAlbastru,butonVerde,butonAlb,butonNegru;

public void init() {

setBackground(Color.white);

setLayout(new FlowLayout(FlowLayout.CENTER,10,10));

butonRosu=new Button("Rosu");

add(butonRosu);

butonAlbastru=new Button("Albastru");

add(butonAlbastru);

butonVerde=new Button("Verde");

add(butonVerde);

butonAlb=new Button("Alb");

add(butonAlb);

butonNegru=new Button("Negru");

add(butonNegru);

}

public boolean action(Event evt, Object arg) {

if (evt.target instanceof Button) {

schimbaCuloare((Button)evt.target);

return true;

} else return false;

}

void schimbaCuloare(Button b) {

if (b==butonRosu) { setForeground(Color.white);sir="Fond rosu";setBackground(Color.red);}

else if (b==butonAlbastru) { setForeground(Color.white);sir="Fond albastru";setBackground(Color.blue);}

else if (b==butonVerde) { setForeground(Color.red);sir="Fond verde";setBackground(Color.green);}

else if (b==butonAlb) { setForeground(Color.red);sir="Fond alb";setBackground(Color.white);}

else { setForeground(Color.white);sir="Fond negru";setBackground(Color.black);}

repaint();

}

public void paint(Graphics ecran) {

ecran.drawString(sir,100,50);

}

}