Curs-10-PJ
-
Upload
danny-alexandru-norocia -
Category
Documents
-
view
215 -
download
1
description
Transcript of Curs-10-PJ
-
Programare Java
Curs 9
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:
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.HOME tasta HOME
Event.END tasta END
Event.PGUP tasta Page Up
Event.PGDN tasta Page Down
Event.UP sageata in sus
Event.DOWN sageata in jos
Event.LEFT sageata la stanga
Event.Right sageata la dreapta
Event.F1 tasta F1
Event.F2 tasta F2
Event.F3 tasta F3
Event.F4 tasta F4
Event.F5 tasta F5
Event.F6 tasta F6
Event.F7 tasta F7
Event.F8 tasta F8
Event.F9 tasta F9
Event.F10 tasta F10
Event.F11 tasta F11
Event.F12 tasta F12
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 drepta 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 mouseului
else // 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 COMPONENTELOR
Aceste 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:
Componenta Tipul argumentului semnificatia
butoane String eticheta butonului
casete de validare Boolean totdeauna true
butoane radio Boolean totdeauna true
meniuri de optiuni String eticheta elementului
selectat
campuri de text String textul 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 evenimentului Semnificatia
SCROLL_ABSOLUTE generat la deplasarea casetei barei de
scroll
SCROLL_LINE_DOWN generat la selectarea butonului din capatul
de jos sau din stanga al barei de csroll
SCROLL_LINE_UP generat la selectarea butonului din capatul
de sus sau din dreapta al barei de csroll
SCROLL_PAGE_DOWN generat la selectarea spatiului de sub sau
din stanga casetei barei de scroll
SCROLL_PAGE_UP generat 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);
}
}