While creating a prototype for a web application using ADF Faces i noticed that Oracle’s JSF implementation still generates Html like it’s 1999. Lots of tables, more tables and more nested tables. ADF Faces even contains an ObjectSpacer component which adds a transparent image in your page. Ough. Big ugly mess.
The problem with tables is, apart from the fact that your pages will be bigger than necessary, that they’re pretty rigid. You don’t have a lot of positioning flexibility when creating the appearance of your page. This flexibility is pretty important when creating web application. Companies want their web applications to look good, not standard, when they are used by the outside world.
I started with the PanelPage component to layout the major parts of the page but because of the tables i could not get the required page design. I tried some other ADF Faces components, but didn’t find what i needed. PanelBox generates a single cell table. PanelHeader was the best i could find. It puts all it’s children in a div, but also generates an unwanted header tag.
What are the alternatives? I could use an html div tag or look for a JSF div component elsewhere (i think the MyFaces project contains a Div component). But instead, to learn a bit more about JSF, i decided to implement a custom Div component. I another post i’ll describe another alternative, a customer renderer for an existing component.
Div Component
The JSF component class contains the behaviour of your class. You can include the html rendering, but it’s cleaner to put that in a separate class. A panel doesn’t have a lot of behaviour as you can see in the following code. I’m subclassing UIPanel because it has the same behaviour as the Div component i want to implement.
package nl.iteye.jsf.components;
import javax.faces.component.UIPanel;
public class UIDiv extends UIPanel {
public static final String COMPONENT_TYPE = "nl.iteye.jsf.Panel";
public static final String RENDERER_TYPE = "nl.iteye.jsf.Div";
public UIDiv() {
setRendererType(RENDERER_TYPE);
}
}
Div Renderer
The renderer creates the required html code. It is also used to read anything send by the browser, but that’s not needed in this case.
package nl.iteye.jsf.components;
import java.io.IOException;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.render.Renderer;
public class DivRenderer extends Renderer {
public DivRenderer() {
}
public void encodeBegin(FacesContext context,
UIComponent component) throws IOException {
ResponseWriter writer = context.getResponseWriter();
writer.startElement("div", component);
writer.writeAttribute("id", component.getClientId(context),
"clientId");
writer.writeAttribute("class",
component.getAttributes().get("styleclass"),
"styleclass");
writer.flush();
}
public void encodeEnd(FacesContext context,
UIComponent component) throws IOException {
ResponseWriter writer = context.getResponseWriter();
writer.endElement("div");
writer.flush();
}
public void decode(FacesContext context, UIComponent component) {
return;
}
}
Div Tag
Next i need to create a JSP tag class, because i’m going to use the JSF component in JSPs. A property for id is not needed, this is provided by the super class.
package nl.iteye.jsf.components;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.webapp.UIComponentTag;
public class DivTag extends UIComponentTag {
private String styleClass;
public DivTag() {
}
public String getComponentType() {
return UIDiv.COMPONENT_TYPE;
}
public String getRendererType() {
return UIDiv.RENDERER_TYPE;
}
public void setProperties(UIComponent component) {
super.setProperties(component);
setStringProperty(component, "styleclass", styleClass);
}
public void setStyleclass(String styleClass) {
this.styleClass = styleClass;
}
public String getStyleclass() {
return styleClass;
}
private void setStringProperty(UIComponent component, String name,
String value) {
if (value == null) {
return;
}
if (isValueReference(value)) {
component.setValueBinding(name,
FacesContext.getCurrentInstance().getApplication()
.createValueBinding(value));
} else {
component.getAttributes().put(name, value);
}
}
}
Configuration
Declare the component in the faces configuration file faces-config.xml. Two entries are required, one for the component, and one for the render-kit. A render-kit isn’t specified, which means that the renderer will be part of the default html renderkit.
<component>
<component-type>nl.iteye.jsf.Panel</component-type>
<component-class>nl.iteye.jsf.components.UIDiv</component-class>
</component>
<render-kit>
<renderer>
<component-family>javax.faces.Panel</component-family>
<renderer-type>nl.iteye.jsf.Div</renderer-type>
<renderer-class>nl.iteye.jsf.components.DivRenderer</renderer-class>
</renderer>
</render-kit>
Register the Div tag in the tag library file:
<?xml version = '1.0' encoding = 'UTF-8'?>
<!DOCTYPE taglib
PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
"http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
<taglib>
<tlib-version>1.0</tlib-version>
<jsp-version>2.0</jsp-version>
<short-name>jsf-layout</short-name>
<uri>/iteye/jsf</uri>
<display-name>Layout components</display-name>
<tag>
<name>div</name>
<tag-class>nl.iteye.jsf.components.DivTag</tag-class>
<attribute>
<name>id</name>
</attribute>
<attribute>
<name>styleclass</name>
</attribute>
</tag>
</taglib>
Example
The following code shows a simple example. Normally i would use an id attribute instead of a class attribute in the example below, because you only have one header and one logo on every page. Unfortunately, JFS makes the id attribute unusable for css styling purposes, as it prepends the ids of all the parent components to the id of a component.
<?xml version='1.0' encoding='UTF-8'?>
<jsp:root xmlns="http://www.w3.org/1999/xhtml"
xmlns:jsp="http://java.sun.com/JSP/Page" version="2.0"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:af="http://xmlns.oracle.com/adf/faces"
xmlns:wt="/iteye/jsf">
<f:view>
<html>
<body>
<h:form>
<wt:div styleclass="page">
<wt:div styleclass="header">
<wt:div styleclass="logo">
<af:objectImage source="/images/logo.gif"/>
</wt:div>
</wt:div>
</wt:div>
</h:form>
</body>
</html>
</f:view>
</jsp:root>
This is not fastest way to create divs using JSF, but still usefull as an example of how to create a JSF component. As said before, you can just use a html div tag (for an interesting discussing about using html tags, see Chris Schalk’s weblog: JSF: Getting the Right Mixture of Components and Markup), but using html may be a problem when you decide to use a non html render kit. If you don’t need a new component, just different markup, a better option is to create a new renderer.
Update:
See the followup posts: JSF productivity, and IDE productivity for JSF: a screencast.

April 25th, 2006 at 20:03:53
You seem to be missing a closing wt:div in that last section.
Seems like alot of work to just get a div.
April 25th, 2006 at 20:49:11
Thanks, i’ve updated the code. I agree, it is a lot of work, just using html is easier. But it is a good example to show what’s involved in created a minimal jsf component. I think modifing the renderer of an existing component makes more sense: less work, and because you use jsf components you can still use a non html renderkit if you want to. It doesn’t tie your solution to html.
April 28th, 2006 at 08:00:46
Why are tables bad? Only because they are old? Some time ago, I tried not to use tables but divs, and it’s support was not very good: several css rules did not work or worked diferently in various browsers – very general statement, but this was my impression: tables are reliable and work in old browsers. What’s bad with them?
May 1st, 2006 at 12:10:02
- tables are rigid, you can’t move tables cell around the page like you can with divs.
- tables require more markup than divs, your pages will be larger than necessary and harder to maintain.
- tables can be confusion for screenreaders, what is tabular data, what is layout?
- using divs it’s easier to create printable pages. Just hide the divs that don’t need to be printed.
- using divs it’s easier to create pages for different screensizes. Need to display you page on a mobile phone? Just place the divs vertically.
May 3rd, 2006 at 08:44:20
Andrej, you convinced me. Only the compatibility remains an issue, I think. Compatibility between current browsers and compatibility with archaic browsers.
May 3rd, 2006 at 09:25:08
Dan Cederholm has written an excellent book called Bulletproof Web Design. He explains how to use css while ensuring that it will work in most browsers.
May 4th, 2006 at 02:00:48
Compatibility is almost a non-issue if you know a few tricks for dealing with IE. Other modern browsers have their quirks(almost always with workarounds), but often you can safely ignore certain fringe percentages anyway.
If you’re so unfortunate as to have to deal with Netscape 4 or older such UAs, well.. find the person demanding this, explain that browser upgrades are free and fairly quick to install, and then punch them in the face.
May 12th, 2006 at 10:31:39
OK…Been studying JSFs for a week now,and it seems that the ONLY way to implement a custom component is to code it directly into a class. This is a bit ugly: if (when) this component gets complicated, you end up with loads of write.startElement stuff….How the hell can you see the actual html structure from that??? There was an attempt to work around this by Hans Bergsten, quote: “…using XML file to represent the component structure and a separate pure HTML file as a template, binding the JSF components in the XML file to the corresponding HTML elements in the template with the help of id attributes.”.
Is there any other way to do this? I’d like to see something like this: declare MyCustomComponent.jsf as a custom component, including it into a taglib, thus enabling to reuse it…Maybe you guessed I was inspired by the .NET framework, which uses similar model, which is, by the way, very simple and powerfull. I expected to find something similar in JSF but no such luck so far…Any ideas?
tnx
May 12th, 2006 at 10:53:56
I agree that coding the html in the java code is pretty ugly, and hard to maintain. Have you looked at facelets?
August 28th, 2006 at 04:45:33
[...] device. Andrej Koelewijn of IT-eye fame wrote an article discussing this issue and in his article provi [...]
November 11th, 2006 at 04:05:34
hello, i’m new in JFS, and i need div tag in my code, would you please tell me how to deploy this code so i can use in my IDE, i’m using Sun Studio Creator
November 11th, 2006 at 09:25:12
This div component cannot be used in Sun Studio Creator, it misses some methods that tell the IDE how to use it. Maybe you can use Apache MyFaces, this JSF implementation also includes a div component.
May 25th, 2007 at 15:56:31
Hello Andrej, I’m using JSF with Oracle 9, jdeveloper 10.1.3.1.0, toplink, Spring, and to follow the graphics rules I have to use a div tag in my jsf pages. I’m using some subview and I can’t have a good display with verbatim. My question is : Can i use your code or Is it more appropriate If i use tobago myfaces?
Thanks
May 28th, 2007 at 09:36:30
You’re free to use the code above, not sure if tobago will solve your issue. I looked through the components list, but didn’t see a div component.
June 9th, 2007 at 19:29:14
doesn’t h:panelGroup render as a div?
June 9th, 2007 at 21:20:40
I believe the panelGroup component doesn’t create divs, it creates spans, and only if you provide it with an attribute. Otherwise it doesn’t write out the span tag.
July 2nd, 2007 at 17:10:40
I’m using rational (websphere), anyone knows why I must to insert the div tag inside a form tag? I can’t use them whihout a form tag? Thanks for all.
August 26th, 2007 at 10:43:28
Here is written that with DIV is possible to be created so good looking Web UI Components (Table) like SwingX (http://www.swinglabs.org/) components. Unfortunately I am not meet such components until now.
If there are, can you give me some URL (link)?
February 27th, 2008 at 14:46:12
@ atiktepika, I my limited experience with JSF, I have learned that there should always be a form inside the body of the page that JSF would render as HTML. Further more, both the div and form tags are “container” tags in terms of valid HTML structures divs should not be nested in a form tag.
February 9th, 2009 at 22:28:47
Hi I am having trouble getting the div to render as a div? I have built a very simple project following the steps above but when the page renders the output is not as expected
Here is what you would expect
Hello World
I get this
Hello Wolrd
Any thoughts? I am using thin in an ADF Faces app would that make a difference?
February 9th, 2009 at 22:30:15
Last comment dropped the source that I tried to include, anyway the output is rendered exactly as it is in the JSF wt:Div page rather than as a simple HTML div
May 8th, 2009 at 03:07:22
Good writeup. But each framework has one or another way to render a div but div cannot be rendered in plain JSF-RI. In RichFaces / A4J you can use a4j:outputPanel with layout=”block”. Using ADF is the worst thing you can do… I am stuck with ADF for our main UI app. But in ADF also you can create a DIV using . I love JSF + facelet + Richfaces + jQuery – that is the best stack you can have!
Hari Gangadharan
May 8th, 2009 at 03:08:43
Sucks! they stipped my adf code… I mean in ADF you can render a div using af:panelGroup with layout=”vertical”.
May 14th, 2009 at 21:04:36
[...] Creating a jsf div component – blog post by Andrej Koelewijn. The amount of code and effort that is required for just [...]
July 20th, 2009 at 09:29:40
A blanket comment that “JSF sucks” makes me ask “compared to what?”. At the present time JSF may be one of the best Web UI environments in *Java*. But JSF without Facelets is inadequate. If you have facelets you can do all the layout/formatting in Facelets. JSF+RichFaces+jQuery is one of the best environments.
Hari Gangadharan