May 31, 2020
Hot Topics:

Wicket: The First Steps

  • By Karthik Gurumurthy
  • Send Email »
  • More Articles »

Depending upon your preference, you might not like the fact that Wicket's components are being held as instance variables in the Login class. (In fact, keeping references to components just to get to their request values is considered an antipattern in Wicket. It was used only to demonstrate one of the several ways of handling input data in Wicket.) Wouldn't it be good if you could just have the user name and password strings as instance variables and somehow get Wicket to update those variables on form submit? Let's quickly see how that can be achieved through Wicket's PropertyModel, as Listing 8 demonstrates.

Listing 8. Login.java
import wicket.markup.html.WebPage;
import wicket.markup.html.form.Form;
import wicket.markup.html.form.PasswordTextField;
import wicket.markup.html.form.TextField;
import wicket.model.PropertyModel;

public class Login extends AppBasePage {

  private String userId;
  private String password;

  public Login(){

    TextField userIdField = new TextField("userId",
                  new PropertyModel(this,"userId"));

    PasswordTextField passField = new PasswordTextField("password",
          new PropertyModel(this, "password"));

    Form form = new LoginForm("loginForm");

  class LoginForm extends Form {
    public LoginForm(String id) {

    public void onSubmit() {
       String userId = getUserId();
       String password = getPassword();
       System.out.println("You entered User id "+ userId +
                  " and Password " + password);

  public String getUserId() {
    return userId;
  public String getPassword() {
    return password

  public void setUserId(String userId) {
    this.userId = userId;

  public void setPassword(String password) {
    this.password= password;

Make the preceding change to Login.java, access the login page, enter values for the User Name and Password fields, and click Login. You should see the same effect as earlier. Some radical changes have been made to the code though that require some explanation.

This time around, note that you don't retain Wicket components as the properties of the page. You have string variables to capture the form inputs instead. But there is something else that demands attention; take a look at Listing 9.

Listing 9. Login Constructor
TextField userIdField = new TextField("userId", new PropertyModel(this,"userId"));

You still specify the ID of the component as userId (first argument to the TextField component) as earlier. But instead of a model object, you supply another implementation of Wicket's IModel interface-PropertyModel.

How Does PropertyModelWork?

When you include new PropertyModel(this,"userId"), you inform the TextField component that it needs to use the Login instance (this) as its model (source of data) and that it should access the property userId of the Login instance for rendering and setting purposes. Wicket employs a mechanism that is very similar to the OGNL expression language (http://www.ognl.org). OGNL expects the presence of getProperty and setProperty methods for expression evaluation, and so does Wicket's implementation. For example, you can access subproperties via reflection using a dotted path notation, which means the property expression loginForm.userId is equivalent to calling getLoginForm().getUserId() on the given model object (loginForm). Also, loginForm.userId= translates to getLoginForm().setUserId(something). (loginForm is an instance of the Login class). In fact, prior to the 1.2 release, Wicket used to employ the services of OGNL, until it was discovered that the latter resulted in limiting Wicket's performance to a considerable extent and was subsequently replaced with an internal implementation.

Using Page Properties as Models

Tapestry encourages maintaining Page properties as shown previously. People coming to Wicket from Tapestry will probably follow this approach.

I like this page-centric approach, but then I like cricket (http://www.cricinfo.com), too. I guess it's a good idea to let you know of some of the "modeling" options that I'm aware of, as I believe that the user is the best judge in such circumstances. Wicket allows you to model your model object as a plain Java object, also known as POJO. (POJO actually stands for Plain Old Java Object.) You can specify a POJO as the backing model for the entire page. Such a model is referred to as a CompoundPropertyModel in Wicket. A Wicket Page class is derived from the Component class and models are applicable to all components. Let's develop another page that allows one to specify personal user details to demonstrate that.

How to Specify a CompoundPropertyModel for a Page

Figure 4 shows another not-so-good-looking page that allows the user to enter his or her profile. Remember, the majority of us are Java developers who don't understand HTML! We will leave the job of beautifying the template to the people who do it best-HTML designers. Therein lies the beauty of Wicket. Its design encourages a clean separation of roles of the designer and the back-end developer with a very minimal overlap. Figure 4 shows a simple page that captures user-related information.

Figure 4. UserProfilePage for capturing user-related information

See Listing 10 for the corresponding HTML template code.

Listing 10. UserProfilePage.html
  <title>User Profile</title>
    <form wicket:id="userProfile">
         User Name <input type="text" wicket:id="name"/><br/>
         Address<input type="text" wicket:id="address"/><br/>
         City <input type="text" wicket:id="city"/><br/>
         Country <select wicket:id="country">
         <!--The markup here is for preview purposes only. Wicket
         replaces this with actual data when rendering the page -->
         Pin <input type="text" wicket:id="pin"/><br/>
      <input type="submit" value="Save"/>

In this case, the POJO UserProfile class (see Listing 11) has been designed to hold onto the information supplied in the HTML template.

Listing 11. UserProfile.java
package com.apress.wicketbook.common;
import java.io.Serializable;

public class UserProfile implements Serializable {

  private String name;
  private String address;
  private String city;
  private String country;
  private int pin;

  public String getAddress() {
    return address;
  public void setAddress(String address) {
    this.address = address;

  public String getCity() {
    return city;

  public void setCity(String city) {
    this.city = city;

  public String getCountry() {
    return country;

  public void setCountry(String country) {
    this.country = country;

  public String getName() {
    return name;

  public void setName(String name) {
    this.name = name;
  * You can return an int!

  public int getPin() {
    return pin;

  public void setPin(int pin) {
    this.pin = pin;

  /* Returns a friendly representation of the UserProfile object */
  public String toString(){
    String result = " Mr " + getName();
    result+= "n resides at " + getAddress();
    result+= "n in the city " + getCity();
    result+= "n having Pin Code " + getPin();
    result+= "n in the country " + getCountry();
    return result;

  private static final long serialVersionUID = 1L;

Page 3 of 6

This article was originally published on April 23, 2007

Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.

Thanks for your registration, follow us on our social networks to keep up-to-date