Creating user interface components

Take advantage of one of the main features of component-based frameworks, the components reuse.

JavaServer Faces (JSF) is a Sun specification that is based in components to be used in web application development. The use of these components for building user interfaces (UI), simplifies the development, keeping hidden the implementation of the complex tasks and providing the programmer only tags with attributes that describe the inputs necessary for the proper functioning of the component.

The possibility of customization of components is a powerful extension that meets specific demands that web applications have today. There are an increase number of applications that have common goals (with diverse behaviors) that may become reusable easily with the support of JSF. For example, it is common to applications a login screen, however each screen can have specific settings that are necessary to validate the login process. Thus, when we change the configuration of a screen we also change their behavior.

Starting with JSF second version, a new way was defined to create UI components called composite components. This technique facilitated the customization task, eliminating the use of Java code and defining a set of tags that allow components to build pages using XHTML. With this, the front-end developer no longer needs to know Java to reuse behavior code, simply by knowing the JSF tags.

Since the JSF is based on components that can be created and extended, over time were created several libraries, some free, some proprietary. These libraries are maintained by companies or communities seeking to ease the life of the developer with quality codes that are ready to be used in various types of web application. Some examples of these libraries are RichFaces, PrimeFaces, ICEfaces, Tomahawk, OpenFaces, among many others.

In this article you will learn to create custom UI components using composite components through the example of a Twitter Reader application. In addition, you will understand how to use the NetBeans IDE assistant to support this customization, making this task even easier.

We will see how simple and useful is to apply this JSF 2 technique. The concepts are presented gradually and the example will be explained in two stages to facilitate understanding.

What are the user interface components?

The concept of component can be defined as a unit of software used to build several systems whose main characteristic is the possibility of setting for the modification of its operation, changing thus their behavior.

Through an implementation abstraction of these components we can make substitutions with other more robust without much effort, since they have the same specification (interface). When building a component is important to define the interfaces with caution, because the services are provided through them and also to in the future not appear requirements that were not planned.

The JSF UI components are characterized to assist the development of visual elements with behavior that can be changed according to the requirements. These elements can be reused in different contexts and extended to the build new components.

When using a UI component, the developer does not need to know its implementation, he needs to know only the interface (contract). This interface informs the attributes required (mandatory and not mandatory) to use the component.

JSF offers several basic components for developing web applications using HTML, including buttons, text boxes, forms, checkboxes, combo boxes and many others. However, during development, it is common arise the needs of more advanced components that are not in the standard library. In these cases, the developer can create their own components.

The use of components in JSF aims to bring the way to create desktop applications to the web development, seeking to facilitate this development which is much more complex because it involves several other variables, such as request, response, and scope. An example of this simplification that is common to all UI components are in the communication between the view layer (pages) and the control layer, which is accomplished by the managed beans call in the components attributes.

When customize UI components?

The components customization should be performed considering some criteria that justify its implementation. Therefore, consider the following criteria before developing your own components:

The UI component may exist, then search other sources like the JSFCentral site (check out the address in the Links section), which contains a list of over 50 individual libraries and components available, and also seeks information in books and magazines. So you will not risk to redo the component, saving time and often finding great quality customizations;

Determine if you really need a new component. If the component that you want to build does not need to change behavior, you may not need to create it. If the goal is to reuse only parts of the page that are repeated, such as a menu, a header or footer, then the Facelets templates, also available in JSF 2, can solve the problem;

The UI components available in JSF 2 can be customized through validators and converters. They prevent invalid entries from reaching the business logic through the data validation and conversion to primitive types or Java objects, respectively. Check if your needs are not met by the use of data processing, thereby avoiding the unnecessary creation of custom components.

Construction types for UI components in JSF

In JSF there are two ways to create custom components using composite components or non-composite components. Consider the differences between these techniques:

Composite Components: This technique started in JSF 2 and remove the need to use classes to create a custom component. Using this technique the components are defined in XHTML pages that uses the composite library for customization. This library contains various tags that define interface, attributes interface, implementations, among others. Furthermore, it is possible the treatment of events and listeners through composite components;v

Non-Composite Components: This technique was already available before the second version of JSF and is distinguished by the need to use Java classes for creating components. This type of development can generate customizations just as composite components. However, it is necessary that the designer knows how to program in Java.

UI components architecture

The JSF standard components can be classified roughly into two categories: those that can boot an action, such as a button, and those that provides data as an input field.

As previously reported, the most important characteristic of components is the possibility of behavior change. With JSF behavior is defined through the use of the attributes of the interface implementation, which is done during the construction process of the component.

Even when developing using the composite components technique, it is important to understand the main classes and interfaces that are behind the components. For example, to initiate an action, you must implement the interface ActionSource2, where is located the logic related to the click of a button.

The use of interfaces provides a higher abstraction and makes it easier to understand the goals of each UI component. Figure 1 shows the classes diagram that summaries the main interfaces and classes.



Figure 1. Classes and interfaces behind the UI components.

In general, a component extends the class UIComponentBase or one of its existing subclasses. UIComponentBase implements the UIComponent interface, and every class that implements this interface is considered a component. Using it reduces coupling and makes the structure more flexible to extensions. The other interfaces are specific to certain responsibilities and are implemented by components in accordance with these goals.

Better understand how these classes and interfaces work is important to understand in what is transformed the components that we develop. Moreover, if there is the need for customization with non-composite components you already have an idea. The Table 1 shows the responsibilities of the classes and interfaces involved in the construction of JSF components.



Table 1. Definition of interfaces and classes used by UI components.

There are several other interfaces involved in building components, however, as we will not work directly with them, we will not list them. If you are interested in knowing them, see the documentation for the JSF over the Links section at the end of the article.

Creating UI components using composite components

Aiming to make learning customization of components easier, we will create a custom Twitter Reader. This reader will display the latest tweets from a user, it will use JSF 2 native AJAX support to update messages and change the user. This example was chosen because it is simple to implement and useful for the developer.

The points defined in the "When customize UI components?" were taken into consideration when choosing the custom reader. No components were found with the same functionality, you cannot use templates to solve the problem and converters and validators are not able to generate a reader to Twitter.

We will learn to create the customized player in two stages: First we will display the tweets, show new tweets and change the component size, but without allowing change the user, and in the second stage we are going to allow this action.

The example was developed using NetBeans IDE. However, you can use the IDE of your choice to customize components. Figure 2 illustrates how the component will look like in the end of the first step.



Figure 2. Custom component appearance in the end of the first stage.

Let's start the component development by creating a project with JSF 2 support in your IDE. This project should have index.xhtml as the main page. This page is important since it is here that our custom component is declared and requested, this means that is here that the component will be rendered to the user. Listing1 describes the index.xhtml page.

Listing 1. index.xhtml: UI Custom component calling page

<?xml version='1.0' encoding='UTF-8' ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:jam="http://java.sun.com/jsf/composite/myComponentsLibrary"> <h:head> <title>Component Customization Example</title> </h:head> <h:body> <jam:tweets/> </h:body> </html>

The first code that deserves attention is the custom component Library statement, called myComponentsLibrary. This statement is accomplished through this code:

xmlns:jam="http://java.sun.com/jsf/composite/ myComponentsLibrary"

The default path for the custom component Libraries includes http://java.sun.com/jsf/composite/LIBRARY_NAME. A composite components library is nothing more than a folder that contains an XHTML page for each component. The LIBRARY_NAME is the same as the folder name. The suffix jam is used to call the components of our library in index.xhtml page. Remembering that it is always interesting to use small suffixes to facilitate the components call.

For the library to be recognized when it is declared, the folder myComponentsLibrary must be within the resources folder (which also needs to be created) and that in must be located in the web folder, as shown in Figure 3. By doing so the project is ready to use custom components that are within our library.



Figure 3. File Structure for custom library.

Continuing the index.xhtml page analysis, we have the call to our Twitter reader being held at the following statement:

<jam:tweets/>

The name tweets is the same name of the page where the component is described, ie, tweets.xhtml. Thus, whenever the need arises on a page to view the latest tweets from a particular user, the developer can use this simple component call. With this, we save time and several lines of code after the component is created.

These are important points of the index.xhtml page, responsible for rendering our custom component. Let's look through Listing 2, the codes and tags that must be implemented to generate the tweet component.

Listing 2. tweets.xhtml: tweets composite component description page.

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:cc="http://java.sun.com/jsf/composite" xmlns:ui="http://java.sun.com/jsf/facelets"> <cc:interface/> <cc:implementation> <h:outputStylesheet library="css" name="styles.css"/> <div id="links"> <ul> <ui:repeat value="#{tweetMB.tweets}" var="tweet"> <li> <a href="#{tweet.link}" target="_blank"> #{tweetMB.user.name} #{tweet.description} <span>#{tweet.data}</span> </a> </li> </ui:repeat> </ul> </div> <a href="#{tweetMB.user.link}" target="_blank">Follow Me!</a> </cc:implementation> </html>

This Listing analysis will allow us to understand how the component customization works, and then we will see the how the classes and files assist in the search for Tweets and component styling.

There are two basic tags for building components, the interface and the implementation. These tags belong to the composite library, declared by the statement:

xmlns:cc="http://java.sun.com/jsf/composite"

The interface is represented on the page with the suffix cc by , and is responsible for defining the component use contract. Through it we define the component configurations that can be changed. As in this first part we do not have any configurations, there are no attributes within the interface.

The tag Implementation, represented by , is responsible for defining the content that is rendered when the component is used. In the first stage this tag will list the latest tweets from a user, and second stage uses attributes defined in the tag interface to change the behavior of the component.

Access to the attributes interface in Implementation is achieved through a specific variable, explained in the second step of our example.

The component content defines the css by the tag . This allows css to render the component with a better look through the style sheet file styles.css. To do this, you must create a folder named css, inside the resources folder, where you must put the styles.css file. This file should contain the same style sheet of the Listing 3.

Listing 3. styles.css: tweets component style sheet.

#links { height:350px; width:430px; overflow:auto; } #links ul { list-style-type:none; margin:0; padding:0; width:400px; } #links li { border:1px dotted #999; border-width:1px 0; margin:5px 0; } #links li a { color:#000066; display:block; font:bold 14px Arial, Helvetica, sans-serif; padding:5px; text-decoration:none; } * html #links li a {width:400px;} /*Necessary to works with IE6*/ #links li a:hover { background-color:#F0F8FF; } #links a em { color:#333; display:block; font:normal 11px Verdana, Arial, Helvetica, sans-serif; line-height:125%; } #links a span { color:#125F15; font:normal 9px Verdana, Arial, Helvetica, sans-serif; line-height:150%; }

Next, the component implementation uses repeating by the tag to display in the screen the latest tweets for a user. The tweets are loaded through a list of Tweets present in the managed bean TweetMB (Listing 4). This managed bean is also used to access other information such as user name and link.

The methods loadTweets() and loadUser() both use the username and pathFeed to get the latest tweets feed. The username is the Twitter user name and pathFeed describes the basic path of the url that allows access to the user feed. The fetched tweets are stored in the Collection tweets.

Every time the method setUsername () is called, the methods LoadTweets() and loadUser() are called too, with the objective to update the User and tweets variables. Finally, the constructor sets the username to "toptweets", and the tweets of this user are shower at the end of this first step.

Listing 4. TweetMB.java: Managed Bean linked to the tweet component.

import com.sun.org.apache.xerces.internal.parsers.DOMParser; import java.util.ArrayList; import java.util.Collection; import javax.faces.bean.ManagedBean; import javax.faces.event.ActionEvent; import org.w3c.dom.Document; import org.w3c.dom.NodeList; @ManagedBean public class TweetMB { private User user = new User(); private Collection<Tweet> tweets = new ArrayList<Tweet>(); private static final String pathFeed = "http://twitter.com/statuses/user_timeline.rss?screen_name="; private String username; public TweetMB() { this.setUsername("toptweets"); } public void setUsername(String username) { this.username = username; carregarTweets(null); carregarUsuario(null); } public void loadTweets(ActionEvent ev) { if (username != null) { try { tweets.removeAll(tweets); DOMParser parser = new DOMParser(); parser.parse(pathFeed + username); Document doc = parser.getDocument(); Tweet tweet = new Tweet(); NodeList description = doc.getElementsByTagName("description"); NodeList pubDate = doc.getElementsByTagName("pubDate"); NodeList link = doc.getElementsByTagName("link"); for (int i = 1; i < description.getLength(); i++) { tweet = new Tweet(); tweet.setDescription(description.item(i).getTextContent()); tweet.setDate(pubDate.item(i).getTextContent()); tweet.setLink(link.item(i).getTextContent()); tweets.add(tweet); } } catch (Exception ex) { /* handle */ } } } public void carregarUsuario(ActionEvent ev) { if (username != null) { try { DOMParser parser = new DOMParser(); parser.parse(pathFeed + username); Document doc = parser.getDocument(); usuario.setName(doc.getElementsByTagName("title").item(0).getTextContent()); usuario.setLink(doc.getElementsByTagName("link").item(0).getTextContent()); } catch (Exception ex) { /* handle */ } } } //getters and setters }

As we can see, were used in this managed bean two assistants beans: Tweet and User, described in Listing 5 and 6, respectively. These beans must also be implemented.

Listing 5. Tweet.java: Assistant bean Class to list tweets.

public class Tweet { private String description; private String data; private String link; public Tweet() { } //getters and setters }

Listing 6. User.java: : Assistant bean Class to retrieve user information.

public class User { private String name; private String link; public User() { } //getters and setters }

Right now our component is ready for operation by loading the user toptweets tweets. From now on we will start the second stage, making some changes that will enable the component configuration and the AJAX utilization to update the tweets and the user change.

Evolving our Tweets reader

Our component already works, but still can’t be configured. In this second step you will know and understand the concepts and tags to make it configurable and allow the AJAX use.

The component configuration is possible by use of the tag within the tag . Each attribute lets you pass a parameter to be used in implementing of the component. This tag has several possible configurations. Consider the list of some of them:

name: defines the attribute name. This name serves to call the attribute in the component implementation;

default: sets a default value for the attribute. So when the developer does not use this attribute in the call tag, the default value is used;

required: it’s mandatory to set a value to the attribute when the component is used;

type: defines a type for the attribute that should be compatible with the allowed types in Java;

method-signature: specifies that the attribute value is a described method by a signature. This attribute can’t be used together with the type attribute as they are mutually exclusive. If they are used together, method-signature is ignored;

targets: used to define the attribute targets. The targets are specified by the ids of the components that are in the Implementation;

displayName: used to describe the attribute;

shortDescription: A short description of the attribute.

The knowledge of these attributes of the tag attribute allows the developer to learn what can be used when creating other custom components.

Another highlight in this second stage is the native use of AJAX in JSF 2 through tag. It is used inside the tag of buttons and links and allows a new rendering of the page components. To determine which of them should be re-rendered simply inform their ids, separated by commas in the render attribute of the tag . You can also specify the @form in the render to make entire form to be rendered, as was done in our example.

The changes required for the component to start using AJAX and become configurable are shown in Listing 7. The parts in bold are the code changes needed.

Listagem 7. tweets.xhtml: tweets composite component page modified to use AJAX and become configurable.

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:cc="http://java.sun.com/jsf/composite" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:f="http://java.sun.com/jsf/core"> <cc:interface> <cc:attribute name="managedBean" required="true"/> <cc:attribute name="width" default="300"/> <cc:attribute name="height" default="400"/> </cc:interface> <cc:implementation> <h:outputStylesheet library="css" name="styles.css"/> <h:form prependId="false"> <h:outputText value="Username:"/> <h:inputText id="usernameId" value="#{cc.attrs.managedBean.username}"/> <h:commandButton value="Change"> <f:ajax execute="usernameId" render="@form"/> </h:commandButton> <div id="links" style="width: #{cc.attrs.widht}px; height: #{cc.attrs.height}px"> <ui:repeat value="#{cc.attrs.managedBean.tweets}" var="tweet"> #{cc.attrs.managedBean.user.name} #{tweet.description} <span>#{tweet.data}</span> </ui:repeat> </ul> </div> <a href="#{cc.attrs.managedBean.user.link}" target="_blank">Follow Me!</a> <h:commandButton value="Update" actionListener="#{cc.attrs.managedBean.loadTweets}"> <f:ajax execute="usernameId" render="@form"/> </h:commandButton> </h:form> </cc:implementation> </html>

Our component now has three attributes to configure it. The first, mandatory, called managedBean is used to pass the managed bean that performs the search for the tweets. The second, called width has a default value of 300 and is used to define the width of the tweets reader. The third and last called height, has a default value of 400 and sets the height of the component.

The Implementation tag now has a tag <h:form> that is necessary to when the user clicks on the buttons to change user and update tweets the data for the new rendering are sent to the server and the changes are implemented on the page.

The tag <f:ajax>, used in both buttons, uses the attributes execute and render. The first, execute, contains the id usernameId, which is used to update the data on the component server that has this id. The second, render, contains the @form used to inform the entire form must be re-rendered.

The use of attributes defined in the tag interface is made by using a pre-defined variable: #{cc.FUNC} where FUNC are the features that support access to attributes. This variable is extremely important because it allows the interaction of customized component with the information inserted by the developer at the time of the component use.

Let’s see some functionality allowed for this variable:

#{cc.attrs.ATTRIBUTE_NAME}: We use the attrs to capture the value of the attribute, where ATTRIBUTE_NAME is defined in the tag atributte within the interface. We have several examples in our custom component, one can be seen in Figure 4;



Figure 4. Example use of variable #{cc.attrs.ATTRIBUTE_NAME}.

#{cc.clientId}: The clientId is used to locate the true identification of the element. An example would be #{cc.clientId}: usernameId;

#{cc.parent}: When the custom component has been created within another component, the parent brings the ability to manipulate the variable #{cc.FUNC} from the parent component;

#{cc.children}: If the custom component has a child component, you can manipulate the variable #{cc.FUNC} from the child using the children.

With the variable #{cc.FUNC}, we have many customization possibilities that can be exploited, depending on the problem, to create other custom components. For example, we could customize a new component for a news reader and use our tweets reader in his Implementation tag (Listing 8). Thus, our tweets reader could access the attributes of the new component by using the parent functionality as follows: #{cc.parent.attrs.ATTRIBUTE_NAME}, as in Listing 9.

Listing 8. news.xhtml: An example of component reuse to build a new component using our tweets reader.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">http://www.w3.org/1999/xhtml" xmlns:cc="http://java.sun.com/jsf/composite" xmlns:jam="http://java.sun.com/jsf/composite/myComponentsLibrary"> <cc:interface> <cc:attribute name="name" required="true"/> </cc:interface> <cc:implementation> … <jam:tweets/> … </composite:implementation>

Listing 9. tweets.xhtml: Example of how could be used the parent functionality in the tweets reader.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">http://www.w3.org/1999/xhtml" xmlns:cc="http://java.sun.com/jsf/composite"> … <cc:implementation> … Responsible News Reader: <h:outputText value="#{cc.parent.attrs.name}"/> … </cc:implementation> </html>

The page index.xhtml also needs some changes, because a set of attributes create, must be mandatorily defined in our component. These changes can be seen in Listing 10, in bold.

Listagem 10. index.xhtml: Page where the configured custom component is used.

<?xml version='1.0' encoding='UTF-8' ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="<a href="http: www.w3.org="" 1999="" xhtml"="">http://www.w3.org/1999/xhtml" xmlns:h="<a href="http: java.sun.com="" jsf="" html"="">http://java.sun.com/jsf/html" xmlns:jam="<a href="http: java.sun.com="" jsf="" composite="" mycomponentlibrary"="">http://java.sun.com/jsf/composite/myComponentLibrary"> <h:head> <title>Components Customization Example</title> </h:head> <h:body> <jam:tweets managedBean="#{tweetMB}" altura="600" largura="460"/> </h:body> </html>

We can see that three attributes of our custom component were set to configure it. The managed bean TweetMB that was used directly within the component, now is passed as parameter. The height and width attributes were also changed to try a different size in the component. With these changes we allow the reader to adapt according to where it is displayed.

The link between the interface definition, implementation and index.xhtml page that uses the component can be seen in Figure 5.



Figure 5. Link between the custom component and the page that uses it.

The result for the end user generated by our custom component can be seen in Figure 6.



Figure 6. Result of the custom with behavior component.

UI components Creation wizard (NetBeans)

The components customization can be facilitated using the NetBeans IDE. From version 6.8, was released an interface for creating composite component quickly and easily using a wizard. See the steps needed to use the wizard.

Step 1

Select the code snippet that will turn into a UIcomponent and right click the mouse button on the selected code. Inside the Refactor option, select the Convert to Component Composite (see Figure7).



Figure 7. Code selection that will be turned into a custom component by the NetBeans wizard.

Step 2

The wizard will launch. The component and folder name should be entered, and will be later used as the name of the XHTML page and the name for the component library, respectively. The default name for the library is ezcomp. After completing the information finalize the wizard (Figure 8).



Figure 8. Wizard for configuring a new custom component.

When the custom component wizard is finalized the code will be generated and will appear as in Listing 11.

Listing 11. nameComponent.xhtml: Code of the page created by custom component wizard.

<?xml version='1.0' encoding='UTF-8' ?> <!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:cc="http://java.sun.com/jsf/composite"> <!-- INTERFACE --> <cc:interface> </cc:interface> <!-- IMPLEMENTATION --> <cc:implementation> <p>This code will be a composite component</p> </cc:implementation> </html>

Next the call to the new component is inserted automatically at the page where the wizard has started, and so the page is replaced in accordance with the code in Listing 12.

Listing 12. index.xhtml: Page created by the wizard with the code of the custom component.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:ss="http://java.sun.com/jsf/composite/ezcomp"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <title>Using the wizard to create the composite components</title> </head> <body> <ss:nameComponent/> </body> </html>

Using the wizard to create custom components makes this task even easier and faster, bringing convenience for the developer.

Conclusion

This paper presented techniques for customizing components highlighting what's new in JSF 2. In this new version is easier to customize using the composite components technique, from which it became possible to build new components without the use of Java code. We saw the composite tags library required for customization and configuration possibilities that allow the creation of a wide variety of components for many different purposes.

We also presented a wizard for creating components, which expedites the process by generating common code on all composite components, making possible a more rapid customization.

The customization can generate a gain in development speed with JSF. From the moment in which the components begin to be reused, developers can focus more on other critical parts of the application.