Java GUI události Cílem kapitoly je přiblížit hlavní princip událostmi řízeného programování a ukázat na příkladu způsob řešení pro konkrétní případ. Soubor obsahuje také tabulku s přehledem nejčastěji používaných událostí. Klíčové pojmy: Událost, obsluha událostí, listenery = posluchači událostí Událostmi řízené programování u konzolové aplikace spustíme program a jeho kód rozhoduje o pořadí provádění jednotlivých činností na rozdíl od toho je chod programu založeného na oknech řízen tím, co s aplikací provádí uživatel program po spuštění nic nedělá, jen čeká na nějakou akci, na nějakou událost událost vzniká jako důsledek činnosti uživatele, programu nebo operačního systému událost (event) jsou signály přijímané programem od operačního systému, většinou na základě akcí uživatele uživatel komunikuje s aplikací pomocí grafických komponent umístěných v okně příkladem událostí jsou: stisk tlačítka, posun myši, stisk klávesy, maximalizace, minimalizace okna, zavření okna, změna rozměrů okna,... když se nějaké komponentě přihodí nějaká událost, může tato komponenta o tom poslat zprávu nějaké jiné grafické komponentě událost způsobí zaslání zprávy posluchači druhá komponenta pak na zprávu může nějak reagovat (změní svoji barvu, svůj text, zmizí nebo se objeví, ) Zpracování = obsluha událostí Listener = posluchač události na formuláři jsme vytvořili několik tlačítek, zatím jsme jim však nepřiřadili žádnou akci, po stisknutí tlačítka se nic neděje každá z vizuálních komponent má vlastní události, na které můžeme reagovat, tzv. je obsloužit (tlačítko můžeme stisknout, radiobutton můžeme vybrat nebo naopak zrušit jeho výběr, textové pole může získat nebo ztratit zaměření = fokus,...) v Javě existují speciální instance, které události zachycují, nazýváme je listenery, tj. posluchači 28.3.2011 Java - GUI - události 1/6
určitý typ listeneru může naslouchat pouze jemu odpovídajícímu typu události, listenery tedy fungují adresně instance, která chce přijímat události, se musí nejprve jako posluchač zaregistrovat je to jako na takové zvláštní vojně: vojáci (posluchači události) si na začátku vyberou velícího důstojníka (zdroj události), kterého chtějí poslouchat, zaregistrují se u něj také si vyberou událost, na jakou budou reagovat (třeba jen na pokyny hlasem nebo jen na pokyny rukama, nebudou reagovat na všechny projevy velícího důstojníka) posluchači událostí v Javě to provedou pomocí metody addxxxlistener(), kde XXX představuje typ události (tady stisk, přejetí myší, ) zaregistrovaný objekt musí implementovat rozhraní XXXListener (voják se zaváže, že dokáže reagovat na určitý druh příkazu, že když příkaz např. uslyší, něco udělá) vojáci (posluchači události) pak jen stojí a čekají, až jejich důstojník jim zadá příkaz domluveným způsobem (např. hlasem), a ten pak provedou na nic jiného, než na co se dohodli, nereagují, je zbytečné, aby důstojník běhal okolo a mával rukama, správným posluchačům je to jedno Třídy událostí když vznikne nová událost, vznikne nová instance události zdroje události jsou potomky třídy java.awt.event instance událostí jsou instancemi odpovídajících tříd událostí, XXXEvent obslužný kód je psán do metod, které nazýváme handlery handleru je předán také objekt události, z jehož vlastností můžeme získat cenné informace Handler metoda ošetřující danou událost v handleru provedeme obsluhu události, tj. nějakým způsobem na ní reagujeme postupujeme tak, že zjistíme název rozhraní XXX pro listener zvoleného objektu (na základě typu události, kterou budeme ošetřovat), např. ActionListener (akce) následně nalezneme jména metod tohoto rozhraní (jejich počet bývá různý dle typu události) a všechny je implementujeme, např. actionperformed() metody nemůžeme přetěžovat, pouze předefinovat, smíme je tedy implementovat pouze jednou odkaz na instanci třídy, jejíž jméno se shoduje s typem události, předáváme jako formální parametr handleru ošetřujícímu tuto událost. 28.3.2011 Java - GUI - události 2/6
Seznam metod a rozhraní Přehled nejčastěji používaných událostí, rozhraní a jejich metod Provedení akce, např. stisk tlačítka ActionEvent ActionListener actionperformed() Změna stavu komponenty ComponentEvent ComponentListener componenthidden() componentmoved() componentresized() componentshown() Detekce přidání/odebrání komponenty ContainerEvent ContainerListener containeradded() containerremoved() Změna zaměření komponenty FocusEvent FocusListener focusgained() focuslost() Vybrání komponenty ItemEvent ItemListener itemstatechanged() Práce s klávesnicí KeyEvent KeyListener keypressed() keyreleased() keytyped() Práce s tlačítky myši MouseEvent MouseListener mouseclicked() mouseentered() mouseexited() mousepressed() mousereleased() Změna stavu okna WindowEvent WindowListener windowactivated() windowclosed() windowclosing() windowdeactivated() windowopened() Změna zaměření okna WindowFocusEvent WindowFocusListener windowfocusgained() WindowFocusLost() Pohyb myši MouseMotionEvent MouseMotionListener mousemotiondragged() mousemotionmoved() Práce s rolovacím kolečkem myši MouseWheelEvent MouseWheelListener mousewheelmoved() 28.3.2011 Java - GUI - události 3/6
Příklad na formuláři máme 2 tlačítka 1 label, jehož obsah se bude měnit podle toho, které tlačítko stiskneme v tomto případě použijeme rozhraní ActionListener pro práci s událostmi je nutno importovat balíček java.awt.event.* s příslušnými událostmi poté prostřednictvím metody addactionlistener() zaregistrujeme posluchače pro příslušnou komponentu (objekt třídy ZmenaNapisu): but1.addactionlistener(new ZmenaNapisu()); but2.addactionlistener(new ZmenaNapisu()); metoda actionperformed() se ve třídě smí vyskytnout pouze jednou, proto používáme vnitřní třídy vnitřní třída, jejíž objekt reaguje na událost, musí implementovat příslušné rozhraní, v tomto případě ActionListener tím se třída zaváže přepsat metodu actionperformed() ošetřující událost Action do této metody napíšeme obsluhu události stisku tlačítka: z objektu události e zjistíme, které tlačítko událost způsobilo text tlačítka nastavíme jako text labelu: class ZmenaNapisu implements ActionListener { JButton zdroj = (JButton)e.getSource(); String napis = zdroj.gettext(); lab.settext(napis); totéž mohu napsat za pomoci anonymních vnitřních tříd: ); ); public void tlacitkostisknuto(actionevent e) { String napis = ((JButton)e.getSource()).getText(); lab.settext(napis); pokud program obsahuje anonymní vnitřní třídu, vznikají při jeho překladu soubory obsahující před příponou class znak $, které obsahují přeložené kódy anonymních vnitřních tříd 28.3.2011 Java - GUI - události 4/6
Několik posluchačů téže události často potřebujeme, aby jedna událost měla více posluchačů, např. při stisku tlačítka potřebujeme, aby se provedlo několik různých činností, příklad pak může vypadat třeba takto: import javax.swing.*; import java.awt.*; import java.awt.event.*; public class Okno extends JFrame { Container obsah; JButton but1, but2; JLabel lab; JTextField text; public Okno() { inicializaceokna(); obsahokna(); zviditelneniokna(); public void inicializaceokna() { this.setsize(300, 200); this.settitle("moje první okno"); this.setlocation(100,100); this.setlayout(new FlowLayout()); obsah = this.getcontentpane(); public void obsahokna() { text = new JTextField("sem něco napiš"); but1 = new JButton("kopírovat"); but2 = new JButton("smazat"); lab = new JLabel("tady se to bude měnit"); obsah.add(text); obsah.add(but1); obsah.add(but2); obsah.add(lab); ); ); 28.3.2011 Java - GUI - události 5/6
public void tlacitkostisknuto(actionevent e) { String akce = ((JButton)e.getSource()).getText(); String napis = text.gettext(); if (akce.equals("kopírovat")) lab.settext(napis); else lab.settext(""); public void zviditelneniokna() { this.setdefaultcloseoperation(jframe.exit_on_close); this.setvisible(true); 28.3.2011 Java - GUI - události 6/6