Interfete grafice
Facilitati Java de lucru cu interfete apar în java.awt Abstract Windowing Toolkit
Exista trei aspecte care trebuie luate în considerare:
crearea si afisarea pe ecran a unei suprafete grafice pe care urmeaza a fi plasate diferite obiecte grafice; în plus pentru suprafata grafica trebuie stabilita o configuratie initiala (un sablon), constând din dimensiunile ei, unele obiecte grafice plasate de la început pe ea etc.;
o modalitate de pozitionarea a obiectelor pe suprafata grafica;
un mecanism prin care programul sa raspunda la diferite actiuni executate asupra obiectelor grafice 444y2424e (ca de exemplu un clic pe unul dintre acestea), conform dorintelor programatorului.
Exemplul 0 Sunt create un buton si un câmp de text. Actiunile asupra lor nu au nici un efect, iar fereastra nu poate fi închisa.
import java.awt.*;
public class Ex0
class F extends Frame
Principalele suprafete grafice corespund urmatoarelor clase din java.awt
Component (clasa
abstracta) Container Window Frame Dialog ScrollPane Panel Applet
Clasa abstracta Component, care este radacina arborelui claselor din AWT, defineste o interfata generala pentru toate componentele grafice. Obiectele de tip Component se numesc componente.
Un container (obiect de tip Container) este o componenta care poate include alte componente AWT, folosind de obicei o structura de lista.
O fereasta AWT (obiect de tipul Window) este o fereastra fara margini si fara bara de meniuri.
Un cadru (obiect de tip Frame) este o ferestra AWT cu margini, titlu si bara de meniuri.
O fereasta de dialog (obiect de tipul Dialog) extinde o fereastra AWT prin adaugarea de margini si a unui titlu; ea este folosita în principal pentru a prelua informatii de la utilizator.
Un panou (obiect de tipul Panel) este folosit pentru a grupa mai multe componente.
Numai componentele de tipurile ScrollPane Panel si Applet pot fi adǎugate containerelor (deci o fereastrǎ nu poate fi adǎugatǎ unui container). Un container poate fi inclus într-un alt container.
Crearea unei suprafete grafice nu implicǎ afisarea ei. De aceea am invocat metoda setVisible cu argumentul true Pentru setarea dimensiunilor cadrului (în pixeli), am invocat metoda staticǎ setSize
Neputând închide suprafata graficǎ, putem termina programul de exemplu prin ^C
Pentru plasarea componentelor în container, trebuie folosit un gestionar de pozitionare (layout manager).
Fiecǎrui container îi este asociat un gestionar de pozitionare implicit (de exemplu pentru cadre este folosit BorderLayout). Vom folosi în continuare doar FlowLayout, care plaseazǎ componentele în container de la stânga la dreapta si de sus în jos.
Gestionarul de pozitionare a fost specificat prin invocarea metodei setLayout din clasa Container. Sǎ observǎm cǎ dacǎ modificǎm dimensiunile suprafetei grafice, se pǎstreazǎ modul de pozitionare specific gestionarului folosit.
Controale grafice (componente elementare)
Component Button Canvas Checkbox Choice Label List Scrollbar TextComponent TextArea TextField
Controalele grafice permit
interactiunea cu utilizatorul. Ele corespond claselor ce apar subliniate
în urmǎtoarea ierarhie:
Controalele grafice pot fi adǎugate containerelor; adaugarea se face conform regulilor stabilite de gestionarul de pozitionare ales. Fie C un container si c un control grafic. Adǎugarea lui c la C se face astfel:
C.add(c);
Schema generalǎ de lucru cu AWT
Schema urmeazǎ asa-numita programare orientatǎ pe evenimente.
Evenimente
Când actionǎm asupra unei componente, apare un eveniment. Un eveniment este un obiect de tipul unei anumite clase. Evenimentul are un tip, care este o clasǎ tipEvent din pachetul java.awt.event
Iatǎ o scurtǎ listǎ de evenimente:
Tip |
Un eveniment de acest tip apare dacǎ actionǎm asupra: |
Action Adjustment Text Mouse Window |
Button, List, TextFieldScrollbar TextArea, TextField Mouse: click, apǎsare, eliberare Window: închidere, minimizare/maximizare |
Pentru a specifica o actiune la aparitia unui eveniment, trebuie mai întâi sǎ îi asociem un gestionar (listener, handler) H
Fie de exemplu c un control grafic sau o fereastrǎ. Putem sǎ îi asociem un gestionar H (mai spunem cǎ H este înregistrat ca gestionar pentru c) astfel:
c.addtipListener(H);
Pentru fiecare tip de actiune asupra unui control grafic, existǎ o metodǎ anuntatǎ în interfata tipListener sau în clasa tipAdapter. De exemplu interfata MouseListener anuntǎ metode separate pentru click, apǎsare si eliberare.
Toate metodele din clasele tipAdapter specificǎ actiunea vidǎ.
În general, metodele din interfetele tipListener si din clasele tipAdapter au un parameter de tipul tipEvent. Acesta foloseste pentru a identifica controlul grafic asupra cǎruia s-a actionat (de exemplu douǎ butoane pot folosi acelasi handler).
Observatie. Este posibil sǎ atasǎm mai multi gestionari unui aceluiasi control grafic. De asemenea, acelasi handler poate fi asociat mai multor controale grafice.
Exemplul 1. În plus fata de exemplul anterior, când apǎsǎm pe buton, apare mesajul "O.K." în câmpul de text.
import java.awt.*;
import java.awt.event.*;
public class Ex1
class F extends Frame
class BHandler implements ActionListener
public void actionPerformed(ActionEvent e)
Observatii:
singura metodǎ anuntatǎ în interfata ActionListener este actionPerformed
în continuare cadrul nu poate fi închis;
este permis sǎ specificǎm drept handler chiar clasa curentǎ, dar este recomandat sǎ separǎm aplicatia de implementare.
Exemplul 1 (variantǎ). Aplicatia si implementarea coincid.
import java.awt.*;
import java.awt.event.*;
public class Ex11
class F extends Frame implements ActionListener
public void actionPerformed(ActionEvent e)
Exemplul 2. Mutǎm un sir de caractere dintr-un câmp de text în altul.
import java.awt.*;
import java.awt.event.*;
public class Ex2
class F extends Frame
}
);
}
class BHandler implements ActionListener
public void actionPerformed(ActionEvent e)
Observatie. Pentru închiderea ferestrei am apelat la clase interne. varianta clasica era de a folosi o clasa:
class WHandler extends WindowAdapter
si apoi de a crea un obiect de tipul ei si a adaga ferestrei acest obiect (handler):
WHandler WH = new WHandler();
addWindowListener(WH);
Exemplul urmǎtor este mai complex si ilustreazǎ urmǎtoarele aspecte:
gruparea mai multor controale grafice într-un panou;
utilizarea mai multor handlere pentru un control grafic;
utilizarea aceluiasi handler de cǎtre mai multe controale grafice.
Exemplul 4. Dorim sa creǎm o interfatǎ graficǎ de forma:
cu un buton, un câmp de text si alte 5 câmpuri de text.
Dorim urmǎtoarele:
- sǎ grupǎm cele 5 câmpuri de text într-un panou;
- la apǎsǎri successive pe buton, caracterele din cele 5 câmpuri de text trebuie sǎ treacǎ de la "literǎ micǎ" la "literǎ mare" si apoi invers. În plus, la apǎsarea butonului, dorim ca la iesirea standard sǎ aparǎ mesajul "Buton apasat";
- la introducerea unui sir de caractere nevid s în primul câmp de text si apǎsarea tastei <Enter>, caracterele din cele 5 câmpuri de text sǎ treacǎ la literǎ micǎ sau literǎ mare, dupǎ cum primul caracter din s este literǎ micǎ sau mare.
import java.awt.*; import java.awt.event.*;
class Ex4
class F extends Frame implements ActionListener
}
);
}
public void actionPerformed(ActionEvent e)
class P extends Panel
}
class HModif implements ActionListener
void modif(boolean bool)
}
public void actionPerformed(ActionEvent e)
else ;
else
}
A fost creat un cadru f, care contine butonul b, câmpul de text t si panoul care grupeazǎ cele 5 câmpuri de text.
Existǎ doi gestionari pentru buton: obiectul f de tipul F si obiectul HM de tipul HModif. Constructorul clasei HModif primeste butonul, câmpul de text si panoul.
Obiectul HM este înregistrat si el ca handler pentru câmpul de text.
Când actionǎm asupra unei componente, apare un eveniment. Un eveniment este un obiect de tipul unei anumite clase. Evenimentul are un tip, care este o clasǎ tipEvent din pachetul java.awt.event
Pentru a specifica o actiune la aparitia unui eveniment, trebuie mai întâi sǎ îi asociem un gestionar (listener, handler) H
Fie de exemplu c un control grafic sau o fereastrǎ. Putem sǎ îi asociem un gestionar H (mai spunem cǎ H este înregistrat ca gestionar pentru c) astfel:
c.addtipListener(H);
Pentru fiecare tip de actiune asupra unui control grafic, existǎ o metodǎ anuntatǎ în interfata tipListener sau în clasa tipAdapter. De exemplu interfata MouseListener anuntǎ metode separate pentru click, apǎsare si eliberare.
Toate metodele din clasele tipAdapter specificǎ actiunea vidǎ.
În general, metodele din interfetele tipListener si din clasele tipAdapter au un parameter de tipul tipEvent. Acesta foloseste pentru a identifica controlul grafic asupra cǎruia s-a actionat (de exemplu douǎ butoane pot folosi acelasi handler).
Observatie. Este posibil sǎ atasǎm mai multi gestionari unui aceluiasi control grafic; în acest caz, declansarea evenimentului este comunicata tuturor gestionarilor. De asemenea, acelasi handler poate fi asociat mai multor controale grafice.
Observatie. Dacǎ un handler este asociat mai multor controale grafice, trebuie sǎ diferentiem între ele.
Dacǎ controalele grafice sunt de tipuri diferite, putem folosi metoda:
public Object getSource()
pentru a identifica sursa.
Dacǎ controalele grafice sunt de acelasi tip, putem folosi metoda:
public String getActionCommand()
care întoarce eticheta sursei.
Button buton
Canvas suprafata de desenare
Checkbox casuta de optiuni
Choice lista de optiuni cu alegere unica
Label eticheta
List lista de optiuni cu alegere multipla
Scrollbar bara de defilare
TextComponent
TextArea arie de text
TextField câmp de text
Etichete. Clasa Label
Clasa:
public class Label extends Component
are constructorii:
Label
construieste o eticheta cu text vid;
Label(String text)
construieste o eticheta cu textul specificat, aliniat la stânga
si constantele publice întregii RIGHT CENTER si LEFT, prin care se poate specifica plasarea etichetei.
Dintre metodele clasei Label mentionam:
public void setText(String text)
public String getText()
public void setAlignment(int i)
prin care este înscris un text pe eticheta, este întors textul asociat etichetei, respectiv se specifica alinierea textului în eticheta (precizând pentru argument una dintre constantele clasei). Alinierea implicita este la stânga.
Butoane. Clasa Button
public class Button extends Component
Un clic pe un buton declanseaza un eveniment de tip ActionEvent
Button
construieste un buton fara eticheta;
Button(String label)
construieste un buton pe care este înscrisa eticheta label
String getLabel()
întoarce eticheta înscrisa pe buton;
void setLabel(String label)
înscrie pe buton eticheta label
Câmpuri si arii de text de text. Clasele TextField si TextArea
Începem prin a prezenta clasa:
public class TextComponent extends Component
care este superclasa claselor TextField si TextArea
Principalele metode publice ale clasei sunt:
void setText(String text)
seteaza textul afisat de componenta;
String getText()
întoarce textul afisat de componenta;
void setEditable(boolean b)
stabileste daca textul atasat componentei este sau nu editabil;
void select(int p, int u)
selecteaza subtextul ce începe de pe pozitia p si se termina pe pozitia u-1. Trebuie ca p u; daca p=u, atunci întreg textul este deselectat;
void selectAll()
selecteaza întreg textul;
String getSelectedText()
întoarce textul selectat;
int getSelectionStart()
întoarce pozitia de început a zonei selectate;
int getSelectionEnd()
întoarce pozitia de sfârsit a zonei selectate;
Mai specificam ca un subtext poate fi selectat si cu ajutorul mouse-ului.
Modificarea textului din componenta declanseaza un eveniment de tipul Text
Clasa:
public class TextField extends TextComponent
ofera facilitati de lucru cu câmpurile de text, ce permit editarea unei unice linii de text.
Prezentam în continuare constructorii si câteva metode publice ale clasei:
TextField
construieste un câmp de text;
TextField(String text)
construieste un câmp de text initializat cu text
TextField(int col)
construieste un câmp de text cu col coloane;
TextField(String text, int col)
construieste un câmp de text cu col coloane, initializat cu text
void setText(String text)
înscrie textul text în câmp;
void addActionListener(ActionListener l)
void removeActionListener(ActionListener l)
La actionarea unei taste în câmpul de text, va fi declansat un eveniment de tipul Key. La apasarea tastei <Enter> este declansat un eveniment de tipul Action
Clasa:
public class TextArea extends TextComponent
ofera facilitati de lucru cu arii de text, care generalizeaza câmpurile de text prin acceptarea mai multor linii de text. De fapt este vorba de un unic text, în care tastarea lui <Enter> pe o pozitie are ca efect trecerea la o linie noua, conform noului caracter introdus. Putem atasa ariei o bara de defilare orizontala, una verticala sau ambele aceste bare; utilitatea lor apare atunci când textul de pe o linie este mai lung decât numarul de coloane stabilit pentru arie, respectiv când numarul efectiv de linii este mai mare decât numarul de linii stabilit pentru aria de text.
Clasa TextArea are câmpurile constante, publice si întregi:
SCROLLBARS_NONE
SCROLLBARS_VERTICAL_ONLY
SCROLLBARS_HORIZONTAL_ONLY
SCROLLBARS_BOTH
prin care putem stabili sistemul de bare de defilare ales.
Constructorii clasei sunt:
public TextArea()
construieste o arie de text cu ambele bare de defilare;
public TextArea(String text)
construieste o arie de text cu ambele bare de defilare, în care este înscris textul text;
public TextArea(int m, int n)
construieste o arie de text cu ambele bare de defilare, având m linii si n coloane;
public TextArea(String text, int m, int n)
construieste o arie de text cu ambele bare de defilare, având m linii si n coloane si în care este înscris textul text
public TextArea(String text, int m, int n, int defilare)
în plus fata de constructorul precedent, este specificat sistemul de bare de defilare ales; defilare trebuie sa fie una dintre cele 4 constante ale clasei.
Dintre metodele, toate publice, ale clasei TextArea, prezentam urmatoarele:
void setRows(int m)
stabileste la m numarul de linii ale ariei de text;
void setColumns(int n)
stabileste la n numarul de coloane ale ariei de text;
void insert(String str, int poz)
insereaza textul str la pozitia poz din aria de text;
void append(String str)
adauga textul str ariei de text;
void replaceRange(String str, int p, int u)
înlocuieste textul dintre pozitiile p si u cu textul str
Pozitiile de mai sus se refera la întreg textul; asa cum am precizat, este vorba de un unic text, în care aparitia unui terminator de linie determina în aria de text deplasarea pe urmatoarea linie.
Actionarea unei taste în câmpul de text conduce la declansarea unui eveniment de tipul Key
Exemplul 5. Vom afisa un câmp de text, o arie de text si un buton. La apasarea tastei <Enter> în câmpul de text, continutul sau este adaugat ariei de text la sfârsitul acesteia. La apasarea butonului, zona selectata din aria de text este copiata în câmpul de text si la iesirea standard, dupa care este eliminata din aria de text.
import java.awt.*;
import java.awt.event.*;
class T_Area
class F extends Frame implements ActionListener
}
);
public void actionPerformed(ActionEvent e)
else ta.append(tf.getText());
Casute de optiuni. Clasele Checkbox si CheckboxGroup
O casuta de optiuni (checkbox) este o componenta simpla care poate fi doar într-una dintre starile "selectata" sau "neselectata".
public class Checkbox extends Component
Clasa Checkbox prevede constructorii:
public Checkbox()
creeaza o casuta de optiuni fara eticheta atasata; starea casutei este "neselectata";
public Checkbox(String et, boolean stare)
creeaza o casuta de optiuni cu eticheta et; starea casutei este data de stare
Pentru setarea etichetei casutei va fi invocata metoda:
public void setLabel(String label)
O actiune asupra unei casute de optiuni declanseaza un eveniment de tipul Item
Clasa urmatoare:
public class CheckboxGroup extends Object
ofera facilitati pentru gruparea mai multor casute de optiuni. Într-un astfel de grup, la orice moment de timp exact o casuta este în starea "selectata". Apasarea unei casute face ca ea sa devina unica în starea "selectata".
Prezentam doar un constructor al clasei:
public CheckboxGroup()
Crearea si adaugarea unei casute de optiuni la un grup se realizeaza folosind urmatorul constructor al clasei CheckBox
public Checkbox(String et, CheckboxGroup grup, boolean stare)
Exemplul 6. Vom construi un cadru format din doua panouri: primul cuprinde trei casute de optiuni independente, iar al doilea cuprinde un grup de alte trei casute de optiuni:
import java.awt.*;
public class Chk_Box extends Frame
cu urmatoarea precizare: cuprinderea unor casute într-un grup nu are nici o legatura cu adaugarea lor într-un panou.
Containerul ScrollPane
Containerul ScrollPane este folosit deobicei în situatia în care construim o interfata grafica ce nu poate aparea în întregime pe ecran, situatie în care sunt necesare bare de defilare orizontala/verticala, sau numai una dintre ele. Clasa corespunzatoare este definita prin:
public class ScrollPane extends Container
implements Accessible
Pentru acest container putem impune crearea barelor de defilare sau putem alege varianta (implicita) în care ele apar numai atunci când este necesar. În acest scop pot fi folosite câmpurile statice întregi SCROLLBARS_ALWAYS si SCROLLBARS_ALWAYS
Este important de notat ca acest container are exact un container fiu asupra caruia se poate actiona prin folosirea barelor de defilare.
Constructorul clasei ScrollPane are signatura vida.
Dintre metode specificam doar:
protected final void addImp(Component c, Object ob, int index)
prin care componenta c este desemnata ca fiul containerului care invoca metoda. Vom lua totdeauna ob=null si index=0
Exemplul 7. Dorim sa cream o interfata grafica în care apar 20 de arii de text pentru care specificam initial 4 linii.
Întrucât continutul interfetei grafice nu poate sa apara în totalitate pe ecran, vom apela la un container ScrollPane
Mai apare dificultatea ca o fereastra nu poate fi adaugata unui container. De aceea procedam dupa cum urmeaza:
construim un cadru f
construim obiectul sp de tipul ScrollPane, pe care îl adaugam cadrului;
la constructia lui sp definim un panou ce contine cele 20 de arii de text, panou pe care îl desemnam ca fiu al lui sp
Mai pe scurt, în loc de a adauga fereastra containerului (lucru nepermis), am adaugat fereastra unui cadru, iar pe acesta îl adaugam containerului.
import java.awt.*;
class S
class Scroll extends ScrollPane
addImpl(p,null,0);
}
Suprafete de desenare. Clasele Canvas si Graphics
Suprafetele grafice ofera facilitatea de control la nivel de pixel. Pe o astfel de suprafata se pot desena, folosind metode ale clasei Graphics, segmente de dreapta, dreptunghiuri, ovale etc.; la desenare poate fi aleasa o culoare. De asemenea contururile închise pot fi "umplute" cu o culoare. Pe o suprafata de desenare mai pot fi plasate si imagini, pot fi create propriile butoane etc.
Clasa Canvas este deosebit de complexa, nu atât direct prin metodele sale, ci mai ales prin posibilitatea de a folosi alte clase ca de exemplu cele pentru grafica bi- si tridimensionala. Vom reduce însa prezentarea la câteva facilitati mai des folosite.
Modul standard de creare a unei suprafete grafice consta în extinderea clasei Canvas, redefinind metoda paint, ce afiseaza componenta. Modificarile ulterioare devin vizibile prin invocarea metodei repaint
O suprafata grafica reprezinta un dreptunghi de pixeli, cu coltul din stânga sus având coordonatele Este folosit un context de desenare; nu vom intra în amanunte, ci vom folosi contextul de desenare standard disponibil.
Pentru clasa Canvas precizam doar urmatoarele elemente:
public class Canvas extends Component
public Canvas()
public paint(Graphics g)
cu mentiunea ca invocarea metodei paint pune la dispozitie contextul de desenare standard g. Faptul ca este extinsa clasa Component permite captarea de evenimente specifice acestei clase, ca de exemplu Key Mouse MouseMotion
Prezentam în continuare câteva elemente legate de clasa Graphics. Atât clasa, cât si metodele sale, au modificatorii public si abstract. Mentionam ca un context de desenare are atasate câteva informatii curente, printre care culoarea curenta de desenare si fontul curent. Drept urmare, de exemplu trasarea unei linii si "umplerea" unui contur se fac folosind culoarea curenta.
class Graphics extends Object
Color getColor()
void SetColor(Color c)
este obtinuta, respectiv setata, culoarea curenta de desenare;
Font getFont()
void setFont(Font f)
este obtinut, respectiv setat, fontul curent;
void drawLine(int x1, int y1, int x2, int y2)
este trasat un segment între punctele de coordonate (x1,y1) si (x2,y2)
void drawPolyline(int[] x, int[] y, int n)
este trasata o linie poligonala ce trece, în ordine, prin n puncte ale caror coordonate sunt specificate în tablourile x si y
void drawRect(int x, int y, int w, int h)
este trasat un dreptunghi: coltul din stânga sus are coordonatele (x,y), iar latimea si înaltimea sa sunt w, respectiv h
void fillRect(int x, int y, int w, int h)
un dreptunghi specificat ca mai sus este "umplut" cu culoarea curenta;
void drawOval(int x, int y, int w, int h)
este trasata o elipsa tangenta la laturile dreptunghiului precizat;
void fillOval(int x, int y, int w, int h)
este umpluta o elipsa tangenta la laturile dreptunghiului precizat.
Exemplul 8. Dorim sa figuram pe ecran puncte din plan (raportate la axele de coordinate).
import java.awt.*; import java.awt.event.*;
import java.io.*;
import java.util.*;
public class Linii
class F extends Frame
}
);
}
class Grafic extends Canvas
catch(FileNotFoundException e)
int x,y;
while( sc.hasNextFloat() )
}
|