Wednesday, April 25, 2007

A Wicket button panel using the sliding doors technique

This Wicket reusable component I created is based on this post, which in turn is based on the same technique used for tabs first described here, and which is used in the Wicket tab panel. I wanted a panel containing an arbitrary number of buttons, which resize according to the length of the text. This example creates a PageLink for each button, but you could change this to a different type of Wicket link.

Sample usage:
ButtonPanel buttons = new ButtonPanel("adddeletebuttons");
buttons.addButton("Add", Add.class);
buttons.addButton("Delete", Delete.class);
add(buttons);
There are 5 files: ButtonPanel.{java,html,css}, slidingdoorsbuttonleft.gif, and slidingdoorsbuttonright.gif. In my implementation, the CSS file lives with the java and html files, while the images live in a central "images" directory. The button images are below.

ButtonPanel.java:
package com.my;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import wicket.behavior.HeaderContributor;
import wicket.markup.html.basic.Label;
import wicket.markup.html.link.Link;
import wicket.markup.html.link.PageLink;
import wicket.markup.html.list.ListItem;
import wicket.markup.html.list.ListView;
import wicket.markup.html.panel.Panel;
import wicket.model.PropertyModel;

public class ButtonPanel extends Panel
{
private List<buttonmodelbean> buttons = new ArrayList<buttonmodelbean>();

public ButtonPanel(String arg0)
{
super(arg0);

add(HeaderContributor.forCss(ButtonPanel.class, "ButtonPanel.css"));

add(new ListView("buttons", new PropertyModel(this, "buttons"))
{
@Override
protected void populateItem(ListItem item)
{
final ButtonModelBean button = (ButtonModelBean) item
.getModelObject();

Link lnk = new PageLink("buttonlink", button.getLinkClass());
lnk.add(new Label("buttontext", button.getButtonLabel()));
item.add(lnk);
}
});
}

public void addButton(String s, Class linkClass)
{
buttons.add(new ButtonModelBean(s, linkClass));
}

public List getButtons()
{
return buttons;
}

protected class ButtonModelBean implements Serializable
{
private String buttonLabel;
private Class linkClass;

public ButtonModelBean(String s, Class linkClass)
{
buttonLabel = s;
this.linkClass = linkClass;
}

public ButtonModelBean(String s)
{
buttonLabel = s;
}

public String getButtonLabel()
{
return buttonLabel;
}

public void setButtonLabel(String node)
{
this.buttonLabel = node;
}

@Override
public String toString()
{
return buttonLabel;
}

public Class getLinkClass()
{
return linkClass;
}

public void setLinkClass(Class linkClass)
{
this.linkClass = linkClass;
}
}
}

ButtonPanel.html:
<html wicket="xmlns:wicket">
<body>
<wicket:panel><div class="buttonpanel">
<ul id="buttons">
<li> <a href="#" id="buttonlink"><span id="buttontext">Button Text</span></a> </li>
</ul>
</div></wicket:panel>
</body>
</html>

ButtonPanel.css:
div.buttonpanel ul {
padding: 0;
margin: 0;
list-style: none;
}

div.buttonpanel li {
float: left;
background: url('/mycontext/images/slidingdoorsbuttonleft.gif') no-repeat left top;
margin: 2px 5px 0 0;
padding: 0 0 0 16px;
}

div.buttonpanel a {
display: block;
background: url('/mycontext/images/slidingdoorsbuttonright.gif') no-repeat right
top;
padding: 6px 15px 9px 0px;
text-decoration: none;
color: black;
white-space: nowrap;
font-size: 11pt;
font-weight: normal;
cursor: pointer;
margin: 0 10px 0 0;
}

No comments: