Wicket Guard #2

Here is a silly Wicket program I wrote. It continues to amaze me how Wicket makes complex stuff simple and simple stuff unbelievably simpler.

Imagine a totally bored Browser that wants to flip coins and display results. Sure you can do that in Servlet/JSP/Spring with meta refresh tag, querying the server every few seconds and redisplay the page. And good luck if you wanna try that with Ajax. But it becomes ridiculously simple with Wicket. The code literally took me less than 20 minutes and I am Wicket beginner (I have Swing background though).

A couple of gotchas:

  • In the FlipMyCoinPage.html, I had to use the style ul.list-style-type: none. With the default bullet type, wicket prints an empty bullet after every flip.
  • In FlipMyCoinPage.java, with Wicket 1.3.6, I was able to add the label with a wicket:id like “Flip coin:” (including the colon). When I recompiled with Wicket 1.4-rc4, there was a runtime error that colon is not allowed as part of id.
//FlipMyCoinPage.java
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.apache.wicket.ajax.AjaxSelfUpdatingTimerBehavior;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.repeater.Item;
import org.apache.wicket.markup.repeater.RefreshingView;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.util.time.Duration;
import org.learnspace.core.AbstractModel;

public class FlipMyCoinPage extends WebPage {

	final List<IModel> flipperList = new ArrayList<IModel>();
	private int heads = 0;
	private int tails = 0;
	
	public FlipMyCoinPage() {
		super();
		final WebMarkupContainer section;
		section = new WebMarkupContainer("section");
		add(section);
		section.setOutputMarkupId(true);
		section.setOutputMarkupPlaceholderTag(true);
		
		final Label coinResult = new Label("coinResult", new Model<String>());
		RefreshingView coinFlipper = new RefreshingView("coinFlipper") {
			@Override
			protected Iterator getItemModels() {
				Model<Integer> m = new Model<Integer>((int) (Math.random() * 2));
				flipperList.add(m);
				if (m.getObject() == 0) heads++;
				else tails++;
				int total = heads + tails;
				String s = String.format("Tries = %d; Heads = %d (%5.2f%%); Tails = %d (%5.2f%%)", total, heads, (double) heads/total*100, tails, (double) tails/total*100);
				coinResult.setDefaultModelObject(s);
				return flipperList.iterator();
			}

			@Override
			protected void populateItem(Item _item) {
				add(new Label("Flip " + _item.getIndex(), new HeadOrTailModel(_item.getModel())));
			}
		};
		section.add(coinFlipper);
		section.add(coinResult);
		section.add(new AjaxSelfUpdatingTimerBehavior(Duration.seconds(3)));
	}
	
	//
	class HeadOrTailModel extends AbstractModel {
		
		public HeadOrTailModel(IModel<Integer> _model) {
			super(_model);
		}
		
		public Object getObject() {  
			return ((Integer) getModelObject() == 0) ? "Heads" : "Tails";  
		}  
	}

}
//HeadOrTailModel uses this AbstractModel for brevity
//Based on Jeremey Thomson's blog
import org.apache.wicket.model.IModel;

public abstract class AbstractModel implements IModel {

	private final IModel nestedModel;
	
	public AbstractModel(IModel _model) {
		nestedModel = _model;
	}
	
	@Override
	public void setObject(Object object) {
		nestedModel.setObject(object);
	}
	
	public IModel getModel() {
		return nestedModel;
	}
	
	public Object getModelObject() {
		return nestedModel.getObject();
	}

	@Override
	public void detach() {
		nestedModel.detach();
	}
}

And here is the corresponding html.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" 
      xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd" 
			xml:lang="en">
<head>
	<title>Coin Flipper Demo!</title>
	<style type="text/css">
		ul {
			font-family: tahoma;
			font-size: 9pt;
			list-style-type: none;
			color: black
		}
		
		span#result {
			color: lightgreen;
			font-family: consolas;
			font-size: 12pt;
			font-weight: bold;
			padding: 1em 1em 1em 1em;
			background-color: black
		}
	</style>
</head>
<body>
<div wicket:id="section">
<h3>A really bored browser is flipping a coin ...</h3>
<p>
<span id="result" wicket:id="coinResult"></span>
</p>
<p></p>
<ul>
 <li wicket:id="coinFlipper"></li>
</ul>
</div>
</body>
</html>
Advertisements

2 Responses to Wicket Guard #2

  1. matthewsteele says:

    Very cool! What does the SmartWicketBasePage class look like?

    Like

    • vasya10 says:

      @matthewsteele:

      Thanks for the comment! SmartWicketBasePage just extends from WebPage and does not do much. I typically put the FeedbackPanel into it so its available for all the pages I extend from it. I’m updating the code to be fully workable with some more bells and whistles (# of heads, #tails and #percentage).

      Like

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: