Vývoj internetových aplikací a vývoj desktopových aplikací jsou dva odlišné světy. Je jen málo programátorů, kteří dobře rozumí obojímu – přechodu z jedné technologie na druhou brání dost vysoká technologická bariéra. Málokdy se proto stane, že by se tyto dva světy navzájem inspirovaly. Jedním z těchto mála případů je komponentový webový framework Apache Wicket.

Komponentová architektura Wicketu připomíná desktopovou knihovnu Swing. Ukažme si to na krátkém příkladu kódu z jedné z ukázek, jak jinak, než na klasickém Hello, world. V následujícím kódu je vytvořen objekt typu Label, a to pro definici komponent jednoduchého příkladu stačí:
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.examples.WicketExamplePage;
public class HelloWorld extends WicketExamplePage {
public HelloWorld() {
add(new Label("message", "Hello World!"));
}
}
Součástí příkladu je xHTML šablona. Pomocí atributu wicket:id je v ní označen tag, který bude nahrazen kódem, který vygeneruje komponenta Label.
<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<title>Wicket Examples - helloworld</title>
</head>
<body>
<span wicket:id="message" id="message">Message goes here</span>
</body>
</html>
Na výše uvedené šabloně je jedna věc zajímavá: je možné ji otevřít offline jako soubor v prohlížeči a získat tím přibližný náhled na výslednou grafickou podobu stránky.
Ukázka – AJAXová tabulka
Druhý příklad je praktičtější, ukazuje AJAXovou řaditelnou a stránkovanou tabulku. Každý, kdo někdy zkoušel psát webové aplikace bez frameworku, mi dá za pravdu, že napsat a odladit kód pro podobnou aplikaci není sice náročné, ale také to není práce na pár minut.

Ukažme si krátký výsek zdrojového kódu druhého příkladu. Zde již se projevuje komponentový charakter frameworku – pro každou položku tabulky je vytvořena nová komponenta Label. Na první pohled neefektivní (stačilo by Label znovu naplnit pro každý řádek zvlášť), ale tento přístup umožňuje, aby si každá položka v tabulce pamatovala svůj stav nezávisle na ostatních položkách.
public class RepeatingPage extends BasePage {
public RepeatingPage() {
Iterator contacts = new ContactDataProvider().iterator(0, 10);
RepeatingView repeating = new RepeatingView("repeating");
add(repeating);
while (contacts.hasNext()) {
WebMarkupContainer item =
new WebMarkupContainer(repeating.newChildId());
repeating.add(item);
Contact contact = (Contact)contacts.next();
item.add(new ActionPanel("actions",
new DetachableContactModel(contact)));
item.add(new Label("contactid",
String.valueOf(contact.getId())));
item.add(new Label("firstname", contact.getFirstName()));
item.add(new Label("lastname", contact.getLastName()));
item.add(new Label("homephone", contact.getHomePhone()));
item.add(new Label("cellphone", contact.getCellPhone()));
}
}
}
Výhody Wicketu
- Podobá se knihovně Swing.
- Komponenty je možné dědit.
- Podporuje tlačítko Zpět, a to tak, že si v paměti uchovává přechozí verze stavů komponent.
- Řeší problém s „ošklivými“ URL, které jsou pro komponentové frameworky typické.
- Podporuje dynamické obrázky.
- Umožňuje implementovat i jiný značkovací jazyk než je xHTML.
- Šablony jsou xHTML validní, nevyžadují speciální rozšíření, které by narušovalo xHTML pravidla.
- Snadná integrace AJAXu.
- Velké množství ukázkových příkladů.
Další výhody naleznete přímo na stránkách Wicketu.
Nevýhody Wicketu
- Webovým vývojářům nemusí být swingový přístup blízký.
- Ve Wicketu nelze rozumným způsobem skinovat komponenty. Díky dědičnosti vytvoříte vlastní grafickou podobu komponenty, to ano, ale pro skinování byste museli použít několik různých tříd. Ale ve všech příkladech a doporučeních je pro vytvoření komponenty použit operátor new a ne návrhový vzor factory – dědičnost tedy není pro skinování vhodným řešením. (Čímž neříkám, že skinovatelnosti nelze dosáhnout jiným postupem.)
- Malý počet dostupných komponent (v porovnání s JSF).
- V ukázkových kódech jsem nenašel rozumné řešení layoutu – Wicket nejspíš vůbec neřeší to, že by webová stránka mohla být složena z několika na sobě relativně nezávislých dynamicky generovaných částí.
Závěr
Wicket je populární a moderní, nově navržený framework. A je navržený dobře. Byl před pár měsíci přijat pod křídla Apache, kde se dál rozvíjí, nyní je již ve verzi 1.3. Připravuje se podpora Wicketu do IDE.
Pokud hledáte perspektivní komponentový framework, pak by pro vás mohl být Wicket dobrou volbou.

10. Duben 2008 - 13:10
Není pravda, že skinování komponent je problém.
Je možné definovat několik HTML šablon pro jedinou komponentu.
Nějak takto:
NejakyKomponent.java
NejakyKomponent.html //standartni sablona
NejakyKomponent_stylA.html //vlastni styly
NejakyKomponent_stylB.html
Více info také viz
http://cwiki.apache.org/WICKET/localization-and-skinning-of-applications...
10. Duben 2008 - 13:58
Používate Wicket 1.3 v oXy?
Robil niekto porovnanie Wicket vs. GWT, napríklad CRUD?
Odporúčam velmi prehladné CRUD porovnanie Wicket vs. JSF:
http://ptrthomas.wordpress.com/2007/05/14/a-wicket-user-tries-jsf/
10. Duben 2008 - 15:24
Bohužel ne. Vážně jsme nad ním uvažovali, ale problém je v tom, že mj. vytváříme pro zákazníky velmi zatížené (navštěvované) weby, takže jsme šli raději cestou MVC frameworku. Škoda, že na stránkách frameworku jsou informace o reálných implementacích, ale už ne zátěže.
10. Únor 2010 - 12:17
Aktualizace: používáme Wicket 1.4, byť ne na veřejně přístupných stránkách, ale v administrační konzoli webu. Osvědčil se, zákazník dostal aplikaci k otestování a produkční nasazení se již blíží.
10. Únor 2010 - 8:57
Wicket je fajn, ale bohuzel mně není úplně jasná práce s modely. A to konkrétně získávání dat.
Konrétní případ: Mám panel, na kterém zobrazuji data pomocí DataView a je umožněno jednotlivé záznamy vybrat pomocí checkboxu.
Vytvořil jsem si tedy panel, do kterého předávám listModel, který získává data pomocí LoadableDetachableModel. V tomto panelu mám private atribut privList, do kterého přidávám jednotlivé prvky kolekce v metodě populate (DataView), tzn. mám tam pouze data zobrazená na aktuální stránce. Jednotlivé řádky mají u sebe checkboxy, které jsou provázány PropertyModelem s prvky privList.
Tento panel obsahuje metodu getSelectedItem, která při submitu projde seznam privList a zjistí, které prvky jsou vybrány. To vše funguje skvěle.
Co mě ovšem zaráží je následující:
Při kliknutí na tlačítko submit se provede opětovné načtení listModelu, potom nějáká business logika, populateItem. Pokud ovšem při debugu listModel změním tak, aby vracel null, potom getSelectedItem nenajde žádný vybraný záznam, protože záznamy v privList jakoby nevěděly nic o svázání s checkboxem, protože všechny záznamy mají atributy isSelected = false.
Děkuju,
Jirka
10. Únor 2010 - 12:14
Nedokážu odpovědět, ale zkusím nápovědu: nejspíš jde o to, že životní cyklus komponent je u RepeatingView odlišný než u běžné komponenty (s modelem to tolik nesouvisí, ale jinak musím říct, že pochopení modelů ve Wicketu také chvíli trvá...)
17. Září 2010 - 10:51
setReuseItems(true) by mělo pomoci