Friday, March 12, 2010

ADF Faces RC: Grab that ADF Skins in 5 minutes

In this post, I applied skinning to the accompanying demo application (UIShellSherman_V02)of the ADF UI Shell to demonstrate how easy it is to apply skinning into an existing ADF application . You can do the same into your current application in just a matter of 5 minutes by following this blogpost. Impress your boss now! :D
Oracle ADF Faces RC has the following skins which could jump-start implementation of skinning into your application:
  • fusion

  • rainforest

  • sporty

  • princess

  • blafplus-rich
  • blafplus-medium
  • fusion projector
  • simple

Before you start the steps below, be sure that you have an extracted copy of the latest adffacesdemo. You can download the same here.

The time starts now...

To apply skinning into your app, do the following:
  1. Copy the skins folder of adffacesdemo.
  2. Copy the trinidad-skins.xml of the adffacesdemo
  3. Add additional "skinFamily" string attribute into your existing session scope managed bean that holds user session information.
  4. Add a skin menu into your menu bar.

Copy the skins folder of adffacesdemo

Copy the skins folder of adffacesdemo located in .../adffacesdemo/public_html and paste it into the public_html directory of your application.

Copy the trinidad-skins.xml of the adffacesdemo

Copy the trinidad-skins.xml of the adffacesdemo located in .../adffacesdemo/public_html/WEB_INF folder and paste the same on the same directory in your application

Add additional "skinFamily" string attribute into your existing session scope managed bean

You can add the "skinFamily" string attribute into an existing session scope manage bean that holds user session information. If nothing is applicable, you can create something like the following class and declare it as a session scope managed bean in adfc-config.xml
package soadev.view.managed;

import java.io.IOException;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import oracle.adf.view.rich.component.rich.nav.RichCommandMenuItem;

public class UserSession {
    private String skinFamily;

    public void setSkinFamily(String skinFamily) {
        this.skinFamily = skinFamily;
        reloadThePage();
    }

    public String getSkinFamily() {
        if (skinFamily == null) {
            skinFamily = "fusion";
        }
        return skinFamily;
    }

    public void skinMenuAction(ActionEvent event) {
        RichCommandMenuItem menuItem = (RichCommandMenuItem)event.getComponent();
        setSkinFamily(menuItem.getText());
        reloadThePage();
    }
    
    //taken from adffacesdemo
    public static void reloadThePage() {
        FacesContext fContext = FacesContext.getCurrentInstance();
        String viewId = fContext.getViewRoot().getViewId();
        String actionUrl =
            fContext.getApplication().getViewHandler().getActionURL(fContext,
                                                                    viewId);
        try {
            ExternalContext eContext = fContext.getExternalContext();
            String resourceUrl =
                actionUrl; //eContext.encodeResourceURL(actionUrl);
            // Use the action URL directly since the encoding a resource URL will NPE in isEmailablePage()
            eContext.redirect(resourceUrl);
        } catch (IOException ioe) {
            System.err.println("Problem trying to reload the page:");
            ioe.printStackTrace();
        }
    }  
}

Add a skin menu into your menu bar

Add a skin menu into your existing menu bar plus menuCommandItems for the skins to be supported. Below is a sample menuBar with a skin menu:
    <af:menuBar id="menuBar" styleClass="AFHideSidePadding">
      <af:menu text="Skin" id="ptm1">
        <af:commandMenuItem text="blafplus-rich" type="radio"
                            actionListener="#{userSession.skinMenuAction}"
                            selected="#{userSession.skinFamily=='blafplus-rich'}"
                            id="ptcmi1"/>
        <af:commandMenuItem text="blafplus-medium" type="radio"
                            actionListener="#{userSession.skinMenuAction}"
                            selected="#{userSession.skinFamily=='blafplus-medium'}"
                            id="ptcmi2"/>
        <af:commandMenuItem text="fusion" type="radio"
                            actionListener="#{userSession.skinMenuAction}"
                            selected="#{userSession.skinFamily=='fusion'}"
                            id="ptcmi31"/>
        <af:commandMenuItem text="fusion-projector" type="radio"
                            actionListener="#{userSession.skinMenuAction}"
                            selected="#{userSession.skinFamily=='fusion-projector'}"
                            id="ptcmi31_1"/>
        <af:commandMenuItem text="simple" type="radio"
                            actionListener="#{userSession.skinMenuAction}"
                            selected="#{userSession.skinFamily=='simple'}"
                            id="ptcmi4"/>
        <af:commandMenuItem text="rainforest" type="radio"
                            actionListener="#{userSession.skinMenuAction}"
                            selected="#{userSession.skinFamily=='rainforest'}"
                            id="ptcmi6"/>
        <af:commandMenuItem text="sporty" type="radio"
                            actionListener="#{userSession.skinMenuAction}"
                            selected="#{userSession.skinFamily=='sporty'}"
                            id="ptcmi7"/>
        <af:commandMenuItem text="princess" type="radio"
                            actionListener="#{userSession.skinMenuAction}"
                            selected="#{userSession.skinFamily=='princess'}"
                            id="ptcmi8"/>
      </af:menu>
    </af:menuBar>
Your done? Congratulations! :D

How did I apply it to the accompanying app (UIShellSherman_V02)?

  • I created a global_links.jspx with the following code:
    <?xml version='1.0' encoding='UTF-8'?>
    <jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="2.1"
              xmlns:f="http://java.sun.com/jsf/core"
              xmlns:h="http://java.sun.com/jsf/html"
              xmlns:af="http://xmlns.oracle.com/adf/faces/rich"
              xmlns:trh="http://myfaces.apache.org/trinidad/html">
      <jsp:directive.page contentType="text/html;charset=UTF-8"/>
      <af:panelGroupLayout id="pgl1">
        <af:menuBar id="menuBar" styleClass="AFHideSidePadding">
          <af:menu text="Skin" id="ptm1">
            <af:commandMenuItem text="blafplus-rich" type="radio"
                                actionListener="#{userSession.skinMenuAction}"
                                selected="#{userSession.skinFamily=='blafplus-rich'}"
                                id="ptcmi1"/>
            <af:commandMenuItem text="blafplus-medium" type="radio"
                                actionListener="#{userSession.skinMenuAction}"
                                selected="#{userSession.skinFamily=='blafplus-medium'}"
                                id="ptcmi2"/>
            <af:commandMenuItem text="fusion" type="radio"
                                actionListener="#{userSession.skinMenuAction}"
                                selected="#{userSession.skinFamily=='fusion'}"
                                id="ptcmi31"/>
            <af:commandMenuItem text="fusion-projector" type="radio"
                                actionListener="#{userSession.skinMenuAction}"
                                selected="#{userSession.skinFamily=='fusion-projector'}"
                                id="ptcmi31_1"/>
            <af:commandMenuItem text="simple" type="radio"
                                actionListener="#{userSession.skinMenuAction}"
                                selected="#{userSession.skinFamily=='simple'}"
                                id="ptcmi4"/>
            <af:commandMenuItem text="rainforest" type="radio"
                                actionListener="#{userSession.skinMenuAction}"
                                selected="#{userSession.skinFamily=='rainforest'}"
                                id="ptcmi6"/>
            <af:commandMenuItem text="sporty" type="radio"
                                actionListener="#{userSession.skinMenuAction}"
                                selected="#{userSession.skinFamily=='sporty'}"
                                id="ptcmi7"/>
            <af:commandMenuItem text="princess" type="radio"
                                actionListener="#{userSession.skinMenuAction}"
                                selected="#{userSession.skinFamily=='princess'}"
                                id="ptcmi8"/>
          </af:menu>
        </af:menuBar>
      </af:panelGroupLayout>
    </jsp:root>
    

  • I added a <jsp:include> tag to the globalLinks facet of the pages that implement the ADF UI Shell template. Below is a code snippet:
    <f:facet name="globalLinks">
      <f:subview id="sv1">
        <jsp:include page="/global_links.jspx" flush="true"/>
      </f:subview>
    </f:facet>
    

Conclusion

In this post we learn the following "how tos":
  • How to easily apply skinning into an existing ADF Faces RC application.
  • How to reload a page programmatically.
  • How to use <jsp:include> tag in ADF pages.
Cheers!

5 comments:

  1. hi Pino

    Is it possible that the ZIP file you refer to ...
    at http://download.oracle.com/otn/java/jdeveloper/1112/extensions/rcf-dvt-demo.war
    ... currently does not contain any configuration or resources for the "sporty" skin you mention?

    thanks
    Jan Vervecken

    ReplyDelete
  2. Hi Jan,
    Right now, I cannot 100% confirm if the demo still has sporty skin (I cannot download it now due to slow connection) but I am pretty sure that it has. Be sure you have downloaded the adffacesdemo just lately, because sometime before it did contain the sporty and rainforest skins (only princess).

    Regards,
    Pino

    ReplyDelete
  3. hey pino,
    I am a newbie to adf. I am trying to implement a template similar to what you have here. How do I add a set of dynamic tabs below the current ones(the first activity etc...) It would be great if u jst give an idea or point in a direction where I could explore myself.

    vinit

    ReplyDelete
  4. The temaplte above is based on the Oracle Dynamic tabs template. You can have more info on JDeveloper online help (Be sure to check for updates Help>Check For Updates). You can also read an online version here: http://www.oracle.com/technology/products/adf/patterns/11/uishell.html

    ReplyDelete
  5. well pino,
    I saw your nice blog,
    ADF UI Shell: Customizing the Dynamic Tab Shell Layout
    http://soadev.blogspot.com/2010/03/customising-dynamic-tab-shell.html

    the above one of your blog post comment section is disable.


    in that i had question with you. in that above blog which i mentioned of you. dicuss with customization of ui shell.

    but i had enough time to complete that. so my question is without customize anything in default ui shell template. i want to do some simple changes. how can i do that.


    following threads i had question. please suggest your answer in those threads.

    Thread: logo of jdev
    https://forums.oracle.com/forums
    /thread.jspa?threadID=2315668&tstart=0

    Thread: tab color - differentiation
    https://forums.oracle.com/forums/thread.jspa?threadID=2315145&tstart=0

    Thread: icons,images location for jdev
    https://forums.oracle.com/forums/thread.jspa?threadID=2315557&tstart=0

    Thread: template location.
    https://forums.oracle.com/forums/thread.jspa?threadID=2315097&tstart=0

    ReplyDelete