/ janturon.cz / Od kodéra k analytikovi / Posluchač událostí

Posluchač událostí (Event Listener)

Posluchač událostí je nativní implementace návrhového vzoru Pozorovatel. Na něm je založena většina grafických frameworků, kde klient nepíše metodu main, ale pouze kód obslužných funkcí (Event Driven Architecture).

Obslužná funkce (handler) bývá obvykle ve tvaru eventHandler(void* source, eventArgs* args), kde source je objekt, který vyvolal událost a args objekt události (určující, které tlačítko myši či klávesnice bylo stisknuto či souřadnice myši). Následující příklady přidávají událost kliknutí buttonClick tlačítku button.

C#

Tento jazyk využívá řízený .NET kód:

button.Click+= new EventHandler(buttonClick); private void buttonClick(object sender, EventArgs e) { ... }

(pomocí knihovny InterOp je možné náročným Boilerplate způsobem volat nativní WinAPI)

C++

Zde* je C++ implementace události používajícího grafického frameworku obsahující pouze práci s tlačítkem, textovým polem, zaškrtávátkem a menu k pochopení principu propracovanějších frameworků jako je WTL, QT, wxWidgets či oficiální MFC. Zkompilujte např. pomocí MinGW jako g++ xapi.cpp main.cpp -mwindows.

Pozn: Volání .NET frameworku neumožňuje přímý přístup k paměti, která je řízena OS Windows. To má za následek syntaktické (i návrhové) doplňky kódu tak rozsáhlé, že bývají označovány jako nový jazyk: řízený (managed) C++, případně C++/CLI (Common Language Interface, mezijazyk volající .NET, do kterého je zdrojový kód překládán). Jedni programátoři tvrdí, že je to velmi mocný nástroj umožňující práci jak na úrovni hardware, tak na úrovni .NET ve více jazycích (všechny jsou překládány do CLI). Druzí tvrdí, že tohoto esperanta nevyužijí, že dochází k prudkému nárůstu složitosti řešící pouze implementační záležitosti (Boilerplate) a snahu smíchat dvě různé úrovně kódu (porušení zásady Low Coupling návrhových principů GRASP). Tyto problémy řeší syntaxe zmíněného C# umožňující efektivně psát řízenou aplikaci. Osobně proto doporučuji používat C++ k psaní pouze nativního a C# pouze řízeného kódu, tedy k psaní grafických aplikací použít buď C#, nebo jeden z výše zmíněných C++ frameworků.

Javascript

Standard W3C definuje metodu addEventListener, čehož se ale nedrží prohlížeč Internet Explorer, proto je zapotřebí napsat vlastní Adaptér:

function addEvent(target,eventFn,handler) { var wrapper = function(e) { handler(target,e|window.event); } if(target.addEventListener) target.addEventListener(eventFn,wrapper,false); else if(target.attachEvent) target.attachEvent("on"+eventFn,wrapper); }

kde wrapper je obalující funkce (jiný název pro jednopříkazový adaptér) obsluhy handler. Třetí parametr addEventListener určuje fázi zpracování mající smysl při vrstvení objektů. Z historických důvodů (různá implementace výrobců) standard W3C definuje zpracování nejprve zachytávání (capturing), kde událost je vyvolávána z nejspodnější vrstvy po nejvyšší, a poté fázi probublávání (bubbling), kde je událost vyvolávána v obráceném pořadí. Protože všechny jazyky Microsoftu podporují pouze probublávání, používá se prakticky pouze tato fáze.

addEvent(button,"click",buttonClick); function buttonClick(sender, eventArgs) { ... }