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.
Last time in my article
A Little Bit About Wicket
,
I extolled the virtues of the MVC framework
Wicket
in creating modular, reusable components for your Java web application.
Today I want to show you a brief run-through of one of the key components for Wicket's reusability - the Wicket
wicket.markup.html.panel.Panel
.
Wicket
Panels
are another type of component, like
Label
or
ListView
from the previous tip.
Unlike Label or ListView, however, a Panel is allowed to have its own associated markup. So while the markup for the
ListView
'people' from our previous tip was embedded in the containing page's markup, a
Panel
has its own markup file, and that makes it
much more reusable.
Here is an example. In my previous tip, I had a table that presented a list of
Person
objects to the user. This page was succinct
and simple. Let's say that a new requirement showed up, however, and we now need to show that table on two different pages. We'd like to be
able to just put the code for the
ListView
on both pages, but we now also have to copy the markup, and that's certainly not
very 'reusable'.
Instead, we can create a panel. Here is how. First, we must create a subclass of
wicket.markup.html.panel.Panel
that contains our
component tree for the stuff we want to reuse - you'll recognize the
ListView
from yesterday's tip:
package com.javalobby.tnt.wicket.aloha;
import java.util.*;
import wicket.markup.html.basic.Label;
import wicket.markup.html.list.*;
import wicket.markup.html.panel.Panel;
/**
* Shows a list of people.
*
* @author R.J. Lorimer
*/
publicclass PersonPanel extends Panel {
/**
* Id constructor.
* @param id the Id.
*/
public PersonPanel(String id) {
super(id);
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));
}
});
}
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;
}
class Person {
String firstName;
String lastName;
String email;
Person(String fName, String lName, String emailAddr) {
this.firstName = fName;
this.lastName = lName;
this.email = emailAddr;
}
}
}
As you can see, it looks very similar to our old Page, but unlike the
Page
,
the
Panel
has to implement a non-empty constructor, passing the ID up to the parent.
That is because all components aside from a
Page
require an ID, as they are not the root of the component hierarchy.
Next, we need to create a new markup file to associate with this panel titled to match (
PersonPanel.html
):
<!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">
<body>
<wicket:panel>
<h3>This is the BEGINNING of the Person Panel</h3>
<table>
<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>
Looking at the above example, you'll see that we have one new and unique tag - the
<wicket:panel>
tag. This new tag
tells wicket how much of the HTML source actually belongs to the panel. Why is this important? It allows us to provide gobs of template
HTML around the panel, or what is often called 'preview markup'. This markup allows for multiple things to be done - first, the panel HTML
page can now have custom documentation embedded in it. This would allow us to show it to someone who wanted to use our panel (let's say for the moment
that we shipped it as a 'wicket extensions' library), and they could learn how to use it just by looking at this file. In addition,
this HTML allows us to supply boilerplate template layout that may not be necessary when the panel is used in context to a page - this allows the
preview to look decent (or at least indicative to what you would want to see), without having to do anything magical. You'll also notice that I added a
little header so we'd know that the panel was responsible for the rendering.
The next step is to adjust our Page class to use the new, reusable
Panel
we created, rather than using the
ListView
that we had before. We can give the panel any ID we want at this point, just like the label or list view we used:
package com.javalobby.tnt.wicket.aloha;
import java.util.Date;
import wicket.markup.html.WebPage;
import wicket.markup.html.basic.Label;
publicclass AlohaPage extends WebPage {
public AlohaPage() {
// A Title for our page
add(new Label("pageTitle", "Aloha - The Time is: " + new Date()));
add(new PersonPanel("personPanel"));
}
}
Well, that certainly got smaller and more concise, didn't it? Now that the panel is in our page component tree, we also make sure
it is referenced in the page markup. We add it by id, like any other component. I've basically replaced the list view from yesterday's
tip with the panel:
<!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>
<title wicket:id="pageTitle">[Page Title]</title>
</head>
<body>
<h1>This is the BEGINNING of the Aloha Page</h1>
<!--
The new panel. Notice that it's just an empty tag that
will be filled in by the panel when it is asked to render.
-->
<div wicket:id="personPanel"></div>
<h1>This is the END of the Aloha Page</h1>
</body>
</html>
Intuitively, the panel tag is allowed to be any empty container tag. In the same way that a label's tag will be populated by the
label, this new empty tag for the panel will be populated by the panel - the page kind of considers it like a black box - in the same
way that a JSP include is a black box. Also notice that I have added a set of headings (h1) to the page to show
that the page is responsible for unique content *around* the panel.
Now, compared to the previous tip, our file tree looks like this:
Notice we only have the two additional files - no extra cruft.
Finally, here is a snapshot of the end result:
This new panel we created can be used in as many places as we want in our application, and all we have to do
is add an instance of it to our component tree, and give it an ID based reference in our markup file. No imports and
includes, no request/session manipulation, no mess.
There are more advanced features in Wicket, and with panels in particular
(such as the ability to provide header contributions to the owning page)
- but as I said yesterday we've only scratched the surface of the Wicket feature-base,
and hopefully I can cover more and more of these nifty features as time goes on.
Wicket: Reusable Panels
At 11:43 PM on Jan 4, 2006, R.J. Lorimer wrote:
Fresh Jobs for Developers Post a job opportunity
Last time in my article A Little Bit About Wicket , I extolled the virtues of the MVC framework Wicket in creating modular, reusable components for your Java web application. Today I want to show you a brief run-through of one of the key components for Wicket's reusability - the Wicket
wicket.markup.html.panel.Panel.Wicket
Panelsare another type of component, likeLabelorListViewfrom the previous tip. Unlike Label or ListView, however, a Panel is allowed to have its own associated markup. So while the markup for theListView'people' from our previous tip was embedded in the containing page's markup, aPanelhas its own markup file, and that makes it much more reusable.Here is an example. In my previous tip, I had a table that presented a list of
Personobjects to the user. This page was succinct and simple. Let's say that a new requirement showed up, however, and we now need to show that table on two different pages. We'd like to be able to just put the code for theListViewon both pages, but we now also have to copy the markup, and that's certainly not very 'reusable'.Instead, we can create a panel. Here is how. First, we must create a subclass of
wicket.markup.html.panel.Panelthat contains our component tree for the stuff we want to reuse - you'll recognize theListViewfrom yesterday's tip:package com.javalobby.tnt.wicket.aloha; import java.util.*; import wicket.markup.html.basic.Label; import wicket.markup.html.list.*; import wicket.markup.html.panel.Panel; /** * Shows a list of people. * * @author R.J. Lorimer */ public class PersonPanel extends Panel { /** * Id constructor. * @param id the Id. */ public PersonPanel(String id) { super(id); 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)); } }); } 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; } class Person { String firstName; String lastName; String email; Person(String fName, String lName, String emailAddr) { this.firstName = fName; this.lastName = lName; this.email = emailAddr; } } }As you can see, it looks very similar to our old Page, but unlike the
Page, thePanelhas to implement a non-empty constructor, passing the ID up to the parent. That is because all components aside from aPagerequire an ID, as they are not the root of the component hierarchy.Next, we need to create a new markup file to associate with this panel titled to match (
PersonPanel.html):<!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"> <body> <wicket:panel> <h3>This is the BEGINNING of the Person Panel</h3> <table> <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>Looking at the above example, you'll see that we have one new and unique tag - the
<wicket:panel>tag. This new tag tells wicket how much of the HTML source actually belongs to the panel. Why is this important? It allows us to provide gobs of template HTML around the panel, or what is often called 'preview markup'. This markup allows for multiple things to be done - first, the panel HTML page can now have custom documentation embedded in it. This would allow us to show it to someone who wanted to use our panel (let's say for the moment that we shipped it as a 'wicket extensions' library), and they could learn how to use it just by looking at this file. In addition, this HTML allows us to supply boilerplate template layout that may not be necessary when the panel is used in context to a page - this allows the preview to look decent (or at least indicative to what you would want to see), without having to do anything magical. You'll also notice that I added a little header so we'd know that the panel was responsible for the rendering.The next step is to adjust our Page class to use the new, reusable
Panelwe created, rather than using theListViewthat we had before. We can give the panel any ID we want at this point, just like the label or list view we used:package com.javalobby.tnt.wicket.aloha; import java.util.Date; import wicket.markup.html.WebPage; import wicket.markup.html.basic.Label; public class AlohaPage extends WebPage { public AlohaPage() { // A Title for our page add(new Label("pageTitle", "Aloha - The Time is: " + new Date())); add(new PersonPanel("personPanel")); } }Well, that certainly got smaller and more concise, didn't it? Now that the panel is in our page component tree, we also make sure it is referenced in the page markup. We add it by id, like any other component. I've basically replaced the list view from yesterday's tip with the panel:
<!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> <title wicket:id="pageTitle">[Page Title]</title> </head> <body> <h1>This is the BEGINNING of the Aloha Page</h1> <!-- The new panel. Notice that it's just an empty tag that will be filled in by the panel when it is asked to render. --> <div wicket:id="personPanel"></div> <h1>This is the END of the Aloha Page</h1> </body> </html>Intuitively, the panel tag is allowed to be any empty container tag. In the same way that a label's tag will be populated by the label, this new empty tag for the panel will be populated by the panel - the page kind of considers it like a black box - in the same way that a JSP include is a black box. Also notice that I have added a set of headings (h1) to the page to show that the page is responsible for unique content *around* the panel.
Now, compared to the previous tip, our file tree looks like this:
Notice we only have the two additional files - no extra cruft.
Finally, here is a snapshot of the end result:
This new panel we created can be used in as many places as we want in our application, and all we have to do is add an instance of it to our component tree, and give it an ID based reference in our markup file. No imports and includes, no request/session manipulation, no mess.
There are more advanced features in Wicket, and with panels in particular (such as the ability to provide header contributions to the owning page) - but as I said yesterday we've only scratched the surface of the Wicket feature-base, and hopefully I can cover more and more of these nifty features as time goes on.
Until next time,
R.J. Lorimer
Contributing Editor -rj -at- javalobby.orgAuthor -http://www.coffee-bytes.comSoftware Consultant -http://www.numbersix.com0 replies so far (
Post your own)