Sunteți pe pagina 1din 9

Lucrarea 9

Interfeţe grafice

Cuprins
Crearea ferestrei unei aplicaţii....................................................................................................................................2
Tratarea evenimentelor în Java...................................................................................................................................2
Crearea unor butoane într-o fereastră .........................................................................................................................4
Introducerea textului de la tastatură ...........................................................................................................................6
Temă...........................................................................................................................................................................9

În cazul programelor pe care le-am făcut până acum, toate mesajele Õi răspunsurile apăreau ca linii
de text succesive, care defilau pe ecran (ecranul era folosit în mod text). Un astfel de stil de
comunicare nu este atractiv pentru utilizatori, motiv pentru care se preferă dialogul prin interfeţe
grafice sau GUI (Graphical User Interface) (ecranul este folosit în mod grafic).
Componentele unei interfeţe grafice se numesc elemente de control (widgets) Õi pot fi activate de
către utilizator cu ajutorul mausului sau al tastaturii. Activarea unui element de control determină
un anumit răspuns din partea programului, răspuns concretizat prin execuţia unei anumite operaţii.
Cele mai răspândite interfeţe grafice sunt cele bazate pe ferestre, adică fiecărei aplicaţii active la
un moment dat i se alocă o zonă dreptunghiulară pe ecran, numită fereastră. În interiorul ferestrei
respective, se vor găsi toate elementele de control necesare dialogului utilizator-aplicaţie, precum
Õi informaţiile afişate de aplicaţie.
Pentru ca o aplicaţie care foloseşte interfaţa grafică să poată funcţiona, este necesară existenţa unei
platforme sau server grafic care să determine intrarea monitorului în regim grafic Õi care să ofere
funcţiile primitive necesare, între altele, pentru desenarea componentelor GUI Õi pentru receptarea
semnalelor generate de maus Õi tastatură. În sprijinul programatorilor au fost create suporturi
software care permit ca o aplicaţie grafică să poată fi construită din `pieseA standardizate, gata
create.
De regulă, un suport software pune la dispoziţia programatorului următoarele elemente:
C o bibliotecă de elemente de control (bare de defilare, chenare, butoane etc.). Această
bibliotecă eliberează programatorul de sarcina de a desena Õi colora de fiecare dată
toate elementele GUI ale unei aplicaţii;
C un manager de ferestre: acesta este cel care impune cum `aratăA elementele GUI,
dictează modul în care este asamblată Õi echipată o fereastră, precum Õi modul în
care va fi manipulată. Mediul Windows are încorporat un astfel de manager de
ferestre, care defineşte aspectul general al unei ferestre Windows. Mediul Linux
este mai configurabil din acest punct de vedere, permiţând utilizatorului o gamă
mai variată de manageri de ferestre: GNOME, KDE, FVWM, etc.;
C o bibliotecă de funcţii sau clase predefinite. Această bibliotecă permite construirea
interfeţei grafice, pornind de la fereastra aplicaţiei, conform standardului impus de
managerul de ferestre instalat pe maşina pe care rulează aplicaţia. Limbajul Java
1
oferă pachetul predefinit java.awt (Abstract Window Toolkit), împreună cu o serie
de subpachete ale acestuia, care încorporează clasele necesare pentru a construi
aplicaţii grafice.

Crearea ferestrei unei aplicaţii


O aplicaţie grafică are o fereastră principală (frame) Õi una sau mai multe ferestre subordonate
celei principale. Clasa java.awt.Frame este cea care conţine elementele de bază necesare
construirii ferestrei principale. În secvenţa de mai jos se creează Õi se afişează o fereastră
principală amplasată în mijlocul ecranului Õi a cărei suprafaţă este 1/4 din suprafaţa ecranului.

import java.awt.*;
class FereastraMea extends Frame
{
public FereastraMea(String titlu)
{
super(titlu);
Toolkit t = Toolkit.getDefaultToolkit();
Dimension d = t.getScreenSize();
int h = d.height;
int w = d.width;
setSize(w/2, h/2);
setLocation(w/4, h/4);
}
}

class PrimaFereastra
{
public static void main(String[] args)
{
Frame f = new FereastraMea("Prima fereastra");
f.show();
}
}
Orice acţionare de către utilizator a unui element GUI prin intermediul mauslui sau al tastaturii
determină apariţia unui eveniment, iar elementul GUI acţionat este sursa evenimentului. Pentru
că acţionarea unui element GUI să se soldeze cu un anumit răspuns, programatorul trebuie să
rezolve partea de tratare a evenimentului. Aceasta înseamnă că cineva trebuie să recepţioneze
evenimentul Õi apoi să execute o anumită funcţie.

Tratarea evenimentelor în Java


La acţionarea unui element GUI se creează un obiect al unei clase predefinite din pachetul
java.awt.Event. Dacă există un obiect receptor (listener) al evenimentului creat Õi acest
obiect este cunoscut de către sursa evenimentului, atunci se încearcă apelarea unei metode a
receptorului căreia i se transmite ca parametru obiectul eveniment. Dacă programatorul a definit
acea metodă, execuţia ei reprezintă tratarea evenimentului.

2
Obiectele eveniment
În momentul acţionării, fiecare element GUI determină un eveniment specific. De exemplu,
diversele acţiuni asupra unei ferestre conduc la crearea unui obiect al clasei
java.awt.event.WindowEvent. Apăsarea unui buton duce la crearea unui obiect al clasei
java.awt.event.ActionEvent.
Receptorul evenimentului
Receptorul de eveniment este un obiect care are metode cu nume prestabilite, ale căror definiţii se
găsesc în interfeţe cu nume prestabilite. Există câte o interfaţă specifică fiecărui tip de eveniment.
De exemplu, pentru recepţionarea evenimentelor din clasa WindowEvent, trebuie implementată
interfaţa WindowListener.
Metodele din interfeţele EvenimentListener au ca parametru o referinţă la evenimentul
corespunzător. De exemplu, metodele din interfaţa WindowListener au ca parametru o
referinţă la WindowEvent. Metodele din clasa ActionListener au ca parametru o referinţă
la ActionEvent.
Numele metodelor reflectă acţiunea executată de utilizator asupra sursei evenimentului. Spre
exemplu, interfaţa WindowListener conţine următoarele metode:
public void windowActivated(WindowEvent e); // este apelată în momentul în
care fereastra devine fereastra activă
public void windowClosed(WindowEvent e); // este apelată după ce fereastra a fost
închisă
public void windowClosing(WindowEvent e); // este apelată în momentul în care
utilizatorul închide fereastra
public void windowDeactivated(WindowEvent e); // este apelată în momentul în
care fereastra nu mai este activă
public void windowDeiconified(WindowEvent e); // este apelată în momentul în
care fereastra minimizată este restaurată
public void windowIconified(WindowEvent e); // este apelată în momentul în
care fereastra este minimizată
public void windowOpened(WindowEvent e); // este apelată în momentul în care
fereastra este deschisă pentru prima oară
Legarea unui receptor de eveniment de sursa evenimentului se face prin invocarea de către
obiectul care reprezintă sursa evenimentului a unei metode predefinite, care primeşte drept
parametru referinţa spre obiectul receptor de eveniment. Numele metodei este format din prefixul
add la care se adaugă numele interfeţei corespunzătoare evenimentului:
obiectSursaEveniment.addEvenimentListener(obiectReceptorEveniment)
;
În exemplul prezentat, obiectul clasei FereastraMea este o sursă de eveniment, iar receptorul
ei este clasa ReceptorEvenimentFereastra. Programul anterior devine:
import java.awt.*;
import java.awt.event.*;

3
class ReceptorEvenimentFereastra implements WindowListener
{
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
// restul metodelor din WindowListener se vor implementa cu
corpul vid
}

class FereastraMea extends Frame


{
public FereastraMea(String titlu)
{
super(titlu);
ReceptorEvenimentFereastra r = new ReceptorEvenimentFe-
reastra();
this.addWindowListener(r);
Toolkit t = Toolkit.getDefaultToolkit();
Dimension d = t.getScreenSize();
int h = d.height;
int w = d.width;
setSize(w/2, h/2);
setLocation(w/4, h/4);
}
}

class PrimaFereastra
{
public static void main(String[] args)
{
Frame f = new FereastraMea("Prima fereastra");
f.show();
}
}

Crearea unor butoane într-o fereastră


Pentru a adăuga butoane, casete de text, etc. într-o fereastră, trebuie create obiecte ale claselor care
modelează acele elemente. Apoi, pentru fiecare element, trebuie apelată metoda add a
containerului în care vor fi păstrate elementele. Referinţa la elementul grafic adăugat interfeţei
grafice va fi parametrul metodei add. Amplasarea elementelor în spaţiul containerului este făcută
de obiecte speciale (plasatori), care aparţin unor clase descendente din LayoutManager. Cele
mai cunoscute asemenea clase sunt FlowLayout Õi BorderLayout. Pentru a folosi plasatorul,
obiectul care reprezintă containerul (în cazul nostru FereastraMea) va trebui ca înainte de a
adăuga elemente GUI, să apeleze metoda setLayout dându-i parametru referinţa la un obiect de
tip FlowLayout.
În Java, butoanele sunt modelate de clasa Button. Unul dintre constructorii clasei Button
acceptă drept parametru un String, reprezentând eticheta înscrisă pe buton. Un buton poate fi
sursa unui eveniment de tip ActionEvent, care apare atunci când utilizatorul a apăsat acel

4
buton. Receptorul unui eveniment ActionEvent trebuie să implementeze interfaţa
ActionListener, care declară metoda actionPerformed.
Pentru exemplificare, este prezentat programul anterior, actualizat astfel încât în fereastră să apară
un buton cu eticheta `Apasa-maA, iar la acţionarea lui să se afişeze valoarea unui contor care
numără de câte ori a fost apăsat butonul. Pentru a stăpâni complexitatea relaţiilor dintre elementele
GUI ale unei interfeţe grafice, aplicaţiile pot fi structurate conform unui şablon de proiectare numit
Mediator. Pentru aplicaţia exemplificată, aceasta presupune definirea următoarelor clase:
C o clasă care să reprezinte fereastra (FereastraMea);
C o clasă care să reprezinte receptorul de evenimente (ReceptorEvenimenteFereastra), cu
precizarea că ea se va ocupa Õi de evenimentele generate de buton;
C o clasă cu rol de mediator, care creează elementele GUI (în cazul de faţă un buton Õi o
etichetă) Õi le asamblează în fereastră, păstrând referinţele la ele Õi, înştiinţat de
către receptorul de evenimente ori de câte ori intervine o modificare a vreunui
element GUI, va actualiza starea tuturor elementelor implicate.
import java.awt.*;
import java.awt.event.*;

class ReceptorEvenimentFereastra extends WindowAdapter implements


ActionListener
{
private Mediator m;
public ReceptorEvenimentFereastra(Mediator m)
{
this.m = m;
}
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
public void actionPerformed(ActionEvent e)
{
m.buttonPressed();
}
}

class Mediator
{
public Mediator(Frame f)
{
this.f = f;
}
public void assembleFrame()
{
ReceptorEvenimentFereastra r = new ReceptorEveniment-
Fereastra(this);
f.addWindowListener(r);
b = new Button("Apasa-ma");
b.addActionListener(r);

5
etic = new Label("0");
f.setLayout(new FlowLayout());
f.add(b);
f.add(etic);
f.show();
}
public void buttonPressed()
{
contor++;
etic.setText(""+contor);
}
private int contor=0;
private Frame f;
private Button b;
private Label etic;
}

class FereastraMea extends Frame


{
public FereastraMea(String titlu)
{
super(titlu);
Toolkit t = Toolkit.getDefaultToolkit();
Dimension d = t.getScreenSize();
int h = d.height;
int w = d.width;
setSize(w/2, h/2);
setLocation(w/4, h/4);
}
}

class PrimaFereastra
{
public static void main(String[] args)
{
Frame f = new FereastraMea("Prima fereastra");
Mediator m = new Mediator(f);
m.assembleFrame();
}
}

Introducerea textului de la tastatură


Pentru a putea introduce text de la tastatură într-o aplicaţie cu interfaţă grafică, se utilizează un
element GUI numit câmp de editare, modelat de clasa TextField. Pentru exemplificare, se
consideră următorul program care citeşte elementele unui tablou. Se utilizează:
C un câmp de editare unde se introduce câte un element al tabloului,
C un buton prin care se comandă introducerea efectivă în tablou a textului editat;
C o etichetă care indică indicele elementului editat.
import java.awt.*;
6
import java.awt.event.*;

class Tablou
{
private int[] tab;
public Tablou(int n)
{
tab=new int[n];
}

public void setElem(int i, int val)


{
tab[i]=val;
}
public int getDim()
{
return tab.length;
}
}

class ReceptorEvenimentFereastra extendsWindowAdapter implements


ActionListener
{
private Mediator m;
public ReceptorEvenimentFereastra(Mediator m)
{
this.m=m;
}
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
public void actionPerformed(ActionEvent e)
{
m.buttonPressed();
}
}
class Mediator
{
public Mediator(Frame f, Tablou t)
{
this.f=f;
this.t=t;
}
public void assembleFrame()
{
ReceptorEvenimentFereastra r = new ReceptorEvenimentFe-
reastra(this);
f.addWindowListener(r);
b = new Button("Adauga");
b.addActionListener(r);
etic = new Label("Element 0");
tx = new TextField(15);
7
f.SetLayout(new FlowLayout());
f.add(b);
f.add(tx);
f.add(etic);
f.show();
}
public void buttonPressed()
{
if (contor < t.getDim())
{
try
{
int val = Integer.parseInt(tx.getText());
t.setElem(contor,val);
contor++;
}
catch (NumberFormatException e)
{
// daca nu s-a introdus o valoare numerica,
nu se actualizeaza tabloul
}
if (contor >= t.getDim())
etic.setText("Tablou plin!");
else
etic.setText("Element "+contor);
tx.setText("");
}
}
private int contor=0;
private Tablou t;
private Frame f;
private Button b;
private Label etic;
private TextField tx;
}

class FereastraMea extends Frame


{
public FereastraMea(String titlu)
{
super(titlu);
Toolkit t = Toolkit.getDefaultToolkit();
Dimension d = t.getScreenSize();
int h = d.height;
int w = d.width;
setSize(w/2, h/2);
setLocation(w/4, h/4);
}
}

class PrimaFereastra
{
public static void main(String[] args)
8
{
Frame f = new FereastraMea("Prima fereastra");
Tablou t = new Tablou(10);
Mediator m = new Mediator(f,t);
m.assembleFrame();
}
}
În cazul în care există mai multe butoane într-o fereastră, se folosesc următoarele soluţii:
C se construiesc două clase distincte pentru receptorii de evenimente ai celor două
butoane, definind corespunzător metodele actionPerformed;
C se utilizează informaţiile furnizate de obiectul eveniment ActionEvent pasat ca
parametru metodei actionPerformed. În acest caz, pentru obiectul eveniment,
poate fi apelată metoda:
public Object getSource();
care returnează o referinţă la obiectul sursă de eveniment.

Temă
Se cere să se realizeze un calculator, a cărui interfaţă să fie cea din figura de mai jos. Acesta
trebuie să permită introducerea a doi operanzi Õi efectuarea celor patru operaţii de bază: adunare,
scădere, înmulţire Õi împărţire. Fiecare operaţie este rezultat al acţionării cu mausul a butonului
corespunzător. Rezultatele vor fi puse într-o listă, care va avea facilitate de golire (prin acţionarea
butonului Clear). Cele patru butoane aferente operaţiilor vor fi deselectate în cazul în care cei
doi operanzi nu au ambii valori valide. În cazul împărţirii la zero se va afişa un mesaj de eroare.