Download as pptx, pdf, or txt
Download as pptx, pdf, or txt
You are on page 1of 82

Advanced Oracle ADF

<Insert Picture Here>

Layout Managers and Skins

Oracle A-Team

Layout Managers

Introduction to layout managers


The case for layout managers
We are not web designers!
Abstraction from HTML (<div>, <table>,
<li>, etc.)
Consistent layout behavior
Consistent behavior across browsers
Manages browser geometry (stretching
and flowing)

Working with layout managers


To stretch or to flow?
Stretching
Maximizes browsers viewport usage
Can also stretch its child components

Flowing
Isolated components not supposed to stretch

Where do I start?
Start with a stretchable outer frame
Inside this frame, have flowing islands, e.g., scrollable areas

Stretchable UI example

Flowing (fixed size) UI example

UI layout with JSF general tips


Try to minimize the number of layout
containers on the page. It will make it smaller
and faster.
Minimize the number of components you
need to stretch; it will make the page faster
Use spacer instead of padding/margin*
Use JDev built-in page style gallery
Make sure to test everything in multiple
browsers. Yes, it can still behave differently.
(* instructors note)

The cost of geometry management is directly

Poetry of
Wisdom

related to the complexity of child components.


Therefore, try minimizing the number of child
components that are under a parent geometrymanaged component.
Oracle Fusion Middleware Web User Interface Developer's Guide - Chapter 8, section 8.2.1.

Stretchable Layout Managers

af:panelStretchLayout

af:panelSplitter

af:panelGroupLayout

af:panelDashboard

Flow vs Stretch

You cannot place components that cannot stretch into


facets of a component that stretches its child

Poetry of
Wisdom

components. Therefore, if you need to place a


component that cannot be stretched into a facet of the
panelStretchLayout component, wrap that component
Oracle Fusion Middleware Web User Interface Developer's Guide - Chapter 8, section 8.2.2.

in a transition component that can stretch (eg,


panelGroupLayout=scroll).

Page layout containers cheat sheet


Stretchable by Parent ?

Stretch its children?

panelStretchLayout

YES

YES

panelSplitter

YES

YES

panelGroupLayout
(scroll, vertical)

YES

NO

panelGroupLayout
(default, horizontal)

NO

NO

panelFormLayout

NO

NO

panelBorderLayout

NO

NO

panelDashboard

YES

YES
(inside a grid; see also
panelBox)

panelTabbed

YES

YES
(stretchChildren=first)

ADF Faces Page Layout DONTS


Do NOT embed raw HTML in your pages.
Do NOT use inlineStyle. Use skinning instead or at least a
peer CSS file. Use the af:resource tag
Do NOT try to stretch something vertically when inside of a
flowing (non-stretched) container.
Do NOT specify a height value with percent unit.
Do NOT use the position style.

Do not attempt to stretch any of the

Poetry of
Wisdom

components in the list of components that


cannot stretch by setting their width to 100%.
You may get unexpected results. Instead,
surround the component to be stretched with
Oracle Fusion Middleware Web User Interface Developer's Guide - Chapter 8, section 8.2.2.

a component that can be stretched

panelGroupLayout=vertical

panelGroupLayout=scroll

Deconstructing Facebook

panelGroupLayout=vertical
panelGrouLayout=horizontal

panelStretchLayout

Leverage JDeveloper Quick Layouts!

Page Templates

Page Templates

Provides layout and behavior

Layout

Uses default ADF Faces layout managers

Can have custom facets for content stamping

Template is referenced, not compiled: easy to change at design time and run time

Behavior

Can have bindings

Can have attributes

Code review

Switching the template dynamically


<af:pageTemplate
<af:pageTemplate id=pt1
id=pt1 viewId=#{yourBean.templateURI}>
viewId=#{yourBean.templateURI}>
<f:facet
<f:facet name=Master>[]
name=Master>[]
</f:facet>
</f:facet>

public
public class
class YourBeanClass{
YourBeanClass{ []
[]
</af:pageTemplate>
</af:pageTemplate>
public
public String
String getTemplateURI(){
getTemplateURI(){
//Add
//Add your
your dynamic
dynamic code
code here
here
return
return /yourPageTemplate.jspx;
/yourPageTemplate.jspx;
}} []
[]

TIP: viewId attribute can never be null; always use a fallback EL:
viewId=#{empty bean.template ? /defaultTemplate.jspx : beanTemplate}

}}

How JavaServer Faces Renders the UI


JavaServer Faces components are display
agnostic
Know about state
Know about behavior

The component display is device specific


handled by component renderers
External classes
One renderer per component
Device related renderers are grouped to renderer kits

To customize a layout you don't change the


renderer
ADF Faces provides CSS hooks instead

ADF Faces Rich Client Components


MODEL

UI RENDERING
ADF Ajax Page Lifecycle

ADF Binding
Expr. Language

ADF DataControl

bindings Object

Ajax Render
Kit

EJB 3.0

Web Service

BPEL

UI Component

Client
RDBMS

About Skins
A skin is a style sheet based on the CSS 3.0 syntax that is
specified in one place for an entire application
Developers can change the styles, icons, properties, and text of
an ADF Faces component using skinning
Skins use CSS to define the layout of ADF Faces and Trinidad
components
Do not operate on HTML elements
Use component selectors

Consistent change of the application look and feel


Skins are located relative to public_html directory
Skins consist of
CSS file
Images
Localized strings

About Skins
Any changes to the skin is picked up at runtime
No change to code is needed

With custom skins, the component's default css styles like color,
font, background-images, images , default text strings and
component properties can be changed
Each component has skinning 'hooks'
Also known as keys or selectors
Define what pieces of a component you can skin

Skin information can be created for a particular agent or


reading direction
Skins automatically transform into the appropriate CSS-2 page
and component styles
Skins can be switched dynamically at runtime

Skin Examples

Skin Examples

<Insert Picture Here>

Cascading Style Sheets


Basics

Cascading Style Sheets (CSS)


W3C Standard
Current Version is CSS 3
Separates Markup from Presentation
Stores presentation definition in central
location
Helps reducing HTML page sizes
Cascading rules define that local definitions
overrule global rules

Document Object Model


Document Object Model (DOM) is a W3C
specification and represents an in memory
hierarchy representation of the page
In web pages, components may be nested in
other components
CSS definitions set on the inner component
precede the definition on the parent
component
If the parent component has defined styles that are not
explicitly overridden on the child component, then the child
component inherits this style

Styles are added through styling rules that


impact a single component or many at once

CSS Rules
CSS rules are applied to elements, attributes
or ID selectors as property-value pairs
Selector{attribute:value; attribute2:value}
h1{color:red; background:yellow}

Rules can be grouped


h1, h2, h3 {color:red; background:yellow}

Element selectors
Markup identifers like table, h1, h2, h3, button etc

Class selectors
.someClassName{color:red}
<p class="someClassName" >
h1.someClassName{color:red}

CSS Rules
ID selectors
#SomeId {color:red}
<p id="SomeId">
Can only be used once per document because it is a unique
identifier

Attribute selectors
h1 [class] references all <h1> elements that have a "class"
attribute
h1 [class = "value"] references all <h1> elements that have a
"class" attribute with exact the iven vaue
Allows to reference attributes with partial value matches as
well

CSS Pattern Matching

Source: http://www.w3.org/TR/REC-CSS2/selector.html

CSS in ADF Faces


ContentStyle
controls the width of a form
control
Styles "box around value"
Works for

Input components
listboxes
Choices
richTextEditor
Shuttle
contentStyle applied to
each list in a shuttle

CSS in ADF Faces


StyleClass
Can be used in conjunction with
skinning
Applies styles to the root DOM
element
Can use EL for context specific
CSS

InlineStyle
Styles the root DOM element
Can use EL for context specific
CSS

Adding Inline Styles Dynamically

Reference InlineStyle string in


managed bean method using EL
In managed bean, access table cell
value and determine CSS to return
Salary > 1000
background-color:green
width: 100 %
height: 100 %
Salary > 5000
background-color:orange
width: 100 %
height: 100 %
Salary > 10000
background-color:red
width: 100 %
height: 100 %

<Insert Picture Here>

ADF Faces Skinning


Basics

How Skinning Works


ADF Faces skins are created as server side
CSS files using defined ADF Faces
component Selectors
The skinning framework processes the skin
file and generates regular CSS-2 documents
that are linked to the rendered page
Skin selectors are resolved to CSS classes
af:inputText::label to af_inputText_label

Skinning vs. CSS


In CSS the <p> element is styled
P {color: red }

In ADF Faces the af:inputText component is styled using a skin


selector
af|inputText {color:red }

To skin pieces of a component, CSS uses the pseudo-element


syntax
p::first-line { text-transform: uppercase }

Pseudo-elements also exist in ADF Faces components like


inputText
The entire component: af|inputText {...}
The label: af|inputText::label {}
The content (the input): af|inputText::content {}

Artefacts
A skin consists of the following artifacts:
A CSS file that defines the actual look of the components
A configuration file trinidad-skins.xml - that lists all skins
available for this application
trinidad-skins.xml has to be located in your applications
WEB-INF directory
An entry in the ADF Faces configuration file trinidad
-config.xml
Any other resources need to create the actual look of the
componets - additional CSS files, Images

<Insert Picture Here>

Developing Custom Skins

Skinning is artwork. You cannot teach good


taste, but you can show the techniques to
achieve the goal

How-to build Custom Skins


Consult the skin-selectors.html page for all
skinning keys defined for each component
and global keys
Creates a skinning .css file that uses the
skinning keys to style the icons, properties,
and styles
The CSS file for your skin must be stored
under the root of your Web application
Make sure that all resources like images and
other CSS files required for the skin are
accessible

How-to build Custom Skins


Create a trinidad-skins.xml that gives the skin
an id, family, render-kit-id, resource bundle
Set the trinidad-config.xml's <skin-family>
element value to the skin family name
Place trinidad-skins.xml into WEB-INF
directory or a JAR file's META-INF directory

Configuration in trinidad-config.xml
Static name
<trinidad-config
xmlns="http://myfaces.apache.org/trinidad/config">
<skin-family>custom_de</skin-family>
</trinidad-config>

Expression
<trinidad-config
xmlns="http://myfaces.apache.org/trinidad/config">
<skin-family>
#{facesContext.viewRoot.locale.language =='de' ?'custom_de' :
</skin-family>
</trinidad-config>

'custom_en'}

Skin Configuration Elements


<id>
Used when referencing a skin in an EL expression

<family>
Configures an application to use a particular family of skins

<extends>
Extends an existing skin

<render-kit-id>
Determines render kit to use for the skin
org.apache.myfaces.trinidad.desktop
org.apache.myfaces.trinidad.pda

<style-sheet-name>
Fully qualified path to the custom CSS file

<bundle-name>
Not needed if no custom resource bundle exists

trinidad-skins.xml Example
<?xml version="1.0" encoding="ISO-8859-1"?>
<skins xmlns="http://myfaces.apache.org/trinidad/skin">
<skin>
<id>blafplus-rich-extended.desktop</id>
<family>blafplus-rich-extended</family>
<render-kit-id>org.apache.myfaces.trinidad.desktop
</render-kit-id>
<style-sheet-name>
skins/blafplus-rich-extended.css
</style-sheet-name>
<extends>blafplus-rich.desktop</extends>
<bundle-name>AdcsResourceBundle</bundle-name>
</skin>
</skins>

Creating a Custom Resource Bundle


Replace default string labels of ADF Faces
Component labels
Validator message text

Create message bundle class


Extending java.util.ListResourceBundle
public class AdcsResourceBundle extends ListResourceBundle {

public Object[][] getContents() { return contents; }

static final Object[][] contents =


{
{"af_dialog.OK","Okay"},
{"af_panelWindow.CLOSE", "Close"},
{"af_document.SPLASH_SCREEN_MESSAGE","Hello and Welcome"}};
}

Inherit from Selector


-tr-rule-ref
Avoids CSS code duplication
Improves readability
.DarkBackground:alias{background-color:#323232}
.MediumBackground:alias{background-color:#707070}

af|document{
-tr-rule-ref:selector(".DarkBackground:alias");
}
af|panelTabbed::body {
-tr-rule-ref:selector(".MediumBackground:alias");
}

Inhibit Inheritance
-tr-inhibit
inhibits styles from a base skin
-tr-inhibit:all
-tr-inhibit:background-color
-tr-inhibit:
af|document::splash-screen-content{
-tr-inhibit:background-image;
-tr-inhibit:background-repeat;
border:transparent;
background-color:transparent;
}

Skinning Keys
Skin Selector
A skin key is used to style a component or components in an
application, not a particular instance
A skin key usually starts with af|, contains the name of the
component, the piece of the component to skin, via a pseudoelement
::label
::content
::read-only

A skin key might look like styleclass, but ends with :alias
skin keys can only be used in a Skinning CSS file
Skin key cannot be used in a component's styleClass attribute

Connecting the Dots


"."
Do not use leading dot for selectors
Do not use leading dot in styleclass properties
Use to define style class in CSS files

":"
Refers to a CSS element of an ADF Faces or Trinidad component

"::"
Refers to a part of the component
af|inputText::content

Mixing styles
af|panelHeader af|inputText:content
Refers to the content part of a textfield in a panelHeader

Functionality Available to "Skinners"


Skinning keys to skin pieces of a component, including icons
Resource bundle keys to skin text of a component
@platform {/skin definitions go here/}
Possible values are: windows, macos, linux, solaris, ppc
Does not work for icons

@agent {/skin definitions go here/} - >


Possible values are: netscape, ie, mozilla, gecko, webkit , ice
Does not work for icons

:lang or :locale
:rtl pseudo-class to create a style or icon definition when the
browser is in a right-to-left language
:alias skinning keys

Using Images in Skins


Absolute
.AFErrroIcon:alias {content: url(http://foo.com/images/err-logo.gif)};

Relative
No protocol and no leading "/"
.AFErrroIcon:alias {content: url(images/err-logo.gif)};

Context relative
Resolved relative to the web application context root
Starts with a single "/"
.AFErrroIcon:alias {content: url(/images/err-logo.gif)};

Relative to server
Allows to reference resources that are not part of the application
deployment
URL starts with "//"
.AFErrroIcon:alias {content: url(//<folder>/images/err-logo.gif)};

Skin Custom Tree Icons

af|tree::expanded-icon
{
content: url(/skins/mycompany/skin_images/expand.gif);
width:16px;
height:16px;
}

af|tree::collapsed-icon
{
content: url(/skins/mycompany/collapse.gif);
width:16px;
height:16px;
}

<Insert Picture Here>

JDeveloper Skinning Support

Skin Development Support


Code editing support
ADF Faces Skin Extension
Tool > Preferences >CSS
Editor
Check ADF Faces Extension

Syntax Help
Image selection
Code Completion
E.g. type "af|inputr" then press
ctrl+Enter

Code Folding
Collapses CSS style definitions
Mouse-over code info

Syntax Help

Skin Development Support

Structure Window Support

Classes
Elements
ID
Use to navigate and
uncomment entries

Error Margin
E.g. syntax error

Theme
Provide a consistent look and feel
across multiple components for a
portion of a page
A component that sets a theme,
exposes that theme to its children
components
Common usage for themes is in a
page template where certain areas
have a distinct look

af:document
af:decorativeBox
af:panelStretchLayout
af:panelGroupLayout

Theme

A theme is exposed to skinning


developers as an attribute
af|panelTabbed[theme="dark"] {color: red;}

<af:document theme="dark">
<af:panelTabbed>...</af:panelTabbed>
</af:document>

BLAF+ skins that provide theme


support are medium and rich
desktop skins

dark
medium
light
none (default)

Theme
Enabling themes in web.xml
<context-param>
<param-name>
oracle.adf.view.rich.tonalstyles.ENABLED
</param-name>
<param-value>false</param-value>
</context-param>

<Insert Picture Here>

Component Skin Example

PanelBox Skin Selectors


The panelBox component has attributes "ramp" and "background"
to provide 8 color schemes
:core :highlight
:default, :light, :medium, :dark
Example: af|panelBox::header-center:core:medium

Skin selectors
af|panelBox, af|panelBox::header-start, af|panelBox::header-center, af|
panelBox::header-end,af|panelBox::content,af|panelBox::icon-style, af|
panelBox::disclosure-link,

Alias

.AFPanelBoxHeaderCoreDefault:alias
.AFPanelBoxContentCoreDefault:alias
.AFPanelBoxHeaderCoreLight:alias
.AFPanelBoxContentCoreLight:alias
more ...

PanelBox Component Skin Example


af|panelBox {width:80%;}
af|panelBox::content {height: 200px;}
af|panelBox::header-start:core:default
{background-image:
url(/skins/images/ccont_p_header_start.png;
}
af|panelBox::header-center:core:default
{background-image:
url(/skins/images/ccont_p_header_bg.png);}
af|panelBox::header-end:core:default
{background-image:
url(/skins/images/ccont_p_header_end.png);}

<af:panelBox
icon="/skins/images/guy.gif"
text="PanelBox Skinned">
<f:facet name="toolbar"/>
</af:panelBox>

PanelBox Component Instance Skin


Example
Use additional styleClass
property value
Class name doesn't need to
exist

Use style class name with


skin selector
.panelBoxInstanceClass af|
panelBox::disclosure-link
{
display:none;
}

<af:panelBox
icon="/skins/images/guy.gif"
text="PanelBox Instance Skinned"
styleClass="panelBoxInstanceClass">
<f:facet name="toolbar"/>
</af:panelBox>

<af:panelBox
icon="/skins/images/guy.gif"
text="PanelBox - Skinned">
<f:facet name="toolbar"/>
</af:panelBox>

Contextual Skins
Instance specific skins that are based on the
page the component is in
Components that are added on a template
may need to be skinned based on the context
they are in
Use styleClass property on component
Reference class property by EL
Use Template parameters if componen part of a template

Resolve context in managed bean

Contextual Skins
Example: references the current view ID for instance specific
skinning of a PanelBox that is part of a template
<af:panelBox styleClass="#{attrs.viewIdString}">

template
<attribute>
panelBox

<attribute-name>viewIdString</attribute-name>
<attribute-class>java.lang.String</attribute-class>
<default-value>"NONE"</default-value>
<required> true</required>

page3

page2

page1
</attribute>

panelBox

panelBox

panelBox
<f:attribute name="viewIdString" value="#{bean.viewId}"/>

CSS:
page1 af|panelBox::header-center:core:default
{background-image: url(/skins/images/ccont_p_blue_header_bg.png);}
af|panelBox::header-center:core:default
{background-image: url(/skins/images/ccont_p_header_bg.png);}

public String getViewId() {


FacesContext fctx = FacesContext.getCurrentInstance();
String viewID = fctx.getViewRoot().getViewId();
return viewID.substring(1); }

Changing the Splash Screen


The Splash Screen can be skinned
Change image
Change load message
Change background color
af|document::splash-screen-content{background-color:Green;}
af|document::splash-screen-icon {content:url("../images/cow.gif");}

From ...

To ...

Skin the Unskinnabel


Some of the generated HTML is not
accessible by a skin selector because it is an
implementation detail of the component
rendering
How to skin a generated HTML fragment
anyway?
Use your CSS knowledge
HTML Body

<body class="af_document p_AFMaximized">


...
First DIV

<div id="j_id__ctru1">
...
</div>

Skin CSS

af|document > div { ... }

<Insert Picture Here>

Skin Deployment

Option 1: Adding the Skin Sources to


the Application Sources
The Skin definition file is contained in the application's
WEB-INF directory
Trinidad-skins.xml
The skin CSS is located in the application's PUBLIC_HML
directory
The images are located relative to the CSS file
In PUBLIC_HTML directory
Subfolder of PUBLIC_HTML directory
Subfolder of CSS folder
All sources are deployed with the application
Easy to do but hard to maintain if a consistent look and
feel should be ensured across applications

Option 2: Deploying a Custom Skin in


a JAR file
A skin can be deployed and developed separately from the
application
Specific rules must be followed when creating the JAR file
The trinidad-skin.xml file that defines the skin and that
references the CSS file must be within the META-INF
directory
All image resources and CSS files too must be under the
META-INF directory
The images - and this is important - must be in a
directory that starts with an "adf" root directory or any
directory name that is mapped in the web.xml file for the
resource servlet.
Place the JAR file in the WEB-INF/lib directory of the
ViewLayer project of the application to deploy

How-to: Deploy Custom Skins in JAR (I)


Create a directory structure similar to the
following
c:\temp\META-INF\adf\oracle\skin\images
META-INF\skins\custom.css
META-INF\trinidad-skins.xml

The image directory in the META-INF


directory must start with "adf" or whatever
string that is defined as the resource loader
path in web.xml
af|inputColor::swatch-overlay-icon:rtl {
content:url(../adf/oracle/skin/images/cfsortl.gif);
width: 12; height: 12;
}

How-to: Deploy Custom Skins in JAR (II)


trinidad-skin.xml file in the META-INF
directory has the following content
Example to create "custom" skin
<?xml version="1.0" encoding="ISO-8859-1"?>
<skins xmlns="http://myfaces.apache.org/trinidad/skin">
<skin>
<id>custom.desktop</id>
<family>custom</family>
<render-kit-id>org.apache.myfaces.trinidad.desktop</render-kit-id>
<style-sheet-name>skins/custom.css</style-sheet-name>
</skin>
</skins>

How-to: Deploy Custom Skins in JAR (III)


Create jar file
jar -cvf customSkin.jar META-INF/

Copy JAR file to WEB-INF\lib


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

<Insert Picture Here>

Example: Skin Discovery at Runtime

Changing Skins at Runtime


Managed Bean
<managed-bean>
<managed-bean-name>skinChooserHandler</managed-bean-name>
<managed-bean-class>view.SkinChooserHandler</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>

Trinidad Config file

<trinidad-config xmlns="http://myfaces.apache.org/trinidad/config">
<skin-family>#{sessionScope.skinFamily}</skin-family>
</trinidad-config>

SelectOneChoice
<af:selectOneChoice id="skinSelector"
label="Select Skin"
value="#{sessionScope.skinFamily}">
<f:selectItems value="#{skinChooserHandler.SkinChoices}"/>
</af:selectOneChoice>

Discover Skins at Runtime Example

public class SkinChooserHandler {


public SkinChooserHandler() {
// Set the default skin to be "blafplus-rich"
ADFContext adfctx = ADFContext.getCurrent();
Map sessionScope = adfctx.getSessionScope();
sessionScope.put("skinFamily", "Oracle");
}
...
}

Discover Skins at Runtime Example


public List getSkinChoices() {
List choices = new ArrayList();
String skinFamily;
String skinLabel;
SkinFactory sf = SkinFactory.getFactory();
FacesContext context = FacesContext.getCurrentInstance();
Locale locale = context.getViewRoot().getLocale();
for (Iterator i = sf.getSkinIds(); i.hasNext(); ) {
String skinID = (String)i.next();
Skin skin = sf.getSkin(context, skinID);
skinFamily = skin.getFamily();
if (skin.getRenderKitId().indexOf("desktop") > 0) {
choices.add(new SelectItem(skinFamily, skinLabel));
}
}
return choices;
}

Product Demonstration

Skin Discovery and Setting at Runtime

<Insert Picture Here>

Skin Debugging

Disable Content Compression


web.xml
<context-param>
<param-name>
org.apache.myfaces.trinidad.DISABLE_CONTENT_COMPRESSION
</param-name>
<param-value>true</param-value>
</context-param>

Firebug
Use within FireFox
Inspect and edit HTML
View and Visualize CSS
Instantly change CSS definitions
Exploring the DOM tree
Execute JavaScript
https://addons.mozilla.org/firefox/1843/

Web Developer PlugIn


Firefox and Mozilla
Menu and a toolbar various
web developer tools
http://chrispederick.com/work
/web-developer/

You might also like