NetBeans 6 delivers great updates to the Matisse GUI builder. Spend a few minutes with Roman Strobl and get an expert briefing on what's new and what has changed. (sponsored)
In this, the third and final installation of Andres' Introduction to Groovy series, you learn about how Groovy handles variable numbers of arguments, named parameters, currying, and more about Groovy operators. Including, some new operators.
Swing Fuse (actually just Fuse), is a framework designed to make it easier to create your own custom desktop components. In this article, Daniel Spiewak shows you how to get started and provides sample source code you can download.
Willam Louth shows how he uses JXInsight Probes to investigate probable performance issues with code bases that he is not familiar with. He also highlights possible pitfalls in creating a benchmark, as well as in the analysis of results.
Replies:
19 -
Pages:
2
[
12
| Next
]
Threads:
[
Previous
|
Next
]
Lets face it, Java MVC web application frameworks are a dime a dozen. That's admittedly why when
Wicket
was first released, I didn't pay very
much attention. Wicket persisted without my attention,
however, and has certainly continued to generate buzz. Recently, I was in a position
to spend some time learning what all the talk was about, and my first impression was certainly
a positive one.
Update:
Since the initial writing of this article, subsequent tips have been written. They
are listed below:
Note that Wicket 1.2 is planned for release very soon, and based on the discussions on the user
and development mailing lists, early 2006 (January/February) is when it is coming. In this article,
I am focusing on Wicket 1.1 usage, since that is the current stable release.
Before going through all of this Wicket example, let's learn just a little bit about Wicket.
Wicket's Approach to Java Web Applications
(Lack of) Specialized Markup and Embedded Logic
Wicket has an interesting philosophy regarding the HTML markup used to template out the view. There are
certainly a lot of rendering technologies available:
JSP/JSTL
,
Velocity
,
Freemarker
,
and
XSL
to name a few. Other MVC frameworks, such as
Tapestry
use a customized
markup, and in Tapestry's case in particular, something largely based in the world of static HTML. Wicket
takes a similar approach as Tapestry's, and ensures that the HTML is easily consumable by standard
'HTML' applications, such as browsers and HTML editors like Macromedia Dreamweaver. Interestingly enough,
Wicket even uses the namespace standards to extend HTML so that there is really no custom syntax at all -
no "special sauce" as the Wicket website calls it. Instead, Wicket empowers the developer through its rich
component model.
Rich Component Model
Wicket has what could be called a rich component model. What I mean by that is instead of having chunks of logic
embedded in the view markup (such as JSP/Velocity/Freemarker scriptlets), you actually have a Wicket component (a 100%
Java object) that contains the behavior that defines the dynamic UI result for that part of the result. This makes
the configurability, extendability, and resuability of the UI components infinitely stronger. All of the wonderful
patterns and techniques you have learned to maintain Java code to make it reusable work perfectly in Wicket. Where as
entire frameworks, such as
Tiles
, were created
to help modularize and componentize JSPs, Wicket naturally centers around that form of reusability, and in a 100% Java way.
Components don't just participate in the rendering process, they define it. Each component
is allowed to have associated markup, and combines that markup with an internal model (provided by the developer).
The behavior and logic of the component is all 100% Java code, and is all pluggable and controllable.
Finally, since all of the GUI behavior and code references are embedded in pure Java code, refactoring and code analysis are a
piece of cake, as standard Java tools work perfectly with Wicket components.
Smart Session Management
Wicket takes session management to a new level. Because of Wicket's rich component model, the session management
is extremely valuable for handling complex behavior such as processing form results - the component you associate
with the UI to do the rendering of the form, will be the same one that consumes the result from the user. Likewise,
session management makes it trivial for Wicket to handle the 'back button problem' for you. For those of you
not familiar, the 'back button' problem is the scenario in which a user clicks the back button to get to a
page of your application (such as a certain part of a form), and can re-submit or travel in a different direction
at that point - even though that re-submit could invalidate server-side data, and potentially cause all kinds of problems.
(Lack of) Configuration Files
One of Wicket's key strengths is that it uses bascially no configuration files. There has certainly
been a push back in recent years on the proliferation of configuration files that have to be managed
just to keep everything running. You have to configure Wicket in the
web.xml
file of your
application (a requirement of the servlet specification), and that's just about it. This makes the configuration
consistent with the rest of the application logic, and also ensures that it is succeptible to standard
refactoring tools such as those embedded in Intellij, Netbeans, and Eclipse.
A Quick Run-Through
Applications
The first step is to create an application object (an implementation of
wicket.protocol.http.WebApplication
) -
this object will help Wicket understand the organization and configuration of our program.
package com.javalobby.tnt.wicket.aloha;
import wicket.ApplicationSettings;
import wicket.protocol.http.WebApplication;
import wicket.util.time.Duration;
publicclass AlohaApplication extends WebApplication {
@Override protectedvoid init() {
// Set the 'Home Page' of the application (the 'index')
getPages().setHomePage(AlohaPage.class);
// Note that many of the settings below are 'defaults', but are being
// set explicitly in this example to clarify.
// Can be enabled/disabled to leave 'wicket' XHTML extensions in
// rendered result to browser (a development assistance setting)
getSettings().setStripWicketTags(false);
// Tells Wicket to explicitly report if a component is specified
// in the component model of a Particular page, but isn't used.
// Useful in development to ensure all components are being rendered.
// (But potentially slower)
getSettings().setComponentUseCheck(true);
// Tells wicket to check the timestamp of certain resources (such as HTML markup)
// and update its local cached representation if they have changed
// Useful in development, but more efficient to leave unset (null) in a production
// environment where you don't need/want polling.
getSettings().setResourcePollFrequency(Duration.ONE_SECOND);
// Tells wicket to use a helpful 'debug' exception page with a snapshot of the
// component model, and the exception stack trace.
// Other settings are available to show pages that say there has been an internal error
// (a production-friendly page)
// In addition, more advanced usage allows you to override this behavior completely.
getSettings().setUnexpectedExceptionDisplay(ApplicationSettings.SHOW_EXCEPTION_PAGE);
// Alternative configuration - common 'configuration types'
// that set some of the settings above based on what you would
// want for production vs. development
//getSettings().configure("development");
// -- or --
//getSettings().configure("deployment");
// Potentially get custom settings from web.xml
System.out.println(getWicketServlet().getInitParameter("aloha-app-setting"));
}
}
Note that strictly speaking, you can just as easily use the constructor of your
WebApplication
class to set all of
your settings and adjust things - the
init()
method used above exists in case you want to get some custom
init-parameters
from the
WicketServlet
as can be seen in the tail end of our configuration above.
Pages
The next step is to create a page. Pages are a combination of components and markup. We'll go through the page class
creation first:
package com.javalobby.tnt.wicket.aloha;
import java.util.*;
import wicket.markup.html.WebPage;
import wicket.markup.html.basic.Label;
import wicket.markup.html.list.*;
publicclass AlohaPage extends WebPage {
public AlohaPage() {
// A Title for our page
add(new Label("pageTitle", "Aloha - The Time is: " + new Date()));
// A Wicket-style Loop/List of Items
add(new ListView("people", getPeople()) {
// This method is called for each 'entry' in the list.
@Override protectedvoid populateItem(ListItem item) {
Person person = (Person)item.getModelObject();
item.add(new Label("firstName", person.firstName));
item.add(new Label("lastName", person.lastName));
item.add(new Label("email", person.email));
}
});
}
// Some arbitrary factory method.
private List<Person> getPeople() {
List<Person> people = new ArrayList<Person>();
people.add(new Person("R.J.", "Lorimer", "rj@javalobby.org"));
people.add(new Person("Rick", "Ross", "rick@javalobby.org"));
people.add(new Person("Matt", "Schmidt", "matt@javalobby.org"));
return people;
}
// some arbitrary class for data.
class Person {
String firstName;
String lastName;
String email;
Person(String fName, String lName, String emailAddr) {
this.firstName = fName;
this.lastName = lName;
this.email = emailAddr;
}
}
}
Note that in many cases you may not want to put the Strings and Person
objects in to the components directly (as I have done). That is because of
Wicket's session-usage model, where components are kept on the session for an entire web conversation.
For larger and more complex applications where session replication and maximum memory consumption control
are important, you may want to install custom
wicket.model.IModel
implementations. Optimum model
usage is a tip for another day, but for those of you who are curious, there are two reasons to implement a custom
model: 1.) to avoid expensive String/model data being stored in the session if it should be freshly retrieved and
collected for each request and 2.) to avoid holding data that isn't serializable (such as our
Person
class)
on the session since this data will break session clustering and failover.
This page effectively has a component tree - this tree logically looks like this:
Now, on to the HTML markup for this new page we have created. This HTML is designed to line up to the
component tree that we have just created.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html
xmlns="http://www.w3.org/1999/xhtml"
xmlns:wicket="http://wicket.sourceforge.net/"
xml:lang="en"
lang="en">
<head>
<!-- The 'pageTitle' label.
We have designated a wicket 'Label' object with the ID 'pageTitle'.
Wicket labels will replace the contents of the markup they represent
(in this case the <title> tag) with their dynamic model data as a
String (in this case the result of '"Aloha - The Time is: " + new Date()'.
-->
<title wicket:id="pageTitle">[Page Title]</title>
</head>
<body>
<!-- A Common Data Table -->
<table>
<thead>
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Email Address</th>
</tr>
</thead>
<tbody>
<!-- The 'example' list item.
List items (which are components roughly representing a 'for loop') are
given example markup. In this case, for each list item we want to have a
<tr> with three <td> tags in it - each one a sub component of the list item.
-->
<tr wicket:id="people">
<!-- For a given list item, render the firstName label. -->
<td wicket:id="firstName">[First Name]</td>
<!-- For a given list item, render the lastName label. -->
<td wicket:id="lastName">[Last Name]</td>
<!-- For a given list item, render the email label. -->
<td wicket:id="email">[Email]</td>
</tr>
</tbody>
</table>
</body>
</html>
What you should keep in mind is that different components respond to their corresponding HTML differently - as an
example, the label simply replaces the contents of its HTML markup with its string representation. The list item, on the
other hand, uses its markup as a 'prototype'. It then loops over its model objects, calling
populateItem
with
each to create the sub-component trees for the various
ListItem
objects. The thing to remember is that none
of these Wicket objects (the Label, the ListItem) are magical - if you needed some specialized markup to be handled in a way
that Wicket isn't familiar, it is a reasonable process to create custom components. Also keep in mind that Wicket has many, many
other components similar to the
ListItem
to provide for the common cases that show up (including Links, BookmarkablePageLinks,
Buttons, Forms, Panels - reusable page chunks, Borders -theme-ing for a site/component, and on and on).
Remember also that these HTML markup pages are designed to be browser-friendly - here is what mine looks like by just looking at the
HTML page with my browser:
Configuration
Next, the mandatory configuration. All we need now is just to register the
WicketServlet
in the
web.xml
file so that the servlet container can start Wicket, and Wicket can start your application:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<display-name>Aloha Application</display-name>
<servlet>
<servlet-name>wicket</servlet-name>
<servlet-class>wicket.protocol.http.WicketServlet</servlet-class>
<init-param>
<param-name>applicationClassName</param-name>
<param-value>com.javalobby.tnt.wicket.aloha.AlohaApplication</param-value>
</init-param>
<init-param>
<param-name>aloha-app-setting</param-name>
<param-value>This is an example app-specific setting.</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>wicket</servlet-name>
<url-pattern>/app/*</url-pattern>
</servlet-mapping>
</web-app>
Finally, we can ship the contents of this project to a Java application server. Here is the final WAR-file layout:
Once the application server starts, we see this print in our log:
This is an example app-specific setting.
That is coming from the combination of the
init-param
in our
web.xml
and this line of code in our
application class:
// Potentially get custom settings from web.xml
System.out.println(getWicketServlet().getInitParameter("aloha-app-setting"));
I configured Wicket on the '/jlwicket' context of my application server on port 8080, so the URL I am hitting to get to this application is
http://localhost:8080/jlwicket/app. Here is a screenshot of the final result. Contrast and compare it to the 'prototype' UI
from the XHTML we browsed above:
This is a very quick and dirty sketch of playing with Wicket - but I highly suggest you pull down the latest and give it a shot.
It's still a young framework, but the methodology and approach is very unique and very powerful.
For those that would like to learn a bit more about wicket, I wrote an introduction to Wicket a while back titled "A First Look At The Wicket Framework", it can be found at:
RJ very nice intro to Wicket, much much nicer than the one I mentally wrote in my head.
I'd like to add my 2 cents and say that my experiences with Wicket thus far have been very similar, it's really straight forward, easy to work with, good errors, good support/docs and I feel like I'm getting things done quickly. I didn't feel this way with JSF.
I'm writing my second application with wicket, couldn't be happier, it's powerful, and fast to develop with, best thing for me is that HTML files are pure HTML.
OK, so let me ask a hypothetical question: let's say I want to display a rich grid component with sorting using let's say the displaytag JSP tag library.
Is there any way I can use the existing repository of custom JSP components in Wicket?
> OK, so let me ask a hypothetical question: let's say
> I want to display a rich grid component with sorting
> using let's say the displaytag JSP tag library.
>
> Is there any way I can use the existing repository of
> custom JSP components in Wicket?
Not directly in a page. Pages are pure HTML, so no JSP taglibraries allowed there. There is a possibility to
include markup from other places
allowing some integration.
Wicket does provide its own means to create such components easily. Check out our live examples at
this place
. We even provide an example showing
displaytag-like functionality
.
In our
extensions project
you can find even more advanced components to create sortable, pageable, *able tables. They are show in action
in these examples
. In our company we make have usage of these components and we are very,
very
content with them.
If Wicket doesn't have the specific JSP tag library you want, I am certain that it takes little effort to build a component that does the same. One of the major benefits of Wicket is that we make it very
easy to create custom components
.
To summarize: Wicket was created to get away from JSP's, so if you are a big fan of JSP's, then this is probably not the answer you were looking for.
But when you're in for something new and exciting, then try Wicket yourself... Our examples project contains a lot of material to get a glimpse of how things work in Wicket, and these articles provided by R.J. Lorimer are a great way to start coding.
Wicket definetly don't work for me. Wherever I put the html file (server Root or WEB-INF/classes/), Wicket won't find it.
Enabling debug messages for wicket.util.resource.Resource should help by showing where it is looking for the file. However, adding the necessary line (log4j.logger.wicket.util.resource=DEBUG) in log4j.properties only displays an error message :
log4j:WARN No appenders could be found for logger (wicket.protocol.http.WicketServlet).
By the way, putting html files in the classes directory is not something I like !
By default, Wicket does expect to find your HTML files paired up with the corresponding class-file. This is the standard choice made by Wicket, and I agree with Martijn Dashorst when he said this on the Wicket mailing list:
Before you go into that path, try the default wicket strategy for some
weeks. You may like it. Most developers I know are very proficient
with this way of working, and our designer is learning it also.
That being said, if you aren't happy with this format, you can certainly override it. Here is the reference on the documentation Wiki:
> Do you *have* to put the HTML files in the classes
> directory?
No, you don't *have* to put the HTML files in the classes directory. It is a matter of convenience.
Wicket makes it very easy to create custom components that can be used inside your pages, and those components can have their own independent markup file(s). The reason I like them together is that when you create many components, you can more easily find both the markup and the corresponding Java file.
The other plus point is that when you put everything together in the classpath, and serve the markup from there, you can distribute your components much more easily as the markup, possible CSS and JavaScript are in the JAR file.
So for one to use your super duper component, all he has to do is put the component JAR on the classpath and start using the component. He doesn't have to worry about putting the JavaScript in the markup directory, or to put the component HTML in some special directory.
Because Wicket makes it easy to create custom components we also wanted to make packaging and redistributing them a day in the park. This is why Wicket has attracted some attention in the OSGi world: they live on creating small focused bundles which are deployed in JAR files. The Wicket philosophy of bundling markup, resources and Java code is a perfect mariage with the OSGi philosopy.
As R.J. already said, and was said earlier, you can override this behavior yourself. I think R.J. has given the right directions on finding the configuration options.
> I haven't found a clear cut answer on the options
> available.
There are several possibilities:
1. take the 'Wicket' way
2. still use the package structure but relocate the root
3. create your own directory structure and relocate the root
Here is the comment on the three options:
1. is the default behavior
2. is easily done using one setting
3. needs you to create your own resource locator as Wicket can't possibly figure out how you want your resources packaged.
Like R.J. already quoted from my response on the mailing list: try (1) first. It has a lot of benefits and you might find it strange at first but after a couple of days you may find it natural. If not, use option 2 or 3.
Wicket: A Little Bit About Wicket
At 11:48 PM on Jan 2, 2006, R.J. Lorimer wrote:
Fresh Jobs for Developers Post a job opportunity
Lets face it, Java MVC web application frameworks are a dime a dozen. That's admittedly why when Wicket was first released, I didn't pay very much attention. Wicket persisted without my attention, however, and has certainly continued to generate buzz. Recently, I was in a position to spend some time learning what all the talk was about, and my first impression was certainly a positive one.
Update: Since the initial writing of this article, subsequent tips have been written. They are listed below:
Note that Wicket 1.2 is planned for release very soon, and based on the discussions on the user and development mailing lists, early 2006 (January/February) is when it is coming. In this article, I am focusing on Wicket 1.1 usage, since that is the current stable release.
Before going through all of this Wicket example, let's learn just a little bit about Wicket.
Wicket's Approach to Java Web Applications
(Lack of) Specialized Markup and Embedded Logic
Wicket has an interesting philosophy regarding the HTML markup used to template out the view. There are certainly a lot of rendering technologies available:
JSP/JSTL,Velocity,Freemarker, andXSLto name a few. Other MVC frameworks, such asTapestryuse a customized markup, and in Tapestry's case in particular, something largely based in the world of static HTML. Wicket takes a similar approach as Tapestry's, and ensures that the HTML is easily consumable by standard 'HTML' applications, such as browsers and HTML editors like Macromedia Dreamweaver. Interestingly enough, Wicket even uses the namespace standards to extend HTML so that there is really no custom syntax at all - no "special sauce" as the Wicket website calls it. Instead, Wicket empowers the developer through its rich component model.Rich Component Model
Wicket has what could be called a rich component model. What I mean by that is instead of having chunks of logic embedded in the view markup (such as JSP/Velocity/Freemarker scriptlets), you actually have a Wicket component (a 100% Java object) that contains the behavior that defines the dynamic UI result for that part of the result. This makes the configurability, extendability, and resuability of the UI components infinitely stronger. All of the wonderful patterns and techniques you have learned to maintain Java code to make it reusable work perfectly in Wicket. Where as entire frameworks, such as Tiles , were created to help modularize and componentize JSPs, Wicket naturally centers around that form of reusability, and in a 100% Java way.
Components don't just participate in the rendering process, they define it. Each component is allowed to have associated markup, and combines that markup with an internal model (provided by the developer). The behavior and logic of the component is all 100% Java code, and is all pluggable and controllable.
Finally, since all of the GUI behavior and code references are embedded in pure Java code, refactoring and code analysis are a piece of cake, as standard Java tools work perfectly with Wicket components.
Smart Session Management
Wicket takes session management to a new level. Because of Wicket's rich component model, the session management is extremely valuable for handling complex behavior such as processing form results - the component you associate with the UI to do the rendering of the form, will be the same one that consumes the result from the user. Likewise, session management makes it trivial for Wicket to handle the 'back button problem' for you. For those of you not familiar, the 'back button' problem is the scenario in which a user clicks the back button to get to a page of your application (such as a certain part of a form), and can re-submit or travel in a different direction at that point - even though that re-submit could invalidate server-side data, and potentially cause all kinds of problems.
(Lack of) Configuration Files
One of Wicket's key strengths is that it uses bascially no configuration files. There has certainly been a push back in recent years on the proliferation of configuration files that have to be managed just to keep everything running. You have to configure Wicket in the
web.xmlfile of your application (a requirement of the servlet specification), and that's just about it. This makes the configuration consistent with the rest of the application logic, and also ensures that it is succeptible to standard refactoring tools such as those embedded in Intellij, Netbeans, and Eclipse.A Quick Run-Through
Applications
The first step is to create an application object (an implementation of
wicket.protocol.http.WebApplication) - this object will help Wicket understand the organization and configuration of our program.package com.javalobby.tnt.wicket.aloha; import wicket.ApplicationSettings; import wicket.protocol.http.WebApplication; import wicket.util.time.Duration; public class AlohaApplication extends WebApplication { @Override protected void init() { // Set the 'Home Page' of the application (the 'index') getPages().setHomePage(AlohaPage.class); // Note that many of the settings below are 'defaults', but are being // set explicitly in this example to clarify. // Can be enabled/disabled to leave 'wicket' XHTML extensions in // rendered result to browser (a development assistance setting) getSettings().setStripWicketTags(false); // Tells Wicket to explicitly report if a component is specified // in the component model of a Particular page, but isn't used. // Useful in development to ensure all components are being rendered. // (But potentially slower) getSettings().setComponentUseCheck(true); // Tells wicket to check the timestamp of certain resources (such as HTML markup) // and update its local cached representation if they have changed // Useful in development, but more efficient to leave unset (null) in a production // environment where you don't need/want polling. getSettings().setResourcePollFrequency(Duration.ONE_SECOND); // Tells wicket to use a helpful 'debug' exception page with a snapshot of the // component model, and the exception stack trace. // Other settings are available to show pages that say there has been an internal error // (a production-friendly page) // In addition, more advanced usage allows you to override this behavior completely. getSettings().setUnexpectedExceptionDisplay(ApplicationSettings.SHOW_EXCEPTION_PAGE); // Alternative configuration - common 'configuration types' // that set some of the settings above based on what you would // want for production vs. development //getSettings().configure("development"); // -- or -- //getSettings().configure("deployment"); // Potentially get custom settings from web.xml System.out.println(getWicketServlet().getInitParameter("aloha-app-setting")); } }Note that strictly speaking, you can just as easily use the constructor of your
WebApplicationclass to set all of your settings and adjust things - theinit()method used above exists in case you want to get some custominit-parametersfrom theWicketServletas can be seen in the tail end of our configuration above.Pages
The next step is to create a page. Pages are a combination of components and markup. We'll go through the page class creation first:
package com.javalobby.tnt.wicket.aloha; import java.util.*; import wicket.markup.html.WebPage; import wicket.markup.html.basic.Label; import wicket.markup.html.list.*; public class AlohaPage extends WebPage { public AlohaPage() { // A Title for our page add(new Label("pageTitle", "Aloha - The Time is: " + new Date())); // A Wicket-style Loop/List of Items add(new ListView("people", getPeople()) { // This method is called for each 'entry' in the list. @Override protected void populateItem(ListItem item) { Person person = (Person)item.getModelObject(); item.add(new Label("firstName", person.firstName)); item.add(new Label("lastName", person.lastName)); item.add(new Label("email", person.email)); } }); } // Some arbitrary factory method. private List<Person> getPeople() { List<Person> people = new ArrayList<Person>(); people.add(new Person("R.J.", "Lorimer", "rj@javalobby.org")); people.add(new Person("Rick", "Ross", "rick@javalobby.org")); people.add(new Person("Matt", "Schmidt", "matt@javalobby.org")); return people; } // some arbitrary class for data. class Person { String firstName; String lastName; String email; Person(String fName, String lName, String emailAddr) { this.firstName = fName; this.lastName = lName; this.email = emailAddr; } } }Note that in many cases you may not want to put the Strings and Person objects in to the components directly (as I have done). That is because of Wicket's session-usage model, where components are kept on the session for an entire web conversation. For larger and more complex applications where session replication and maximum memory consumption control are important, you may want to install custom
wicket.model.IModelimplementations. Optimum model usage is a tip for another day, but for those of you who are curious, there are two reasons to implement a custom model: 1.) to avoid expensive String/model data being stored in the session if it should be freshly retrieved and collected for each request and 2.) to avoid holding data that isn't serializable (such as ourPersonclass) on the session since this data will break session clustering and failover.This page effectively has a component tree - this tree logically looks like this:
AlohaPage | *--- Label id='pageTitle' model='The Time is ####' | *--- ListView id='people' model=ArrayList of Person objects | *--- ListItem model=Person[0] | | | *--- Label id='firstName' model='R.J.' | | | *--- Label id='lastName' model='Lorimer' | | | *--- Label id='email' model='rj at javalobby dot org' | *--- ListItem model=Person[1] | | | *--- Label id='firstName' model='Rick' | | | *--- Label id='lastName' model='Ross' | | | *--- Label id='email' model='rick at javalobby dot org' | *--- ListItem model=Person[2] | *--- Label id='firstName' model='Matt' | *--- Label id='lastName' model='Schmidt' | *--- Label id='email' model='matt at javalobby dot org'Now, on to the HTML markup for this new page we have created. This HTML is designed to line up to the component tree that we have just created.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.sourceforge.net/" xml:lang="en" lang="en"> <head> <!-- The 'pageTitle' label. We have designated a wicket 'Label' object with the ID 'pageTitle'. Wicket labels will replace the contents of the markup they represent (in this case the <title> tag) with their dynamic model data as a String (in this case the result of '"Aloha - The Time is: " + new Date()'. --> <title wicket:id="pageTitle">[Page Title]</title> </head> <body> <!-- A Common Data Table --> <table> <thead> <tr> <th>First Name</th> <th>Last Name</th> <th>Email Address</th> </tr> </thead> <tbody> <!-- The 'example' list item. List items (which are components roughly representing a 'for loop') are given example markup. In this case, for each list item we want to have a <tr> with three <td> tags in it - each one a sub component of the list item. --> <tr wicket:id="people"> <!-- For a given list item, render the firstName label. --> <td wicket:id="firstName">[First Name]</td> <!-- For a given list item, render the lastName label. --> <td wicket:id="lastName">[Last Name]</td> <!-- For a given list item, render the email label. --> <td wicket:id="email">[Email]</td> </tr> </tbody> </table> </body> </html>What you should keep in mind is that different components respond to their corresponding HTML differently - as an example, the label simply replaces the contents of its HTML markup with its string representation. The list item, on the other hand, uses its markup as a 'prototype'. It then loops over its model objects, calling
populateItemwith each to create the sub-component trees for the variousListItemobjects. The thing to remember is that none of these Wicket objects (the Label, the ListItem) are magical - if you needed some specialized markup to be handled in a way that Wicket isn't familiar, it is a reasonable process to create custom components. Also keep in mind that Wicket has many, many other components similar to theListItemto provide for the common cases that show up (including Links, BookmarkablePageLinks, Buttons, Forms, Panels - reusable page chunks, Borders -theme-ing for a site/component, and on and on).Remember also that these HTML markup pages are designed to be browser-friendly - here is what mine looks like by just looking at the HTML page with my browser:
Configuration
Next, the mandatory configuration. All we need now is just to register the
WicketServletin theweb.xmlfile so that the servlet container can start Wicket, and Wicket can start your application:<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app> <display-name>Aloha Application</display-name> <servlet> <servlet-name>wicket</servlet-name> <servlet-class>wicket.protocol.http.WicketServlet</servlet-class> <init-param> <param-name>applicationClassName</param-name> <param-value>com.javalobby.tnt.wicket.aloha.AlohaApplication</param-value> </init-param> <init-param> <param-name>aloha-app-setting</param-name> <param-value>This is an example app-specific setting.</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>wicket</servlet-name> <url-pattern>/app/*</url-pattern> </servlet-mapping> </web-app>Finally, we can ship the contents of this project to a Java application server. Here is the final WAR-file layout:
Once the application server starts, we see this print in our log:
That is coming from the combination of the
init-paramin ourweb.xmland this line of code in our application class:// Potentially get custom settings from web.xml System.out.println(getWicketServlet().getInitParameter("aloha-app-setting"));I configured Wicket on the '/jlwicket' context of my application server on port 8080, so the URL I am hitting to get to this application is
http://localhost:8080/jlwicket/app. Here is a screenshot of the final result. Contrast and compare it to the 'prototype' UI from the XHTML we browsed above:This is a very quick and dirty sketch of playing with Wicket - but I highly suggest you pull down the latest and give it a shot. It's still a young framework, but the methodology and approach is very unique and very powerful.
Until next time,
R.J. Lorimer
Contributing Editor -rj -at- javalobby.orgAuthor -http://www.coffee-bytes.comSoftware Consultant -http://www.numbersix.com19 replies so far (
Post your own)
Re: Wicket: A Little Bit About Wicket
Nice intro.For those that would like to learn a bit more about wicket, I wrote an introduction to Wicket a while back titled "A First Look At The Wicket Framework", it can be found at:
http://ensode.net/wicket_first_look.html
David
Author, JasperReports For Java Developers
Re: Wicket: A Little Bit About Wicket
RJ very nice intro to Wicket, much much nicer than the one I mentally wrote in my head.I'd like to add my 2 cents and say that my experiences with Wicket thus far have been very similar, it's really straight forward, easy to work with, good errors, good support/docs and I feel like I'm getting things done quickly. I didn't feel this way with JSF.
Re: Wicket: A Little Bit About Wicket
I'm writing my second application with wicket, couldn't be happier, it's powerful, and fast to develop with, best thing for me is that HTML files are pure HTML.Re: Wicket: A Little Bit About Wicket
OK, so let me ask a hypothetical question: let's say I want to display a rich grid component with sorting using let's say the displaytag JSP tag library.Is there any way I can use the existing repository of custom JSP components in Wicket?
Re: Wicket: A Little Bit About Wicket
> OK, so let me ask a hypothetical question: let's say> I want to display a rich grid component with sorting
> using let's say the displaytag JSP tag library.
>
> Is there any way I can use the existing repository of
> custom JSP components in Wicket?
Not directly in a page. Pages are pure HTML, so no JSP taglibraries allowed there. There is a possibility to include markup from other places allowing some integration.
Wicket does provide its own means to create such components easily. Check out our live examples at this place . We even provide an example showing displaytag-like functionality .
In our extensions project you can find even more advanced components to create sortable, pageable, *able tables. They are show in action in these examples . In our company we make have usage of these components and we are very, very content with them.
If Wicket doesn't have the specific JSP tag library you want, I am certain that it takes little effort to build a component that does the same. One of the major benefits of Wicket is that we make it very easy to create custom components .
To summarize: Wicket was created to get away from JSP's, so if you are a big fan of JSP's, then this is probably not the answer you were looking for.
But when you're in for something new and exciting, then try Wicket yourself... Our examples project contains a lot of material to get a glimpse of how things work in Wicket, and these articles provided by R.J. Lorimer are a great way to start coding.
Re: Wicket: A Little Bit About Wicket
Thank you for your response, I will look into them.Re: Wicket: A Little Bit About Wicket
Wicket definetly don't work for me. Wherever I put the html file (server Root or WEB-INF/classes/), Wicket won't find it.Enabling debug messages for wicket.util.resource.Resource should help by showing where it is looking for the file. However, adding the necessary line (log4j.logger.wicket.util.resource=DEBUG) in log4j.properties only displays an error message :
log4j:WARN No appenders could be found for logger (wicket.protocol.http.WicketServlet).
By the way, putting html files in the classes directory is not something I like !
Re: Wicket: A Little Bit About Wicket
By default, Wicket does expect to find your HTML files paired up with the corresponding class-file. This is the standard choice made by Wicket, and I agree with Martijn Dashorst when he said this on the Wicket mailing list:
That being said, if you aren't happy with this format, you can certainly override it. Here is the reference on the documentation Wiki:
Wicket Wiki: Control Where HTML Files Are Loaded From
In regards to your logging problem, it sounds like a configuration problem with your log4j setup, and not with Wicket. This:
...is a log4j error message; perhaps you need to specify a root logger in your properties file?
Regards,
Re: Wicket: A Little Bit About Wicket
Do you *have* to put the HTML files in the classes directory?I haven't found a clear cut answer on the options available.
Thanks,
Re: Wicket: A Little Bit About Wicket
Todd,No, Not at all. See my other response here:
http://www.javalobby.org/java/forums/m91984364.html
Regards
Re: Wicket: A Little Bit About Wicket
> Do you *have* to put the HTML files in the classes> directory?
No, you don't *have* to put the HTML files in the classes directory. It is a matter of convenience.
Wicket makes it very easy to create custom components that can be used inside your pages, and those components can have their own independent markup file(s). The reason I like them together is that when you create many components, you can more easily find both the markup and the corresponding Java file.
The other plus point is that when you put everything together in the classpath, and serve the markup from there, you can distribute your components much more easily as the markup, possible CSS and JavaScript are in the JAR file.
So for one to use your super duper component, all he has to do is put the component JAR on the classpath and start using the component. He doesn't have to worry about putting the JavaScript in the markup directory, or to put the component HTML in some special directory.
Because Wicket makes it easy to create custom components we also wanted to make packaging and redistributing them a day in the park. This is why Wicket has attracted some attention in the OSGi world: they live on creating small focused bundles which are deployed in JAR files. The Wicket philosophy of bundling markup, resources and Java code is a perfect mariage with the OSGi philosopy.
As R.J. already said, and was said earlier, you can override this behavior yourself. I think R.J. has given the right directions on finding the configuration options.
> I haven't found a clear cut answer on the options
> available.
There are several possibilities:
1. take the 'Wicket' way
2. still use the package structure but relocate the root
3. create your own directory structure and relocate the root
Here is the comment on the three options:
1. is the default behavior
2. is easily done using one setting
3. needs you to create your own resource locator as Wicket can't possibly figure out how you want your resources packaged.
Like R.J. already quoted from my response on the mailing list: try (1) first. It has a lot of benefits and you might find it strange at first but after a couple of days you may find it natural. If not, use option 2 or 3.
Re: Wicket: A Little Bit About Wicket
Thanks for the advice ! I will try again.More Wicket articles
This article has been posted on dzone. Vote for it if you like it!
More Wicket articles:
More Wicket articles
This article has been posted on dzone. Vote for it if you like it!
More Wicket articles: