Skip Headers
Oracle® Fusion Middleware Web User Interface Developer's Guide for Oracle Application Development Framework
11g Release 1 (11.1.1.5.0)

Part Number B31973-09
Go to Documentation Home
Home
Go to Book List
Book List
Go to Table of Contents
Contents
Go to Index
Index
Go to Feedback page
Contact Us

Go to previous page
Previous
Go to next page
Next
PDF · Mobi · ePub

30 Creating Custom ADF Faces Components

This chapter describes how to create custom ADF Faces rich client components.

This chapter includes the following sections:

30.1 Introduction to Custom ADF Faces Components

The ADF Faces component library provides a comprehensive set of UI components that covers most of your requirements. However, there are situations when you will want to create a custom rich component that is specific to your application. A custom rich component will allow you to have custom behavior and perform actions that best suit the needs of your application.

Note:

Creating custom standard JSF components is covered in many books, articles, web sites, and the JavaServer Faces specification, therefore, it is not covered in this guide. This chapter is intended to describe how to create ADF Faces components.

JSF technology is built to allow self-registering components and other framework parts. The core JSF runtime at web application startup accomplishes this by inspecting all JAR files in the class path. Any JAR files whose /META-INF/faces-config.xml file contains JSF artifacts will be loaded. Therefore, you can package custom ADF Faces components in a JAR file and simply add it into the web project.

For each ADF Faces component, there is a server-side component and there can also be a client-side component. On the server, for JSPs, a render kit provides a base to balance the complex mixture of markup language and JavaScript. The server-side framework also adds a custom lifecycle to take advantage of the API hooks for partial page component rendering. On the client, ADF Faces provides a structured JavaScript framework for handling various nontrivial tasks. These tasks include state synchronization using partial page rendering. For more information about the ADF Faces architecture, see Chapter 3, "Using ADF Faces Architecture."

ADF Faces components are derived from the Apache MyFaces Trinidad component library. Because of this, many of the classes you extend when creating a custom ADF Faces component are actually MyFaces Trinidad classes. For more information about the history of ADF Faces, including its evolution, see Chapter 1, "Introduction to ADF Faces Rich Client."

Between the JSP and the JSF components is the Application class. The tag library uses a factory method on the application object to instantiate a concrete component instance using the mnemonic referred to as the componentType.

A component can render its own markup but this is not considered to be a best practice. The preferred approach is to define a render kit that focuses on a strategy for rendering the presentation. The component uses a factory method on the render kit to get the renderer associated with the particular component. If the component is consumed in an application that uses Facelets, then a component handler creates the component.

In addition to functionality, any custom component you create must use an ADF Faces skin to be able to be displayed properly with other ADF Faces components. To use a skin, you must create and register the skinning keys and properties for your component. This chapter describes only how to create and register skins for custom components. For more information about how skins are used and created in general, see Chapter 20, "Customizing the Appearance Using Styles and Skins."

Tip:

To work with ADF Faces components, your custom component must use at least the ADF Faces simple skin, because the FusionFX, blafplus-rich, and blafplus-medium skins inherit from the simple skin. Additionally, if there is any chance your component will be used in an Oracle WebCenter application, then your skin must also be registered with the simple.portlet skin.

30.1.1 Developing a Custom Component with JDeveloper

An ADF Faces component consists of both client-side and server-side resources. On the client side, there is the client component, the component peer (the component presenter), and any events associated with the client component.

On the server side, there is the server component, server component events, and event listeners. Also, there is a component renderer, a component JSP tag, a composite resource loader, a JavaScript resource loader, and a resource bundle.

The component also has several configuration and support files. Together, these classes, JavaScripts, and configuration files are packaged into a JAR file, which can be imported as a library into an application and used like other components.

You can use JDeveloper to set up the application workspace and project in which you develop the custom component. After you have created the workspace and project, you add starter working files for the required classes, JavaScript files, and configuration files that make up the custom component. During development, you edit and add code to each of these files, specific for the custom component.

The development process is as follows:

  1. Create an application, workspace, and project as an environment for development. This includes adding library dependencies and registering XML schemas. You should not create the component in the same application in which you plan to use the component.

  2. Create a deployment profile for packaging the component into a JAR file.

  3. Create the following starter configuration and support files:

    • faces-config.xml: Used to register many of the artifacts used by the component.

    • trinidad-skins.xml: Used to register the skins that the component uses.

    • Cascading style sheet: Used to define the style properties for the skins.

    • Render kit resource loader: Allows the application to load all the resources required by the component.

    • adf-js-features.xml: Allows the component to become part of a JavaScript partition. For more information about partitions, see Section 1.2.1.2, "JavaScript Library Partitioning."

    • JSP tag library descriptor (TLD) (for JSP): Defines the tag used on the JSF page.

    • Component handler (for Facelets): Defines the handler used to render the component.

  4. Create the following client-side JavaScript files:

    • Client Component: Represents the component and its attributes on the client.

    • Client Peer: Manages the document object model (DOM) for the component.

    • Client Event: Invokes processing on the client and optionally propagates processing to the server.

  5. Create the following server-side Java files:

    • Server Component class: Represents the component on the server.

    • Server Event Listener class: Listens for and responds to events.

    • Server Events class: Invokes events on the server.

    • Server Renderer class: Determines the display of the component.

    • Resource Bundle class: Defines text strings used by the component.

  6. Further develop the component by testing and debugging the JavaScript and Java code. You can use the JDeveloper debugger to set breakpoints and to step through the code. You can also use Java logging features to trace the execution of the component.

  7. Deploy the component into a JAR file.

  8. Test the component by adding it into an application.

Table 30-1 lists the client-side and server-side component artifacts for a custom component. The configuration and support files are not included in the table.

Table 30-1 Client-Side and Server-Side Artifacts for a Custom Component

Client Server

Component class:

oracle.component_package.js.component.prefixComponent_name.js

Extends:

oracle.adf.view.js.component.AdfUIObject.js

Component:

oracle.<component_package>.faces.component.<Component_name>.java

Extends:

org.apache.myfaces.trinidad.component.UIXObject.java

Event:

oracle.<component_package>.js.event.<prefix><Event_name>.js

Extends:

oracle.adf.view.js.component.AdfComponentEvent.js

Event:

oracle.<component_package>.faces.event.<Event_name> .java

Extends:

javax.faces.event.FacesEvent.java

 

Event Listener:

oracle.<component_package>.faces.event<Listener_name>

Extends:

com.faces.event.FacesListener

Component Peer:

com.<component_package>.js.component.<prefix><Peer_name>Peer.js

Extends:

oracle.adf.view.js.laf.rich.AdfRichUIPeer.js.js

 
 

Component Renderer:

com.<component_package>.faces.render.<Renderer_name>.java

Extends:

oracle.adf.view.rich.render.RichRenderer.java

 

Component JSP Tag (JSP only):

com.<component_package>.faces.taglib.<Tagname_name>Tag.java

Extends:

javax.faces.webapp.UIComponentELTag.java

 

Composite Resource Loader:

com.<component_package>.faces.resource.<Loader_name>ResourceLoader.java

Extends:

org.myfaces.trinidad.resource.RegxResourceLoader.java

 

JavaScript Resource Loader:

com.<component_package>.faces.resource.<Script_Loader_name>ResourceLoader.java

Extends:

org.myfaces.trinidad.resource.AggregateingResourceLoader.java

 

Resource Bundle:

com.<component_package>.faces.resource.<Bundle_name>Bundle.java

Extends:

java.util.ListResouceBundle.java


30.1.2 An Example Custom Component

To help illustrate creating a custom component, a custom component named tagPane will be used as an example throughout the procedures. The tagPane custom component is created for reuse purposes. Although the tagPane presentation might have been implemented using a variety of existing components, having a single custom component simplifies the work of the page developer. In this case, there may be a trade-off of productivity between the component developer and the page developers. If this particular view composition were needed more than once, the development team would reduce costs by reducing the lines of code and simplifying the task of automating a business process.

The tagPane component displays a series of tags and their weighted occurrences for a set of files. Tags that are most frequently used are displayed in the largest font size, while the least used tags are displayed in the smallest font size. Each tag is also a link that triggers an event, which is then propagated to the server. The server causes all the files that contain an occurrence of that tag to then be displayed in a table. Figure 30-1 shows how the tagPane component would be displayed if it was added below the Search pane in the File Explorer application.

Figure 30-1 Custom tagPane Component

Custom component used to show most popular link

The tagPane component receives a collection of tags in a Java Map collection. The key of the map is the tag name. The value is a weight assigned to the tag. In the File Explorer application, the weight is the number of times the tag occurs and in most cases, the number of files associated with the tag. The tag name is displayed in the body text of a link and the font size used to display the name represents the weight. Each tag's font size will be proportionally calculated within the minimum and maximum font sizes based upon the upper and lower weights assigned to all tags in the set of files. To perform these functions, the tagPane custom component must have both client-side and server-side behaviors.

On the server side, the component displays the map of tags by rendering HTML hyperlinks. The basic markup rendering is performed on the server. A custom event on the component is defined to handle the user clicking a link, and then to display the associated files. These server-side behaviors are defined using a value expression and a method expression.

For example, the tagPane component includes:

  • A tag property for setting a Map<String, Number> collection of tags.

  • A tagSelectionListener method-binding event that is invoked on the server when the user clicks the link for the tag.

  • An orderBy property for displaying the sequence of tags from left to right in the order of descending by weight or alternatively displaying the tag links ascending alphabetically.

To allow each tag to be displayed in a font size that is proportional to its weight (occurrences), the font size is controlled using an inline style. However, each tag and the component's root markup node also uses a style class.

Example 30-1 shows how the tagPane component might be used in a JSF page.

Example 30-1 tagPane Custom Component Tag in a JSF Page

<acme:tagPane id="tagPane" tags="#{explorer.navigatorManager.tagNavigator.tags}"
  tagSelectListener="#{explorer.navigatorManager.tagNavigator.onTagSelect}"
  orderBy="alpha" 
  partialTriggers="tagCountLabel"/>

Because the tagPane component must be used with other ADF Faces components, it must use the same skins. Therefore, any styling is achieved through the use of cascading style sheets (CSS) and corresponding skin selectors. For example, the tagPane component needs skin selectors to specify the root element, and to define the style for the container of the links and the way the hyperlinks are displayed. Example 30-2 shows a sample set of style selectors in the CSS file for the tagPane component.

Example 30-2 CSS Style Selectors for the Sample Custom Component

acme|tagPane     - root element
acme|tagPane::content - container for the links
acme|tagPane::tag - tag hyperlink

You may need to specify the HTML code required for the custom component on the server side.

Example 30-3 shows HTML server-side code used for the tagPane component.

Example 30-3 HTML Code for the Server Side

<div class=" acme|tagPane">
  <span class=" acme|tagPane::content ">
    <a class=" acme|tagPane::tag" href="#" style="font-size:9px;">Tag1</a>
    <a class=" acme|tagPane::tag" href="#" style="font-size:10px;">Tag2</a>
  </span>
</div>

On the client side, the component requires a JavaScript component counterpart and a component peer that defines client-side behavior. All DOM interaction goes through the peer (for more information, see Chapter 3, "Using ADF Faces Architecture"). The component peer listens for the user clicking over the hyperlinks that surround the tag names. When the links are clicked, the peer raises a custom event on the client side, which propagates the event to the server side for further processing.

Table 30-2 lists the client-side and server-side artifacts for the tagPane component. Referencing the naming conventions in Table 30-1, the component_package is com.adfdemo.acme and the prefix is Acme.

Table 30-2 Client-Side and Server-Side Artifacts for the tagPane Custom Component

Client Server

Component:

com.adfdemo.acme.js.component.AcmeTagPane.js

Extends:

oracle.adf.view.js.component.AdfUIObject.js

Component

com.adfdemo.acme.faces.component.TagPane.java

Extends:

org.apache.myfaces.trinidad.component.UIXObject.java

Event:

com.adfdemo.acme.js.event.AcmeTagSelectEvent.js

Extends:

oracle.adf.view.js.component.AdfComponentEvent.js

Event:

com.adfdemo.acme.faces.event.TagSelectEvent.java

Extends:

javax.faces.event.FacesEvent.java

 

Event Listener:

com.adfdemo.acme.faces.event.SelectListener

Extends:

com.faces.event.FacesListener

Component Peer:

com.adfdemo.acme.js.component.AcmeTagPanePeer.js

Extends:

oracle.adf.view.js.laf.rich.AdfRichUIPeer.js

 
 

Component Renderer:

com.adfdemo.acme.faces.render.TagPaneRenderer.java

Extends:

oracle.adf.view.rich.render.RichRenderer.java

 

Component JSP Tag:

oracle.adfdemo.acme.faces.taglib.TagPaneTag.java

Extends:

javax.faces.webapp.UIComponentELTag.java

 

Composite Resource Loader:

oracle.adfdemo.acme.faces.resource.AcmeResourceLoader.java

Extends:

org.myfaces.trinidad.resource.RegxResourceLoader.java

 

JavaScript Resource Loader:

oracle.adfdemo.acme.faces.resource.ScriptsResourceLoader.java

Extends:

org.myfaces.trinidad.resource.AggregateingResourceLoader.java

 

Resource Bundle:

oracle.adfdemo.acme.faces.resource.AcmeSimpleDesktopBundle.java

Extends:

java.util.ListResouceBundle.java


30.2 Setting Up the Workspace and Starter Files

Use JDeveloper to set up an application and a project to develop the custom component. After your skeleton project is created, you can add a deployment profile for packaging the component into a JAR file.

During the early stages of development, you create starter configuration and support files to enable development. You may add to and edit these files during the process. You create the following configuration files:

For example, for the tagPane component, the following configuration files are needed:

After the files are set up in JDeveloper, you add content to them. Then, you create the client-side files nd server-side files. For more information, see Section 30.3, "Client-Side Development," and Section 30.4, "Server-Side Development."

30.2.1 How to Set Up the JDeveloper Custom Component Environment

This chapter assumes you have experience using JDeveloper and are familiar with the steps involved in creating and deploying an application. For more information about using JDeveloper to create applications, see Chapter 2, "Getting Started with ADF Faces." For more information about deployment, see the "Deploying Fusion Web Applications" chapter of the Oracle Fusion Middleware Fusion Developer's Guide for Oracle Application Development Framework.

To set up the custom component development environment in JDeveloper:

  1. Create an application to serve as a development container for the component. Use JDeveloper to create a workspace and project. For procedures on creating an application, see Section 2.2, "Creating an Application Workspace." When selecting an application template, select the Generic Application template.

    Note:

    Do not select any other application template, or add any technologies to your application. Because the custom component will be packaged into a JAR file, you do not need to create unnecessary folders such as public_html that JDeveloper creates by default when you use a template specifically for web applications, or add web technologies. Instead, create the starter configuration file from the XML schemas.
  2. Prepare the project to be deployed as a JAR file by creating a new deployment profile.

    1. In the Application Navigator, right-click the project and choose New.

    2. In the New Gallery, select Deployment Profile and then ADF Library JAR File, and click OK.

    3. In the Create Deployment Profile dialog, enter a name for the Deployment Profile name. For example, the tagPane component might use adf-richclient-demo-acme.

    4. In the Edit JAR Deployment Profile Properties dialog, click OK.

  3. In the Project Properties dialog, add library dependencies.

    1. Select Libraries and Classpath in the left pane.

    2. Click Add Library.

    3. In the Add Library dialog, select ADF Faces Runtime 11, Facelets Runtime (if using Facelets), JSF 1.2, and JSP Runtime, and click OK.

    4. Click OK to close the Project Properties dialog.

  4. Register XML schemas.

    The custom component requires several XML configuration files. You can use JDeveloper to register the XML schemas associated with these configuration files. You must add schemas for three configuration files: faces-config.xml, trinidad-skins.xml, and trinidad-config.xml. By preregistering these schemas, you can create a template XML configuration file without having to know the specifics about the markup structure. The names and locations of the schemas are assumed by the base installation of JDeveloper.

    1. Select Tools > Preferences. In the Preferences dialog, select XML Schemas in the left pane, and click Add.

    2. In the Add Schema dialog, click Browse to navigate to the XML schemas included in your JDeveloper build, as shown in Table 30-3.

      Note:

      In the Add Schema dialog, make sure Extension is set to .xml. If you change it to XSD, when you later create XML files, you will not be able to use the XML schema you have created.

      Table 30-3 XML Schema Locations

      XML Configuration File Schema Location

      /META-INF/faces-config.xml

      JDeveloper_Home/jdeveloper/modules/oracle.jsf_1.2.9/glassfish.jsf_1.2.9jar!/com/sun/faces/web-facesconfig_1_2.xsd

      /META-INF/trinidad-skins.xml

      JDeveloper_Home/jdeveloper/modules/oralce.adf.view_11.1.1/trinidad-impl.jar!/org/apache/myfaces/trinidadinternal/ui/laf/xml/schemas/skin/trinidad-skins.xsd

      /META-INF/trinidad-config.xml

      JDeveloper_Home/jdeveloper/modules/oracle.adf.view_11.1.1/trinidad-api.jar!/trinidad-config.xsd

      /META-INF/adf-js-features.xml

      JDeveloper_Home/jdeveloper/modules/oracle.adf.view_11.1.1/adf-richclient-api-ll.jar!/adf-js-features.xsd


30.2.2 How to Add a Faces Configuration File

Although the custom component will be registered in the consuming application's faces-config.xml file, during development, the workspace requires a faces-config.xml file.

Note:

Do not use any of JDeveloper's declarative wizards or dialogs to create the faces-config.xml file. These declarative methods assume you are creating a web application, and will add uneccessary artifacts to your custom component application.

To create a faces-config.xml file for the custom component:

  1. In the Application Navigator, right-click the project and select New.

  2. In the New Gallery, expand General, select XML, and then Select XML Document from XML Schema, and click OK.

  3. In the Create XML from XML Schema dialog:

    • XML File: Enter faces-config.xml.

    • Directory: Append \src\META-INF to the end of the directory entry.

    • Select Use Registered Schemas and click Next.

  4. Enter the following:

    • Target Namespace: Select http://java.sun.com/xml/ns/javaee.

    • Root Element: Select faces-config.

    Leave the defaults for the other fields, and click Finish.

    The new file will automatically open in the XML editor.

  5. Add the following schema information after the first line in the file:

    <?xml version="1.0" encoding="US-ASCII"?>
     <faces-config version="1.2" xmlns="http://java.sun.com/xml/ns/javaee">
    

    Adding a schema provides better WYSIWYG tool support.

30.2.3 How to Add a MyFaces Trinidad Skins Configuration File

Add a MyFaces Trinidad skins file to register the component's CSS file, which is used to define the component's styles.

To create a trinidad-skins.xml file for the custom component:

  1. In the Application Navigator, right-click the project and select New.

  2. In the New Gallery, expand General and select XML.

  3. Select XML Document from XML Schema and click OK.

  4. In the Create XML from XML Schema dialog:

    • XML File: Enter trinidad-skins.xml.

    • Directory: Append \src\META-INF to the end of the Directory entry.

    • Select Use Registered Schemas, and click Next.

  5. Enter the following:

    • Target Namespace: Select http://myfaces.apache.org/trinidad/skin.

    • Root Element: Select skins.

    • Click Finish. The new file will automatically open in the XML editor.

30.2.4 How to Add a Cascading Style Sheet

Add a cascading style sheet to define component's style.

To create a cascading style sheet for the custom component:

  1. In the Application Navigator, right-click the project and select New.

  2. In the New Gallery, expand General, select File and click OK.

  3. In the Create File dialog:

    • Enter a file name, for example, acme-simple-desktop.css.

    • Append \src\META-INF\component_prefix\styles to the end of the Directory entry, where component_prefix is the prefix that will be used in the component library. For example, for the tagPane component, acme is the prefix, therefore, the string to append would be \META-INF\acme\styles.

30.2.5 How to Add a Resource Kit Loader

Create an empty file and add the fully qualified classpath to the custom resource loader.

To create a resource loader for the custom component:

  1. In the Application Navigator, right-click the project and select New.

  2. In the New Gallery, expand General and then File, and click OK.

  3. In the Create File dialog:

    • Enter component_prefix.resources for File Name, where component_prefix will be the prefix used in the component library. For example, for the tagPane component, acme is the prefix, therefore, the string to enter is acme.resources.

    • Append \src\META-INF\sevlets\resources\ to the end of the Directory entry.

30.2.6 How to Add a JavaServer Pages Tag Library Descriptor File

You need a JSP TLD file to work with JSF pages.

To create a JavaServer Pages TLD file for the custom component:

  1. In the Application Navigator, right-click the project and select New.

  2. In the New Gallery, expand Web Tier and select JSP.

  3. Select JSP Tag Library and click OK.

  4. In the Create JavaServer Page Tag Library dialog, select Deployable and click Next.

  5. Enter the following:

    • Tag Library Descriptor Version: Select 2.1.

    • Short Name: A name. For example, for the tagPane component, you would enter acme.

    • Tag Library URI: A URI for the tag library. For example, for the tagPane component, you would enter http://oracle.adfdemo.acme.

  6. Click Next and optionally enter additional tag library information, then click Finish.

30.2.7 How to Add a JavaScript Library Feature Configuration File

Add a features file to define the JavaScript files associated with the custom component, including the files for the client component, the client peer, and the client events.

To create an adf-js-features.xml file for the custom component:

  1. In the Application Navigator, right-click the project and select New.

  2. In the New Gallery, expand General and select XML.

  3. In the right pane, select XML Document from XML Schema and click OK.

  4. In the Create XML from XML Schema dialog:

    • XML File: Enter adf-js-features.xml.

    • Directory: Append \src\META-INF to the end of the Directory entry.

    • Select Use Registered Schemas, and click Next.

  5. Do the following:

    • Target Namespace: Select http://xmlns.oracle.com/adf/faces/feature.

    • Root Element: Select features.

    • Click Finish. The new file will automatically open in the XML editor.

30.2.8 How to Add a Facelets Tag Library Configuration File

If a consuming application uses Facelets, then you must define the handler for the component.

To create a Facelets tag library file:

  1. In the Application Navigator, right-click the project and select New.

  2. In the New Gallery, expand General and select XML.

  3. In the right pane, select XML Document and click OK.

  4. In the Create XML file dialog, enter the following:

    • File Name: Enter prefix_name.taglib.xml

    • Directory: Append \src\META-INF to the end of the Directory entry.

  5. Copy and paste the code shown in Example 30-4:

    Example 30-4 Code for Facelets Tag Library Configuration File

    <?xml version="1.0" encoding="utf-8"?>
    <!DOCTYPE facelet-taglib
              PUBLIC "-//Sun Microsystems, Inc.//DTD Facelet Taglib 1.0//EN" "http://java.sun.com/dtd/facelet-taglib_1_0.dtd">
    <facelet-taglib xmlns="http://java.sun.com/JSF/Facelet">
     
      <namespace>http://xmlns.oracle.adfdemo/acme</namespace>
     
        <tag>
          <tag-name>tagPane</tag-name>
          <handler-class>
            oracle.adfinternal.view.faces.facelets.rich.RichComponentHandler
          </handler-class>
        </tag>
    </facelet-taglib>
    
  6. Replace the namespace and tag-name code shown in bold with code appropriate for your application.

30.3 Client-Side Development

After the JDeveloper workspace and configuration files have been created, you can create and code the client-side JavaScript files. When you have finished with the client-side development, create the server-side files, as described in Section 30.4, "Server-Side Development."

Best Practice:

Because JavaScript libraries do not have namespaces, you should create all JavaScript object names for the custom component using the same prefix. You do not need to do this on the server because the server-side Java package names will prevent name collisions. For example, for the tagPane component, the client-side JavaScript object names all have the acme prefix.

Client components hold state for properties that are not defined within the corresponding DOM element. These properties are bound to an associated DOM element using the clientId. The clientId uniquely defines a server-side component within the component tree representing a page. The DOM element holds the clientId within the Id attribute.

Note:

Place each JavaScript object in its own separate source file for best practice and consistency.

Developing the client-side component requires creating a JavaScript file for the component, the peer, and the component event.

In addition to the client component, client-side events must be defined. The tagPane component's client-side event is fired and propagated to the server when the user clicks one of the three file types. The client event passed to the server is queued so that the target server-side component can take the appropriate action.

Finally, the custom component requires a client peer. The peer is the component presenter. Peers act as the links between a client component and an associated DOM element. Client peers add client behaviors. A peer must be bound to a component through a registration method.

As with the client component, the associated peer is bound to a DOM element using the component's clientId. There are two types of peers, statefull and stateless.

Peers add behavior to the component by dynamically registering and listening for DOM events. Conceptually, a peer's function is similar to the role of a managed bean. However, the client component is not bound to the peer using EL like the server-side component is bound to a view model (#{backingbean.callback}). The peer registers client component events in the InitSubclass (AdfRichUIPeer.addComponentEventHandlers("click")) callback method. The callback is assumed by using a naming convention of (<Peer>.prototype.HandleComponent<Event>). The peer manages DOM event callbacks where the server-side component handles the linking using EL bindings to managed beans. For more information about client-side architecture, including peers, see Section 3.1, "Introduction to Using ADF Faces Architecture."

The following section assumes you have already set up a custom component development template environment. This development environment includes the setting up of application workspace, projects, deployment profiles, and registering schemas. If you have not done so, see Section 30.2, "Setting Up the Workspace and Starter Files."

30.3.1 How to Create a JavaScript File for a Component

Use JDeveloper to create a JavaScript file for the component. In it, you will define the component type for the component.

To create the component JavaScript file:

  1. In the Application Navigator, right-click the project and click New.

  2. In the New Gallery, expand Web Tier and select HTML.

  3. Select JavaScript File and click OK.

  4. In the Create JavaScript File dialog, do the following:

    • File Name: Enter the name of the client-side component. For example, for the tagPane component, you might enter AcmeTagPane.js.

      Tip:

      To prevent naming collisions, start the name with the component prefix.
    • Directory: Enter the directory path of the component in a subdirectory under the src directory. For example, for the tagPane component, you might enter adfrichclient-demo-acme\src\oracle\adfdemo\acme\js\component.

  5. Open the JavaScript File in the editor and add the component code to define the component type. Example 30-5 shows the code that might be used for the tagPane component.

    Example 30-5 tagPane Component JavaScript

    AdfUIComponents.createComponentClass(
     "AcmeTagPane",
     {
          componentType:"oracle.adfdemo.acme.TagPane",superclass:AdfUIObject 
     }
    );
    

30.3.2 How to Create a Javascript File for an Event

Use JDeveloper to create a JavaScript file for the event. Add code to the JavaScript to perform the functions required when a event is fired, such as a mouse click.

To create the JavaScript for the event:

  1. In the Application Navigator, right-click the project and select New.

  2. In the New Gallery, expand Web Tier and select HTML.

  3. Select JavaScript File and click OK.

  4. In the Create JavaScript File dialog, do the following:

    • File Name: Enter the name of the client-side event. For example, for the tagPane component, you might enter AcmeTagSelectEvent.js.

      Tip:

      To prevent naming collisions, start the name with the component prefix.
    • Directory: Enter the directory path of the event in a subdirectory under the src directory. For example, for the tagPane component, you might enter adf-richclient-demo-acme\src\oracle\adfdemo\acme\js\event.

  5. Open the JavaScript File in the editor and add the event code. Example 30-6 shows the event code that might be added for the tagPane component.

    Example 30-6 tagPane Event JavaScript

    /**
     * Fires a select type event to the server for the source component 
    * when a tag is clicked. 
    */
    function AcmeTagSelectEvent(source, tag)
    {
     AdfAssert.assertPrototype(source, AdfUIComponent);
     AdfAssert.assertString(tag); this.Init(source, tag);
    }
    // make AcmeTagSelectEvent a subclass of AdfComponentEvent
    
    AdfObject.createSubclass(AcmeTagSelectEvent, AdfComponentEvent);
    /**
     * The event type 
    */
    AcmeTagSelectEvent.SELECT_EVENT_TYPE = "tagSelect";
    /**
     * Event Object constructor 
    */
    AcmeTagSelectEvent.prototype.Init = function(source, tag)
    {
      AdfAssert.assertPrototype(source, AdfUIComponent);
      AdfAssert.assertString(tag);
      this._tag = tag;
     AcmeTagSelectEvent.superclass.Init.call(this, source, AcmeTagSelectEvent.SELECT_EVENT_TYPE);}
    /**
     * Indicates this event should be sent to the server 
    */
    AcmeTagSelectEvent.prototype.propagatesToServer = function()
    { 
      return true;
    }
    /**
     * Override of AddMarshalledProperties to add parameters * sent server side. 
    */
    AcmeTagSelectEvent.prototype.AddMarshalledProperties = function( properties) 
    { 
      properties.tag = this._tag;
    
    
     }
    /**
     * Convenient method for queue a AcmeTagSelectEvent.
     */
    AcmeTagSelectEvent.queue = function(component, tag)
    {  
    AdfAssert.assertPrototype(component, AdfUIComponent);
     AdfAssert.assertString(tag);
     AdfLogger.LOGGER.logMessage(AdfLogger.FINEST,     "AcmeTagSelectEvent.queue(component, tag)");
     new AcmeTagSelectEvent(component, tag).queue(true);
    }
    /**
     * returns the selected file type 
    */
    AcmeTagSelectEvent.prototype.getTag = function()
    {
      return this._tag;}
    /**
     * returns a debug string 
    */
    AcmeTagSelectEvent.prototype.toDebugString = function()
    { 
     var superString = AcmeTagSelectEvent.superclass.toDebugString.call(this);
     return superString.substring(0, superString.length - 1)
      +     ", tag=" 
      + this._tag     + "]";
    }
    /*
    *
    * Make sure that this event only invokes immediate validators 
    * on the client. 
    */
    AcmeTagSelectEvent.prototype.isImmediate = function()
    { 
      return true;
    }
    

30.3.3 How to Create a JavaScript File for a Peer

Use JDeveloper to create a JavaScript file for the peer. Add code to register the peer and bind it to the component.

To create the peer JavaScript file:

  1. In the Application Navigator, right-click the project and select New.

  2. In the New Gallery, expand Web Tier and select HTML.

  3. Select JavaScript File and click OK.

  4. In the Create JavaScript File dialog, do the following:

    • File Name: Enter the name of the client-side peer. For example, for the tagPane component, you might enter AcmeTagPanePeer.js.

      Tip:

      To prevent naming collisions, start the name with the component prefix.
    • Directory: Enter the directory path of the event in a subdirectory under the src directory. For example, for the tagPane component, you might enter adf-richclient-demo-acme\src\oracle\adfdemo\acme\js\component.

  5. Open the JavaScript file in the editor and add code for the peer. In this code, you must create the peer, add event handling with respect to the DOM, and register the peer with the component. Example 30-7 shows the code that might be added for the tagPane component.

    Example 30-7 tagPane JavaScript Peer

    AdfRichUIPeer.createPeerClass(AdfRichUIPeer, "AcmeTagPanePeer", true);
    AcmeTagPanePeer.InitSubclass = function()
    { 
    AdfLogger.LOGGER.logMessage(AdfLogger.FINEST,
     "AcmeTagPanePeer.InitSubclass()");
      AdfRichUIPeer.addComponentEventHandlers(this,
         AdfUIInputEvent.CLICK_EVENT_TYPE);
    }
    
    AcmeTagPanePeer.prototype.HandleComponentClick = function(componentEvent)
    {  
    AdfLogger.LOGGER.logMessage(AdfLogger.FINEST, "AcmeTagPanePeer.HandleComponentClick(componentEvent)");
      // if the left mouse button was pressed 
    if (componentEvent.isLeftButtonPressed())
     {
       // find component for the peer
      var component = this.getComponent();
      AdfAssert.assertPrototype(component, AcmeTagPane);
       // find the native dom element for the click event  
    var target = componentEvent.getNativeEventTarget(); 
        if (target && target.tagName == "A")
       { 
       AdfLogger.LOGGER.logMessage(AdfLogger.FINEST, "File type element (A)
     found: " + componentEvent.toString());
         var tag = target.firstChild.nodeValue;
       AdfAssert.assertString(tag);
    
    
       AdfLogger.LOGGER.logMessage(AdfLogger.FINEST, "tag :" + tag);
       // fire a select event   
    AcmeTagSelectEvent.queue(component, tag);
       //cancel the native dom onclick to prevent browser actions based on the
       //'#' hyperlink. The event is of type AdfIEUIInputEvent. This event
       //will cancle the native dom event by calling
        //AdfAgent.AGENT.preventDefault(Event)
          componentEvent.cancel();
      } 
    // event has dom node  
      }
    }
    // Register the peer with the component. This bit of script must
    // be invoked after the AcmeTagPane and AcmeTagSelectEvent objects
    // are created. This is enforced by the ordering of the script files
    // in the
     oracle.asfdemo.acme.faces.resource.AcmeResourceLoader.
     AcmeScriptsResourceLoader.AdfPage.PAGE.getLookAndFeel()
    .registerPeerConstructor("oracle.adfdemo.acme.TagPane",
            "AcmeTagPanePeer");
    

30.3.4 How to Add a Custom Component to a JavaScript Library Feature Configuration File

Now that you have created all the JavaScript files for the component, you can add the component to the adf-js-features.xml file you created. Follow the procedures documented in Section A.9.1, "How to Create a JavaScript Feature," omitting the steps for creating the XML files, as you have already done so. Example 30-8 shows the adf-js-features.xml file used for the tagPane component.

Example 30-8 adf-js-features.xml File for the tagPane Component

<?xml version="1.0" encoding="UTF-8" ?>
<features xmlns="http://xmlns.oracle.com/adf/faces/feature">
  <feature>
    <feature-name>AcmeTagPane</feature-name>
    <feature-class>
      oracle/adfdemo/acme/js/component/AcmeTagPane.js
    </feature-class>
    <feature-class>
      oracle/adfdemo/acme/js/event/AcmeTagSelectEvent.js
    </feature-class>
    <feature-class>
      oracle/adfdemo/acme/js/component/AcmeTagPanePeer.js
    </feature-class>
  </feature>
</features>

30.4 Server-Side Development

Server-side development involves creating Java classes for:

After you have created the classes, add the component class and the renderer class to the faces-config.xml file. Then, complete the configuration files started in Section 30.2, "Setting Up the Workspace and Starter Files."

30.4.1 How to Create a Class for an Event Listener

The ADF Faces event API requires an event listener interface to process the event. The custom component has a dependency with the event and the event has a dependency with an event listener interface. The Java import statements must reflect these dependencies. You also must define the componentType for the component.

To create the EventListener class:

  1. In the Application Navigator, right-click the project and select New.

  2. In the New Gallery, expand General and select Java.

  3. Select Java Interface and click OK.

  4. In the Create Java Interface File dialog, do the following:

    • Name: Enter a listener name. For example, for the tagPane component, you might enter TagSelectListener.

    • Package: Enter a name for the package. For example, for the tagPane component, you might enter oracle.adfdemo.acme.faces.event.

  5. Open the Java file in the editor and add the following:

    • Have the listener extend the javax.faces.event.FacesListener interface.

    • Add an import statement, and import the FacesListener class and any other classes on which your event is dependent.

    • Add a method signature that will process the new event. Even though you have not created the actual event, you can enter it now so that you will not have to enter it later.

    Example 30-9 shows the code for the tagPane event listener.

    Example 30-9 tagPane Event Listener Java Code

    package oracle.adfdemo.acme.faces.event;
    
    import javax.faces.event.AbortProcessingException;
    import javax.faces.event.FacesListener;
    
    public interface TagSelectListener
     extends FacesListener
    {
     /**
      * <p>Process the {@link TagSelectEvent}.</p>
      * @param event fired on click of a tag link
      * @throws AbortProcessingException error processing {@link TagSelectEvent}
      */
     public void processTagSelect(TagSelectEvent event)
      throws AbortProcessingException;
    }
    

30.4.2 How to Create a Class for an Event

You must create a server-side event that will be the counter representation of the JavaScript event created in Section 30.3.2, "How to Create a Javascript File for an Event." Server-side JSF events are queued by the component during the Apply Request Values lifecycle phase. Events propagate up to the UIViewRoot class after all the phases but the Render Response phase. Queued events are broadcast to the associated component.

The server-side Java component must raise the server-side event, so you must create the event source file first to resolve the compilation dependency.

To create the server-side event class:

  1. In the Application Navigator, right-click the project and select New.

  2. In the New Gallery, expand General and select Java.

  3. Select Java Class and click OK.

  4. In the Create Java Class File dialog, do the following:

    • Name: Enter an event name. For example, for the tagPane component, you might enter TagSelectEvent.

    • Package: Enter the package name. For example, for the tagPane component, you might enter oracle.adfdemo.acme.faces.event.

    • Extends: Enter a name for the class that the event class extends. This is usually javax.faces.event.FacesEvent.

    • In the Optional Attributes section, select the following:.

      • In the Access Modifiers section, select public.

      • At the bottom, select Constructors from Superclass and Implement Abstract Methods.

Example 30-10 shows the code for the event class.

Example 30-10 tagPane Event Java Code

package oracle.adfdemo.acme.faces.event;
import javax.faces.component.UIComponent;
import javax.faces.event.FacesEvent;
import javax.faces.event.FacesListener;

public class TagSelectEvent
 extends FacesEvent
{
 /**
  * <p>Tag selected on the client.</p>
  */
 private String tag = null;
 /**
  * <p>Overloade constructor passing the <code>source</code> 
  * {@link oracle.adfdemo.acme.faces.component.TagPane} component and the 
  * selected <code>tag</code>.
  * </p>
  * @param source component firing the event
  * @param tag selected tag link type
  */
 public TagSelectEvent(UIComponent source, 
            String tag)
 {
  super(source);
  this.tag = tag;
 }

 /**
  * <p>Returns <code>true</code> if the <code>facesListener</code> is a
  * {@link TagSelectListener}.</p>
  * 
  * @param facesListener listener to be evaluated
  * @return <code>true</code> 
  * if <code>facesListener</code> instancof {@link TagSelectListener}
  */
 public boolean isAppropriateListener(FacesListener facesListener)
 {
  return (facesListener instanceof TagSelectListener);
 }
 /**
  * <p>Delegates to the <code>processTagSelect</code>
  * method of a <code>FacesListener</code>
  * implementing the {@link TagSelectListener} interface.
  * 
  * @param facesListener target listener realizing {@link TagSelectListener}
  */
 public void processListener(FacesListener facesListener)
 {
  ((TagSelectListener) facesListener).processTagSelect(this);
 }
 /**
  * @return the tag that was selected triggering this event
  */
 public String getTag()
 {
  return tag;
 }
}

30.4.3 Creating the Component

A JSF component can be described as a state holder of properties. These properties define behavior for rendering and how a component responds to user interface actions. When you are developing the component class, you identify the types of the needed properties. You also define the base component that it will extend from the MyFaces Trinidad Framework. For example, the tagPane component extends the UIXObject in MyFaces Trinidad.

Most components will have several properties that should be implemented. Some of the properties are inherited from the base class, and some are required for the rich client framework. Other properties are required because they are best practice. And finally, some properties are specific to the functionality of the custom component.

For example, the tagPane component has the properties shown in Table 30-4.

Table 30-4 Component Properties for the tagPane Custom Component

Origin Property Data Type Description

Inherited

id

String.class

The identifier for a component.

rendererType

String.class

The logical identifier registered as a component renderer.

rendered

Boolean.class

True or false flag that determines if the component is rendered.

binding

ValueExpression.class

A binding value expression to store a component instance in a managed bean.

Rich Client Framework

clientComponent

Boolean.class

True or false flag that determines whether a client-side component will be generated.

clientListeners

ClientListenerSet.class

A binding expression that registers a client listener on a component.

clientAttributes

Set.class

A client attribute on a component. The attribute is added both to the server-side JSF component as well as the client-side equivalent.

Best Practice

inlineStyle

String.class

A CSS style applied to the root component's class attribute.

styleClass

String.class

A CSS style added to the component's class attribute.

visible

Boolean.class

True or false flag that returns the visibility of the component. The visible property is not the same as the rendered property. The visible attribute affects the CSS style on the CSS root of the component.

partialTriggers

String[].class

The IDs of the components that should trigger a partial page update.

Specific to tagPane

tags

Map.class

The map of weighted tags. The key represents the tag name and the value as a number. Map<String.Number>.

 

orderBy

String.class

The order that the tags are rendered. The valid enumerations are alpha and weight.

 

tagSelectListener

MethodExpression.class

The newselectListener method binding expression that expects a single parameter of type oracle.adfdemo.acme.faces.event.TagSelectEvent. This binding will be when the client-side oracle.adfdemo.acme.js.event.AcmeTagSelectEvent.js event is queued from clicking one of the tags.


ADF Faces and MyFaces Trinidad component libraries are defined differently from other libraries. A JSF component has a collection called attributes that provides access to component properties (using the Java simple beans specification) through a MAP interface. The collection also holds value pairs that do not correspond to a component's properties. This concept is called attribute transparency. The JSF runtimes (both MyFaces Trinidad and the JSF reference implementation) implement this concept using the Java reflection API.

My Faces Trinidad defines its own internal collection, which does not use the Java reflection API. This difference means that it is more efficient than the base implementation. The solution in MyFaces Trinidad collects more metadata about the component properties. This metadata declares state properties, which allows the base class to fully implement the StateHolder interface in a base class.

My Faces Trinidad extends the javax.faces.component.UIComponent class with the org.apache.trinidad.component.UIXComponent class, followed by a complete component hierarchy. To ease code maintenance, the framework has a strategy for generating code based on configuration files and templates.

This component strategy is a trade-off in terms of development. It requires more coding for defining properties, but you will not have to code the two methods (saveState, restoreState) for the StateHolder interface for each component.

Note:

Do not have your custom component extend from any ADF Faces implementation packages. These implementations are private and might change.

30.4.4 How to Create a Class for a Component

Use JDeveloper to create a Java file for the component. Create a Type bean to hold property information and define a PropertyKey for each property. Then, generate accessors for the private attributes.

To create the component class:

  1. In the Application Navigator, right-click the project and select New.

  2. In the New Gallery, expand General and select Java.

  3. Select Java Class. Click OK.

  4. In the Create Java Class File dialog, do the following:

    • Name: Enter a component name. For example, for the tagPane component, you might enter TagPane.

    • Package: Enter a name for the package. For example, for the tagPane component, you might enter oracle.adfdemo.acme.faces.component.

    • Extends: Enter a name for the class the component class extends. For example, for the tagPane component, you would enter org.apache.myfaces.trinidad.component.UIXObject.

    • In the Optional Attributes section, select the following:.

      • In the Access Modifiers section, select public.

      • At the bottom, select Constructors from Superclass, and Implement Abstract Methods.

  5. In the source editor, create a Type bean that contains component property information. This static class attribute shadows an attribute with the same name in the superclass. The type attribute is defined once per component class. Through the Type constructor, you pass a reference to the superclass's Type bean, which copies property information. For example, the tagPane class would contain the following constructor:

    static public final FacesBean.Type TYPE = new FacesBean.Type(UIXObject.TYPE);
    
  6. For each property, define a static PropertyKey that is used to access the properties state. Use the TYPE reference to register a new attribute. Specify the property type using the class reference. The component data type should correspond to the component property. There is another overload of the registerKey method that allows you to specify state information. The default assumes the property is persistent. Example 30-11 shows the PropertyKey methods for the tagPane component.

    Example 30-11 PropertyKey Definition

    /**
      * <p>Custom CSS applied to the style attribute of the root markup node.</p>
      */
     static public final PropertyKey INLINE_STYLE_KEY = 
      TYPE.registerKey("inlineStyle", String.class);
     /**
      * <p>Custom CSS class to the class attribute of the root markup node.</p>
      */
     static public final PropertyKey STYLE_CLASS_KEY = 
      TYPE.registerKey("styleClass", String.class);
    
  7. Right-click in the editor and choose Generate Accessors. In the Generate Accessors dialog, click Select All, ensure the Scope is set to Public, and click OK. This allows JDeveloper to generate get and set methods for the private attributes.

    Then, remove the private attribute and replace with calls to getProperty(PropertyKey) and getProperty(PropertyKey).

    Example 30-12 shows the code after replacing the private attribute.

    Example 30-12 Component Properties

    public void setInlineStyle(String newinlineStyle)
     {
      // inlineStyle = newinlineStyle;
      setProperty(INLINE_STYLE_KEY, newinlineStyle);
     }
     /**
      * <p>CSS value applied to the root component's style attribute.</p>
      * 
      * @return newinlineStyle CSS custom style text 
      */
     public String getInlineStyle()
     {
      // return inlineStyle;
      return (String) getProperty(INLINE_STYLE_KEY);
     }
    
  8. You may need to override any methods to perform specific functions in the component. For example, to allow your component to participate in partial page rendering (PPR), you must override the getBeanType method, as shown in Example 30-13.

    Example 30-13

    /**
     * <p>Exposes the <code>FacesBean.Type</code> for this class through a protected
     * method.  This method is called but the <code>UIComponentBase</code> superclass
     * to setup the components <code>ValueMap</code> which is the container for the
     * <code>attributes</code> collection.</p>
     *
     * @return <code>TagPane.TYPE</code> static property
     */
    @Override
    protected FacesBean.Type getBeanType()
     {
       return TYPE;
     }
    

    Refer to the ADF Faces JavaDoc for more information about the class your component extends, and the methods you may need to override.

    For the tagPane component, the component must act on the event fired from the client component. A reference to the source component is passed as a parameter to the event's constructor.

    For the tagPane component, the broadcast method checks if the event passed in using the formal parameter is a TagSelectEvent. If it is, the broadcast method invokes the method expression held by the tagSelectListener attribute.

    Most events have an immediate boolean property that specifies the lifecycle phase in which the event should be invoked. If the immediate attribute is true, the event is processed in the Apply Values phase; otherwise, the event is processed in the Invoke Application phase. For more information, see Chapter 4, "Using the JSF Lifecycle with ADF Faces."

    Example 30-14 shows the overwritten broadcast method for the tagPane component.

    Example 30-14 The broadcast Method in the tagPane Component

    /**
      * @param facesEvent faces event
      * @throws AbortProcessingException exception during processing
      */
     @Override
     public void broadcast(FacesEvent facesEvent)
      throws AbortProcessingException
     {
      // notify the bound TagSelectListener 
      if (facesEvent instanceof TagSelectEvent)
      {
       TagSelectEvent event = (TagSelectEvent) facesEvent;
       // utility method found in UIXComponentBase for invoking method event 
       // expressions
       broadcastToMethodExpression(event, getTagSelectListener());
      }
      super.broadcast(facesEvent);
     }
    

30.4.5 How to Add the Component to the faces-config.xml File

After creating the component class, register the component by adding it to the /META-INF/faces-config.xml file. By defining the component in the faces configuration file packaged with the JAR project, you ensure that component is automatically recognized by the JSF runtime during web application startup.

To register the component, enter the component type, which is a logical name used by the applications factory to instantiate an instance of the component. For example, the tagPane component's type is oracle.adfdemo.acme.TagPane. You also need to add the fully qualified class path for the component, for example oracle.adfdemo.acme.faces.component.TagPane.

To register a custom component:

  1. In the Application Navigator, double-click the faces-config.xml file.

  2. Click the Overview tab and click the Components navigation tab.

  3. Click the Add icon and enter the type and class for the component.

  4. Optionally, add any attributes, properties, or facets.

Example 30-15 shows the tagPane component defined within a faces-config.xml file.

Example 30-15 tagPane Component Added to the faces-config.xml File

<?xml version="1.0" encoding="UTF-8" ?>
<faces-config version="1.2" xmlns="http://java.sun.com/xml/ns/javaee">
 <application>
 </application>
 
 <component>
  <component-type>oracle.adfdemo.acme.TagPane</component-type>
  <component-class>oracle.adfdemo.acme.faces.component.TagPane
  </component-class>
 </component>

30.4.6 How to Create a Class for a Resource Bundle

Resource bundles are used to store information for the component, such as text for labels and messages, as well as translated text used if the application allows locale switching. Skins also use resource bundles to hold text for components. Because your custom component must use at least the simple skin, you must create at least a resource bundle for that skin. For a custom component, create a Java file for the resource bundle. For more information about resource bundle classes, see Section 20.3, "Defining Skin Style Properties."

Tip:

You can also use a properties file for your resources.

To create the resource bundle class:

  1. In the Application Navigator, right-click the project and select New.

  2. In the New Gallery, expand General and select Java.

  3. Select Java Class and click OK.

  4. In the Create Java Class File dialog, do the following:

    • Name: Enter a resource bundle name. The name should reflect the skin with which it will be used. For example, for the sample component, you might enter AcmeSimpleDesktopBundle.

    • Package: Enter a name for the package. For example, for the sample component, you might enter oracle.adfdemo.acme.faces.resource.

    • Extends: For resource bundles, you must enter java.util.ListResourceBundle.

    • In the Optional Attributes section, select the following:.

      • In the Access Modifiers section, select public.

      • At the bottom, select Constructors from Superclass and Implement Abstract Methods.

  5. Add any keys and define the text as needed. For more information about creating resource bundles for skins, see Section 20.3.1, "How to Apply Skins to Text."

    Example 30-16 shows the resource bundle code for the tagPane component.

    Example 30-16 tagPane Resource Bundle Java Code

    package oracle.adfdemo.acme.faces.resource;
    import java.util.ListResourceBundle;
    /**
     * <p>Holds properties used by the components bundled in the jar project.
     * This bundle is part of the trinidad component skin that is configured
     * in the "/META-INF/trinidad-skins.xml" file. Component Renderers
     * will use the <code>RenderingContext</code> to lookup a key by calling
     * the <code>getTranslatedString(key)</code> method.</p>
     */
    public class AcmeSimpleDesktopBundle
     extends ListResourceBundle
    {
     /**
      * <p>Returns a two dimensional object array that represents a resource bundle
    . * The first 
      * element of each pair is the key and the second the value.</p>
      * 
      * @return an array of value pairs
      */
     protected Object[][] getContents()
     {
      return new Object[][]
       {
        {"AcmeTagPane_tag_title","Tag Weight: {0}"}
       };
     }
    }
    
  6. To register the resource bundle for the simple desktop skin and any other desired skins, double-click the /META-INF/trinidad-skins.xml file to open it and do the following:

    1. In the Structure window, select skin-addition.

    2. In the Property Inspector, enter a skin ID. For the simple skin ID, enter simple.desktop.

    3. In the Structure window, right-click skin-addition and choose Insert inside skin-addition > bundle-name.

    4. In the Property Inspector, enter the fully qualified name of the resource bundle just created.

    Note:

    JDeveloper adds translation-source and bundle-name elements as comments. Instead of declaratively creating another bundle-name element, you can manually enter the bundle-name value in the generated element, and then remove the comment tag.

    Example 30-17 shows the code for registering the tagPane resource bundle with the simple skin (you will add the style-sheet-name element value in a later step).

    Example 30-17 Registering a Resource Bundle with a Skin

    <skins xmlns="http://myfaces.apache.org/trinidad/skin">
     <skin-addition>
      <skin-id>simple.desktop</skin-id>
      <style-sheet-name></style-sheet-name>
      <bundle-name>
        oracle.adfdemo.acme.faces.resource.AcmeSimpleDesktopBundle
      </bundle-name>
     </skin-addition>
    </skins>
    

30.4.7 How to Create a Class for a Renderer

ADF Faces components delegate the functionality of the component to a component class, and when the consuming application uses JSPs, the display of the component to a renderer. By default, all tags for ADF Faces combine the associated component class with an HTML renderer, and are part of the HTML render kit. HTML render kits are included with ADF Faces for display on both desktop and PDA devices.

Renderers are qualified in a render kit by family and renderer type. The family is a general categorization for a component, and should be the same as the family defined in the superclass. You do not have to override the getFamily() method in the component because the component will have the method through inheritance.

To create the renderer class:

  1. In the Application Navigator, right-click the project and select New.

  2. In the New Gallery, expand General then select Java.

  3. Select Java Class and click OK.

  4. In the Create Java Class File dialog, do the following:

    • Name: Enter a renderer name. For example, for the tagPane component, you might enter TagPaneRenderer.

    • Package: Enter a name for the package. For example, for the tagPane component, you might enter oracle.adfdemo.acme.faces.render.

    • Extends: Enter oracle.adf.view.rich.render.RichRenderer.

    • In the Optional Attributes section, select the following:.

      • In the Access Modifiers section, select public.

      • At the bottom, select Constructors from Superclass and Implement Abstract Methods.

  5. Add any needed functionality. For example, the skinning functionality provides an API you can use to get the CSS style properties for a given CSS selector during rendering of the component. This API is useful if you need to do conditional rendering based on what styling is set. For more information, see RenderingContext#getStyles and Styles#getSelectorStyleMap in the MyFaces Trinidad Javadoc at http://myfaces.apache.org/trinidad/trinidad-1_2/trinidad-api/apidocs/index.html.

30.4.8 How to Add the Renderer to the faces-config.xml File

After you create the renderer, register it using the faces-config.xml configuration file. If you want the custom component to work with the other ADF Faces components, you must use the same render kit ID that ADF Faces components use.

Tip:

The most granular level that JSF allows for defining a render kit is at the view root.

To register the render kit and renderer:

  1. In the Application Navigator, double-click the faces-config.xml file to open it in the editor.

  2. Select the Overview tab and then select the Render Kits navigation tab.

  3. Click the Add icon for the Render Kits and enter oracle.adf.rich for the render kit ID.

  4. Register your renderer by clicking the Add icon for Renderers and doing the following:

    • Family: Enter the class that the component extends. For example, for the tagPane component, you would enter org.apache.myfaces.trinidad.Object.

    • Type: Enter the type for the component. For example, for the tagPane component, you would enter oracle.adfdemo.acme.TagPane. This must match the renderer type.

    • Class: Enter the fully qualified class path to the renderer created in Section 30.4.7, "How to Create a Class for a Renderer." For example, for the tagPane component, you would enter oracle.adfdemo.acme.faces.render.TagPaneRenderer.

Example 30-18 shows the registration of the tagPane component render kit and renderer.

Example 30-18 tagPane Renderer Added to the faces-config.xml File

<render-kit>
  <render-kit-id>oracle.adf.rich</render-kit-id>
  <renderer>
    <component-family>org.apache.myfaces.trinidad.Object</component-family>
    <renderer-type>oracle.adfdemo.acme.TagPane</renderer-type>
    <renderer-class>oracle.adfdemo.acme.faces.render.TagPaneRenderer
    </renderer-class>
  </renderer>
</render-kit>

30.4.9 How to Create JSP Tag Properties

To use the component on a JSP page, you create a custom tag that will instantiate the custom component. The JSP tag has nothing to do with rendering because the component's renderer will actually perform that task. In JSF 1.1, the JSP tag would invoke rendering on the component after creating and adding it to the component tree. This caused problems because the non-JSF/JSP tags were writing to the same response writer. The timing of the interleaving did not work out for components that rendered their own child components.

Note:

(An application that uses Facelets uses a handler to instantiate the component. For more information, see Section 30.2.8, "How to Add a Facelets Tag Library Configuration File")

In JSF 1.2, the target for Java EE 5 (Servlet 2.5, JSP 2.1), most of the JSP problems were fixed. The JSF/JSP component acts as a component factory that is responsible only for creating components. This means that the rendering response phase is divided into two steps. First the component tree is created, and then the tree is rendered, instead of rendering the components as the component tree was being built. This functionality was made possible by insisting that the entire view be represented by JSF components. The non-JSF/JSP generates markup that implicitly becomes a JSF verbatim component.

As a result of changing these mechanics, in JSF 1.2, custom JSP tags extend the javax.faces.webapp.UIComponentELTag class. The encodeBegin, encodeChildren, and encodeEnd methods in the JSP tag have been deprecated. These methods once made corresponding calls to the component. Because the view root in JSF 1.2 does the rendering, all the work can be done in the doStartTag and doEndTag methods. MyFaces Trinidad has its own version of this base class that you will use. The org.apache.myfaces.Trinidad.webapp.UIComponentELTag hooks into the components property bag and makes coding JSPs simpler.

The tag class includes the creation of the component's properties. You must choose tag properties carefully. There are some properties that you can ignore for tag implementation, but they may be required as TLD attributes.

The following three attributes are implemented by superclasses and shared by many components through Java inheritance:

  • id

  • binding

  • rendered

Do not implement the id attribute because the id attribute is implemented by the superclass javax.faces.webapp.UIComponentTagBase. The superclass javax.faces.webapp.UIComponentELTag implements the other two attributes, binding and rendered. Therefore, you do not need to add these to your tag class.

To add a JSP tag:

  1. In the Application Navigator, right-click the project and select New.

  2. In the New Gallery, expand General then select Java.

  3. Select Java Class and click OK.

  4. In the Create Java Class File dialog, do the following:

    • Name: Enter a tag name. For example, for the tagPane component, you might enter TagPaneTag.

    • Package: Enter a name for the package. For example, for the tagPane component, you might enter oracle.adfdemo.acme.faces.taglib.

    • Class: Enter org.apache.myfaces.trinidad.webapp.UIXComponentELTag.

    • In the Optional Attributes section, select the following:.

      • In the Access Modifiers section, select public.

      • At the bottom, select Constructors from Superclass and Implement Abstract Methods.

  5. In the source editor, add all the attributes to the file.

    Example 30-19 shows the code for the attributes for the TagPaneTag class.

    Example 30-19 Attributes in the TagPaneTag Class

    public class TagPaneTag
     extends UIXComponentELTag
    {
     private ValueExpression _partialTriggers = null;
     private ValueExpression _visible = null;
     private ValueExpression _inlineStyle = null;
     private ValueExpression _styleClass = null;
     private ValueExpression _tags = null;
     private ValueExpression _orderBy = null;
     private MethodExpression _tagSelectListener = null;
    
  6. To declaratively generate the accessor methods for the attributes, right-click the file in the source editor and choose Generate Accessors.

  7. In the Generate Accessors dialog, click Select All, set the Scope to public and click OK.

  8. Add the render type and component type to the class. The component type will be used by the superclass to instantiate the component using the application's factory method, createComponent(componentType).

    Example 30-20 shows the code for the TagPaneTag class, where both the component type and render type are oracle.adfdemo.acme.TagPane.

    Example 30-20 Component Type and Render Type for the TagPaneTag Class

    public String getComponentType()
     {
      return COMPONENT_TYPE;
     }
     public String getRendererType()
     {
      return RENDERER_TYPE;
     }
    
     /**
      * <p>This component's type, <code>oracle.adfdemo.acme.TagPane</code></p>
      */
     static public final String COMPONENT_TYPE = 
      "oracle.adfdemo.acme.TagPane";
     /**
      * <p>Logical name given to the registered renderer for this component.</p>
      */
     static public final String RENDERER_TYPE = "oracle.adfdemo.acme.TagPane";
    
  9. Override the setProperties method from the superclass that has a single formal parameter of type FacesBean. This is a MyFaces Trinidad version on the base UIComponentELTag, but it is passed the components state holder instead of the component reference. The job of the setProperties method is to push the JSP tag attribute values to the component.

    Example 30-21 shows the overridden method for the tagPaneTag class.

    Example 30-21 Overridden setProperties Method in the TagPaneTag Class

    @Override
      protected void setProperties(FacesBean facesBean) {
        super.setProperties(facesBean);
        
        setStringArrayProperty(facesBean, TagPane.PARTIAL_TRIGGERS_KEY, 
                    _partialTriggers);
        setProperty(facesBean, TagPane.VISIBLE_KEY, _visible);
        setProperty(facesBean, TagPane.INLINE_STYLE_KEY, _inlineStyle);
        setProperty(facesBean, TagPane.STYLE_CLASS_KEY, _styleClass);
        setProperty(facesBean, TagPane.TAGS_KEY, _tags);
        setProperty(facesBean, TagPane.ORDER_BY_KEY, _orderBy);
        facesBean.setProperty(TagPane.TAG_SELECT_LISTENER_KEY, 
                   _tagSelectListener);
        
      }
    

30.4.10 How to Configure the Tag Library Descriptor

A tag library descriptor (TLD) provides more information on the Java Class to the JSP compilation engine and IDE tools (TLDs are not used in applications that use Facelets).

Before you begin:

Associate the tag library with a URI, assign a version, and give it a name. You should have already performed this step when you created the tag library stub file in Section 30.2.6, "How to Add a JavaServer Pages Tag Library Descriptor File."

To configure the TLD:

  1. Open the skeleton TLD file.

  2. In the Component Palette, drag and drop a tag element.

  3. In the Insert tag dialog, do the following:

    • name: Enter the name of the component. For example, for the tagPane component, you might enter tagPane.

    • body-content: Enter JSP.

    • tag-class: Click the ellipses button and navigate to the components tag class file.

  4. Define each of the attributes as follows. For each attribute:

    1. In the Structure window, right-click the tag element and choose Insert inside tag > attribute.

    2. In the Insert Attribute dialog, enter a value for the name. This should be the same as the name given in the tag class.

    3. In the Structure window, select the attribute and in the Property Inspector, set any attribute values.

      There are three types of elements to define for each attribute. The <id> element is a simple string. Additionally attributes can be either deferred-value or deferred-method attributes. These allow late (deferred) evaluation of the expression. Now that JSP and JSF share the same EL engine, the compiled EL can be passed directly to the component.

    Example 30-22 shows the TLD for the tagPane component.

Example 30-22 tagPane acme.tld Tag Library Descriptor Code

<?xml version = '1.0' encoding = 'UTF-8'?>
<taglib xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
     http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd"
     version="2.1" xmlns="http://java.sun.com/xml/ns/javaee">
 <description>Acme Corporation JSF components</description>
 <display-name>acme</display-name>
 <tlib-version>1.0</tlib-version>
 <short-name>acme</short-name>
 <uri>http://oracle.adfdemo.acme</uri>
  <tag>
  <description>
  </description>
  <name>tagPane</name>
  <tag-class>oracle.adfdemo.acme.faces.taglib.TagPaneTag</tag-class>
  <body-content>JSP</body-content>
  <attribute>
   <name>id</name>
   <rtexprvalue>true</rtexprvalue>
  </attribute>
  <attribute>
   <name>rendered</name>
   <deferred-value>
    <type>boolean</type>
   </deferred-value>
  </attribute>
  <attribute>
   <name>tagSelectListener</name>
   <deferred-method>
    <method-signature>void
    </method-signature>
        myMethod(oracle.adfdemo.acme.faces.event.TagSelectEvent)
   </deferred-method>
  </attribute>
  <attribute>
   <name>visible</name>
   <deferred-value>
    <type>boolean</type>
   </deferred-value>
  </attribute>
  <attribute>
   <name>partialTriggers</name>
   <deferred-value>
   </deferred-value>
  </attribute>
  <attribute>
   <name>inlineStyle</name>
   <deferred-value/>
  </attribute>
  <attribute>
   <name>inlineClass</name>
   <deferred-value/>
  </attribute>
  <attribute>
   <name>tags</name>
   <deferred-value/>
  </attribute>
  <attribute>
   <name>binding</name>
   <deferred-value/>
  </attribute>
  <attribute>
   <name>orderBy</name>
   <deferred-value/>
  </attribute>
 </tag>
</taglib>

30.4.11 How to Create a Resource Loader

A resource loader is required only if the custom component has image files needed for the component's skinning. The images files are packaged into the JAR project so that the consumer of the component library will need to include the JAR into the class path of their web project and add a few entries into their web deployment descriptor file (web.xml). The rich client framework uses a resource servlet to deliver images. You need to register this servlet in the web.xml file and then create the resource loader class. A component library requires a resource loader that is auto-loaded by the resource servlet. You create a URL pattern folder mapping for the servlet, which will be used to locate and identify resources within your custom component library.

To create a resource loader class:

  1. In the Application Navigator, right-click the project and select New.

  2. In the New Gallery, expand General and select Java.

  3. Select Java Class and click OK.

  4. In the Create Java Class File dialog, do the following:

    • Name: Enter a resource loader name. For example, for the tagPane component, you might enter AcmeResourceLoader.

    • Package: Enter a name for the package. For example, for the tagPane component, you might enter oracle.adfdemo.acme.faces.resources.

    • Extends: Enter a name for the class that the tag extends. For example, for the tagPane component, you would enter org.apache.myfaces.trinidad.resource.RegexResourceLoader.

    • In the Optional Attributes section, select the following:.

      • In the Access Modifiers section, select public.

      • At the bottom, select Constructors from Superclass and Implement Abstract Methods.

  5. In the source editor, register regular expressions that map to more specific resource loaders. For example, you might create an expression that maps image resources located under an images directory.

    Example 30-23 shows the expression for the tagPane component that maps the /acme/images/ directory located relative to the /META-INF folder of the custom component JAR. As a result of the registration, the custom component images should be located under /META-INF/acme/images.

    Example 30-23 Resource Loader for the tagPane Component

    public class AcmeResourceLoader
     extends RegexResourceLoader
    {
     public AcmeResourceLoader()
     {
      // any resource in "/acme/" with the following suffixes will be
      // loaded from the base folder of "META-INF".
      // The servlet pattern match "/acme/*" should exist under "META-INF".
      // For example URL : context-root/acme/images/type1.gif
      //      map to: META-INF/acme/images/type1.gif
      register("(/.*\\.(jpg|gif|png|jpeg))", 
           new ClassLoaderResourceLoader("META-INF"));
    
  6. Register the Libraries Resource Loader by opening the /META-INF/servlet/resources/name.resources file and adding the fully qualified name of the resource loader class bound to the URI pattern.

    The MyFaces Trinidad ResourceServlet uses the servlet context to scan across all JAR files within the class path of the web application. The servlet looks at its own URI mappings in the web deployment descriptor to formulate the location of this resource file. This file must contain the fully qualified name of the Java class bound to the URI pattern. During startup, the ResourceServlet will locate and use this file in a manner similar to how FacesServlet locates and uses the faces-config.xml files.

    For the tagPane component, the acme.resources file would contain this entry for the composite resource loader:

    oracle.adfdemo.acme.faces.resource.AcmeResourceLoader
    

30.4.12 How to Create a MyFaces Trinidad Cascading Style Sheet

A skin is a style sheet based on the CSS 3.0 syntax specified in one place for an entire application. Instead of inserting a style sheet on each page, you use one or more skins for the entire application. Every component automatically uses the styles as described by the skin. No design time code changes are required.

ADF Faces provides three skins for use in your applications:

  • blafplus-rich: Defines the default styles for ADF Faces components. This skin extends the blafplus-medium skin.

  • blafplus-medium: Provides a modest amount of styling. This style extends the simple skin.

  • simple: Contains only minimal formatting.

Skins provide more options than setting standard CSS styles and layouts. The skin's CSS file is processed by the skin framework to extract skin properties and icons and register them with the Skin object. Style sheet rules include a style selector, which identifies an element, and a set of style properties, which describes the appearance of the components.

All ADF Faces components use skins. The default skin is the simple skin. Because your custom components will be used in conjunction with other ADF Faces components, you add style selectors to an existing ADF Faces skin. Because the rich and medium skins inherit styles from the simple skin, you can simply add your selectors to the simple skin, and it will be available in all skins. However, you may want to style the selector differently for each skin. You set these styles in the CSS file you created. This file will be merged with other CSS styles in the application in which the component is used.

The text used in a skin is defined in a resource bundle. Create the text by creating a custom resource bundle and declaring the text you want to display. After you create your custom resource bundle, you register it with the skin. Coupling resource bundles with your CSS provides a method to make your components support multiple locales.

The /META-INF/trinidad-skins.xml file you created is used to register your CSS file and your resource bundle with an ADF Faces skin.

To create styles for your component:

  1. Open the CSS file you created in Section 30.2.4, "How to Add a Cascading Style Sheet."

  2. Define a root style selector for the component. This style will be associated with the <DIV> element that establishes the component.

  3. Add other style selectors as needed. Example 30-24 shows the CSS file for the tagPane component.

    Example 30-24 CSS File for the tagPane component

    acme|tagPane          -  root element
    acme|tagPane::content -  container for the links
    acme|tagPane::tag - tag hyperlink
    

    For more information about creating CSS for components to be used by skins, see Section 20.3, "Defining Skin Style Properties."

  4. Create any needed resource bundle for your component.

  5. To register your CSS with an ADF Faces skin, open the /META-INF/trinidad-skins.xml file.

  6. In the Structure window, select the skin-addition element, and in the Property Inspector, do the following:

    • skin-id: Enter the ADF Faces skin to which you want to add the custom component selectors. You must register the selectors at least to the simple.desktop skin in order for them to be compatible with ADF Faces components.

      Note:

      If there is a possibility that the component will be used in an Oracle WebCenter application, then you must also register the selectors with the simple.portlet skin. Skins are also available for PDAs (for example, simple.pda). For more information, see Chapter 20, "Customizing the Appearance Using Styles and Skins."
    • style-sheet-name: Use the dropdown menu to choose Edit, and navigate to the CSS file you created.

  7. If you created a resource bundle, add the fully qualified path to the bundle as the value for the <bundle-name> element.

    Example 30-25 show the code for the tagPane component.

    Example 30-25 tagPane trinidad-skins.xml Code

    <?xml version="1.0" encoding="UTF-8" ?>
    <skins xmlns="http://myfaces.apache.org/trinidad/skin">
     <skin-addition>
      <skin-id>simple.desktop</skin-id>
      <style-sheet-name>acme/styles/acme-simple-desktop.css</style-sheet-name>
      <bundle-name>oracle.adfdemo.acme.faces.resource.AcmeSimpleDesktopBundle
      </bundle-name>
     </skin-addition>
    </skins>
    
  8. Add an image folder for the images used for the custom component. This folder should be under the META-INF directory. Place any images used by the custom component into this folder.

    For tagPane, the image folder is /META-INF/acme/images.

30.5 Deploying a Component Library

After creating the custom component library, you must create a deployable artifact that can be used by a web application. Before you can build a Java archive (JAR) file, update the project's deployment profile by adding the many resources you created.

To create the JAR file for deployment:

  1. In the Application Navigator, double-click the project to open the Project Properties dialog.

  2. In the left pane, select Compiler.

  3. On the right, ensure that all file types to be deployed are listed in the Copy File Types to Output Directory text field.

    Note:

    Some file types, such as .css and .js are not included by default. You will need to add these.
  4. In the left pane, select Deployment.

  5. On the right, under Deployment Profiles, select the ADF Library JAR file, and click Edit.

  6. In the left pane, select JAR Options.

  7. Verify the default directory path or enter a new path to store your ADF Library JAR file. Ensure that Include Manifest File is selected, and click OK.

  8. To deploy, right-click the project and select Deploy >Project_name from the context menu. By default, the JAR file will be deployed to a deployment directory within the project directory.

30.6 Adding the Custom Component to an Application

After the component has been created and you have created an ADF Library, you can proceed to import it and use it in another application. However, before using it in an application under development, you should use it in a test application to ensure it works as expected. To do so, import the custom library into your test application. For procedures, see the "Adding ADF Library Components into Projects" section of the Oracle Fusion Middleware Fusion Developer's Guide for Oracle Application Development Framework.

After you add the library, you configure the web deployment descriptor to add a resource servlet mapping. When you use the component and run your test application, you may find you need to debug the component. Therefore, it helps to have logging and assertions enabled for the project.

Tip:

Importing a library into an application allows the custom component to appear in JDeveloper's Component Palette.

30.6.1 How to Configure the Web Deployment Descriptor

You configured the component resource loader to assume a servlet resource mapping (for example, for the tagPane component, the mapping was acme). Therefore, you must add the expected resource servlet mappings to the consuming application's web.xml file.

By default, MyFaces Trinidad skinning compresses the CSS classes when it normalizes CSS 3 into CSS 2. Turn off this compression while you are debugging the component. For a production deployment, toggle off this setting.

To configure the web.xml file:

  1. In the Application Navigator, double-click the web.xml file to open it.

  2. In the overview editor, select the Servlets navigation tab, and click the Add icon to add a new servlet.

  3. In the Servlets table, do the following:

    • Name: Enter resources.

    • Servlet Class: Enter org.apache.myfaces.trinidad.webapp.ResourceServlet.

  4. Below the table, click the Servlet Mappings tab, then click the Add icon.

  5. Enter a URI prefix. Resources beginning with this prefix will be handled by the servlet. For example, for the tagPane component, you might enter the prefix /acme/*.

  6. To disable compression of the style sheet:

    1. Select Application.

    2. Click the Add icon for Context Initialization Parameters.

    3. For Name, enter org.apache.myfaces.trinidad.DISABLE_CONTENT_COMPRESSION and for Value enter true.

30.6.2 How to Enable JavaScript Logging and Assertions

JavaScript debugging can be a difficult task. To help debug this dynamic language with no type checking, the rich client JavaScript libraries provide a logging mechanism similar to Java logging. There is also an assertion strategy to make the client scripts more type safe. Both of these features are turned on using configuration parameters in the web.xml file. The logging and assertion routines are browser specific. The client JavaScript libraries will support Gecko, Internet Explorer, Opera, and Safari versions of browser agents. For more information, see Section A.2.3.4, "Resource Debug Mode."

To turn on logging and assertion:

  1. In the Application Navigator, double-click the web.xml file.

  2. In the overview editor, click the Application navigation tab.

  3. On the Application page, click the Add icon for the Context Initialization Parameters.

  4. Add the following parameter to turn on debugging:

    • Name: org.apache.myfaces.trinidad.resource.DEBUG

    • Value: true

    This setting prevents MyFaces Trinidad from setting the cache headers for resources like JavaScript. It prevents the browser from caching resources.

  5. Add the following parameter to set the debug level for client side JavaScript.

    • Name: oracle.adf.view.rich.LOGGER_LEVEL

    • Value: ALL

    The valid values are OFF, SEVERE, WARNING, INFO, CONFIG, FINE, FINER, FINEST and ALL. The default is OFF.

  6. Add the following parameter to turn on client-side script assertions:

    • Name: oracle.adf.view.rich.ASSERT_ENABLED

    • Value: true

    This setting works together with logging. Toggling this switch to on will make debug information available to the browser. The assertions and logging are displayed differently, depending on the browser. For Internet Explorer, a child browser window will appear beside the active window. For FireFox with the Fire Bug plugin, the debug information will be available through the Fire Bug console.

30.6.3 How to Add a Custom Component to JSF Pages

To add the custom component to a JSF page:

  1. Open the jspx page in the source editor.

  2. Add the TLD namespace to the root tag.

    For example, for the tagPane component, because the tag library's URI is: http://adf-richclient-demo-acme, you would add:

    xmlns:acme="http://oracle.adfdemo.acme"
    
  3. Use the Component Palette to add the component to the page. Use the Property Inspector to set any attributes.

    Tip:

    If you are developing the application outside of JDeveloper, then on the page, use TLD short name and the component name. Also, add any values for attributes. For example, for the tagPane, you might add:
    <acme:tagPane>
      <visible="true">
      <orderBy="alpha">
      <tagSelectionListener=#(tagBean.onTagSelect)
    </tagPane>
    

30.6.4 What You May Need to Know About Using the tagPane Custom Component

If you wish to create the tagPane component as described in this chapter, and use it in an application, you will need to use backing beans to bind the custom component to the application components.

Example 30-26 shows the backing bean code that is used to bind the tagPane component to the File Explorer application.

Example 30-26 Backing Bean Logic for the tagPane Custom Component

public Map<String, Number> getTags()
 {
  if (_tags == null)
  {   
    _tags = new TreeMap<String, Number>();
    List<FileItem> nameToFileItems = feBean.getDataFactory().getFileItemList();
   _doDeepTagCollection(_tags, nameToFileItems);
  }
  return _tags;
 }
 public void onTagSelect(TagSelectEvent event)
 {
  _selectedTag = event.getTag();
  CriteriaFileItemFilter criteria = new CriteriaFileItemFilter(_selectedTag);
  List<FileItem> nameToFileItems =    _feBean.getDataFactory().getFileItemList();
    if (_selectedTagFileItemList == null) {
       _selectedTagFileItemList = new ArrayList<FileItem>(); 
    else {
      _selectedTagFileItemList.clear();
     }
    _doDeepTagSearch(criteria, _selectedTagFileItemList, nameToFileItems);
    _selectedTagResultsTableModel = new SortableModel(_selectedTagFileItemList);

 }