Curs-10-PJ

11
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

description

hjgjhg

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);

    }

    }