Forum Controls
Spotlight Features

The Rich Engineering Heritage Behind Dependency Injection

Andrew McVeigh takes us on a tour of the rich heritage behind dependency injection, what it represents, and tells us why its here to stay.

NetBeans 6: Matisse Updates

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.

Introduction to Groovy Part 3

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.

Easier Custom Components with Swing Fuse

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.

Benchmark Analysis: Guice vs Spring

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: 2 - Pages: 1  
Threads: [ Previous | Next ]
  Click to reply to this thread Reply

Wicket: Let Components Contribute to the Header Section

At 8:14 PM on Jan 5, 2006, R.J. Lorimer wrote:

Welcome to the third article in my Wicket series. If you haven't read the first two, I would recommend that you do:

Last time, in the 'Reusable Panels' article, I discussed the ability to make a component that showed a table of user information, and we could reuse that component inside any page/container-style component we wanted to (it could be put inside another panel for instance!).

Certainly, we could achieve something similar using JSP includes and some request attribute, or even page-context attribute. Now, let's say we wanted to make the table in that result sortable using ECMAScript (*cough* JavaScript *cough*). We could use something like this straightforward MIT licensed library: sorttable: Make all your tables sortable .

This table sorting JavaScript is very easy to integrate - from the site:

  1. Include the Javascript library, by putting a link to it in the HEAD of your page, like so:
    <script src="sorttable.js"></script>
    
  2. Mark your table as a sortable one by giving it a class of "sortable":
    <table class="sortable">
    
  3. Ensure that your table has an ID:
    <table class="sortable" id="unique_id">
    

Ahh, but in the JSP world now we have a problem. Now we have to do more than just add the JSP include to our page; we also have to add a script import to the HEAD section of our overall JSP page. The same would be true if the JSP fragment we were including required some custom CSS as well, or needed some code to be run onLoad() . This can become a major frustration in more complicated cases, as you'd like to turn on and off certain parts of the JavaScript/CSS if you aren't using it, but the only way to know is whether or not you included the JSP that requires it - which is often times very far away from the code that renders the HEAD (particularly if your site is themed by a technology such as Tiles - but theme-ing in Wicket is a topic for another day).

Wicket takes a novel approach to solving this problem. Unlike JSP includes, a Wicket panel is a full-blown Java object - because of that, it is allowed to participate in all kinds of things a JSP include may not be able to.

Remember our PersonPanel from the last Wicket tip? Well, let's make it sortable. First, let's handle the cases we already know - that includes tagging the various parts of the table with the CSS class and ID attributes recommended by the library above:

...
<table class="sortable" id="personTable">
...

Now, to make this work well, there are two things we'd like to add to the HEAD of the owning page - the JavaScript tag that will import the 'sorttable' library, and the CSS that will make the columns appear like clickable buttons that support sorting. Here is the contents we'd like to add to our HEAD:

<script language="JavaScript" src="scripts/sorttable.js"></script>
<style type="text/css">
	table.sortable a.sortheader {
	    background-color:#eee;
	    color:#666666;
	    font-weight: bold;
	    text-decoration: none;
	    display: block;
	}
	table.sortable span.sortarrow {
	    color: black;
	    text-decoration: none;
	}
</style>

So, how do we tell Wicket that our PersonPanel needs these new chunks of code? Well, we tell it using the <wicket:head> tag. This tag is a special wicket tag (typically at the top of a the markup for a component, or in the regular <head> tag), and it tells wicket that the contents are a contribution of this component to the owning page's HEAD section. Here is how our PersonPanel 's markup looks with these two new additions:

<!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">
	

<wicket:head>
	<script language="JavaScript" src="scripts/sorttable.js"></script>
	<style type="text/css">
		table.sortable a.sortheader {
		    background-color:#eee;
		    color:#666666;
		    font-weight: bold;
		    text-decoration: none;
		    display: block;
		}
		table.sortable span.sortarrow {
		    color: black;
		    text-decoration: none;
		}
	</style>
</wicket:head>
	

<body>
	<wicket:panel>
		<h3>This is the BEGINNING of the Person Panel</h3>
		<table class="sortable" id="personTable">
			<thead>
				<tr>
					<th>First Name</th>
					<th>Last Name</th>
					<th>Email Address</th>
				</tr>
			</thead>
			<tbody>
				<tr wicket:id="people">
					<td wicket:id="firstName">[First Name]</td>
					<td wicket:id="lastName">[Last Name]</td>
					<td wicket:id="email">[Email]</td>
				</tr>
			</tbody>
		</table>
		<h3>This is the END of the Person Panel</h3>
	</wicket:panel>
</body>
</html>

That's it! At this point, the owning Page will get these new HEAD contributions, and will render them like they were its own.

Here is a snippet of the finished HTML source on my workstation:

...
<head>
	<title wicket:id="pageTitle">Aloha - The Time is: Thu Jan 05 18:41:50 CST 2006</title>

	<script language="JavaScript" src="scripts/sorttable.js"></script>
	<style type="text/css">
		table.sortable a.sortheader {
		    background-color:#eee;
		    color:#666666;
		    font-weight: bold;
		    text-decoration: none;
		    display: block;
		}
		table.sortable span.sortarrow {
		    color: black;
		    text-decoration: none;
		}
	</style>
</head>
<body>
	<h1>This is the BEGINNING of the Aloha Page</h1>

...

Here is a picture of it in action:

I'd like to note especially that we only touched the PersonPanel class, and didn't have to touch the AlohaPage at all - this is key to reusable components in Wicket. Here is what our source tree looks like now:

/
|
*---scripts/
|   |
|   *--- sorttable.js - The sorttable library.
|
*-- WEB-INF/
    |
    *---classes/
    |   |
    |   *---com/javalobby/tnt/wicket/aloha/
    |   |   |
    |   |   *--- AlohaApplication.class - Application definition
    |   |   | 
    |   |   *--- AlohaPage.class - AlohaPage component definition
    |   |   |
    |   |   *--- AlohaPage.html - Associatied HTML markup for aloha page.
    |   |   |
    |   |   *--- PersonPanel.class - PersonPanel component definition
    |   |   |
    |   |   *--- PersonPanel.html - Associated HTML markup for PersonPanel
    |   |
    |   *--- log4j.properties - log4j properties of your making (or java.util.logging properties)
    |
    *--- web.xml - The web.xml file.

Oh, and by the way, Wicket also handles the onload attribute of the body tag. For instance, if you had this in your AlohaPage

<body onload="fromAlohaPage();">

... and you had this in your PersonPanel

<body onload="fromPersonPanel();">

... the final markup would be like this:

<body onload="fromAlohaPage();fromPersonPanel();">

Finally, for those Wicket familiars who will say at this point 'actually, you can ship sorttable.js as a resource with the component, and don't have to include it separately' or [insert other cool thing here] I will say - I know, but let's tackle one-thing-at-a-time :).

Until next time,

R.J. Lorimer
Contributing Editor - rj -at- javalobby.org
Author              - http://www.coffee-bytes.com
Software Consultant - http://www.numbersix.com

1 . At 2:30 AM on Jan 6, 2006, Martijn Dashorst DeveloperZone Top 100 wrote:
  Click to reply to this thread Reply

Re: Wicket: Let Components Contribute to the Header Section

Finally, for those Wicket familiars who will say at this point 'actually, you can ship sorttable.js as a resource with the component, and don't have to include it separately' or [insert other cool thing here] I will say - I know, but let's tackle one-thing-at-a-time


When you don't need to build a component that is used across applications, then this is by far the most easy way to work with JavaScript that doesn't need to be altered, such as third party javascript files.

I use this technique for doing prototype.js and scriptaculous.js work and it works great.

When building a reusable component that is shipped to third parties, then you should load it from the classpath and include it in your jar, or tell your customers to put the javascript in the afore mentioned directory in the webapp folder. The former is by far the most user friendly, the latter shifts the problem to documentation ('don't forget to put foo.js in the scripts/ subdirectory of your webapp') and distribution (now you have to ship the javascript seperately).

Can't wait til the next tip!
2 . At 9:48 AM on Mar 10, 2008, Eyal Golan wrote:
  Click to reply to this thread Reply

Re: Wicket: Let Components Contribute to the Header Section

wicket has SortableDataProvider which this is what I'm using. My question is, how can I integrate the JavaScript and this? when I use your example with the wicket's sorting provider, I see the arrow just for a brief second and it disappears. I am not a JS expert (at all) and I was wondering if there is a way of combining a nice arrow with the SortableDataProvider. And I really like your tips and tricks :)

thread.rss_message