Extending PrimeFaces components


The purpose of this post is to show how we can use PrimeFaces base classes to create new custom components. In a nutshell we will see how to extend PrimeFaces. We will do that by developing a simplified version of the PrimeFaces Extensions Analogclock.

Let’s start with the component class:

@FacesComponent(value = AnalogClock.COMPONENT_TYPE)
		@ResourceDependency(library = "moment", name = "moment.min.js"),
		@ResourceDependency(library = "primefaces", name = "jquery/jquery.js"),
		@ResourceDependency(library = "raphael", name = "raphael-min.js"),
		@ResourceDependency(library = "primefaces", name = "primefaces.js"),
		@ResourceDependency(library = "strazzfaces", name = "analog-clock.js") })
public class AnalogClock extends UIComponentBase implements Widget {

	public static final String COMPONENT_TYPE = "it.strazz.faces.AnalogClock";
	public static final String COMPONENT_FAMILY = "it.strazz.faces.components";

	public String getFamily() {

	public void setStartTime(Date _pattern) {
		getStateHelper().put(PropertyKeys.startTime, _pattern);

	public Date getStartTime() {
		return (Date) getStateHelper().eval(PropertyKeys.startTime, new Date());

	public String getMode() {
		return (java.lang.String) getStateHelper().eval(PropertyKeys.mode,"client");

	public void setMode(String _mode) {
		getStateHelper().put(PropertyKeys.mode, _mode);

	public Integer getWidth(){
		return (Integer) this.getStateHelper().eval(PropertyKeys.width,null);

	public void setWidth(Integer width){
		this.getStateHelper().put(PropertyKeys.width, width);

	public String getWidgetVar() {
		return (String) getStateHelper().eval(PropertyKeys.widgetVar, null);

	public void setWidgetVar(String _widgetVar) {
		getStateHelper().put(PropertyKeys.widgetVar, _widgetVar);

	public String resolveWidgetVar() {
		FacesContext context = getFacesContext();
		String userWidgetVar = (String) getAttributes().get("widgetVar");

		if (userWidgetVar != null)
			return userWidgetVar;
			return "widget_"
					+ getClientId(context).replaceAll(
							"-|" + UINamingContainer.getSeparatorChar(context),

	protected static enum PropertyKeys {
		width, widgetVar, startTime, mode;

The most interesting thing in this component is to be a Widget. All the components that implements this interface will have a JavaScript counterpart. Basically for every AnalogClock instance on the server, a mirror object will exists on the client browser. The only method we need to implement to use this interface is solveWidgetVar. Its purpose is to return the widgetVar of the component, namely the name of the JavaScript variable assigned to our component.

Analyzing the code above you can notice that if you did not manually set a widgetVar to the component (invoking the setWidgetVar method), the value is automatically generated using the clientId. Some of the others attribute of the AnalogClock are:




width of the clock in pixel, set ‘auto’ to adjust to the width of the container. The default value is ‘auto’.


‘server’ for using server time, use the client time otherwise.


time to display when the mode is €˜server€™, the default value is current time.


One of the ResourceDependencies of AnalogClock it’s the file analog-clock.js. This is a resource file and it must be placed in the resources folder of our project, just like in the next picture.

The file must contain the JavaScript definition of the AnalogClock widget. On the client every widget will be instantiated through a constructor function that extends PrimeFaces.widget.BaseWidget.

PrimeFaces.widget.BaseWidget = Class.extend({ 

        init: function(cfg) {
            this.cfg = cfg;
            this.id = cfg.id;
            this.jqId = PrimeFaces.escapeClientId(this.id);
            this.jq = $(this.jqId);



The heart of this function is the init method, here a configuration obect and a reference of the main DOM element of the component are memorized. The Class function its created by Jonh Resig author of the book Secrets of the JavaScript Ninja. In this post theres a detailed explanation of the logic behind this pattern.

Lets create PrimeFaces.widget.AnalogClockthat will extend the BaseWidget. We just have to recall to invoke the superinit manually.

PrimeFaces.widget.AnalogClock = PrimeFaces.widget.BaseWidget.extend({
			init : function(cfg) {


				this.startTime = cfg.time && cfg.mode !== 'client' ? moment(cfg.time) : moment();

				this.colorScheme = cfg.colorScheme || 'standard';

				this.dimensions = new PrimeFaces.widget.AnalogClock.Dimensions(this.cfg.width || this.jq.width());

				this.interval = setInterval((function(self) {
					return function() {
				})(this), 1000);


			draw : function() {

				this.canvas = Raphael(this.id, this.dimensions.size, this.dimensions.size);

				this.clock = this.canvas.circle(this.dimensions.half, this.dimensions.half, this.dimensions.clock_width);
					"fill" : PrimeFaces.widget.AnalogClock.colorSchemes[this.colorScheme].face,
					"stroke" :PrimeFaces.widget.AnalogClock.colorSchemes[this.colorScheme].border,
					"stroke-width" : "5"



				var pin = this.canvas.circle(this.dimensions.half, this.dimensions.half, this.dimensions.pin_width);
				pin.attr("fill", PrimeFaces.widget.AnalogClock.colorSchemes[this.colorScheme].pin);


			draw_hour_signs: function(){
				var hour_sign;

				for (i = 0; i < 12; i++) {

					var start_x = this.dimensions.half + Math.round(this.dimensions.hour_sign_min_size * Math.cos(30 * i	* Math.PI / 180));
					var start_y = this.dimensions.half + Math.round(this.dimensions.hour_sign_min_size * Math.sin(30 * i * Math.PI / 180));
					var end_x = this.dimensions.half + Math.round(this.dimensions.hour_sign_max_size * Math.cos(30 * i * Math.PI	/ 180));
					var end_y = this.dimensions.half + Math.round(this.dimensions.hour_sign_max_size * Math.sin(30 * i * Math.PI	/ 180));

					hour_sign = this.canvas.path("M" + start_x + " " + start_y	+ "L" + end_x + " " + end_y);
						"stroke-width" : this.dimensions.hour_sign_stroke_width

			draw_hands: function(){

				this.hour_hand = this.canvas.path("M" + this.dimensions.half + " " + this.dimensions.half	+ "L" + this.dimensions.half + " " + this.dimensions.hour_hand_start_position);
					stroke : PrimeFaces.widget.AnalogClock.colorSchemes[this.colorScheme].hour_hand,
					"stroke-width" : this.dimensions.hour_hand_stroke_width

				this.minute_hand = this.canvas.path("M" + this.dimensions.half + " " + this.dimensions.half	+ "L" + this.dimensions.half + " " + this.dimensions.minute_hand_start_position);
					stroke : PrimeFaces.widget.AnalogClock.colorSchemes[this.colorScheme].minute_hand,
					"stroke-width" : this.dimensions.minute_hand_stroke_width

				this.second_hand = this.canvas.path("M" + this.dimensions.half + " " + this.dimensions.half	+ "L" + this.dimensions.half + " " + this.dimensions.second_hand_start_position);
					stroke : PrimeFaces.widget.AnalogClock.colorSchemes[this.colorScheme].second_hand,
					"stroke-width" : this.dimensions.second_hand_stroke_width

			update : function() {
				var now = this.startTime;

				this.hour_hand.rotate(30 * now.hours() + (this.startTime.minutes() / 2.5), this.dimensions.half, this.dimensions.half);
				this.minute_hand.rotate(6 * this.startTime.minutes(), this.dimensions.half, this.dimensions.half);
				this.second_hand.rotate(6 * this.startTime.seconds(), this.dimensions.half, this.dimensions.half);

				this.startTime.add('s', 1);


We will omit the draw function because its not the focus of this article. The only thing that we need to know its that it uses the JavaScript library Raphal to draw a clock via HTML5 canvas. This function is a patchwork of various works Ive found on the internet. Its not very complex, you only need to know a little trigonometry. The cfg parameter holds all the parameters of our AnalogClock component, this attributes are used during the draw phase.


The purpose of the Renderer is to link the AnalogClock instance on the server with the JavaScript brother on the client. PrimeFaces API make this operation very easy using the WidgetBuilder. This class handles to build and configure a new widget.

@FacesRenderer(componentFamily = AnalogClock.COMPONENT_FAMILY, rendererType = AnalogClockRenderer.RENDERER_TYPE)
public class AnalogClockRenderer extends CoreRenderer {

	public static final String RENDERER_TYPE = "it.strazz.faces.AnalogClockRenderer";

	public void encodeEnd(FacesContext context, UIComponent component) throws IOException {
		AnalogClock analogClock = (AnalogClock) component;

		encodeMarkup(context, analogClock);
		encodeScript(context, analogClock);

	protected void encodeMarkup(FacesContext context, AnalogClock clock) throws IOException {
		ResponseWriter writer = context.getResponseWriter();

		writer.startElement("div", clock);
		writer.writeAttribute("id", clock.getClientId(), null);

	protected void encodeScript(FacesContext context, AnalogClock analogClock) throws IOException {

		String clientId = analogClock.getClientId();
		String widgetVar = analogClock.resolveWidgetVar();

		WidgetBuilder wb = getWidgetBuilder(context);

		wb.init("AnalogClock", widgetVar, clientId);
		wb.attr("mode", analogClock.getMode());
		wb.attr("time",	analogClock.getStartTime() != null ? analogClock.getStartTime().getTime() : null);

		if(analogClock.getWidth() != null){
			wb.attr("width", analogClock.getWidth());


As you can see our Renderer extends the PrimeFacess CoreRenderer, so that writing a component to the response its enormously simplified task. In this way our code will remain extremely maintainabile.


We can now try our component. In the next example we will create four AnalogClocks: three of the them will display a server time, the last one the client time.


<html xmlns="http://www.w3.org/1999/xhtml"
	<h1>StrazzFaces Clock</h1>
		<p:panelGrid columns="4">
				<h1>New York</h1>
				<s:analogClock width="250" />

Managed Bean:

public class ClockBean implements Serializable {

	private static final long serialVersionUID = 1L;

	private Date romeTime;
	private Date londonTime;
	private Date newYorkTime;

	public void loadTimes(){
		romeTime = new Date();

		Calendar c = Calendar.getInstance();

		c.add(Calendar.HOUR, -1);
		londonTime = c.getTime();

		c.add(Calendar.HOUR, -5);
		newYorkTime = c.getTime();

	public Date getRomeTime() {
		return romeTime;

	public Date getLondonTime(){
		return londonTime;

	public Date getNewYorkTime(){
		return newYorkTime;


extend primefaces



Francesco Strazzullo – software architect and one of the committer in the Primefaces Extensions project.