Welcome!

Java Authors: Maureen O'Gara, Liz McMillan, Walter H. Pinson, III, Yakov Werde, Tony Bishop

Related Topics: Java

Java: Article

Apache Trinidad - A World Cup Skinning Experience?

A global style sheet that only has to be set in one place for the entire application

Notice that the Apache Trinidad skinning feature provides bi-directional support, causing the duplication of the style class name with an additional :rtl suffix to provide "right to left" style information in the second style class. It is also important that you add width and height to any style using images/icons, since some browsers, such as Internet Explorer, might have problems displaying the actual icons. Next we are going to look at the Apache Trinidad's tr:navigationPane control. This component is slightly more complex than the tr:inputDate component with more controls and attributes that can be adjusted. The default look and feel for this to control is shown in Figure 5.

We are going to add Listing 1 just below the inputDate styles in our trinidadSkin.css file.

By using the alias class - AFTabBarItem:alias - we can add a set of styles to the skin that are generic to all navigationPane controls. We have also added styles that are unique to all navigationPane link controls by using the component-specific selector.

We are not going to bore you with too much repetitive code, so to finish off the CSS bit of our new skin we are going to look at how you can apply a slightly different style to a nested component compared to how it would look outside its parent component. In this sample we have a panelHeader component that has the following skin setting:

/** panelHeader **/
/** ----------- **/
af|panelHeader
{
    padding: 4px 4px 4px 6px;
    background-color: #DDDDDD;
    border: 1px solid #999999;
    vertical-align: middle;
}

af|panelHeader::level-one
{
    color: #900000;
    font-weight:bold;
    font-size: x-large;
}

af|panelHeader::level-two
{
    color: #333333;
    background-color: #EEEEEE;
    border: 1px solid #AAAAAA;
    font-weight:bold;
    font-size: large;
}

At runtime this will translate to H1, H2 equivalents, which will look like the Welcome note and the release announcement.

This is fine as long as you don't use this panelHeader component anywhere else, say nested within a panelSideBar component. In that case the styles will be too overwhelming, but there is a very simple standard CSS solution:

af|panelSideBar af|panelHeader
{
    font-size: smaller;
    border-left: 0px;
    border-right: 0px;
    border-top: 0px;
    border-bottom: 1px solid #AAAAAA;
    background-color: #F0F0F0;
    padding-top: 2px;
    padding-left: 9px;
    color: #49635a;
}

In this code sample we have defined that any panelHeader within a panelSideBar should have a different style.

Setup of a Custom Skin
Let's now have a look at how to set up your application to use an Apache Trinidad custom skin. First of all, we need the CSS file, stored somewhere at the root of our Web application. In our sample application, it's stored in the /skin/trinidad directory. We should also make sure that we have access to all resources needed for the skin, such as images and other CSS files. For our application, these are stored in the /skin/trinidad/images directory.

Second, we need to make sure that our Apache Trinidad application is aware of the custom skin. This is done by adding a configuration file to the WEB-INF directory called trinidad-skins.xml (the name of the file is a leftover from the Oracle donation and will soon be renamed to comply with the Apache Trinidad's naming conventions). The content of our trinidad-skins.xml file looks like Listing 2.

Register a Custom Skin
The <id> element in the trinidad-skins.xml can be used to reference a skin in an EL expression. For example, if you want to have different skins for different locals, you can create an EL expression that will select the correct skin based on its ID.

The <family> element configures an application to use a particular family of skins. This allows you to group skins together for an application, based on the render kit used.

The <render-kit-id> determines which render-kit to use for the skin. You can enter one of the following:

  • org.apache.myfaces.trinidad.desktop: the skin will automatically be used when the application is rendered on a desktop.
  • org.apache.myfaces.trinidad.pda: the skin will be used when rendered on a PDA.
The <style-sheet-name> element defines the path to the custom CSS file.

Configuring an Application to Use a Custom Skin
When you have created a skin and are ready to use it, you need to make your application aware of it by defining which skin to use in the trinidad-config.xml file. You set an element in the trinidad-config.xml file that determines which skin to use, and, if necessary, under what conditions.

<?xml version="1.0" encoding="windows-1252"?>
< trinidad-config xmlns="http://myfaces.apache.org/trinidad">

<skin-family>#{sessionScope.skinFamily == null ? "minimal" : sessionScope.skinFamily }</skin-family>

<debug-output>true</debug-output>

</ trinidad-config>
If you only have one skin for your application, you only need to replace the <skin-family> value with the family name for the skin(s) you wish to use.

<skin-family>trinidad</skin-family>

To conditionally set the skin-family value, you can enter an EL expression that can be evaluated to determine the skin to display. For example, if you want to use the German skin if the user's browser is set to the German locale, and use the English skin otherwise, you could have the following entry in the adf-faces-config.xml file.

<skin-family>#{facesContext.viewRoot.locale.language=='de' ? 'german' : 'english'}</skin-family>

In our sample application, we are going to use a selectOneChoice component to switch skins at runtime. For this we need to define the following in the trinidad-config.xml file with:

<skin-family>#{sessionScope.skinFamily == null ? "minimal" : sessionScope.skinFamily }</skin-family>

The actual component that will perform the actual switching at runtime looks like this:

<tr:selectOneChoice label="Select Skin" value="#{sessionScope.skinFamily}" onchange="form.submit();">
   <tr:selectItem label="Simple" value="simple"/>
   <tr:selectItem label="Minimal" value="minimal"/>
   <tr:selectItem label="Trinidad" value="trinidad"/>
   <tr:selectItem label="MyCompany" value="mycompany"/>
</tr:selectOneChoice>

The onchange event handler will perform a form POST whenever a skin is selected in the selectOneChoice component. Alternatively, you can add a commandButton to the page that will re-submit the page. Every time there is a POST, the EL expression will be evaluated, and if there is a new value, redraw the page with the new skin. 

Summary
Creating Apache Trinidad skins are easy and using them even easier. An application developer can set a skin based on any criteria using EL expression and JSF backing beans (not shown in this article). This allows application developers to have different skins per user, page, application, and so on, without impacting the actual application logic! We should also take a note that Apache Trinidad is still in incubation as an Apache podling, thus skinning artifacts, such as style selectors discussed in this article, might change in future builds.

More Stories By Jonas Jacobi

Jonas Jacobi is co-founder and chief executive officer of Kaazing Corporation. A native of Sweden, Jacobi has worked in the software industry for more than 15 years with a mission to simplify application development. Prior to founding Kaazing, he worked for Oracle for eight years as a Java EE evangelist and product manager responsible for the product management of JavaServer Faces, Oracle ADF Faces, and Oracle ADF Faces Rich Client in the Oracle JDeveloper team. As co-founder and CEO of Kaazing, Jonas sets the company's business and product strategy and oversees all aspects of Kaazing's operations and mission to become the world-wide leader in real-time software. He is co-author of the best-selling book, "Pro JSF and Ajax: Building Rich Internet Components," (Apress).

More Stories By John Fallows

John Fallows, Co-Founder & CTO of Kaazing Corporation, is a pioneer in the field of rich and highly interactive user interfaces. In his role as chief technology officer, John formulates Kaazing's vision of creating the best real-time web framework based on the Java standard. He defines the architecture of the Kaazing product suite and oversees its development.

Comments (2) View Comments

Share your thoughts on this story.

Add your comment
You must be signed in to add a comment. Sign-in | Register

In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.


Most Recent Comments
janet 12/14/06 03:46:23 PM EST

is the new skinning features going to allow for multiple skins for a component. Such as the selectOneTab. I want it to look two different ways(one flipped upside down and one right side up) but there seems to be no way to do this with the current ADF faces version.

JDJ News Desk 09/24/06 04:42:32 PM EDT

One of the 2006 Soccer World Cup highlights must surely be the Trinidad and Tobago versus Sweden game. The underdogs Trinidad and Tobago managed to push off the onslaught from the Swedish team. The game ended 0-0, which was for the people of Trinidad and Tobago a divine experience - their teams very first World Cup point!