359 Lotus blogs updated hourly. Who will post next? Home | Downloads | Events | Pods | Blogs | Search | myPL | About 
 
Latest 7 Posts
On SocialBizUg: Modern Domino: Bootstrap 3 Inheritable Layout
Fri, May 30th 2014 132
XMage, your XPrentice will surely miss you
Mon, May 12th 2014 150
On SocialBizUg - Web Worker Basics
Sun, Apr 13th 2014 144
Popover to Google Maps
Wed, Jan 1st 2014 153
My first impressions of using Titanium Appcelerator
Sun, Dec 8th 2013 179
Asymmetric Modernization Explained
Mon, Nov 25th 2013 157
2 Days with Domino 9.0.1 Mobile Controls - And I'm not happy
Wed, Oct 30th 2013 161
Top 10
Implementing a Dojo Scrollable pane with the XPages Mobile Controls
Mon, Jul 29th 2013 183
My first impressions of using Titanium Appcelerator
Sun, Dec 8th 2013 179
2 Days with Domino 9.0.1 Mobile Controls - And I'm not happy
Wed, Oct 30th 2013 161
Asymmetric Modernization Explained
Mon, Nov 25th 2013 157
Popover to Google Maps
Wed, Jan 1st 2014 153
Easy Mobile Browser Detection
Tue, Nov 27th 2012 151
XMage, your XPrentice will surely miss you
Mon, May 12th 2014 150
On SocialBizUg - Web Worker Basics
Sun, Apr 13th 2014 144
On SocialBizUg: Modern Domino: Bootstrap 3 Inheritable Layout
Fri, May 30th 2014 132
Make your Bootstrap site Responsive
Fri, Sep 20th 2013 118


Custom Component Creation in an NSF - Part deux
Keith Strickland    

I apologize for the delay in getting this out, but I ended up breaking the ability to post in XBlog. I've actually had this post written for a week or so, but just couldn't get around to fixing my blog. But in the last installment we left off with a configured development environment and a basic definition for our custom component. In this installment we'll build our custom renderer. The theory around all the different parts of a component is that the component class (what we built in the last installment) is an object that Java can work with. It defines all of the properties and methods of our component and if necessary any children this component may have. The renderer defines what the component will look like in the browser.  Any markup you want sent to the browser is defined in the renderer. So, let's start putting together our renderer class.

We now need to create a new class in our com.keithstric.renderkit package. We'll name it CommonContactInfoRenderer and in the Super Class field add javax.faces.render.Renderer. The class name isn't really important, but just for simplicity and maintainablity sake I always name my renderer like ComponentClassNameRenderer. This makes it easy to know which renderers go with which components. Also, our renderer doesn't need a constructor, all we need is encodeBegin, encodeChildren and encodeEnd methods and then any helper methods we may need. So, let's go ahead and define our encodeBegin method.

	@Override
	public void encodeBegin(FacesContext context, UIComponent component) {
		try {
			super.encodeBegin(context, component);
			ResponseWriter writer = context.getResponseWriter();
			writer.startElement("fieldset", component);
			writer.writeAttribute("class", "ContactFieldset", null);
			writer.startElement("legend", component);
			writer.writeAttribute("class", "ContactLegend", null);
			writer.append("Contact Information");
			writer.endElement("legend");		
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

As you can see in this method we're just basically building HTML for a field set. We're using the ResponseWriter to do this. Basically the ResponseWriter is just a fancy String builder but with enough intellect to know what HTML tags to output based on what you tell it you want. I'm not absolutely sure, but I believe if you miss closing something, the response writer will even close it for you, but don't quote me on that. But we start our field set with ResponseWriter.startElement, this will create a <fieldset> tag for us. The writeAttribute method will add html attributes to the previously defined element (i.e. the field set). We then add a legend to the field set and that's it for encode begin.

The next method we need to be concerned with is encodeChildren. This method will encode and render any child components that may be present with our main component. For the most part, you can always leave this as "super.encodeChildren(context,component)" but if you need to touch each child of a component to add a property or perform other logic, this is where you would take over rendering of the children to do that. If you are so inclined, take a look at the FacesUtil class in the extension library and specifically the renderChildren and renderComponent methods. Also of note with encodeChildren, all of the fields associated with this component are children of this component. This is where the table, fields and labels will be rendered. Since they know how to render themselves, we don't have to do anything. Also, the addition of the child components required a change to the original component which we'll get to in a moment.

Lastly is the encodeEnd method. This is where we'll close any tags that we opened in encodeBegin or even encodeChildren. However, defining HTML in encodeChildren is generally bad practice as each child should know how to encode itself. So our encodeEnd will be:

	@Override
	public void encodeEnd(FacesContext context, UIComponent component) {
		try {
			super.encodeEnd(context, component);
			ResponseWriter writer = context.getResponseWriter();
			writer.endElement("fieldset");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

And that's it for our renderer. We should end up with:

package com.keithstric.renderkit;

import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.render.Renderer;

public class CommonContactInfoRenderer extends Renderer {

	/**
	 * Here is the common encodeBegin method. This method is present in almost all renderers
	 * This is where we'll start opening tags and do anything that needs to be done before
	 * we start rendering children of the component.
	 */
	@Override
	public void encodeBegin(FacesContext context, UIComponent component) {
		try {
			super.encodeBegin(context, component);
			ResponseWriter writer = context.getResponseWriter();
			writer.startElement("fieldset", component);
			writer.writeAttribute("class", "ContactFieldset", null);
			writer.startElement("legend", component);
			writer.writeAttribute("class", "ContactLegend", null);
			writer.append("Contact Information");
			writer.endElement("legend");		
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * Here is the encodeChildren method. This method is present in almost all renderers.
	 * This is where you can wrap logic around the rendering of children or completely take
	 * over the rendering of children in order to add additional properties or whatever.
	 */
	@Override
	public void encodeChildren(FacesContext context, UIComponent component) {
		try {
			super.encodeChildren(context, component);		
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * Here is the encodeEnd method. This method is present in almost all renderers.
	 * This is where you close any tags you opened in encodeBegin and perform any
	 * logic that may be necessary after the children are encoded
	 */
	@Override
	public void encodeEnd(FacesContext context, UIComponent component) {
		try {
			super.encodeEnd(context, component);
			ResponseWriter writer = context.getResponseWriter();
			writer.endElement("fieldset");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
}

During the course of writing this blog post, I had to make massive changes to the original component. My initial idea was to have this component store the values for the different fields that will be present within the component. However in practice, this is not practical and just produces more work than necessary. Plus, we've got a data source for that.  So click the "read more" link below to see the changes I made to the component.



---------------------
http://xprentice.gbs.com/A55BAC/keithstric.nsf/default.xsp?documentId=82770C11FA7B9B21852579C100581766
Mar 14, 2012
50 hits



Recent Blog Posts
132


On SocialBizUg: Modern Domino: Bootstrap 3 Inheritable Layout
Fri, May 30th 2014 6:35p   Keith Strickland
I've got a new post over on SocialBizUg. Modern Domino: Bootstrap 3 Inheritable Layout [read] Keywords: domino
150


XMage, your XPrentice will surely miss you
Mon, May 12th 2014 3:45p   Keith Strickland
I am truly saddened and devastated by the news I received today of the death of Tim Tripcony. I would like to express my heartfelt condolences and sympathy to Tim's family and friends. I would also like to explain how Tim helped change both my personal and professional life. The loss of Tim has already left me feeling a rather large empty space where he once stood. Before I was hired at GBS I learned a lot from Tim's blog and the few chat sessions I had with him. I had never met him [read] Keywords: xpages development
144


On SocialBizUg - Web Worker Basics
Sun, Apr 13th 2014 11:26a   Keith Strickland
Over on SocialBizUg - Web Worker Basics [read] Keywords:
153


Popover to Google Maps
Wed, Jan 1st 2014 11:34a   Keith Strickland
Posted over on SocialBizUg - Popover to Google Maps [read] Keywords: google
179


My first impressions of using Titanium Appcelerator
Sun, Dec 8th 2013 11:48a   Keith Strickland
A couple of weeks ago I started messing with Titanium Appcelerator. Coming from Domino Designer and Eclipse the IDE will look very familiar. It's eclipse and it's based off of Aptana Studio. I guess the biggest issue to being productive is the learning curve for the API. But honestly when is that not the case? So starting to delve into this, Titanium apps are purely client side javascript based. You write the CSJS that builds the UI, Business Logic, Layout, everything. While this may [read] Keywords: domino ibm lotus notes notes client application dojo eclipse iphone javascript mobile oop openntf wiki
157


Asymmetric Modernization Explained
Mon, Nov 25th 2013 6:32a   Keith Strickland
Posted Asymmetric Modernization Explained over on SocialBizUg. [read] Keywords:




161


2 Days with Domino 9.0.1 Mobile Controls - And I'm not happy
Wed, Oct 30th 2013 1:42p   Keith Strickland
OK, so today is the 2nd day I've spent with the Mobile controls from Domino 9.0.1. I must say the lack of a 9.0.1 Beta is quite obvious. So some of the "improvements" IBM made to the mobile controls are the addition of onBeforeTransitionIn/Out onAfterTransitionIn/Out. While these events are sorely needed, the implementation IBM chose to use doesn't work is kind-of odd. So, a brief rundown of the transition events pre 9.0.1. I posted a while back about how to implement these methods i [read] Keywords: domino ibm application community dojo mobile network server
118


Make your Bootstrap site Responsive
Fri, Sep 20th 2013 2:50p   Keith Strickland
Just posted over on SocialBizUg a tutorial for putting together a responsive layout for your XPage Applications. [read] Keywords: applications
108


The Modern Notes Developer
Mon, Aug 19th 2013 8:09a   Keith Strickland
On SocialBiz User Group - The Modern Notes Developer [read] Keywords: notes xpages
183


Implementing a Dojo Scrollable pane with the XPages Mobile Controls
Mon, Jul 29th 2013 4:45p   Keith Strickland
Check out my first NotesIn9 video about adding a Dojo Scrollable Pane in order to get a fixed bottom tab bar with the Extension Library Mobile Controls. A big thanks to David Leedy for publishing my video. Hope you enjoy the video. [read] Keywords: xpages dojo mobile planetlotus planetlotus.org




Created and Maintained by Yancy Lent - About - Blog Submission - Suggestions - Change Log - Blog Widget - Advertising - Mobile Edition