Wicket hat sich als ernstzunehmendes Framework für die Entwicklung von komplexen Informationssystemen etabliert. UI-Komponenten lassen sich einfach und intuitiv entwickeln, der Support durch die Community aus Anwendern und Entwicklern ist ausgezeichnet.
Diese Merkmale sind aber häufig nicht die ausschlaggebenden Argumente für oder wider den Einsatz eines Frameworks. Meist steht die Integration in eine vorgegeben Infrastruktur aus Frameworks, Entwicklungsrichtlinien, Wissensstand der Mitarbeiter an erster Stelle bei den Auswahlkriterien.
Welch gute Figur dabei Wicket macht zeigen wir anhand diverser Beispiele aus unserer täglichen Praxis. Von der Zusammenarbeit mit diversen Peristenzframeworks, Wickets Integration mit Spring oder CDI, der Integration von JQuery bis hin zur Arbeitserleichterung mit IDE-Plugins - anhand von konkreten Beispielen zeigen wir wie einfach die Arbeit mit Wicket sein kann.
Senior Developer, Architekt bei T-Systems MMS
XML is like violence. If it doesn't solve your problem, you're not using enough of it.
Entwickler, Architekt, Operations, Trainer bei intecsoft GmbH & Co. KG
An optimist person will say that the glass is half-full.
A pessimist person will say that the glass is half-empty.
A programmer will say that the glass is twice as large as necessary.
mvn archetype:generate -DarchetypeGroupId=org.apache.wicket \
-DarchetypeArtifactId=wicket-archetype-quickstart \
-DarchetypeVersion=6.14.0 \
-DgroupId=de.practicalwicket -DartifactId=demo \
-DarchetypeRepository=https://repository.apache.org/ \
-DinteractiveMode=false
public class HomePage extends WebPage {
private Person goethe = new Person("Goethe", "Mehr Licht!");
public HomePage() {
setDefaultModel(new CompoundPropertyModel<Person>(goethe));
add(new Label("name"));
add(new Label("famousLastWord"));
}
private class Person {
private String name;
private String famousLastWord;
private Person(String name, String famousLastWord) {...}
}
}
<!DOCTYPE html>
<html xmlns:wicket="http://wicket.apache.org">
<head<title>Famous last Words</title></head>
<body<
<span wicket:id="name">[name]</span> sagte
<span wicket:id="famousLastWord">[noch nichts]</span>
</body>
</html>
Geerbt von Basisklasse
Von spez. Klasse bereitgestellt
Komponenten
Geerbt von Basisklasse
Von spez. Klasse bereitgestellt
Komponenten
public class BasePage extends WebPage {
private final String title;
public BasePage(String title) {
this.title = title;
}
@Override
protected void onInitialize() {
super.onInitialize();
add(new Label("title", title));
add(new BookmarkablePageLink<HomePage>("homepage", HomePage.class));
add(new BookmarkablePageLink<Page1>("page1", Page1.class));
add(new BookmarkablePageLink<Page2>("page2", Page2.class));
}
}
<!DOCTYPE html>
<html xmlns:wicket="http://wicket.apache.org">
<head>
[...]
</head>
<body>
[...]
<wicket:child>
</wicket:child>
[...]
</body>
</html>
public class Page1 extends BasePage {
public Page1() {
super("Page 1");
}
}
<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
<body>
<wicket:extend>
<h1>Page 1</h1>
</wicket:extend>
</body>
</html
public class BasePage extends WebPage {
[...]
@Override
protected void onInitialize() {
[...]
add(getFooterPanel("footerPanel"));
}
public component getFooterPanel(String wicketID) {
return new EmptyPanel(wicketID);
}
}
public class Page1 extends BasePage {
[...]
@Override
protected Component getFooterPanel(String wicketID) {
return new Page1FooterPanel(wicketID);
}
}
Form<Registration> form = new Form<Registration>(
"form",
new CompoundPropertyModel<Registration>(new Registration())) {
@Override
protected void onSubmit() {
super.onSubmit();
setResponsePage(new RegistrationSuccess(getModel()));
}
};
form.add(new TextField<String>("email"));
form.add(new TextField<String>("userName"));
form.add(new PasswordTextField("password"));
public interface IConverter<C> extends IClusterable {
C convertToObject(String value, Locale locale) throws ConversionException;
String convertToString(C value, Locale locale);
}
userName.add(new IValidator<String>() {
@Override
public void validate(IValidatable<String> validatable) {
if (validatable.getValue().length() < 4 ) {
ValidationError validationError
= new ValidationError().addKey("username.error");
validationError.setVariable("userName", validatable.getValue());
validatable.error(validationError);
}
}
});
form.visitFormComponents(new IVisitor<FormComponent<?>, Object>() {
@Override
public void component(FormComponent<?> component, IVisit<Object> visit) {
component.add(new ErrorMarkingBehavior());
}
});
public class ErrorMarkingBehavior extends Behavior {
@Override
public void onComponentTag(Component component, ComponentTag tag) {
if ( ! ((FormComponent)component).isValid()) {
String oldValue = tag.getAttribute("class");
if (oldValue == null) {
tag.put("class", "error");
} else {
tag.put("class", "error " + oldValue);
}
}
}
}
public interface IModel<T> extends IDetachable {
T getObject();
void setObject(final T object);
}
public interface IDetachable extends IClusterable {
void detach();
}
public class WicketApplication extends WebApplication {
@Override
public void init() {
mountPage("mountingDemo/named/${author}/#{foo}", MountingIndexed.class);
mount(new MountedMapper("mountingDemo/query"
, MountingQuery.class, new UrlPathPageParametersEncoder()));
}
}
public class MountingIndexed extends BasePage {
public MountingIndexed(PageParameters parameters) {
super("mounting page with named parameters");
String author = parameters.get("author").toString();
String foo = parameters.get("foo").toString();
}
}
public class MountingQuery extends BasePage {
public MountingQuery(PageParameters parameters) {
super("mounting page with query parameters");
String author = parameters.get("demoParam").toString("default");
String foo = parameters.get(1).toString("default-foo");
add(new Label("par0", author));
add(new Label("par1", foo));
}
}
@Inherited
@Retention(RetentionPolicy.RUNTIME)
public @interface SecuredPage {
}
<link href='http://fonts.googleapis ... ' rel='stylesheet' type='text/css'>
<link href="css/bootstrap.css" rel="stylesheet" >
<link href="css/style.css" rel="stylesheet" >
<script src="js/bootstrap.js"></script>
@Override
public void renderHead(HtmlHeaderContainer container) {
super.renderHead(container);
container.getHeaderResponse()
.render(CssHeaderItem.forReference(new BootstrapCssReference()));
container.getHeaderResponse()
.render(CssHeaderItem.forReference(new ApplicationCssReference()));
container.getHeaderResponse()
.render((CssHeaderItem.forUrl("http://fonts.googleapis ... ")));
container.getHeaderResponse()
.render(JavaScriptHeaderItem.forReference(new BootstrapCssReference()));
WicketTester tester = new WicketTester(new WicketApplication());
tester.startPage(HomePage.class);
tester.assertRenderedPage(HomePage.class);
tester.assertLabel("title", "Home Page");
tester.clickLink("registration");
tester.assertLabel("title", "Registration");
WicketTester tester = new WicketTester(new WicketApplication());
tester.startPage(RegistrationPage.class);
FormTester formTester = tester.newFormTester("form", false);
formTester.setValue("userName", "jb");
[...]
formTester.submit();
tester.assertErrorMessages("invalid user name: jb");