interfata grafica

Upload: morariu-dragos-ilie

Post on 09-Mar-2016

237 views

Category:

Documents


1 download

DESCRIPTION

JAVA PROGRAMMING

TRANSCRIPT

  • 1

    Disciplina: Metode avansate de programare

    Cadru didactic: Ralf Fabian

    Specializarea: Informatic, anul II.

    Interfaa grafic n Java

    Interfaa grafic cu utilizatorul (GUI), este un termen cu neles larg care se refer la toate tipurile de comunicare vizual ntre un program i utilizatorii si. De la apariia limbajului Java, bibliotecile de clase care ofer servicii grafice au suferit probabil cele mai mari schimbri n trecerea de la o versiune la alta. Acest lucru se datoreaz, pe de o parte dificultii legate de implementarea noiunii de portabilitate, pe de alt parte nevoii de a integra mecanismele GUI cu tehnologii aprute i dezvoltate ulterior, cum ar fi Java Beans. In momentul actual, exist dou modaliti de a crea o aplicaie cu interfa grafic i anume:

    AWT (Abstract Windowing Toolkit) - este API-ul iniial pus la dispoziie ncepnd cu primele versiuni de Java;

    Swing - parte dintr-un proiect mai amplu numit JFC (Java Foundation Classes) creat n urma colaborrii dintre Sun, Netscape i IBM, Swing se bazeaz pe modelul AWT, extinznd funcionalitatea acestuia i adugnd sau nlocuind componente pentru dezvoltarea aplicaiilor GUI.

    Este de preferat ca aplicaiile Java s fie create folosind tehnologia Swing, aceasta punnd la dispoziie o palet mult mai larg de faciliti, ns nu se renun complet la AWT deoarece aici exist clase eseniale, reutilizate n Swing.

    In principiu, crearea unei aplicaii grafice presupune urmtoarele lucruri: 1. Design

    Crearea unei suprafee de afiare (cum ar fi o fereastr) pe care vor fi aezate obiectele grafice (componente) care servesc la comunicarea cu utilizatorul (butoane,

    controale pentru editarea textelor, liste, etc);

    Crearea i aezarea componentelor pe suprafaa de afiare la poziiile corespunztoare;

    2. Funcionalitate

    Definirea unor aciuni care trebuie s se execute n momentul cnd utilizatorul interacioneaz cu obiectele grafice ale aplicaiei;

    Ascultarea evenimentelor generate de obiecte n momentul interaciunii cu utilizatorul i executarea aciunilor corespunztoare, aa cum au fost ele definite.

    Universitatea Lucian Blaga din Sibiu

    Facultatea de tiine Departamentul de Matematic i Informatic

  • 2

    Ierarhia de componente AWT

    Componente AWT

  • 3

    Ierarhia de componete Swing

    Componente Swing

  • 4

    Interfaa grafic cu pachetul AWT

    Pachetul care ofer componente AWT este java.awt. Obiectele grafice sunt derivate din

    Component, cu excepia meniurilor care descind din clasa MenuComponent.

    Prin noiunea de component se nelege orice obiect care poate avea o reprezentare grafic i care poate interaciona cu utilizatorul. Exemple de componente sunt ferestrele, butoanele, listele, bare de defilare, etc. Toate componentele AWT sunt definite de clase proprii ce se gsesc n pachetul java.awt, clasa Component fiind superclasa abstract a tuturor acestor clase.

    Crearea obiectelor grafice nu realizeaz automat i afiarea lor pe ecran. Mai nti ele trebuie aezate pe o suprafa de afiare, care poate fi o fereastr, i vor deveni vizibile n momentul n care suprafaa pe care sunt afiate va fi vizibil. O astfel de suprafa pe care sunt plasate componente se mai numete container i reprezint o instan a unei clase derivate din Container.

    Clasa Container este o subclas aparte a lui Component, fiind la rndul ei superclasa tuturor

    suprafeelor de afiare Java. n momentul n care utilizatorul a efectuat o aciune, componentele trebuie s genereze

    evenimente n funcie de aciunea pe care au suferit-o (aciune transmis de la tastatur, mouse, etc.). ncepnd cu versiunea 1.1 a limbajului Java, evenimentele sunt instane ale claselor derivate din AWTEvent.

    Un eveniment este produs de o aciune a utilizatorului asupra unui obiect grafic, deci evenimentele nu trebuie generate de programator. n schimb, ntr-un program trebuie specificat

    codul care se execut la apariia unui eveniment. Tratarea evenimentelor se realizeaz prin intermediul unor clase de tip listener (asculttor, consumator de evenimente), clase care sunt definite n pachetul java.awt.event.

    Exemplu 1. O fereastr cu dou butoane.

    //varianta AWT

    import java.awt.*;

    public class FirstGUI{

    public static void main ( String args []) {

    // Crearea ferestrei - un obiect de tip Frame

    Frame f = new Frame ("Prima mea fereastra");

    // Setarea modului de dipunere a componentelor

    f.setLayout (new FlowLayout());

    // Crearea celor doua butoane

    Button b1 = new Button ("OK");

    Button b2 = new Button ("Cancel");

    // Adaugarea butoanelor

    f.add(b1);

    f.add(b2);

    f.pack();

    // Afisarea fereastrei

    f.setVisible(true);

    }

    }

    //varianta Swing

    import java.awt.*;

    import javax.swing.*;

    public class FirstGUISwing {

    public static void main(String args[]) {

    // Crearea ferestrei - un obiect de tip Frame

    JFrame f = new JFrame("Prima mea fereastra");

    // setarea actiune implicite de terminare a

    // aplicatiei la inchiderea ferestrei

    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

  • 5

    // Setarea modului de dipunere a componentelor

    f.setLayout(new FlowLayout());

    // Crearea celor doua butoane

    JButton b1 = new JButton("OK");

    JButton b2 = new JButton("Cancel");

    // Adaugarea butoanelor

    f.add(b1);

    f.add(b2);

    f.pack();

    // Afisarea fereastrei

    f.setVisible(true);

    }

    }

    Att butoanele adugate ct i butonul de nchidere a ferestrei pot fi apsate, dar nu realizeaz nimic. Acest lucru se ntmpl deoarece nu s-a specificat nicieri codul care trebuie s se execute la apsarea acestor butoane. De asemenea, mai trebuie remarcat c nu s-a specificat nicieri dimensiunile ferestrei sau ale butoanelor i nici poziiile de amplasare. Cu toate acestea ele sunt plasate unul lng celalalt, fr s se suprapun iar suprafaa ferestrei este suficient de mare nct s cuprind ambele obiecte. Aceste fenomene sunt provocate de un obiect special de tip FlowLayout care se ocup cu gestionarea ferestrei i cu plasarea componentelor ntr-o anumit

    ordine pe suprafaa ei. Aadar, modul de aranjare nu este o caracteristic a suprafeei de afiare ci, fiecare container are asociat un obiect care se ocup cu dimensionarea i dispunerea componentelor pe suprafaa de afiare i care se numete gestionar de poziionare (layout manager).

    Generaliti despre componentele AWT n pachetul java.awt, se regsesc urmtoarele clasa de componente:

    Button - butoane cu eticheta format dintr-un text pe o singur linie;

    Canvas - suprafa pentru desenare;

    Checkbox - component ce poate avea dou stri; mai multe obiecte de acest tip pot fi

    grupate folosind clasa CheckBoxGroup;

    Choice - liste n care doar elementul selectat este vizibil i care se deschid la apsarea lor;

    Container - superclasa tuturor suprafeelor de afiare;

    Label - etichete simple ce pot conine o singur linie de text needitabil;

    List - liste cu selecie simpl sau multipl;

    Scrollbar - bare de defilare orizontale sau verticale;

    TextComponent - superclasa componentelor pentru editarea textului: TextField (pe o

    singur linie) i TextArea (pe mai multe linii).

    Din cauza unor diferene eseniale n implementarea meniurilor pe diferite platforme de operare, acestea nu au putut fi integrate ca obiecte de tip Component, superclasa care

    descrie meniuri fiind MenuComponent.

  • 6

    Componentele AWT au peste 100 de metode comune, motenite din clasa Component. Acestea

    servesc uzual pentru aflarea sau setarea atributelor obiectelor, cum ar fi: dimensiune, poziie, culoare, font, etc. i au formatul general getProprietate, respectiv setProprietate. Cele mai folosite, grupate pe tipul proprietii gestionate sunt:

    Poziie getLocation, getX, getY, getLocationOnScreen,

    setLocation, setX, setY

    Dimensiuni getSize, getHeight, getWidth

    setSize, setHeight, setWidth

    Dimensiuni i poziie getBounds

    setBounds

    Culoare getForeground, getBackground

    setForeground, setBackground

    Font getFont

    setFont

    Vizibilitate setVisible

    isVisible

    Interactivitate setEnabled

    isEnabled

    Generaliti despre suprafee de afiare Mai nti obiectele grafice trebuie aezate pe o suprafa, i vor deveni vizibile n momentul

    n care suprafaa respectiv va fi vizibil. O astfel de suprafa pe care sunt plasate componentele se numete suprafaa de afiare sau container i reprezint o instan a unei clase derivat din Container.

    O parte din clasele care au drept printe pe Container sunt urmtoarele:

    Window - este superclasa tuturor ferestrelor. Din aceast clas sunt derivate:

    Frame - ferestre standard;

    Dialog - ferestre de dialog modale sau nemodale;

    Panel - o suprafa fr reprezentare grafic folosit pentru gruparea altor componente. Din

    aceast clas deriv Applet, folosit pentru crearea appleturilor.

  • 7

    ScrollPane - container folosit pentru implementarea automat a derulrii pe orizontal sau

    vertical a unei componente.

    Componentele adugate sunt memorate ntr-o list iar poziiile lor din aceast list vor defini ordinea de traversare front-to-back a acestora n cadrul containerului. Dac nu este specificat nici un index la adugarea unei componente, atunci ea va fi adugat pe ultima poziie a listei.

    Clasa Container conine metodele comune tuturor suprafeelor de afiare. Cele mai

    folosite sunt:

    add - permite adugarea unei componente pe suprafaa de afiare. O component nu poate

    aparine dect unui singur container, ceea ce nseamn c pentru a muta un obiect dintr-un container n altul trebuie eliminat mai nti de pe containerul iniial.

    remove - elimin o component de pe container;

    setLayout - stabilete gestionarul de poziionare al containerului;

    getInsets - determin distana rezervat pentru marginile suprafeei de afiare;

    validate - foreaz containerul s reaeze toate componentele sale. Aceast metod

    trebuie apelat explicit atunci cnd se adaug sau se elimin componente pe suprafa de afiare dup ce aceasta a devenit vizibil.

    Frame f = new Frame("O fereastra");

    // Adauga un buton direct pe fereastra

    Button b = new Button("Hello");

    f.add(b);

    // Adauga doua componente pe un panel

    Label et = new Label("Nume:");

    TextField text = new TextField();

    Panel panel = new Panel();

    panel.add(et);

    panel.add(text);

    // Adauga panel-ul pe fereastra i, indirect, cele doua componente

    f.add(panel);

    Gestionarea poziionrii Un gestionar de poziionare (layout manager) este un obiect care controleaz dimensiunea

    i aranjarea (poziia) componentelor unui container. Aadar, modul de aranjare a componentelor pe o suprafaa de afiare nu este o caracteristica a clasei Container. Fiecare obiect de tip

    Container, sau o extensie a lui (Applet, Frame, Panel) are asociat un obiect care se ocupa

    cu dispunerea componentelor pe suprafaa sa: gestionarul de poziionare. Toate clasele care instaniaz obiecte pentru gestionarea poziionrii implementeaz interfaa LayoutManager. La

  • 8

    instanierea unui container se creeaz implicit un gestionar de poziionare asociat acestui container. De exemplu pentru o fereastra (un obiect de tip Window sau o subclasa a sa) gestionarul implicit

    este de tip BorderLayout, n timp ce pentru un container de tip Panel este o instan a clasei

    FlowLayout.

    Folosirea gestionarilor de poziionare

    Orice container are un gestionar implicit de poziionare - un obiect care implementeaz interfaa LayoutManager, acesta fiindu-i ataat automat la crearea sa. n cazul n care acesta nu

    corespunde necesitilor noastre el poate fi schimbat cu uurin. Cei mai utilizai gestionari din pachetul java.awt sunt:

    FlowLayout

    BorderLayout

    GridLayout

    CardLayout

    Ataarea explicit a unui gestionar de poziionare la un container se face cu metoda setLayout a

    clasei Container. Metoda poate primi ca parametru orice instan a unei clase care implementeaz

    interfaa LayoutManager. Secvena de ataare a unui gestionar pentru un container este:

    FlowLayout gestionar = new FlowLayout();

    container.setLayout(gestionar);

    sau, mai uzual : container.setLayout(new FlowLayout());

    Programele nu apeleaz n general metode ale gestionarilor de poziionare iar n cazul cnd avem nevoie de obiectul gestionar l putem obine cu metoda getLayout din clasa Container.

    Una din facilitile cele mai utile oferite de gestionarii de poziionare este rearanjarea componentele unui container atunci cnd acesta este redimensionat. Poziiile i dimensiunile componentelor nu sunt fixe, ele fiind ajustate automat de ctre gestionar la fiecare redimensionare astfel nct sa ocupe ct mai estetic suprafaa de afiare.

    Pentru situaii n care se dorete o amplasare a componentelor la anumite poziii fixe, iar acestea s rmn acolo chiar dac se redimensioneaz containerul, se trimite argumentului null

    metodei setLayout:

    //pozitionare absoluta a componentelor in container

    container.setLayout(null);

    Folosind poziionarea absoluta, nu va mai fi suficient adugarea cu metoda add a

    componentelor n container ci va trebui specificat poziia i dimensiunea lor - acest lucru era fcut automat de gestionarul de poziionare.

    container.setLayout( null );

    Button b = new Button("Buton");

    b.setSize(10, 10);

    b.setLocation (0, 0);

    b.add();

    In general, se recomanda folosirea gestionarilor de poziionare n toate situaiile cnd acest lucru este posibil, deoarece permit programului sa aib aceeai nfiare indiferent de platforma i rezoluia pe care este rulat.

  • 9

    Gestionarul FlowLayout

    Acest gestionar aeaz componentele pe suprafaa de afiare n flux liniar, mai precis, componentele sunt adugate una dup alta pe linii, n limita spaiului disponibil. In momentul cnd o componenta nu mai ncape pe linia curenta se trece la urmtoarea linie, de sus n jos. Adugarea componentelor se face de la stnga la dreapta pe linie, iar alinierea obiectelor n cadrul unei linii poate fi de trei feluri: la stnga, la dreapta, centrate. Implicit componentele sunt centrate

    pe fiecare linie iar distanta implicita ntre componente este de 5 uniti pe verticala i 5 pe orizontal.

    Exemplu 2.

    import java.awt.*;

    import javax.swing.*;

    public class TestFlowLayout {

    public static void main(String args[]) {

    JFrame f = new JFrame("Flow Layout");

    f.setLayout(new FlowLayout());

    JButton b1 = new JButton("Button 1");

    JButton b2 = new JButton("2");

    JButton b3 = new JButton("Button 3");

    JButton b4 = new JButton("Long-Named Button 4");

    JButton b5 = new JButton("Button 5");

    f.add(b1); f.add(b2); f.add(b3); f.add(b4); f.add(b5);

    f.pack();

    f.setVisible(true);

    }

    } Componentele ferestrei vor fi afiate astfel:

    Redimensionnd fereastra astfel nct cele cinci butoane sa nu mai ncap pe o linie, ultimele dintre ele vor fi trecute pe linia urmtoare:

    Gestionarul BorderLayout

    Gestionarul BorderLayout mparte suprafaa de afiare n cinci regiuni, corespunztoare

    celor patru puncte cardinale i centrului. O componenta poate fi plasata n oricare din aceste regiuni,

  • 10

    dimensiunea componentei fiind calculata astfel nct sa ocupe ntreg spaiul de afiare oferit de regiunea respectiva. Pentru a aduga mai multe obiecte grafice ntr-una din cele cinci zone, ele trebuie grupate n prealabil ntr-un panel, care va fi amplasat apoi n regiunea dorita.

    Aadar, la adugarea unei componente pe o suprafa gestionat de BorderLayout, metoda add

    va mai primi pe lng numele componentei i zona n care aceasta va fi amplasata, acesta fiind specificat prin una din constantele clasei BorderLayout: NORTH, SOUTH, EAST, WEST,

    CENTER.

    Exemplu 3.

    import java.awt.BorderLayout;

    import javax.swing.*;

    import static java.awt.BorderLayout.*;

    public class TestBorderLayout {

    public static void main(String args[]) {

    JFrame f = new JFrame("Border Layout");

    // poate sa lipseasca, e implicit la JFrame

    f.setLayout(new BorderLayout());

    f.add(new JButton("Nord"), NORTH);

    f.add(new JButton("Sud"), SOUTH);

    f.add(new JButton("Est"), EAST);

    f.add(new JButton("Vest"), WEST);

    f.add(new JButton("Centru"), CENTER);

    f.pack();

    f.setVisible(true);

    }

    } Cele cinci butoane ale ferestrei vor fi afiate astfel:

    La redimensionarea ferestrei se pot observa urmtoarele lucruri: nordul i sudul se redimensioneaz doar pe orizontala, estul i vestul doar pe verticala, n timp ce centrul se redimensioneaz att pe orizontala ct i pe verticala. Redimensionarea componentelor se face astfel nct ele ocupa toat zona containerului din care fac parte.

    Gestionarul GridLayout

    Gestionarul GridLayout organizeaz containerul ca un tabel cu rnduri i coloane,

    componentele fiind plasate n csuele tabelului de la stnga la dreapta ncepnd cu primul rnd. Csuele tabelului au dimensiuni egale iar o component poate ocupa doar o singura csu. Numrul de linii i coloane poate fi specificat n constructorul gestionarului dar poate fi modificat i ulterior prin metodele setRows i setCols. De asemenea, distanta ntre componente pe orizontala

    i distanta ntre rndurile tabelului pot fi specificate n constructor sau stabilite ulterior.

    Exemplu 4.

  • 11

    import java.awt.*;

    import javax.swing.*;

    public class TestGridLayout {

    public static void main(String args[]) {

    JFrame f = new JFrame("Grid Layout");

    f.setLayout(new GridLayout(3, 2));

    f.add(new JButton("Button 1"));

    f.add(new JButton("2"));

    f.add(new JButton("Button 3"));

    f.add(new JButton("Long-Named Button 4"));

    f.add(new JButton("Button 5"));

    f.pack();

    f.setVisible(true);

    }

    }

    Cele cinci butoane ale ferestrei vor fi pe trei rnduri i doua coloane astfel:

    Redimensionarea ferestrei va determina redimensionarea tuturor componentelor.

    Gestionarul CardLayout

    Gestionarul CardLayout trateaz componentele adugate pe suprafaa sa ntr-o manier

    similar cu cea a dispunerii crilor de joc ntr-un pachet. Suprafaa de afiare poate fi asemnat cu pachetul de cri iar fiecare component este o carte din pachet. La un moment dat, numai o singur component este vizibil.

    Clasa dispune de metode prin care s poat fi afiat o anumit component din pachet, sau s se poat parcurge secvenial pachetul, ordinea componentelor fiind intern gestionarului.

    Principala utilitate a acestui gestionar este utilizarea mai eficient a spaiului disponibil n situaii n care componentele pot fi grupate n aa fel nct utilizatorul s interacioneze la un moment dat doar cu un anumit grup (o carte din pachet), celelalte fiind ascunse.

    Exemplu 5. Aplicaia arat modul de funcionare a unui CardLayout. Clasa TestCardLayout

    particularizeaz clasa JFrame prin motenire. Sunt tratate evenimentele de click pe dou butoane

    prin implementarea interfeei asculttor ActionListener. // ontine si tratarea de evenimente pt. 2 butoane

    import java.awt.*;

    import java.awt.event.*;

    import javax.swing.*;

    public class TestCardLayout extends JFrame implements ActionListener {

    JPanel tab;

    public TestCardLayout() {

    super("TestCardLayout");

    JButton card1 = new JButton("Card 1");

    JButton card2 = new JButton("Card 2");

    JPanel butoane = new JPanel();

  • 12

    butoane.add(card1);

    butoane.add(card2);

    // partea care se va ascunde

    JLabel et = new JLabel("Nume:");

    JTextField text = new JTextField(20);

    JPanel panel = new JPanel();

    panel.add(et);

    panel.add(text);

    tab = new JPanel();

    tab.setLayout(new CardLayout());

    TextField tf = new TextField("Text Field");

    tab.add("Card 1", tf);

    tab.add("Card 2", panel);

    add(butoane, BorderLayout.NORTH);

    add(tab, BorderLayout.CENTER);

    // adaugarea de ascultatoare pt. evenimente

    card1.addActionListener(this);

    card2.addActionListener(this);

    pack();

    }

    public void actionPerformed(ActionEvent e) {

    CardLayout gestionar = (CardLayout) tab.getLayout();

    gestionar.show(tab, e.getActionCommand());

    }

    public static void main(String args[]) {

    new TestCardLayout().setVisible(true);

    }

    }

    Rezultatul acestui exemplu arata grafic astfel:

    Gruparea componentelor (Clasa Panel)

    Plasarea componentelor direct pe suprafaa de afiare poate deveni incomoda n cazul n care avem multe obiecte grafice. Din acest motiv se recomanda gruparea obiectelor grafice nrudite

    ca funcionalitate astfel nct sa putem fi siguri c, indiferent de gestionarul de poziionare al suprafeei de afiare, ele se vor gsi mpreun. Gruparea componentelor se face n panel-uri.

    Un panel este cel mai simplu model de container. El nu are o reprezentare vizibila, rolul sau

    fiind de a oferi o suprafa de afiare pentru componente grafice, inclusiv pentru alte panel-uri. Clasa care instaniaz aceste obiecte este Panel, extensie a superclasei Container. Pentru a aranja

    corespunztor componentele grupate ntr-un panel, acestuia i se poate specifica un gestionar de poziionare anume, folosind metoda setLayout. Gestionarul implicit pentru containerele de tip

    Panel este FlowLayout.

    Aadar, o aranjare eficienta a componentelor unei ferestre nseamn:

    gruparea componentelor nfrite (care nu trebuie sa fie desprite de gestionarul de poziionare al ferestrei) n panel-uri;

  • 13

    aranjarea componentelor unui panel, prin specificarea acestuia a unui gestionar de poziionare corespunztor

    aranjarea panel-urilor pe suprafaa ferestrei, prin specificarea gestionarului de poziionare al ferestrei.

    Exemplu 6.

    import java.awt.*;

    import javax.swing.*;

    public class TestPanel {

    public static void main(String args[]) {

    JFrame f = new JFrame("Panel");

    JPanel panel = new JPanel();

    panel.setLayout(new FlowLayout());

    panel.add(new JLabel("Text:"));

    panel.add(new JTextField("", 20));

    panel.add(new JButton("Reset"));

    f.add(panel, BorderLayout.NORTH);

    f.add(new JButton("OK"), BorderLayout.EAST);

    f.add(new JButton("Cancel"), BorderLayout.WEST);

    f.pack();

    f.setVisible(true);

    }

    }

  • 14

    Evenimente n interfee grafice

    ntr-o interfa grafic, eveniment este produs de o aciune a utilizatorului asupra unei componente grafice i reprezint mecanismul prin care utilizatorul comunic efectiv cu programul. Exemple de evenimente sunt: apsarea unui buton, modificarea textului ntr-un control de editare, nchiderea, redimensionarea unei ferestre, etc. Componentele care genereaz anumite evenimente se mai numesc i surse de evenimente.

    Interceptarea evenimentelor generate de componentele unui program se realizeaz prin intermediul unor clase de tip listener (asculttor, consumator de evenimente). In Java, orice

    obiect poate consuma evenimentele generate de o anumita component grafic.

    Utilizator Component Listener (aciune) (generare de eveniment) (interceptarea evenimentului)

    Aadar, pentru a scrie cod care s se execute n momentul n care utilizatorul interacioneaz cu o componenta grafic trebuie sa facem urmtoarele lucruri:

    s scriem o clasa de tip Listener care s asculte evenimentele produse de acea

    component i n cadrul acestei clase s implementm metode specifice pentru tratarea lor;

    s comunicm componentei surs c respectiva clas i ascult evenimentele pe care le genereaz, cu alte cuvinte s nregistram acea clasa drept consumator al evenimentelor produse de componenta respectiv.

    Evenimentele sunt, ca orice altceva n Java, obiecte. Clasele care descriu aceste obiecte se

    mpart n mai multe tipuri n funcie de componenta care le genereaz, mai precis n funcie de aciunea utilizatorului asupra acesteia. Pentru fiecare tip de eveniment exist o clasa care instaniaz obiecte de acel tip; de exemplu: evenimentul generat de acionarea unui buton este implementat prin clasa ActionEvent, cel generat de modificarea unui text prin clasa TextEvent, etc.

    Toate aceste clase au ca superclasa comuna clasa AWTEvent.

  • 15

    O clasa consumatoare de evenimente (listener) poate fi orice clasa care specifica n

    declaraia sa ca dorete s asculte evenimente de un anumit tip. Acest lucru se realizeaz prin implementarea unei interfee specifice fiecrui tip de eveniment. Astfel, pentru ascultarea evenimentelor de tip ActionEvent clasa respectiv trebuie s implementeze interfaa

    ActionListener, pentru TextEvent este TextListener, etc. Toate aceste interfee au

    superinterfaa comun EventListener.

    Se poate scrie ceva de forma:

    class AscultaButoane implements ActionListener

    class AscultaTexte implements TextListener

    ntruct o clasa poate implementa oricte interfee ea va putea s asculte evenimente de mai multe tipuri:

    class Ascultator implements ActionListener, TextListener

    Vom vedea n continuare metodele fiecrei interfee pentru a ti ce trebuie s implementeze o clas consumatoare de evenimente.

    Pentru ca evenimentele unei componente s fie interceptate de ctre o instan a unei clase asculttor, aceast clas trebuie nregistrat n lista asculttorilor componentei respective. nregistrarea unei clase n lista asculttorilor unei componente se face cu metode din clasa Component de tipul addYYYListener, iar eliminarea ei din aceast list cu

    removeYYYListener unde YYY reprezenta tipul evenimentului.

    Exemplu 1. O fereastra care s conin doua butoane cu numele OK, respectiv Cancel. La apsarea fiecrui buton se scrie pe bara de titlu a ferestrei mesajul Ati apasat butonul ...". import java.awt.*;

    import java.awt.event.*;

    class Fereastra extends JFrame {

    public Fereastra(String titlu) {

    super(titlu);

    //se stabileste gestionarul

    setLayout(new FlowLayout());

    //se dimensioneaza fereastra

    setSize(300, 100);

    //se construiesc si se adauga butoanele Ok si Cancel

    JButton b1 = new JButton("OK");

    add(b1);

    JButton b2 = new JButton("Cancel");

    add(b2);

    //se construieste un obiect de tip Ascultator.

    //la creare este pasata o referinta spre obiectul curent

    //pt. ca ascultatorul sa aiba acces la elementle obiectului

    //pe care a aparut evenimentul

    Ascultator listener = new Ascultator(this);

    //ambele butoane sunt ascultate de obiectul "listener"

    //instanta a clasei Ascultator, definita mai jos

    b1.addActionListener(listener);

    b2.addActionListener(listener);

    }

    }

  • 16

    //implementarea ascultatotului pentru butoanele aplicatiei

    class Ascultator implements ActionListener {

    //atribut care va retine o referinta spre obiectul

    //care contine butoanele tratate

    private Fereastra f;

    //constructorul Ascultatorului

    public Ascultator(Fereastra f) {

    this.f = f;

    }

    //metoda interfetei ActionListener (unica)

    public void actionPerformed(ActionEvent e) {

    //se afla comanda din obiectul de eveniment

    String command = e.getActionCommand();

    //numele comenzii este numele butonului apasat

    System.out.println(e.toString());

    if (command.equals("OK"))

    f.setTitle("Ati apasat OK");

    else

    if (command.equals("Cancel"))

    f.setTitle("Ati apasat Cancel");

    }

    }

    public class ListenOkCancel { //fereastra principala

    public static void main(String args[]) {

    Fereastra f = new Fereastra("Evenimente pe 2 butoane");

    f.setVisible(true);

    }

    }

    Nu este obligatoriu s definim clase speciale pentru ascultarea evenimentelor. In exemplul de mai sus am definit o clasa special Ascultator pentru a intercepta evenimentele produse de cele doua butoane i din acest motiv a trebuit s trimitem ca parametru acestei clase instana la fereastr. Mai uor ar fi fost s folosim chiar clasa Fereastra pentru a asculta evenimentele produse de componentele ei:

    class Fereastra extends JFrame implements ActionListener{

    public Fereastra(String titlu) {

    super(titlu);

    . . .

    //ambele butoane sunt ascultate chiar din clasa Fereastra

    //deci ascultatorul este instanta curenta: this

    b1.addActionListener(this);

    b2.addActionListener(this);

    }

    public void actionPerformed(ActionEvent e) {

    String command = e.getActionCommand();

    System.out.println(e.toString());

    if (command.equals("OK"))

    this.setTitle("Ati apasat OK");

    else

    if (command.equals("Cancel"))

    this.setTitle("Ati apasat Cancel");

    }

    }

  • 17

    Aadar, orice clas poate asculta evenimente de orice tip cu condiia s implementeze interfeele specifice acelor evenimente.

    Tipuri (clase) de evenimente si componentele care le genereaz In tabelul de mai jos sunt prezentate n stnga tipurile de evenimente i interfeele iar n

    dreapta lista componentelor ce pot genera evenimente de acel tip precum i o scurt explicaie despre motivul care le provoac.

    Eveniment/Interfa Componente care genereaz acest eveniment ActionEvent

    ActionListener Button, List, TextField, MenuItem, CheckboxMenuItem, Menu,

    PopupMenu

    Aciuni asupra unui control AdjustmentEvent

    AdjustmentListener Scrollbar i orice clasa care implementeaz interfaa Adjustable Modificarea unei valori variind ntre doua limite

    ComponentEvent

    ComponentListener Component si subclasele sale

    Redimensionri, deplasri, ascunderi ale componentelor ContainerEvent

    ContainerListener Container si subclasele sale

    Adugarea, tergerea componentelor la un container FocusEvent

    FocusListener Component si subclasele sale

    Preluarea, pierderea focusului de ctre o componenta KeyEvent

    KeyListener Component i subclasele sale Apsarea, eliberarea unei taste cnd focusul este pe o anumita componenta.

    MouseEvent

    MouseListener Component si subclasele sale

    Click, apsare, eliberare a mouse-ului pe o componenta, intrarea, ieirea mouse-ului pe/de pe suprafaa unei componente

    MouseEvent

    MouseMotionListener Component si subclasele sale

    Micarea sau drag-ul mouse-ului pe suprafaa unei componente WindowEvent

    WindowListener Window si subclasele sale Dialog, FileDialog, Frame

    nchiderea, maximizarea, minimizarea, redimensionarea unei ferestre ItemEvent

    ItemListener Checkbox, CheckboxMenuItem, Choice, List i orice clasa care implementeaza interfata ItemSelectable

    Selecia, deselecia unui articol dintr-o lista sau meniu. TextEvent

    TextListener Orice clasa derivata din TextComponent cum ar fi : TextArea,

    TextField

    Modificarea textului dintr-o componenta de editare a textului

  • 18

    Evenimente suportate de o componenta

    Urmtorul tabel prezint o clasificare a evenimentelor n funcie de componentele care le suport:

    Componenta Evenimente suportate de componenta Adjustable AdjustmentEvent

    Applet ContainerEvent, FocusEvent, KeyEvent, MouseEvent,

    ComponentEvent

    Button ActionEvent, FocusEvent, KeyEvent, MouseEvent,

    ComponentEvent

    Canvas FocusEvent, KeyEvent, MouseEvent, ComponentEvent

    Checkbox ItemEvent, FocusEvent, KeyEvent, MouseEvent,

    ComponentEvent

    CheckboxMenuItem ActionEvent, ItemEvent

    Choice ItemEvent, FocusEvent, KeyEvent, MouseEvent,

    ComponentEvent

    Component FocusEvent, KeyEvent, MouseEvent, ComponentEvent

    Container ContainerEvent, FocusEvent, KeyEvent, MouseEvent,

    ComponentEvent

    Dialog ContainerEvent, WindowEvent, FocusEvent, KeyEvent,

    MouseEvent, ComponentEvent

    FileDialog ContainerEvent, WindowEvent, FocusEvent, KeyEvent,

    MouseEvent, ComponentEvent

    Frame ContainerEvent, WindowEvent, FocusEvent, KeyEvent,

    MouseEvent, ComponentEvent

    Label FocusEvent, KeyEvent, MouseEvent, ComponentEvent

    List ActionEvent, FocusEvent, KeyEvent, MouseEvent,

    ItemEvent, ComponentEvent

    Menu ActionEvent

    MenuItem ActionEvent

    Panel ContainerEvent, FocusEvent, KeyEvent, MouseEvent,

    ComponentEvent

    PopupMenu ActionEvent

    Scrollbar AdjustmentEvent, FocusEvent, KeyEvent, MouseEvent,

    ComponentEvent

    ScrollPane ContainerEvent, FocusEvent, KeyEvent, MouseEvent,

    ComponentEvent

    TextArea TextEvent, FocusEvent, KeyEvent, MouseEvent,

    ComponentEvent

    TextComponent TextEvent, FocusEvent, KeyEvent, MouseEvent,

    ComponentEvent

    TextField ActionEvent, TextEvent, FocusEvent, KeyEvent,

    MouseEvent, ComponentEvent

    Window ContainerEvent, WindowEvent, FocusEvent, KeyEvent,

    MouseEvent, ComponentEvent

  • 19

    Metodele interfeelor de tip listener Orice clas care trateaz evenimente trebuie s implementeze obligatoriu metodele

    interfeelor corespunztoare evenimentelor pe care le trateaz. Tabelul de mai jos prezint, pentru fiecare interfaa, metodele puse la dispoziie i care trebuie implementate de clasa asculttor.

    Interfata Metodele interfetei ActionListener actionPerformed(ActionEvent)

    AdjustmentListener adjustmentValueChanged(AdjustmentEvent)

    ComponentListener componentHidden(ComponentEvent)

    componentShown(ComponentEvent)

    componentMoved(ComponentEvent)

    componentResized(ComponentEvent)

    ContainerListener componentAdded(ContainerEvent)

    componentRemoved(ContainerEvent)

    FocusListener focusGained(FocusEvent)

    focusLost(FocusEvent)

    KeyListener keyPressed(KeyEvent)

    keyReleased(KeyEvent)

    keyTyped(KeyEvent)

    MouseListener mouseClicked(MouseEvent)

    mouseEntered(MouseEvent)

    mouseExited(MouseEvent)

    mousePressed(MouseEvent)

    mouseReleased(MouseEvent)

    MouseMotionListener mouseDragged(MouseEvent)

    mouseMoved(MouseEvent)

    WindowListener windowOpened(WindowEvent)

    windowClosing(WindowEvent)

    windowClosed(WindowEvent)

    windowActivated(WindowEvent)

    windowDeactivated(WindowEvent)

    windowIconified(WindowEvent)

    windowDeiconified(WindowEvent)

    ItemListener itemStateChanged(ItemEvent)

    TextListener textValueChanged(TextEvent)

    Folosirea adaptorilor i a claselor interne n tratarea evenimentelor O clas care trateaz evenimente de un anumit tip trebuie sa implementeze interfaa

    corespunztoare acelui tip. Aceasta nseamn ca trebuie s implementeze obligatoriu toate metodele definite de acea interfa, chiar dac nu specific nici un cod pentru unele dintre ele. Sunt ns situaii cnd acest lucru este suprtor, mai ales atunci cnd nu ne intereseaz dect o singur metoda a interfeei.

    Un exemplu sugestiv este urmtorul: o fereastra care nu are specificat cod pentru tratarea evenimentelor sale nu poate fi nchisa cu butonul standard marcat cu 'x' din colul dreapta sus i nici cu combinaia de taste Alt+F4. Pentru a realiza acest lucru trebuie interceptat evenimentul de nchidere a ferestrei n metoda windoClosing i apelat apoi metoda dispose de nchidere a

    ferestrei, eventual urmat de ieirea din program, n cazul cnd este vorba de fereastra principala a aplicaiei. Aceasta nseamn c trebuie sa implementam interfaa WindowListener care are nu

    mai puin de apte metode.

  • 20

    Exemplu 2. Crearea unei ferestre cu ascultarea evenimentelor sale folosind implementarea directa a

    interfeei WindowListener.

    import java.awt.*;

    import java.awt.event.*;

    class Fereastra extends JFrame implements WindowListener {

    public Fereastra(String titlu) {

    super(titlu);

    this.addWindowListener(this);

    }

    //metodele interfetei WindowListener

    public void windowOpened(WindowEvent e) {}

    public void windowClosing(WindowEvent e) {

    dispose(); //inchid fereastra

    System.exit(0); //termin programul

    }

    public void windowClosed(WindowEvent e) {}

    public void windowIconified(WindowEvent e) {}

    public void windowDeiconified(WindowEvent e) {}

    public void windowActivated(WindowEvent e) {}

    public void windowDeactivated(WindowEvent e) {}

    }

    public class TestWindowListener {

    public static void main(String args[]) {

    Fereastra f = new Fereastra("O fereastra");

    f.setVisible(true);

    }

    }

    Se observ c trebuie implementate toate metodele interfeei, chiar dac nu se scriem nici un cod pentru ele. Singura metoda care intereseaz este windowClosing n care se specific ce

    trebuie fcut atunci cnd utilizatorul dorete s nchid fereastra. Pentru a evita scrierea inutil a acestor metode exista o serie de clase care implementeaz interfeele de tip listener far a

    specifica nici un cod pentru metodele lor. Aceste clase se numesc adaptori.

    Utilizarea adaptorilor

    Un adaptor este o clasa abstracta care implementeaz o interfa de tip listener. Scopul

    unei astfel de clase este ca la crearea unui asculttor de evenimente, n loc s implementeze o anumita interfa i implicit toate metodele sale, se extinde adaptorul corespunztor interfeei respective i se supradefinete doar metodele care intereseaz (cele n care se scrie o anumit secven de cod).

    De exemplu, adaptorul interfeei WindowListener este WindowAdapter iar folosirea

    acestuia este data n exemplul de mai jos.

  • 21

    Exemplu 3. Crearea unei ferestre cu ascultarea evenimentelor sale folosind extinderea clasei

    WindowAdapter.

    import java.awt.*;

    import java.awt.event.*;

    class Fereastra extends JFrame {

    public Fereastra(String titlu) {

    super(titlu);

    this.addWindowListener(new Ascultator());

    }

    }

    class Ascultator extends WindowAdapter {

    //suprdefinim metodele care ne intereseaza

    public void windowClosing(WindowEvent e) {

    //?.dispose();

    // dispose nu se mai poate apela, de ce?

    System.exit(0);

    }

    }

    public class TestWindowAdapter {

    public static void main(String args[]) {

    Fereastra f = new Fereastra("O fereastra");

    f.setVisible(true);

    }

    }

    Avantajul clar al acestei modaliti de tratare a evenimentelor este reducerea codului programului, acesta devenind mult mai uor lizibil. nsa exist i doua dezavantaje majore.

    Dup cum ai observat, faa de exemplul anterior clasa Fereastra nu poate extinde

    WindowAdapter deoarece ea extinde deja clasa Frame i din acest motiv s-a construi o

    noua clasa numit Ascultator. Acest dezavantaj poate fi eliminat prin folosirea unei clase

    interne.

    Un alt dezavantaj este c orice greeala de sintax n declararea unei metode a interfeei nu va produce o eroare de compilare dar nici nu va supradefini metoda interfeei ci, pur si simplu, va crea o metoda a clasei respective.

    class Ascultator extends WindowAdapter {

    //exemple de erori sintactice:

    // in loc de windowClosing scriem WindowClosing

    // nu supradefinim vreo metoda a clasei WindowAdapter

    // nu da nici o eroare

    // nu face nimic !

    public void WindowClosing(WindowEvent e) {

    System.exit(0);

    }

    }

  • 22

    n tabelul de mai jos sunt dai toi adaptorii interfeelor de tip listener - se observ c o

    interfa YYYListener are un adaptor de tipul YYYAdapter. Interfeele care nu au un adaptor sunt

    cele care definesc o singura metoda i prin urmare crearea unei clase adaptor nu i are rostul.

    Interfaa "listener" Adaptor ActionListener nu are

    AdjustmentListener nu are

    ComponentListener ComponentAdapter

    ContainerListener ContainerAdapter

    FocusListener FocusAdapter

    ItemListener nu are

    KeyListener KeyAdapter

    MouseListener Mouse

    MouseMotionListener MouseMotionAdapter

    TextListener nu are

    WindowListener WindowAdapter

    Folosirea claselor interne (anonime)

    O clas interna este o clas declarata n cadrul altei clase iar clasele anonime sunt acele clase interne folosite doar pentru instanierea unui singur obiect de acel tip. Un exemplu tipic de folosire a lor este instanierea adaptorilor direct n corpul unei clase care conine componente ale cror evenimente trebuie interceptate. Clasa Fereastra din exemplul anterior poate fi scrisa astfel:

    class Fereastra extends JFrame {

    public Fereastra(String titlu) {

    super(titlu);

    this.addWindowListener(new WindowAdapter() {

    //corpul clasei anonime

    public void windowClosing(WindowEvent e) {

    System.exit(0);

    }

    });

    }

    }

    Codul programului a fost redus substanial prin folosirea unui adaptor i a unei clase anonime.

  • 23

    Java GUI API --- Swing

  • 24