Introduction to the Wicket Web Framework
This tutorial needs a review. You can edit it in GitHub following these contribution guidelines. |
This document takes you through the basics of creating reusable components and assembling them into a web application. Each component consists of a Java class and an HTML file. The framework that allows you to develop your application in this way is called Wicket. In addition to its component-based approach, a distinguishing feature of Wicket is the absence of XML configuration files. Instead of an XML configuration file, you use a Java class for application-wide settings, such as the identification of a home page.
Each widget in your web application is created in a Java class and rendered in an HTML page. The Java class and HTML page must have the same name and exist in the same source structure. They are linked to each other via a Wicket identifier. You will be shown how the IDE supports the development of Wicket applications so that you can quickly and efficiently create reusable components that can give your web application a consistent look and feel without very much work on your part.
To follow this tutorial, you need the following software and resources.
Software or Resource | Version Required |
---|---|
7.2, 7.3, 7.4, 8.0, Java EE |
|
Java Development Kit (JDK) |
version 7 or above |
Wicket plugin for NetBeans IDE |
|
GlassFish Server Open Source Edition or Tomcat servlet container |
3.1.x or above _ _ version 7.x or above |
Notes:
-
The Wicket support plugin for NetBeans consists of the following modules:
-
org-netbeans-modules-web-wicket.nbm. Provides the Wicket-specific functionality that is used in this tutorial.
-
org-netbeans-modules-wicket-templates.nbm. Provides Wicket file-level templates for creating typical Wicket artifacts, such as pages and panels.
-
org-netbeans-modules-wicket-library.nbm. Provides the Wicket JARs, installs them in the IDE’s Library Manager. Therefore, you do not need to download the Wicket distribution from the Wicket site, because the plugin provides everything you need.
-
To install the Wicket support plugin into the IDE, go to the Plugin Manager (Tools > Plugins from the main menu) and install the plugin under the Downloaded tab. For more detailed instructions on how to install a framework plugin into the IDE, see: Adding Support For A Web Framework.
-
For more information on Wicket, see http://wicket.sourceforge.net/. For the development page for support for Wicket in NetBeans IDE, see http://java.net/projects/NbWicketSupport. If you are familiar with Wicket, you are welcome to contribute code to the Wicket plugin for NetBeans IDE.
Setting Up the Environment
Before you start writing your Wicket application, you have to make sure you have all of the necessary software and that your project is set up correctly. Once you have installed the Wicket support plugin for NetBeans IDE as described above, you will have a wizard that sets up all the basic files needed for a Wicket application.
Creating the Source Structure of a Wicket Application
The source structure of our application must include the Wicket JAR files, the registration of the Wicket servlet in the web.xml
file, as well as some standard artifacts such as the application class and a home page. Since we are using an IDE, we shouldn’t need to create all these files by hand. Instead, we have wizards to do the work for us.
Depending on your needs, choose one of the appropriate scenarios below:
Scenario 1: Creating an Ant Based Wicket Application from Scratch
When creating a new web application in the IDE, the final panel of the Web Application wizard will be very useful in the context of our Wicket application.
-
Choose File > New Project. Under Categories, select Web. Under Projects, select Web Application. Click Next.
-
In the Name and Location panel, type
MyFirstWicketApp
in Project Name. Change the Project Location to any directory on your computer. Click Next. -
Leave all the settings unchanged. Or, if you like, you can change them. Wicket supports any version of Java EE. A Wicket application can be deployed to any server. Click Next. 4. In the Frameworks panel, choose Wicket, as shown here:
Note: Depending on the modules installed into the IDE, you may see more or less items in the Frameworks list shown in the screenshot above.
In the panel shown above, leave all the defaults unchanged. The fields in the panel above provide the following:
-
Wicket Filter Name. Shows the name of the filter that will be defined in the
web.xml
file. -
Wicket URL Pattern. Adds the relative URL pattern to the
web.xml
file. -
Wicket Application Class. Specifies name of the class where the application-wide settings, such as the home page, are set.
-
Wicket Home Page. Specifies the name of the home page, which will consist of a file called
xxx.java
andxxx.html
. -
Main Package. The Java package in which all the generated artifacts will be put by the IDE.
-
Version. The Wicket version. Any library in the Library Manager with a name starting with "Wicket" will be listed in the Version drop-down above. By default, the only version listed is 1.6.0 because that is the version provided by the plugin.
-
Click Finish.
-
The IDE creates the MyFirstWicketApp
project. The project contains all of your sources and project metadata, such as the project’s Ant build script. The project opens in the IDE. You can view its logical structure in the Projects window (Ctrl-1):
Scenario 2: Creating a Maven Based Wicket Application from Scratch
When you already have an Ant based application, the IDE can help you add Wicket support.
-
Choose File > New Project. Under Categories, select Maven. Under Projects, select Web Application.
Click Next.
-
In the Name and Location panel, type
MyFirstWicketApp
in Project Name. Change the Project Location and the default Maven settings as required by your needs.
Click Next.
-
Choose the appropriate server for your needs, as well as "Java EE 6 Web" for the Java EE Version setting.
Click Finish. The IDE creates the source structure shown below:
-
Because we have added support for Java EE 6, no
web.xml
file is created in the previous step. However, Wicket requires the Wicket application filter to be registered in theweb.xml
file. Therefore, before continuining, we add a newweb.xml
file in the application.
Right-click the application, choose New > Other, followed by Web > Standard Deployment Descriptor (web.xml). Click Next and then click Finish.
-
Now we are ready to add Wicket support to the application. Right-click the project node and choose Properties. In the Project Properties dialog, select Frameworks, and click Wicket. Use the descriptions in the previous sections to fill out the details in the Wicket Configuration part of the dialog. Click OK.
The IDE creates all the Wicket files needed to get started:
Scenario 3: Creating a Maven Based Wicket Application from Archetype
Archetypes exist in Maven repositories for setting up Wicket applications.
-
Choose File > New Project. Under Categories, select Maven. Under Projects, select Project from Archetype.
Click Next.
-
In the Search field, type "wicket" and then select the archetype you would like to use.
Complete the wizard with values appropriate to your needs. Click Finish.
The IDE adds Wicket support to the application created from archetype.
Scenario 4: Adding Wicket Support to an Existing Application
When you already have an application, whether created on Ant or Maven, the IDE can help you add Wicket support.
-
Right-click the application and choose Properties.
-
In the Project Properties dialog, select the Frameworks panel, and then click Add. Then choose Wicket. Click OK.
-
Use the descriptions in the previous section to fill out the Wicket Configuration in the Frameworks panel.
-
Click OK to confirm.
The IDE adds Wicket support to the existing application.
In the next section, we will explore each of the generated files in detail.
Providing Support for Alternative Versions of Wicket
The version of Wicket included in the NetBeans Wicket plugin might not be the one you need. Take the steps below to register and use an alternative version of Wicket.
-
Go to Tools | Ant Libraries. Notice that the Wicket JARs registered by the NetBeans Wicket plugin are available:
-
In the dialog shown above, click New Library and create a new library with a name beginning with "Wicket". Add JARs to the library, that is, register the JARs of your preferred version of Wicket into the library you have created.
. When next you create a new web application, or when you add Wicket support to an existing application, the Frameworks panel will display your newly registered library, if its name begins with the word "Wicket":
When you complete the wizard, the JARs registered in the selected library will be put on the classpath of your application.
Note: The approach above applies to Ant-based Wicket applications. If you want to use an alternative version of Wicket in a Maven-based application, change the relevant POM file.
Examining the Source Structure of the Generated Wicket Application
The IDE’s Web Application wizard has created a lot of files for us. Here, we look at the files and see how they relate to each other within the context of a Wicket development.
-
Let’s begin our tour of the generated files.
-
Web Descriptor. We begin by looking in the
web.xml
file, which is the general deployment descriptor common to all web applications that comply with the Servlet specification. Expand theWEB-INF
folder or the Configuration Files folder, open the file in raw XML view, and notice the definition of the Wicket filter:
-
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<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>com.myapp.wicket.Application</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>WicketApplication</filter-name>
<url-pattern>/wicket/*</url-pattern>
</filter-mapping>
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file/>
</welcome-file-list>
</web-app>
Note: The value of the application class name is set to com.myapp.wicket.Application
. In the next step, we will open the application class file and inspect its content.
-
Wicket Application Class. Open the
com.myapp.wicket
package in the Source Packages folder and then open theApplication.java
file. It looks like this:
package com.myapp.wicket;
import org.apache.wicket.protocol.http.WebApplication;
public class Application extends WebApplication {
public Application() {
}
@Override
public Class getHomePage() {
return HomePage.class;
}
}
This is the Java file that provides application-wide settings, comparable to struts-config.xml
in the Struts framework and faces-config.xml
in the JSF framework. Notice the definition of the getHomePage()
method. This method is the minimum requirement of the application-wide class. It specifies the first page (the home page) that will be displayed when you deploy the application. Notice that HomePage.class
is returned. In the next step, we will open the HomePage.java
file and inspect its content.
-
Wicket Home Page. Open
HomePage.java
. It looks like this:
package com.myapp.wicket;
public class HomePage extends BasePage {
public HomePage() {
add(new Label("message", "Hello, World!"));
}
}
The file adds a label to the home page. Rendering of Wicket widgets created in this file is done in a file with the same name in the same source structure, which can only be HomePage.html
, which looks as follows, currently:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd"
xml:lang="en"
lang="en">
<head>
<wicket:head>
<title>Wicket Example</title>
</wicket:head>
</head>
<body>
<wicket:extend>
<h1 wicket:id="message">This gets replaced</h1>
</wicket:extend>
</body>
</html>
Notice that in HomePage.java
we are extending BasePage
. In HomePage.html
we have a wicket:id
attribute, which tells us that this is a placeholder for something created somewhere by a Java file. Also, we have a reference to the CSS stylesheet that the IDE generated for us. You can find it in the Web Pages folder, in the Projects window. In the next step, we will open BasePage
and examine its content.
-
Base Page. Open
BasePage.java
. This is what it looks like:
package com.myapp.wicket;
import org.apache.wicket.markup.html.WebPage;
public abstract class BasePage extends WebPage {
public BasePage() {
super();
add(new HeaderPanel("headerpanel", "Welcome To Wicket"));
add(new FooterPanel("footerpanel", "Powered by Wicket and the NetBeans Wicket Plugin"));
}
}
This is the class that we want all our web pages to extend. Every class extending BasePage
will inherit an instance of HeaderPanel
and FooterPanel
. This ensures that all our web pages will have the same header and footer. The HTML side of the base page is as follows:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd"
xml:lang="en"
lang="en">
<head>
<wicket:head>
<wicket:link>
<link rel="stylesheet" type="text/css" href="style.css"/>
</wicket:link>
</wicket:head>
</head>
<body>
<header wicket:id="headerpanel" />
<section class="content_container">
<wicket:child/>
</section>
<footer wicket:id="footerpanel" />
</body>
</html>
In the next step, we will open HeaderPanel.java
and inspect its content.
-
Header Panel. Open
HeaderPanel.java
. This is what it looks like:
package com.myapp.wicket;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.panel.Panel;
public class HeaderPanel extends Panel {
public HeaderPanel(String componentName, String exampleTitle)
{
super(componentName);
*add(new Label("exampleTitle", exampleTitle));*
}
}
Notice the line in bold above. Here, we create a Wicket Label widget. The HeaderPanel is a reusable component. This is the Java side, where widgets are created. Next we will look at the HTML side, which is where we can expect the Wicket Label widget to be rendered. In the next step, we will open the HeaderPanel.html
file and inspect its content.
Now change the second argument to "My Very First Component Based Application", so that the definition of the Label is now as follows:
add(new Label("exampleTitle", "My Very First Component Based Application"));
Open HeaderPanel.html
. Notice that it has the same name as the Java file we have just looked at. It is found within the same package structure. This is what it looks like:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd"
xml:lang="en"
lang="en">
<head><title>Wicket Example</title></head>
<body>
<wicket:panel>
<h1>Wicket Example</h1>
<p id="titleblock">
<b><font size="+1">Start of <span wicket:id="exampleTitle">Example Title Goes Here</span></font></b>
</p>
</wicket:panel>
</body>
</html>
Notice the line in bold above. This is how you specify where a widget should be rendered in the HTML side of a web page. Hold down the Ctrl key and move your mouse over the value of the wicket:id
attribute in the span
tag. Notice that the value turns into a hyperlink:
Click the hyperlink and notice that the Java side of the web page opens.
Now click the left arrow at the top of the Source Editor to return to the HTML page:
In this way, you can navigate quickly and efficiently between the two sides of Wicket components.
-
Footer Panel. The structure of the footer panel is the same as the header panel, described above.
. Right-click the project and run it. The IDE compiles the application, creates a WAR file, sends it to the deployment server, opens the IDE’s default browser, and displays the application:
Note: Make sure that "/wicket" is appended to the URL, as shown above, which maps the URL to the Wicket filter registered in the web.xml
file.
Using Wicket Features
In the next sections, you will learn about three key Wicket features and how NetBeans IDE supports them via the NetBeans Wicket plugin:
The sections below also introduce you to various supporting features that the NetBeans Wicket plugin makes available.
Adding a Widget
In this section, we create our first widget in Wicket. Just like most other artifacts in Wicket, a widget has a Java side and an HTML side. On the Java side, the widget is created. On the HTML side, it is rendered. As shown previously, navigation between the two sides is made possible via a hyperlink.
-
Open
HomePage.html
. If the Palette does not open automatically, open it via Window > Palette (Ctrl-Shift-8).
-
After adding a line below the H1 element in the HTML file, drag the Label item from the Palette and drop it below the H1 element. You see the dialog below:
Change the values in the dialog to the following:
Click OK. Notice that the tag in bold below has been added to the file:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd"
xml:lang="en"
lang="en">
<head>
<wicket:head>
<title>Wicket Example</title>
</wicket:head>
</head>
<body>
<wicket:extend>
<h1 wicket:id="message">This gets replaced</h1>
*<span wicket:id="message1">This gets replaced</span>*
</wicket:extend>
</body>
</html>
Now you can style the newly added widget by, for example, using H3 tags:
<h3 wicket:id="message1">This gets replaced</h3>
Next, open HomePage.java
and notice that a label has been added, with the same identifier as in the HTML file (changes in bold):
public class HomePage extends BasePage {
public HomePage() {
add(new Label("message", "Hello, World!"));
*add(new Label("message1", "Hello again, World!"));*
}
}
.
Save the files. Refresh the browser and you will see the Wicket Label, rendered in the HomePage.html
file:
You can create placeholders, just like the tag you created in the HomePage.html
file above, and then hand the HTML file to your web designer. While the web designer designs the web page, you can work on the Java side and create the widgets completely independently. Since the HTML tags are not embedded in the Java file, you and the web designer can reap the rewards of Wicket’s central focus of "separation of concerns".
Open the Navigator (Window > Navigating > Navigator), while the above HTML file is selected in the editor, and then you can see an overview of the tags, in the Navigator’s "Wicket Tags" list:
If there is no matching tag in the matching HTML page, you see an error message in the Java file:
Adding a Reusable Component
One of strengths of Wicket is the concept of "reusable components". Here, in this section, we use a wizard to generate a panel, which again has a Java side and an HTML side. We will create this panel so that we have a banner that we will reuse in our web pages, so that the banner is consistent across our web site. We will see how easy it is to add a panel to a web page.
-
Right-click the
com.myapp.wicket
package node and choose New > Other. Under Categories, choose Web. Under File Types, notice the following templates:
Choose Wicket Panel and click Next.
-
Type
BannerPanel
in File Name. You should now see the following:
Click Finish.
Notice that we now have two new files in our package, BannerPanel.html
and BannerPanel.java
.
-
Open
BannerPanel.html
and notice that the content of the file is as follows:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns:wicket>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<title>BannerPanel</title>
</head>
<body>
<wicket:panel>
<!-- TODO - add components here, ala
<span wicket:id="title">title here</span>
-->
</wicket:panel>
</body>
</html
Between wicket:panel
tags, a Wicket placeholder is found. Remove the line above and below the SPAN tag, so that the line with the SPAN tag is no longer commented out. Hold down the Ctrl key, move the mouse over the value of the Wicket id, and click the hyperlink that appears. The BannerPanel.java
file opens:
package com.myapp.wicket;
import org.apache.wicket.markup.html.panel.Panel;
public final class BannerPanel extends Panel {
BannerPanel(String id) {
super (id);
}
}
Add a label, as you did earlier in the HomePage.java
file, shown in bold below:
package com.myapp.wicket;
*import org.apache.wicket.markup.html.basic.Label;*
import org.apache.wicket.markup.html.panel.Panel;
public final class BannerPanel extends Panel {
BannerPanel(String id) {
super (id);
*add(new Label("title","I am a reusable component!"));*
}
}
-
Our panel, while simple, is actually complete already. Lets add it to the home page. Open
HomePage.java
and then create a new instance of BannerPanel, by adding the following line to the end of the Constructor:
add(new BannerPanel("bannerPanel"));
-
Next, we need to render the panel. Open
HomePage.html
and add the placeholder tag right above the closing BODY tag, making sure to use the same Wicket identifier as used in the Java file:
<span wicket:id='bannerPanel'/>
. Run the project again. Notice that the panel is displayed, exactly where the HTML file specified it should be rendered:
In Wicket terminology, a panel is a reusable component. Exactly as shown in this section, you can reuse the panel as often as you like and in as many web pages as you fancy.
Adding AJAX Features
Instead of using JavaScript to add asynchronous web features (via AJAX technology) to a Wicket application, Wicket makes available a Java component model that encapsulates AJAX features. Below, you are shown how to change the BannerPanel to include an AJAX autocomplete widget, instead of the label widget you created previously.
-
On the HTML side of the
BannerPanel
class, drag an AJAX Text Input item from the Palette (Ctrl-Shift-8), as shown below:
Drop the item below the existing Wicket placeholder, as shown below:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns:wicket>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<title>BannerPanel</title>
</head>
<body>
<wicket:panel>
<span wicket:id="title">title here</span>
*<input type="text" wicket:id="countries" size="50"/>*
</wicket:panel>
</body>
</html>
-
On the matching Java side, notice that the following has been added automatically:
final AutoCompleteTextField field = new AutoCompleteTextField("countries", new Model("")) {
@Override
protected Iterator getChoices(String input) {
if (Strings.isEmpty(input)) {
return Collections.EMPTY_LIST.iterator();
}
List choices = new ArrayList(10);
Locale[] locales = Locale.getAvailableLocales();
for (int i = 0; i < locales.length; i++) {
final Locale locale = locales[i];
final String country = locale.getDisplayCountry();
if (country.toUpperCase().startsWith(input.toUpperCase())) {
choices.add(country);
if (choices.size() == 10) {
break;
}
}
}
return choices.iterator();
}
};
-
Press Ctrl-Shift-I and then make sure to select the correct import statements:
Click OK and make sure the BannerPanel
class uses the following import statements:
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import org.apache.wicket.extensions.ajax.markup.html.autocomplete.AutoCompleteTextField;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.Model;
import org.apache.wicket.util.string.Strings;
. Refresh the browser again and you will have an AJAX autocomplete field. As you type, the field will be filled with countries matching the entered text.
Next Steps
This is the end of the introduction to Wicket development in NetBeans IDE. You are encouraged to continue your journey in the Wicket framework by working through the Pizza Application Sample described in A First Look at the Wicket Framework by David R. Heffelfinger. Note that the result of that tutorial is available as a sample in the New Project wizard, together with other samples, as shown here: