Archive for October, 2008

Wicket 10: Form binding with a value object

30 October 2008

This is part 10 of a series about Wicket.

We need to collect user input about persons. This input will be passed to another page, so we’ll build two of them: Input that accepts user input and Output that displays the result.

Each person has a name and an age.

public class Person implements Serializable {
   private String name;
   private Integer age;

   // getters and setters
}

Output

Output.html simply displays the values of a Person.

  Hello <span wicket:id="name"></span>, you are <span wicket:id="age"></span> years old!

Output.java receives a Person,

public Output(Person person) {
}

and makes its values available to the markup.

public Output(Person person) {
   add(new Label("name", person.getName()));
   add(new Label("age", String.valueOf(person.getAge())));
}

Input

Input.html has a form. The trick is to use the exact name of the fields in the HTML form.

<form wicket:id="form">
  Name <input type="text" wicket:id="name" /><br />
  Age <input type="text" wicket:id="age" /><br />
  <input type="submit" value="OK" />
</form>

So the form has the same fields with the same name as the value object.

Input.java has the same form,

Form form = new Form("form") {
   protected void onSubmit() {
      // redirect to the Output page
   }
};

that should redirect to the Output page

Person person = new Person();
Form form = new Form("form") {
   protected void onSubmit() {
      setResponsePage(new Output(person));
   }
};

and should automatically bind user input to the value object.

Person person = new Person();
Form form = new Form("form", new CompoundPropertyModel(person)) {
   protected void onSubmit() {
      setResponsePage(new Output(person));
   }
};

Complete code

Input.html

<html>
  <body>
    <form wicket:id="form">
      <table>
        <tr><td>Name</td><td><input type="text" wicket:id="name" /></td></tr>
        <tr><td>Age</td><td><input type="text" wicket:id="age" /></td></tr>
        <tr><td colspan="2"><input type="submit" value="OK" /></td></tr>
      </table>
    </form>
  </body>
</html>

Input.java

public class Input extends WebPage {
   private Person person = new Person();
   public Input() {
      final Form form = new Form("form", new CompoundPropertyModel(person)) {
         protected void onSubmit() {
            setResponsePage(new Output(person));
         }
      };
      final TextField name = new TextField("name");
      final TextField age = new TextField("age");
      form.add(name);
      form.add(age);
      add(form);
   }
}

Output.html

<html>
  <body>
    Hello <span style="color:coral" wicket:id="name"></span>,
    you are <span wicket:id="age"></span> years old!
  </body>
</html>

Output.java

public class Output extends WebPage {
   public Output(Person person) {
      add(new Label("name", person.getName()));
      add(new Label("age", String.valueOf(person.getAge())));
   }
}

Result

Let’s type something,

The user enters some data

The user enters some data

and submit.

The result

The result

Review

  • A Serializable value object is passed between two pages.
  • The value object is automatically filled with the values of the form using a CompoundPropertyModel.
  • The value object is bound to the form.

Here’s an elegant alternative coding style.

   IModel<Person> model = new CompoundPropertyModel<Person>(new Person());
   final Form form = new Form("form", model) {
      protected void onSubmit() {
         setResponsePage(new Output(model.getObject()));
      }
   };

Wicket 9: Setup a form

29 October 2008

This is part 9 of a series about Wicket.

We simply want to pass the value of a text field to another page, so we’ll build two pages: Input that accepts user input and Output that displays the result.

Input.html

Consider this simple form. It consists of a text field and a submit button.

<form>
  <input type="text" /><input type="submit" value="OK" />
</form>

Let’s add wicket ids.

<form wicket:id="form">
  <input type="text" wicket:id="name" /><input type="submit" value="OK" />
</form>

Output.html

Output.html simply says hello to whatever is the value of the <span>.

Hello <span></span> !!

Let’s give it a wicket id.

Hello <span wicket:id="output"></span> !!

Output.java

There is a single element in the HTML markup that needs a value.

add(new Label("output", new Model()));

So we can pass it through the constructor.

public Output(Model model) {
   add(new Label("output", model));
}

Input.java

Here’s the form and the field.

final Form form = new Form("form");
final TextField field = new TextField("name");

The form contains the field and the page contains the form.

form.add(field);
add(form);

We’d like to specify the behavior of the form when it is submitted.

final Form form = new Form("form") {
   protected void onSubmit() {
   }
};

Actually, the request should be received by an Output page.

final Form form = new Form("form") {
   protected void onSubmit() {
      setResponsePage(new Output(null));
   }
};

The trick is to send the model of the field to the constructor of that page.

private Model model = new Model();
public Input() {
   final Form form = new Form("form") {
      protected void onSubmit() {
         setResponsePage(new Output(model));
      }
   };
   final TextField field = new TextField("name", model);
   form.add(field);
   add(form);
}

Complete code

Input.html

<html>
  <body>
    <form wicket:id="form">
      Please enter your name :
      <input type="text" wicket:id="name" /><input type="submit" value="OK" />
    </form>
  </body>
</html>

Input.java

public class Input extends WebPage {
   private Model model = new Model();
   public Input() {
      final Form form = new Form("form") {
         protected void onSubmit() {
            setResponsePage(new Output(model));
         }
      };
      final TextField field = new TextField("name", model);
      form.add(field);
      add(form);
   }
}

Output.html

<html>
  <body>
    Hello <span wicket:id="output" style="font-size:x-large;"></span> !!
  </body>
</html>

Output.java

public class Output extends WebPage {
   public Output(Model model) {
      add(new Label("output", model));
   }
}

Result

A simple form

A simple form

Let’s type something,

The user enters data

The user enters data

and submit.

The result

The result

Review

  • To specify the behavior of a Form during submission, just implement its onSubmit() method.
  • You may pass anything that IS-A Serializable between two pages.

Wicket: Full guide for JDeveloper 11g

27 October 2008

This article presents how a complete Wicket project is built from ground-up in JDeveloper 11g.

Go through steps 1-3 to setup a wicket project.

Go through step 4 to create a page.

Go through steps 5-7 to deploy, test and debug the page.

1. Create a web project

File → New… → General → Projects → Web Project → OK.

Creating a new web project in JDeveloper

Creating a new web project in JDeveloper

In the wizard click next, give the project a name, e.g. WicketFun and click Next until the option Finish appears. The project should now appear in the Projects tab.

Project tab of JDeveloper

Project tab of JDeveloper

2. Concentrate all jars

Download wicket from wicket.apache.org → Releases → Wicket 1.4 → Select an appropriate mirror and get apache-wicket-1.4-m3.zip

Download simple logging facade from slf4j.org → Download → slf4j-1.5.2.zip

Create a folder and place inside the following:

  • apache-wicket-1.4-m3\lib\wicket-1.4-m3.jar
  • slf4j-1.5.2\slf4j-simple-1.5.2.jar
  • slf4j-1.5.2\slf4j-api-1.5.2.jar

Add these jars to the classpath by right clicking on the project → Project Properties… → Libraries and Classpath → Add JAR/Directory…

These three are all you need for a wicket application. However, there are some extra interfaces of great interest: The date-time functionality (wicket-datetime-1.4-m2.jar) and the integration with Spring (wicket-spring-1.4-m2.jar).

3. Make the WebApplication

Wicket’s starting point is a WebApplication.

Right click on project → New → General → Simple Files → Java Class → Provide the name MyApplication, declare that it extends WebApplication and click OK.

Create a new class in JDeveloper

Create a new class in JDeveloper

This class should implement the getHomePage() method.

package wicketfun;

import org.apache.wicket.Page;
import org.apache.wicket.protocol.http.WebApplication;

public class MyApplication extends WebApplication {

    public Class<? extends Page> getHomePage() {
        return null;
    }

}

For the time being just let it return null.

Accessing web.xml through the Projects tab

Accessing web.xml through the Projects tab

In the Projects tab double-click on web.xml → XML and paste the following elements

<filter>
   <filter-name>WicketApplication</filter-name>
   <filter-class>org.apache.wicket.protocol.http.WicketFilter</filter-class>
   <init-param>
      <param-name>applicationClassName</param-name>
      <param-value>wicketfun.MyApplication</param-value>
   </init-param>
</filter>
<filter-mapping>
   <filter-name>WicketApplication</filter-name>
   <url-pattern>/*</url-pattern>
</filter-mapping>

Here’s how web.xml should look.

DD in the XML editor of JDeveloper

DD in the XML editor of JDeveloper

4. Make a page

Let’s call it Hello. We should create Hello.html and Hello.java! As simple as it gets.

Right click on project → New → General → Simple Files → Java Class → Provide the name Hello, the package pages, make it extend WebPage and click OK.

This class should provide a default no-arg constructor.

package pages;

import org.apache.wicket.markup.html.WebPage;

public class Hello extends WebPage {

    public Hello() {
        // wicket action here
    }

}

To make the classes compile right click the project and select Rebuild.

After a successful compilation, right click on project → New… → Web Tier → HTML → HTML Page → Provide the name Hello and click on Browse….

Creating an HTML file in JDeveloper

Creating an HTML file in JDeveloper

Expand the classes folder and double-click on pages.

Bundling the HTML page together with the class file

Bundling the HTML page together with the class file

In this way the html file will be bundled in the same directory with the class file. Just press OK to complete.

Let’s make this page simply display the current year.

<html>
  <body>
      The year is: <span wicket:id="year"></span>
  </body>
</html>

Back to the class for some action.

package pages;

import java.util.Calendar;
import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.markup.html.basic.Label;

public class Hello extends WebPage {

    public Hello() {
        Integer year = Calendar.getInstance().get(Calendar.YEAR);
        add(new Label("year", year.toString()));
    }

}

5. Declare the home page

Every time you create a page you’d like to test it.

Just go to the getHomePage() of your WebApplication and make it return your page.

package wicketfun;

import pages.Hello;
import org.apache.wicket.Page;
import org.apache.wicket.protocol.http.WebApplication;

public class MyApplication extends WebApplication {

    public Class<? extends Page> getHomePage() {
        return Hello.class;
    }

}

In this way when the application context is called on the browser, e.g. http://localhost:8080/wicket, this page will be called.

6. Run the page

Deploy the application to your favorite server, for example JBoss, GlassFish or the bundled Weblogic, to see it in action.

7. Debug the page

Wicket keeps the java code totally independent from the HTML markup. So debugging is easy.

Make a breakpoint by clicking on the left of the desired line.

Debugging a wicket page is trivial

Debugging a wicket page is trivial

References

JBoss integration with JDeveloper 11g

26 October 2008

Let’s see how easy is to deploy applications to JBoss by using a handy feature of JDeveloper.

Right click on your project → New → General → Deployment Profiles → WAR File

Creating a WAR file in JDeveloper

Creating a WAR file in JDeveloper

Give a profile name, e.g. wicket, and click OK.

Specifying the name of the deployment profile in JDeveloper

Specifying the name of the deployment profile in JDeveloper

Specify the hot deploy directory of JBoss using the Browse… button.

Configuring the deployment in JDeveloper

Configuring the deployment in JDeveloper

Now you can easily deploy the application by right clicking on project → Deploy → wicket → to WAR file

Easy deployment in JDeveloper

Easy deployment in JDeveloper

Your application is available at http://localhost:8080/wicket/.

Free SCJP Mock exams

10 October 2008

These practice exams focus on specific objectives of the Sun Certified Java Programmer certification. They should be useful at the final stages of your preparation.

© 2008-2009 Nikos Pougounias. This is a free contribution to the Java and JavaRanch communities. Please distribute it for free.