Dr. Winston Prakash Ph.D. 

Personal Website

Creating an AJAX enabled JSF component - Part 2

In part 1, we  created  a simple Image Slider component.  The Image Slider component takes one or more images and displays the image with a previous and a next link. Clicking on the next or previous link  displays the next or previous image.   We  aslol added AJAX capability to our image slider component using Dynamic Faces.  Adding the AJAX capability, helps the Image Slider component  to display the next or previous image by fetching them with out submitting the form.

In part 2, we will add design time to our component and create a complib archive. This complib can be later imported in to  Netbeans Visual Web Pack and the component can be added to the the visual web application by drag and drop. The design time will allow us to specify rich user interaction when the component is added to the designer.

You can down the complete set of projects form here.

Initial Steps to create the skeleton project

  • Create a new Java Library Project and call it ImageSlider-Designtime using File -> New Project... menu item. In the dialog select General -> Java Class Library
  •  Create a new package called com.examples.imageslider 
  • Create the BeanInfo  Class (Java Bean Standarad)
    • Right click on the package  com.examples.imageslider and create a class called ImageSliderBeanInfo.java. Note, the first part of the class name must exactly match the name of your JSF component.
  • Add the required designtime API jars designtime.jar and designtime & designtime-base.jar. These jars are bundled with Netbeans if Visual Web Pack is installed (available at <Netbeans6.0-install-dir>/visualweb1/modules/ext)
    • Right click on the Libraries node of the project and add the two jars designtime.jar and designtime-base.jar from Netbeans installation directory.

Adding code to  ImageSliderBeanInfo.java

Modify the class declaration to make it to extend SimpleBeanInfo

public class ImageSliderBeanInfo extends SimpleBeanInfo{

Add code to tell the Designtime System of Netbeans Visual Web Pack to

  • Display name of the Component in the Palette
  • Instance name when the component is added to the application
  •  Tag name for the component
  • Tag name prefix
  • Taglib URI to be added to the JSP
public BeanDescriptor getBeanDescriptor() {
  BeanDescriptor beanDescriptor = new BeanDescriptor(ImageSlider.class , null );
  beanDescriptor.setDisplayName( "Image Slider" );
  beanDescriptor.setShortDescription( "Image Slider AJAX Component" );

  beanDescriptor.setValue(Constants.BeanDescriptor.INSTANCE_NAME,"image");
  beanDescriptor.setValue(Constants.BeanDescriptor.IS_CONTAINER,Boolean.TRUE);
  beanDescriptor.setValue(Constants.BeanDescriptor.PROPERTY_CATEGORIES,
    CategoryDescriptors.getDefaultCategoryDescriptors());
  beanDescriptor.setValue(Constants.BeanDescriptor.TAG_NAME,"ImageSlider");
  beanDescriptor.setValue(Constants.BeanDescriptor.TAGLIB_PREFIX,"is");
  beanDescriptor.setValue
    (Constants.BeanDescriptor.TAGLIB_URI,"http://com.examples.imageslider");
  return beanDescriptor;
} 

Add code to tell the IDE to display about the information of the ImageSlider component Properties in the properties sheet.  After adding the following code, right-click inside the editor and select Fix Imports.

public PropertyDescriptor[] getPropertyDescriptors() {
  PropertyDescriptor[] properties = new PropertyDescriptor[8];

  try {
   properties[0] = new PropertyDescriptor("height", ImageSlider.class,
                                        "getHeight", "setHeight" );
   AttributeDescriptor attrib = new AttributeDescriptor("height", false, null, false);
   properties[0].setValue(Constants.PropertyDescriptor.ATTRIBUTE_DESCRIPTOR, attrib);
   properties[0].setValue(Constants.PropertyDescriptor.CATEGORY, 
                                                 CategoryDescriptors.GENERAL);

   properties[1] = new PropertyDescriptor("id", ImageSlider.class,
                                                     "getId", "setId" );
   attrib = new AttributeDescriptor("id", false, null, false);
   properties[1].setValue(Constants.PropertyDescriptor.ATTRIBUTE_DESCRIPTOR, attrib);
   properties[1].setValue(Constants.PropertyDescriptor.CATEGORY, 
                                               CategoryDescriptors.GENERAL);

   properties[2] = new PropertyDescriptor("imageIndex", ImageSlider.class,
                                             "getImageIndex", "setImageIndex" );
   properties[2].setValue(Constants.PropertyDescriptor.CATEGORY, 
                                               CategoryDescriptors.APPEARANCE);

   properties[3] = new PropertyDescriptor("imageUrls", ImageSlider.class,
                                            "getImageUrls", "setImageUrls" );
   properties[3].setValue(Constants.PropertyDescriptor.CATEGORY, 
                                           CategoryDescriptors.APPEARANCE);

   properties[4] = new PropertyDescriptor("rendered", ImageSlider.class,
                                                  "isRendered", "setRendered" );
   attrib = new AttributeDescriptor("rendered", true, "", false);
   properties[4].setValue(Constants.PropertyDescriptor.ATTRIBUTE_DESCRIPTOR,attrib);
   properties[4].setValue(Constants.PropertyDescriptor.CATEGORY, 
                                                       CategoryDescriptors.ADVANCED);

   properties[5] = new PropertyDescriptor("style", ImageSlider.class,
                                                 "getStyle", "setStyle" );
   attrib = new AttributeDescriptor("style", false, null, false);
   properties[5].setValue(Constants.PropertyDescriptor.ATTRIBUTE_DESCRIPTOR,attrib);
   properties[5].setValue(Constants.PropertyDescriptor.CATEGORY, 
                                               CategoryDescriptors.APPEARANCE);

   properties[6] = new PropertyDescriptor("url", ImageSlider.class,
                                                           "getUrl", "setUrl" );
   attrib = new AttributeDescriptor("url", true, "", false);
   properties[6].setValue(Constants.PropertyDescriptor.ATTRIBUTE_DESCRIPTOR,attrib);
   properties[6].setValue(Constants.PropertyDescriptor.CATEGORY, 
                                                CategoryDescriptors.APPEARANCE);

   properties[7] = new PropertyDescriptor("width", ImageSlider.class,
                                                    "getWidth", "setWidth" );
   attrib = new AttributeDescriptor("url", true, "", false);
   properties[7].setValue(Constants.PropertyDescriptor.ATTRIBUTE_DESCRIPTOR,attrib);
   properties[7].setValue(Constants.PropertyDescriptor.CATEGORY, 
                                                   CategoryDescriptors.APPEARANCE);

  } catch(IntrospectionException e) {
    e.printStackTrace();
  }
  return properties;
} 

Specify the icon Image 

public java.awt.Image getIcon(int iconKind) {
  return loadImage("/com/examples/imageslider/ImageSlider.png"); 
} 

Now build the project. Select Build > Build Main Project from the main menu bar.  As a result of successfully building the project, you will see the build Output window showing the newly created ImageSlider-Designtime.jar in directory dist

Creating the component library

The component library is a jar file that bundles the run time (ImageSlider-Runtime.jar) and design time jar files (ImageSlider-Runtime.jar along with other required jars such as the Dynamic Faces jars) . The component library consist of a JAR manifest file (MANIFEST.MF) that points to a second configuration XML file (complib-config.xml), which in turn catalogs the contents of the component library. The configuration XML contains all the information about the library.  See Component Library Package File Specification for details.

To create the component library, let us create a complib-bundle.properties, complib-config.xml and a build.xml file to build the component library. Here we assume the Dynamic Faces libraries are placed under a directory "libs" along with the runtime and designtime projects.

First Create the complib-bundle.properties file

# Localizable resources for component import library
titleKey=Image Slider
folder1Key=Image

Next Create the complib-config.xml

<?xml version="1.0" encoding="UTF-8"?> 
<complibConfiguration version="1.0" resourceBundleBaseName="complib-bundle">
  <identifier>
    <uri>http://com.examples.imageslider</uri>
    <version>0.1.1</version>
  </identifier>
  <titleKey>titleKey</titleKey>
  <runtimePath>
    <pathElement>dist/ImageSlider-Runtime.jar</pathElement>
    <pathElement>commons-logging-1.1.jar</pathElement>
    <pathElement>jsf-extensions-common-0.1.jar</pathElement>
    <pathElement>jsf-extensions-dynamic-faces-0.1.jar</pathElement>
    <pathElement>shale-remoting-1.1.0-swdp-a.jar</pathElement>
  </runtimePath>
  <designTimePath prependRuntimePath="true">
    <pathElement>dist/ImageSlider-Designtime.jar</pathElement>
  </designTimePath>

  <initialPalette>
    <folder key="folder1Key">
      <item className="com.examples.imageslider.ImageSlider"/>
    </folder>
  </initialPalette>
</complibConfiguration>

Finally write the ant script build.xml

<?xml version="1.0" encoding="UTF-8"?>
<project name="Complib" default="jar" basedir=".">
 <target name="jar" description="Build the component library">
  <jar destfile="imageslider.complib">
   <fileset dir="."
     includes="complib-config.xml, complib-bundle.properties"
   />
   <fileset dir="../libs"
    includes="commons-logging-1.1.jar, 
    jsf-extensions-common-0.1.jar,
    jsf-extensions-dynamic-faces-0.1.jar,
    shale-remoting-1.1.0-swdp-a.jar"
   />
   <fileset dir="../ImageSlider-Designtime"
    includes="dist/**"
   />
   <fileset dir="../ImageSlider-Runtime"
    includes="dist/**"
   />
   <manifest>
    <attribute name="X-Rave-API-Compatibility-Version" value="2.0"/>
    <attribute name="X-Rave-Complib-Configuration" value="complib-config.xml"/>
    <attribute name="Extension-Name" value="com.examples.imageslider"/>
   </manifest> 
  </jar>
 </target>
</project>

Run the ant script and it builds the component library called imageslider.complib

Testing the Component Library using a visual web project

In this step we are going to create a Visual Web Project and import the component library we created in the previous step.

  • Create a new Visual Web Project and call it ImageSlider-VWP using File -> New Project... menu item. In the dialog select Web -> Web project and select Visual JSF Framework in the Select Framework Panel (Netbeans 6.0)
  • Configure the Deployment Descriptor. Dynamic Faces technology requires an initialization parameter in the web application's deployment descriptor.
    • Dubleo Click and open the web.xml (expand Web Pages and expand WEB-INF)
    • In the editing toolbar, click Servlets, then click the Add button that appears under Initialization Parameters  and type
      • Param Name: javax.faces.LIFECYCLE_ID
      • Param Value: com.sun.faces.lifecycle.PARTIAL
  • Import the Component LIbrary
    • From the IDE Tools Menu select the menu item "Component Library manager"
    • In the dialog click "Import..." button, browse and select the component library selected in previous step.
    • After the component libarary is added to the IDE, we need to add the library to the project, by clicking on the Component Libraries node in the ImageSlider-VWP project and then select the menu item Add Component Library. In the dialog select the ImageSlider Library. Make sure  in the Palette the Category "Image" appears along with the Palette Item "ImageSlider".
  • Add few images to the resources directory in the project.
    • Select the "resources" folder. Then from the File Menu select the menu item Add Existing Item -> Image File.
  • Double click and open Page1.jsp if it is not already opened. Then drag and drop the ImageSlider palette item on to the designer. You drag the component resize handle and resize the component.
  • In the property sheet, select the property url and sets its value as "/resources/image1.jpg,/resources/image2.jpg" pointing to the image url you added earlier to the project.
  • Deploy the application and the browser shouls display the ImageSlider as