Sonntag, 2. Januar 2011

How to Customize the Wicket Feedback Panel

Motivation

The standard FeedbackPanel of Wicket is showing the error and warning messages that occur when validating input fields, which is done by simply showing the text message. There are simple way to customize this standard FeedbackPanel by replacing the used CSS class.

However, sometimes it would be nice to show also the error-level of the message, e.g., by showing a corresponding icon together with the message. This is not possible with the FeedbackPanel given by Wicket. One way of doing that, is to provide a new implementation for the FeedbackPanel.

Realization of a new FeedbackPanel

A good starting point for an own implementation is to copy the source code of the standard FeedbackPanel class. It can be found in the package org.apache.wicket.markup.html.panel of the Wicket source code. Note, it would be much nicer to inherit code instead of copying it, but sometimes this is not possible, as Wicket is (too?) restrictive and much of the code is declared as final.

A new FeedbackPanel must inherit the marker interface IFeedback, as the original class does:

    public class FeedbackPanel extends Panel implements IFeedback

This marker interface is needed to guide the Wicket-Framework when the new FeedbackPanel component has to be rendered. Implementors of IFeedback are rendered after all non-feedback components. This is necessary because non-feedback components must create feedback messages before they can be processed by the feedback panel the FeedbackPanel.

The implementation uses a list view that shows all messages that have been gathered on the current page. For this purposes the FeedbackPanel uses the FeedbackMessagesModel of Wicket. The list view simply iterates through the message items when being rendered and attaches the content of the messages to the corresponding html markups used for the Feedback panel. The following code of the list view, which is used by the FeedbackPanel, provides this functionality:


private final class MessageListView extends ListView {
public final static String IMG_ERROR = "images/error.gif";
public final static String IMG_WARNING = "images/warning.gif";
public final static String IMG_NOTE = "images/note.gif";

private static final long serialVersionUID = 1L;

/**
* @see org.apache.wicket.Component#Component(String)
*/
public MessageListView(final String id, List msgs) {
super(id);
setDefaultModel(newFeedbackMessagesModel());
}

/**
* @see org.apache.wicket.markup.html.list.ListView
* #populateItem(org.apache.wicket.markup.html
* .list.ListItem)
*/
@Override
protected void populateItem(final ListItem listItem) {
final FeedbackMessage message = listItem.getModelObject();
message.markRendered();


WebMarkupContainer container = new WebMarkupContainer("message");
ContextImage image = new ContextImage("messageType", new
Model(getLevelImage(message.getLevel())));
container.add(image);
Component text = newMessageDisplayComponent("text", message);
container.add(text);

listItem.add(container);
}

public String getLevelImage(int level) {
String img = "";
if (level == FeedbackMessage.INFO ||
level == FeedbackMessage.DEBUG || level == FeedbackMessage.UNDEFINED) {
img = IMG_NOTE;
} else if (level == FeedbackMessage.WARNING) {
img = IMG_WARNING;
} else if (level == FeedbackMessage.ERROR ||
level == FeedbackMessage.FATAL) {
img = IMG_ERROR;
}
return img;
}
}


The method populateItem(…) does the main job. It gets the message text as well as the error-level of the message. The latter is got with the help of the method getLevelImage(). This method takes an integer and returns the path to an image which is representing the corresponding error-level of the message.

The html tags of the FeedbackPanel looks as follows and provides simply the tag structure for the list of the message content.


<table border="0" width="800px" cellpadding="0" cellspacing="0">
<tr wicket:id="message">
<td> </td>
<td width="20px">
<img wicket:id="messageType"
src="../../../../../../webapp/images/note.gif">
</td>

<td width="780px">
<span wicket:id="text" >
Message to show.
</span>
</td>
<td> </td>
</tr>
</table>


The rest of the implementation is as provided by the Wicket framework.

The source code for the example can be downloaded here (same sample project as in the previous blog article, for building and execution instructions refer to this article). The Java implementation is given by the file com/blogspot/m3g4h4rd/wicket/FeedbackPanel.java and the html markup can be found in com/blogspot/m3g4h4rd/wicket/FeedbackPanel.html. Note this the source code is published under Apache license 2.0.