The Source for Java Technology Collaboration
User: Password:
Register | Login help    

Search

Online Books:
java.net on MarkMail:


Writing a simple Composite Component with JSF 2.0

Posted by driscoll on November 1, 2008 at 11:46 AM PDT

One of the pain points for JSF has always been the complexity that you face in creating components. In JSF 2.0, creating a new component that's made up of existing components is a snap.

Here's a quick example of how you can create a new component, and use it in your page.

For this example, I wanted to create a simple text box that has a yellow background. Useful? No. Simple? Yes :-) In fact, it only needs two files. (This may look like a bit of code for a blog entry, but bear with me - most of it is just xhtml fluff. There's only about 4 or 5 lines that you'll actually need to learn.)

The first file is the page itself. Since JSF 2.0 uses Facelets as the preferred way to create pages, we'll use that. Here's the page:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:ez="http://java.sun.com/jsf/composite/simpleout">
<h:head>
    <title>Yellow Text Example</title>
</h:head>
<h:body>
        <h1>Output Text Example</h1>
        <h:form id="form1">
                <ez:out value="Test Value"/>
            <p><h:commandButton value="reload"/></p>
            <h:messages/>
        </h:form>
</h:body>
</html>

Two lines you need to care about here:
xmlns:ez="http://java.sun.com/jsf/composite/simpleout"
defines the composite component library, and
<ez:out value="Test Value"/>
then uses the composite component. But where is the "simpleout" component library? It's in the directory WEB-INF/resources/simpleout, and the "out" component is defined in a file named out.xhtml in that directory. Here's the contents of that file:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:composite="http://java.sun.com/jsf/composite">
<head>
<title>This will not be present in rendered output</title>
</head>
<body>

<composite:interface>
    <composite:attribute name="value" required="false"/>
</composite:interface>

<composite:implementation>
    <h:outputText value="#{cc.attrs.value}" style="background-color: yellow"/>
</composite:implementation>
</body>
</html>

Again, there's really two bits to look at here. The first is
<composite:attribute name="value" required="false"/>
says that our out component can take one attribute, named "value", and that it's presence is optional. Then,
<h:outputText value="#{cc.attrs.value}" style="background-color: yellow"/>
is where we actually define the component, with the "value" attribute set to the value attribute that's been passed in.

And that's it. No Java code is required for this very simple example.

I'll do other blogs about how to create more complex composite components, but I hope that I've made my point about how very simple this new way of component creation can be.

As always, if you have any questions, feel free to ask. And remember that you can try out this example by downloading GlassFish, and updating to JSF EDR2.

Update: I've updated this example to be more clear, and to conform with the latest JSF 2.0 PR release.

Related Topics >> Web Applications      
Comments
Comments are listed in date ascending order (oldest first)

Using JSF 2.0.0 Beta 1 the code line <h:outputText value="#{compositeComponent.attrs.value}" style="background-color: yellow"/> needs to look like this <h:outputText value="#{cc.attrs.value}" style="background-color: yellow"/> to work properly.

That's a very good starting for JSF2.0 Please put more examples, with more complex and practical situations, I am eagerly awaiting for next blog on this topic :) Also can you blog on PDL? I hope somebody is also working on standarding skinning issue.

How do you do for write attributes with the Java Bean convection? This is necessary for programmatic control. JSF 2.0 generated the tag Handlers for attributes in java source code?

Ah, that's the next blog :-) But JSF 2.0 takes care of all that for you as well, you'll see.

Looks like Howard Lewis Ship saw this and showed the Tapestry 5 equiv: http://tapestryjava.blogspot.com/2008/11/simple-jsf-20-component-vs-tape...

If I had 2 components in the ez component library? how would that second component look? What part of the component library defines the "out" component?

Sounds good, I wait for the next blog.

Hrm, I wonder if the showed example is an example that the contract on the composite:interface / composite:implementation is just very weak. You specify an attribute before and just refer to it later. I think that this isn't really hand able in large projects... I personally found things in this blog entry kinda right: http://tapestryjava.blogspot.com/2008/11/simple-jsf-20-component-vs-tape...

The interface just specifies the interface. I'm mystified why this would be any more of a problem in large projects than in small ones. Prehaps if you could expand on that idea?

>What part of the component library defines the "out" component? it's defined by the out.xhtml file's name, and the contents of that file. One source of confusion for this example seems to be the attributes on the component interface tag. As I implied in my blog, ignore them - they're there for tools, and don't mean anything to you right now. They will not be required in the final version.

Inheritance? I have done similar things with Facelets following the "Facelets fits like a glove" example but as the number of my custom components increased I wanted to start inheriting base functionality but couldn't find how. I had lots of components of the style my:combo, my:float, my:text, my:checkbox containing a lot of duplicated code. Any suggestions?

There's a simple mistake on this post, I have tried this example long time before, it just doesn't work. The problem is resource fold should be under root content, not under WEB-INF

Thanks for the example. Is it possible to build this project using netbeans 6.5 which deploys into glassfish v2 ? I have been struggling to get this working, hence the question. (Followed release notes btw).

Thanks for the example. Is it possible to build this using netbeans 6.5 which deploys into glassfish v2 ? I am not able to get this working hence the question. (Followed the release notes btw).