Programovanie

Java a spracovanie udalostí

Väčšina programov, aby boli užitočné, musí reagovať na príkazy používateľa. Programy Java sa pri tom spoliehajú na udalosti, ktoré popisujú akcie používateľov.

Minulý mesiac som predviedol, ako zostaviť grafické používateľské rozhranie z komponentov poskytnutých v súbore nástrojov abstraktného okna knižnice triedy Java. Po zostavení niekoľkých takýchto rozhraní som krátko hovoril o téme spracovania udalostí, ale zastavil som sa pred úplným popisom spracovania udalostí, ako ho implementuje AWT. Tento mesiac pokračujeme tam, kde sme skončili.

Bude riadený udalosťami

V dávnej minulosti musel program, ktorý chcel vedieť, čo používateľ robí, sám aktívne zhromažďovať tieto informácie. V praxi to znamenalo, že keď sa program sám inicializoval, vstúpil do veľkej slučky, v ktorej opakovane zisťoval, či používateľ robí niečo zaujímavé (napríklad stlačenie tlačidla, dotknutie sa klávesu, posunutie posúvača, pohyb myši). a potom vykonal príslušné kroky. Táto technika je známa ako volebné urny.

Anketa dokončí svoju prácu, ale má tendenciu byť nepraktická, keď sa používa v súčasných aplikáciách, a to z dvoch súvisiacich dôvodov: Po prvé, použitie dotazovania má tendenciu tlačiť všetok kód na spracovanie udalostí na jedno miesto (vo veľkej slučke); po druhé, výsledné interakcie v rámci veľkej slučky bývajú zložité. Okrem toho si dopytovanie vyžaduje, aby program sedel v slučke, spotrebovával cykly CPU a čakal, kým používateľ niečo urobí - vážne plytvanie cenným zdrojom.

AWT tieto problémy vyriešila prijatím inej paradigmy, ktorá je základom všetkých moderných okenných systémov: programovania riadeného udalosťami. V rámci AWT patria všetky akcie používateľov do abstraktnej sady nazývaných vecí diania. Udalosť dostatočne podrobne popisuje konkrétnu akciu používateľa. Namiesto toho, aby program aktívne zhromažďoval udalosti generované používateľmi, čas behu programu Java upozorní program, keď dôjde k zaujímavej udalosti. Programy, ktoré takýmto spôsobom riešia interakciu používateľov, sú údajne také udalosťami riadené.

Trieda udalosti

Trieda udalostí je hlavným hráčom v hre udalostí. Pokúša sa zachytiť základné charakteristiky všetkých udalostí generovaných používateľom. stôl 1 zoznam verejných dátových členov poskytnutých triedou Udalosť.

TypnázovPopis
ObjektcieľOdkaz na komponent, ktorý pôvodne prijal udalosť.
dlhokedyČasový okamih, v ktorom k udalosti došlo.
intidTyp udalosti (ďalšie informácie nájdete v časti Typy udalostí).
intXSúradnica x, na ktorej došlo k akcii, vo vzťahu k komponentu, ktorý udalosť momentálne spracováva. Pre danú udalosť sa bude meniť súradnica x, keď sa udalosť posúva hore v hierarchii komponentov. Počiatok súradnicovej roviny je v ľavom hornom rohu komponentu.
intrSúradnica y, pri ktorej došlo k akcii, vo vzťahu k komponentu, ktorý momentálne spracováva udalosť. Pre danú udalosť sa bude meniť súradnica y, keď sa udalosť posúva hore v hierarchii komponentov. Počiatok súradnicovej roviny je v ľavom hornom rohu komponentu.
intkľúčV prípade udalostí na klávesnici sa použije klávesový kód práve stlačeného klávesu. Jeho hodnotou bude zvyčajne hodnota Unicode znaku, ktorý kláves predstavuje. Medzi ďalšie možnosti patria hodnoty pre špeciálne klávesy HOME, END, F1, F2 atď.
intmodifikátoryAritmeticky alebo kombinovaná kombinácia hodnôt SHIFT_MASK, CTRL_MASK, META_MASK a ALT_MASK. Jeho hodnota predstavuje stav klávesov shift, control, meta a alt.
intclickCountPočet po sebe idúcich kliknutí myšou. Tento dátový člen je významný iba v MOUSE_DOWN udalostiach.
ObjektargArgument závislý od udalosti. Pre objekty Button je tento objekt objekt String, ktorý obsahuje textúrny štítok tlačidla.
Tabuľka 1: Verejné dátové členy poskytnuté triedou Udalosť

Ako vysvetlím v časti s názvom Odoslanie a šírenie udalosti, inštancia triedy Event je zvyčajne vytvorená systémom Java run-time. Je však možné, aby program vytváral a odosielal udalosti do komponentov prostredníctvom ich postEvent () metóda.

Typy udalostí

Ako už bolo spomenuté vyššie, trieda Event je modelom udalosti používateľského rozhrania. Udalosti prirodzene spadajú do kategórií podľa typu udalosti (typ udalosti je označený symbolom id údajový člen). Tabuľka 2 uvádza všetky udalosti definované AWT, zoradené podľa kategórií.

Tabuľka 2: Udalosti definované AWT, zoradené podľa kategórie

Môže byť poučné vidieť generovanie udalostí v akcii. Po stlačení tlačidla na obrázku 1 sa vytvorí prehľadávač udalostí, ktorý zobrazuje informácie o udalostiach, ktoré prehliadač prijíma. Zdrojový kód pre prehliadač udalostí je k dispozícii tu.

Na prezeranie tohto appletu potrebujete prehliadač s podporou Java

Obrázok 1: Generovanie udalostí v akcii

Odoslanie a šírenie udalosti

Zvážte applet na obrázku 2. Skladá sa z dvoch inštancií triedy Button, ktoré sú vložené do inštancie triedy Panel. Táto inštancia triedy Panel je sama o sebe zakomponovaná do inej inštancie triedy Panel. Posledná inštancia triedy Panel sa nachádza pod inštanciou triedy TextArea a obe inštancie sú vložené do inštancie triedy Applet. Obrázok 3 predstavuje prvky, ktoré tvoria tento applet, usporiadaný ako strom, s inštanciami TextArea a Button ako listy a inštanciou appletu ako koreň. (Ďalšie informácie o hierarchickom usporiadaní komponentov v používateľskom rozhraní nájdete v úvode AWT z minulého mesiaca.)

Na prezeranie tohto appletu potrebujete prehliadač s podporou Java

Obrázok 2: Triedy vložené do tried

Obrázok 3: Strom prvkov appletu (hierarchia)

Keď používateľ interaguje s appletom na obrázku 2, prevádzkový systém Java vytvorí inštanciu triedy Event a naplní svojich dátových členov informáciami popisujúcimi akciu. Systém Java run-time potom umožňuje appletu spracovať túto udalosť. Začína sa to komponentom, ktorý pôvodne prijal udalosť (napríklad tlačidlom, na ktoré ste klikli), a posúva sa hore po strome komponentov, komponent po komponente, až kým sa nedostane ku kontajneru v hornej časti stromu. V priebehu procesu má každý komponent možnosť ignorovať udalosť alebo na ňu reagovať jedným (alebo viacerými) z nasledujúcich spôsobov:

  • Upravte dátových členov inštancie udalosti
  • Vykonajte akciu a vykonajte výpočet na základe informácií obsiahnutých v udalosti
  • Označte systému run-time Java, že udalosť by sa nemala šíriť ďalej v strome

Systém Java run-time prenáša informácie o udalosti do komponentu prostredníctvom komponentov handleEvent () metóda. Všetky platné handleEvent () metódy musia mať formu

public boolean handleEvent (Udalosť e) 

Obsluha udalosti vyžaduje jednu informáciu: odkaz na inštanciu triedy Event obsahujúci informácie o udalosti, ktorá sa práve stala.

Hodnota vrátená z handleEvent () metóda je dôležitá. Indikuje to za behu systému Java, či bola udalosť v rámci obsluhy udalosti úplne vyriešená alebo nie. Skutočná hodnota označuje, že udalosť bola spracovaná a šírenie by sa malo zastaviť. Falošná hodnota označuje, že udalosť bola ignorovaná, nemohla byť spracovaná alebo bola spracovaná neúplne a mala by pokračovať hore stromom.

Zvážte nasledujúci popis interakcie imaginárneho používateľa s appletom na obrázku 2. Používateľ klikne na tlačidlo označené „Jeden“. Systém runtime jazyka Java zhromažďuje informácie o udalosti (počet kliknutí, umiestnenie kliknutia, čas, ku ktorému došlo ku kliknutiu a komponent, ktorý kliknutie prijal) a zbalí tieto informácie do inštancie triedy Event. Systém Runtime Java potom začína na komponente, na ktorý ste klikli (v tomto prípade na tlačidlo s označením „Jeden“), a prostredníctvom hovoru na komponent handleEvent () metóda ponúka komponentu možnosť reagovať na udalosť. Ak komponent nezvláda udalosť alebo s ňou zaobchádza neúplne (označené návratovou hodnotou false), systém Java run-time ponúkne inštanciu udalosti nasledujúcej vyššej zložke v strome - v tomto prípade inštancii Panelová trieda. Systém Java run-time pokračuje týmto spôsobom, kým sa nespracuje udalosť alebo kým v systéme run-time nedôjde k vyskúšaniu komponentov. Obrázok 4 zobrazuje cestu tejto udalosti, keď sa ju applet pokúša spracovať.

Obrázok 4: Cesta udalosti

Každý komponent tvoriaci applet na obrázku 2 pridáva do objektu TextArea riadok, ktorý naznačuje, že prijal udalosť. Potom umožňuje, aby sa udalosť rozšírila na ďalší komponent v strome. Zoznam 1 obsahuje kód pre typické handleEvent () metóda. Celý zdrojový kód tohto appletu je k dispozícii tu.

public boolean handleEvent (Event evt) {if (evt.id == Event.ACTION_EVENT) {ta.appendText ("Panel" + str + "videl akciu ... \ n"); } else if (evt.id == Event.MOUSE_DOWN) {ta.appendText ("Panel" + str + "pilovala myš dole ... \ n"); }

návrat super.handleEvent (evt); }

Výpis 1: Typický handleEvent () metóda

Pomocné metódy udalostí

The handleEvent () metóda je jedno miesto, kde môže programátor vložiť aplikačný kód na spracovanie udalostí. Príležitostne sa však komponent bude zaujímať iba o udalosti určitého typu (napríklad o udalosti myši). V týchto prípadoch môže programátor umiestniť kód do a pomocná metóda, skôr ako ho umiestniť do handleEvent () metóda.

Tu je zoznam pomocných metód dostupných programátorom. Pre určité typy udalostí neexistujú žiadne pomocné metódy.

akcia (Event evt, Object what)

gotFocus (Event evt, Object what)

lostFocus (Event evt, Object what)

mouseEnter (udalosť evt, int x, int y)

mouseExit (udalosť evt, int x, int y)

mouseMove (udalosť evt, int x, int y)

mouseUp (udalosť evt, int x, int y)

mouseDown (udalosť evt, int x, int y)

mouseDrag (udalosť evt, int x, int y)

keyDown (udalosť evt, int kľúč)

keyUp (udalosť evt, int kľúč)

false na označenie, že pomocná metóda udalosť nezvládla.

Vykonávanie handleEvent () metóda poskytovaná triedou Component vyvoláva každú pomocnú metódu. Z tohto dôvodu je dôležité, aby predefinované implementácie handleEvent () metóda v odvodených triedach vždy končí príkazom

návrat super.handleEvent (e);

Kód v zozname 2 ilustruje toto pravidlo.

public boolean handleEvent (Event e) {if (e.target instanceof MyButton) {// do something ... return true; }

návrat super.handleEvent (e); }

Výpis 2: Pravidlo pre ukončenie výpisu v handleEvent () metóda

Nedodržanie tohto jednoduchého pravidla zabráni správnemu vyvolaniu pomocných metód.

Obrázok 5 obsahuje applet, ktorý spracováva udalosti myši výlučne prostredníctvom kódu umiestneného v pomocných metódach. Zdrojový kód je k dispozícii tu.

UdalosťevtNasledujúca udalosť v prepojenom zozname udalostí.
Okenné udalosti
Udalosti okna sa generujú ako reakcia na zmeny stavu okna, rámca alebo dialógového okna.
UdalosťID
WINDOW_DESTROY201
WINDOW_EXPOSE202
WINDOW_ICONIFY203
WINDOW_DEICONIFY204
WINDOW_MOVED205
Udalosti klávesnice
Udalosti klávesnice sa generujú ako reakcia na stlačenie a uvoľnenie klávesov, zatiaľ čo komponent má vstupné zameranie.
UdalosťID
STLAČENIE KLÁVESY401
KEY_RELEASE402
KEY_ACTION403
KEY_ACTION_RELEASE404
Myšie udalosti
Udalosti myši sa generujú ako reakcia na akcie myši, ktoré sa vyskytujú v rámci hranice komponentu.
UdalosťID
MOUSE_DOWN501
MOUSE_UP502
MOUSE_MOVE503
MOUSE_ENTER504
MOUSE_EXIT505
MOUSE_DRAG506
Posúvajte udalosti
Udalosti posúvania sa generujú ako reakcia na manipuláciu s posúvačmi.
UdalosťID
SCROLL_LINE_UP601
SCROLL_LINE_DOWN602
SCROLL_PAGE_UP603
SCROLL_PAGE_DOWN604
SCROLL_ABSOLUTE605
Zoznam udalostí
Udalosti zoznamu sa generujú ako reakcia na výbery vykonané v zozname.
UdalosťID
LIST_SELECT701
LIST_DESELECT702
Rôzne udalosti
Rôzne udalosti sa generujú ako reakcia na rôzne akcie.
UdalosťID
ACTION_EVENT1001
LOAD_FILE1002
ULOŽENIE SÚBORU1003
GOT_FOCUS1004
LOST_FOCUS1005
Todd Sundsted programuje od chvíle, keď boli počítače k ​​dispozícii v stolných modeloch. Aj keď sa Todd pôvodne zaujímal o budovanie aplikácií distribuovaných objektov v C ++, prešiel na programovací jazyk Java, keď sa Java stala jasnou voľbou pre tento druh vecí. Okrem písania Todd poskytuje konzultačné služby v oblasti internetu a webových aplikácií spoločnostiam v juhovýchodných Spojených štátoch.

Získajte viac informácií o tejto téme

  • Výukový program Java predkladajú Mary Campione a Kathy Walrath. Online koncept je k dispozícii na adrese //java.sun.com/tutorial/index.html.

Tento príbeh, „Java a spracovanie udalostí“, bol pôvodne publikovaný spoločnosťou JavaWorld.

$config[zx-auto] not found$config[zx-overlay] not found