Java programozási nyelv 2007-2008/ősz 4. óra Eseménykezelés Java környezetben, AWT alapok Felhasználói felületek Eseménykezelés AWT ablakozó rendszer legradi.gabor@nik.bmf.hu szenasi.sandor@nik.bmf.hu
Eseménykezelés, AWT alapok Témakörök Felhasználói felületek AWT alapok Események kezelése NetBeans lehetőségei 2
Felhasználói felület Felhasználói felület: olyan, az alkalmazáshoz rendelt felület, amely megkönnyíti az ember-gép kommunikációt, segítségével akár kis előképzettséggel is a program könnyen kezelhető. Formái: Karakteres: kis erőforrásigényű, viszont szegényes eszközkészletű Grafikus ( GUI, graphical user interface): gazdag eszközkészletű, de több erőforrást is igényel MVC modell (Model-View-Controller modell): az adott alkalmazást három, jól elkülöníthető részként értelmező modell Model: az alkalmazásban elvégzendő feladat modellje View: a megjelenítést végző rész Controller: a modell működése alapján ez vezérli (utasítja) a megjelenítő részt 3
Eszközkönyvtárak A Java nyelv két eszközkönyvtárat is elérhetővé tesz a felhasználói felületek kialakítására AWT (Abstract Windowing Toolkit): jobban kötődik a hordozó operációs rendszerhez, annak eszközeit használja, gyors, kisszámú komponensből áll SWING: gazdag komponenskészlet jellemzi, kevébé kötődik a hordozó operációs rendszerhez, Java-ban írták meg (lassabb működésű az AWT-nél) Ezen eszközkészletek felhasználása mindig az adott alkalmazástól függ Az eszközkészlet felhasználása során mindig figyelembe kell venni, hogy a program használata során milyen eszközkészlet lesz majd elérhető (JVM verzió) 4
Komponensek A felhasználó felületet komponensek alkotják, melyek lehetnek: Hordozó típusú komponensek ( konténerek ): képesek más hordozó, illetve hordozott komponenseket viselni, ilyenek lehetnek például az ablakok Hordozott komponensek ( komponensek ): megjelenítésükhöz és működtetésükhöz szükség van hordozó típusú komponensekre is, ilyenek lehetnek például a gombok, adatbeviteli mezők stb. A hordozó komponensek általában hordozottként is viselkednek, emiatt ezek egymásbaágyazhatók A grafikus felhasználói felületű alkalmazás hierarchikus módon építhető fel, amely felépítés kiindulópontja mindig egy hordozó komponens, levélelemei pedig általában hordozott komponensek 5
GUI létrehozásának lépései Alkalmazási kör meghatározása A szükséges komponsenek listájának összeállítása Az alkalmazható komponens hierarchia megtervezése, A komponensek összeállítása (a hordozott komponensek irányából azaz a levélelemektől haladunk a hierarchia kiindulóponja azaz a gyökérelem felé) A komponensek viselkedését szabályozó eseménykezelőket a megfelelő komponsesekhez kötjük Elinditjuk (megjeleníttetjük) a főablakot jelentő hordozó komponenst A grafikus felületű programot általában üzenetvezérelt módon működtetjük. A program indítása után a vezérlés egy végtelenített ciklusba kerül, amely a felhasználótól érkező üzeneteket továbbítja a megfelelő komponensek felé (pl. egérkattintás esemény a gomb felé) 6
Eseménykezelés, AWT alapok Témakörök Felhasználói felületek AWT alapok Események kezelése NetBeans lehetőségei 7
AWT alapok AWT eszközkészlet: jobban kötődik a hordozó operációs rendszerhez, viszont gyorsabb működésű a SWING-nél Az AWT minden komponensének őse: java.awt.component Az AWT minden konténerének őse: java.awt.container A Container a Component osztály leszármazottja, ezek egymásbaágyazása tehát egyszerűen megoldható A konténerek feladata a bennük található komponensek megjelenítése. Hogy pontosan milyen sorrendben és hol, ez nem (feltételnül) a más nyelvekben megszokott koordináták alapján történik, hanem tetszőleges ún. pakolási stratégiák szerint (ezek is objektumok, amik megvalósítják a LayoutManager interfészt) 8
AWT konténerek Új komponensek felvétele/módosítása public Component add(component comp) Új komponens felvétele a komponens lista végére public Component add(component comp, int index) Komponens felvétele megadott helyre public void add(component comp, Object constraints) Komponens felvétele, a második paraméterben van lehetőség a pakolási stratégiától függő helymeghatározásra public void remove(component comp) Megadott komponens törlése a listából public void validate() Módosítás esetén a komponensek újrarendszerezése Komponensek listájának lekérdezése public Component[] getcomponents() 9
Alapvető (gyári) pakolási stratégiák Pakolási stratégia kiválasztása: public void setlayout(layoutmanager mgr) FlowLayout.add(komp); Egymás mellé pakolja a vezérlőket, amíg lehet, majd a következő sorba BorderLayout N.add(komp, North ); Az égtáj szerint megadott területet W C kitölti a komponens. Egyéb: CardLayout, GridLayout stb. S Layout manager nélkül: paraméterként null-t átadva nincs pakolási stratégia (abszolút koordináták) Az elhelyezett komponensek természetesen lehetnek panelek is egy másik elhelyezési stratégiával E 10
AWT konténer implementációk java.awt.panel Legegyszerűbb konténer, tartalmazza és megjeleníti a tartalmazott komponenseket java.awt.applet Panel leszármazottja, weboldalba ágyazható java.awt.scrollpane Panel leszármazott, amennyiben az általa tartalmazott konténereket nem tudja kirajzolni egyszerre, automatikusan megjeleníti a szükséges gördítősávokat java.awt.window Panel leszármazott, önmagában működőképes ablak java.awt.frame Ablak leszármazottja, fejléccel/kerettel kiegészítve java.awt.dialog Ablak leszármazott, fejléc/keret egyszerűbb adatbevitelre 11
Egyszerű konténer példa Példa egy Frame létrehozására két komponenssel: import java.awt.*; public class Main { public static void main(string[] args) { Frame fr = new Frame(); fr.setlayout setlayout(new FlowLayout()); fr.setbounds setbounds(100, 10, 300, 300); Button btn = new Button("Lenyom"); fr.add add(btn, "South"); TextField tx = new TextField(); fr.add add(tx, "North"); fr.setvisible setvisible(true); } } Próbáljunk ki más elrendezési stratégiákat is 12
AWT hordozott komponensek Hordozott komponensek általános tulajdonságai public void setname(string name) public Container getparent() public void setbounds(int x, int y, int width, int height) public void paint(graphics g) public void setfocusable(boolean focusable) public boolean isfocusowner() public void add(popupmenu popup) Eseménykezelők feliratkozása: add...listener(...) Eseménykezelők leiratkozása: remove...listener(...) Érdemes megjegyezni, hogy a konténerek is a Component osztály leszármazottai, tehát ugyanazokkal a tulajdonságokkal rendelkeznek 13
AWT hordozott komponensek Button: egyszerű nyomógomb public Button(String label) public void setlabel(string label) public String getlabel() Label: nem módosítható szöveg megjelenítése public Label(String text) public void settext(string text) public String gettext() Canvas: téglalap alakú terület, amelyre közvetlenül rajzolni lehet public void paint(graphics g) Ilyenkor célszerű ezt a metódust felülbírálni 14
AWT hordozott komponensek Checkbox: logikai érték kiválasztására szolgál public Checkbox(String label) public Checkbox(String label, boolean state) public Checkbox(String label, boolean state, CheckboxGroup grp) public void setlabel(string label) public String getlabel() public void setstate(boolean state) public boolean getstate() CheckboxGroup: segítségével lehetőség van Checkbox komponensek (kizáró) csoportban való kezelésére public Checkbox getselectedcheckbox() public void setselectedcheckbox(checkbox selected) 15
AWT hordozott komponensek Choice: legördülő lista public add(string item) public remove(int pos) public remove(string str) lista elemek karbantartása public int getitemcount() public String getitem(int pos) public int getselectedindex() public String getselecteditem() kiválasztott elem public void select(int pos) public void select(string str) Lista: hasonló, csak egyszerre több elem kiválasztását is engedélyezi. További metódusai: public void setmultiplemode(boolean b) public String[] getselecteditems() public boolean isindexselected(int index) 16
AWT hordozott komponensek TextField: egysoros szöveg bevitelére szolgál public String gettext() public settext(string text) public String getselectedtext() public int getselectionstart() public int getcolumns() public void setcolumns(int columns) public void seteditable(boolean b) TextArea: többsoros szöveg bevitelére szolgál public void getrows(int rows) public void setrows(int rows) public void append(string str) public void insert(string str, int pos) 17
AWT hordozott komponensek Scrollbar: számérték beolvasása csúszkával public void setminimum(int newminimum) public void setmaximum(int newmaximum) public int getvalue() TextField: egysoros szöveg bevitelére szolgál public String gettext() public settext(string text) public String getselectedtext() public int getselectionstart() public void seteditable(boolean b) TextArea: többsoros szöveg bevitelére szolgál public void append(string str) public void insert(string str, int pos) 18
Feladatok 4.1. feladat: Készítsünk egy egyszerű Hello world alkalmazást vizuális felületen! 4.2. feladat: készítsünk alkalmazást, amely bemutatja a LayoutManager lehetőségeit! 4.3. feladat: készítsen alkalmazást, amely grafikus felületen keresztül létrehoz Személy objektumokat, majd ezekből feltölt egy tömböt! 4.3. Feladat: készítsünk alkalmazást, amely újabb osztályok (Font, Color) alkalmazásával módosítja a program kinézetét! 19
Eseménykezelés, AWT alapok Témakörök Felhasználói felületek AWT alapok Események kezelése NetBeans lehetőségei 20
Események kezelése Esemény: olyan történés, amely az adott komponens működését befolyásolja, és amelyet az adott komponens le is tud kezelni, pl. gomblenyomás, mely után a gomb megfelelő eseménykezelő metódusa elindít egy alkalmazást Események fajtái: Közvetlen beviteli esemény, Komponensek által kiváltott esemény, OOP alapú eseménykezelés résztvevői: Esemény létrehozó ( eseményforrás ): pl. egy gomb, amelynek lenyomására elindul az eseménykezelés Esemény objektum: a lenyomás által létrehozott objektum, amelyet megkapnak a az eseménykezelők Esemény feldolgozó (esemény nyelő): olyan objektum (illetve annak egy metódusa), amely az esemény feldolgozását végzi el Nem minden komponenshez értelmezett minden esemény, a vezérlőeszközől függően más-más eseményekre számíthatunk 21
Esemény feldolgozása (AWT) Eseményt leíró osztályok őse: java.util.eventobject Az AWT komponensei által küldött események leírása a java.awt.event csomagban java.awt.awteventőssel Minden...Event eseményhez tartozik egy...listener interfész, amely az eseményre reagáló metódusokat definiálja A komponensenk által küldött eseményeket az interfész által definiált process...event(...) metódusok megvalósításával dolgozzák fel a fogadók Az események fogadásához a figyelő objektumot egy add...listener(object) metódus hívásával regisztrálni kell az eseményeket küldő komponensnél Megszüntetés remove...listener(object) művelettel Ha az interfésznek több metódusa is van, akkor általában tartozik hozzá egy...adapter osztály is, amely üres törzzsel implementálja a specifikált metódusokat 22
Gomb lenyomásának figyelése Esemény objektum java.awt.event.actionevent public void setsource(object newsource) public int getmodifiers() Esemény figyelők által megvalósítandó interfész java.awt.event.actionlistener void actionperformed(actionevent e) Esemény regisztráció metódusai a gomb komponensen java.awt.button public void addactionlistener(actionlistener l) public void removeactionlistener(actionlistener l) Eseménykezelés lépései: Eseménykezelő objektum példányosítása Regisztráció az esemény forrásánál 23
Egyszerű konténer példa Előző program kiegészítése eseménykezeléssel: import java.awt.event.*; class EsemenyForrasKiiro implements ActionListener { TextField modositando; public EsemenyForrasKiiro(TextField tx) { modositando = tx; } public void actionperformed(actionevent event) { modositando.settext settext("lenyomtak:" + event.getsource getsource()); } }...... EsemenyForrasKiiro szm = new EsemenyForrasKiiro(tx); btn.addactionlistener addactionlistener(szm); 24
Eseménykezelő architektúrák Külső eseménykezelő Az eseményt kezelő objektum és az esemény forrása az osztályhierarchia, illetve az objektumpéldányok kialakítása során is egymástól függetlenül kezelhetők (csak az interfész tartja közöttük a kapcsolatot) Az eseménykezelő vagy az eseményobjektumból, vagy előzőleg kapott (pl. a konstruktor) paramétereiből ismerheti a küldő környezetét Eseménykezelő konténer Mint az előző példában is látható, ez gyakran nem alkalmazható jól a gyakorlatban. Gyakori feladat ugyanis, hogy egy komponens eseménykezelőjének el kell érnie a komponenssel egy ablakon található többi vezérlőt Ezért gyakori megoldás, hogy a komponenseket tartalmazó legmagasabb szinten található konténer (az általunk tervezett ablak) fogadja az összes benne található komponens eseményeit 25
Eseménykezelő architektúrák Több eseménylétrehozóra való feliratkozás Bár minden egyes komponenshez írható egy-egy eseménykezelő osztály, vagy hozható létre egy osztálynak több példánya, a gyakorlatban ez nem minden esetben ajánlott a kód olvashatósága érdekében. Ilyenkor célszerű egy eseménykezelő objektumot több eseményforrásnál is regisztrálni Küldő meghatározása Ebben az esetben azonban bármelyik komponens indítja az eseményt, mindig ugyanaz az eseménykezelő objektum ugyanaz a metódusa fut le Emiatt szükség lehet a küldő azonosítására, ez azonban mindig egyszerűen megoldható az eseményobjektum getsource() metódusa segítségével A mai fejlesztői környezetek képesek az eseménykezelő kód generálására, így a fejlesztés jelentősen gyorsítható 26
Eseménykezelés, AWT alapok Témakörök Felhasználói felületek AWT alapok Események kezelése NetBeans lehetőségei 27
NetBeans támogatás Új Frame osztály létrehozása File/New Paraméterek beállítása Osztály neve Állomány név Csomag 28
NetBeans támogatás Vizuális tervezés Generált kód 29
Ajánlott irodalom Az óra anyagához kapcsolódó irodalom Nyékyné Gaizler Judit: Java 2 útikalauz programozóknak 1.3 I.; ELTE TTK Hallgatói alapítvány, Budapest 259 279..o. Creating UI with AWT http://brandt.kurowski.net/teaching/java/tutorial.htmljava SWING Tutorial http://java.sun.com/docs/books/tutorial/uiswing/index.html 30