Tuesday, January 24, 2012

Using Wicket Panel to create Reusable Component (Widget)

Why do we like components? They save our time. Once developed, they can be used many times. In this article we will create reusable component using Wicket Panel.


Imagine a video hosting service that allows users to browse, search and play videos. Video usually has a title, length, thumbnail and other meta information. So we need a component that would represend a video in our listings.

Our widget would have title, link, thumbnail image, length and rating. In Wicket we need to create 2 files: Html template and Java class.

Html template

    <wicket:panel>
        <div class="linkbox" wicket:id="listview" >
            <a wicket:id="detailThumbLink" href="#">
              <img wicket:id="thumbnail" width="150" height="150" />
            </a>
            <br /><br />
            <a wicket:id="detailLink" href="#">
              <span wicket:id="title" />
            </a>
            <br /><br />
            <span wicket:id="contentLength" /> | <span wicket:id="rating" />%
        </div>
        <div class="clear"></div>
    </wicket:panel>  

Java class

package videoservice.web.panels;

import videoservice.entities.Feed;
import videoservice.images.ExternalImage;
import videoservice.web.pages.VideoPage;
import org.apache.wicket.AttributeModifier;
import org.apache.wicket.markup.html.WebComponent;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.image.Image;
import org.apache.wicket.markup.html.link.BookmarkablePageLink;
import org.apache.wicket.markup.html.link.Link;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.ListView;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.request.mapper.parameter.PageParameters;

/**
 * Thumbnail Panel
 *
 * @author sergej.sizov
 */
public class ThumbPanel extends Panel {
     public ThumbPanel(String id, IModel model) {
        super(id, model);
        ListView listView = new ListView("listview", model) {
            @Override
            protected void populateItem(ListItem item) {
                createThumbnailBox(item);
            }
        };
        add(listView);
    }

    private void createThumbnailBox(ListItem item) {
        Feed feed = (Feed) item.getModelObject();
        IModel model = item.getModel();
       
        // link with title
        PageParameters linkParams = new PageParameters();
        linkParams.add("id", feed.getId());
        Link<VideoPage> detailLink = new BookmarkablePageLink<VideoPage>("detailLink", VideoPage.class, linkParams);
        detailLink.add(new Label("title", new PropertyModel(model, "title")));
        item.add(detailLink);

        // length
        item.add(new Label("contentLength", new PropertyModel(model, "contentLength")));

        // rating
        item.add(new Label("rating", new PropertyModel(model, "rating"));
       
        // thumbnail
        WebComponent thumbnail;

        thumbnail = new ExternalImage("thumbnail", attachment.getImageUrl());       
        thumbnail.add(AttributeModifier.replace("alt", new PropertyModel(model, "title")));
        thumbnail.add(AttributeModifier.replace("title", new PropertyModel(model, "title")));
       
        Link<VideoPage> detailThumbLink
            = new BookmarkablePageLink<VideoPage>("detailThumbLink", VideoPage.class, linkParams);
        detailThumbLink.add(thumbnail);
       
        item.add(detailThumbLink);
    }
   
}


Then we can use this ThumbPanel component everywhere we need.

In template: <div wicket:id="listview" />

In Java code: add(new ThumbPanel("listview", videosListModel));

That is all.


No comments:

Post a Comment