This chapter describes how to change the appearance of your application by changing style properties using ADF Faces skins and component style attributes.
This chapter includes the following sections:
Section 20.1, "Introduction to Skins, Style Selectors, and Style Properties"
Section 20.4, "Changing the Style Properties of a Component"
JDeveloper supports two options for applying style information to your ADF Faces components:
Build a skin and a cascading style sheet (CSS) using defined style selectors and configure your ADF application to use the skin and style sheet.
Use style properties to override the style information from the skin CSS to set specific instances of component display.
ADF Faces components delegate the functionality of the component to a component class, and 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. You cannot customize ADF Faces renderers. However, you can customize how components display using skins.
If you do not wish to change ADF Faces components throughout the entire application, you can choose to change the styles for the instance of a component on a page. You can also programmatically set styles conditionally. For example, you may want to display text in red only under certain conditions. For more information, see Section 20.4, "Changing the Style Properties of a Component".
The File Explorer application allows you to select several skins from a dropdown list. It provides several CSS files to support skin selection. For more information, see Section 1.4.3, "Overview of the File Explorer Application".
It is beyond the scope of this guide to explain the concept of CSS. For extensive information on style sheets, including the official specification, visit the W3C web site at:
A skin is a style sheet based on the CSS 3.0 syntax specified in one place for an entire application. Instead of providing a style sheet for each component, or inserting a style sheet on each page, you can create one skin for the entire application. Every component automatically uses the styles as described by the skin. You do not have to make design-time changes to JSF pages to change their appearance when you use a skin. You can use the skins provided by ADF Faces or extend these skins to create your own custom skin.
ADF Faces provides the following skins for use in your applications:
blafplus-medium
: Provides a modest amount of styling. This style extends the simple
skin.
blafplus-rich
: This skin extends the blafplus-medium
skin. Provides more styling than the blafplus-medium
skin. For example, graphics in the blafplus-rich
skin have rounded corners.
fusion
: Defines the default styles for ADF Faces components. This skin provides a significant amount of styling.
fusion-11.1.1.3.0
: Modifies the fusion
skin to make the hierarchy structure in certain components that render tabs clearer. These components are panelTabbed
, navigationPane
(attribute hint="tabs"
), and decorativeBox
. This skin also defines a more subtle background image for disclosed panelAccordion
component panes to make text that appears in these panes easier to read.
fusionFx-v1
: This skin extends from the fusion-11.1.1.3.0
skin. Use the following values in the trinidad-skins.xml
file if you want your application to use the fusionFx-v1
skin:
<skin> <id>fusionFx-v1.desktop</id> <family>fusionFx</family> …</skin>
Use the following value in the trinidad-config.xml
file if you want your application to use the fusionFx-v1
skin or a custom skin that extends from it:
<skin-family>fusionFx</skin-family>
The fusionFx-v1
contains design improvements and changes to address a number of issues. Specifically, it adds:
A background color to the .AFMaskingFrame
global style selector to prevent the display of content from an underlying frame when an inline popup displays in certain browsers.
A boolean ADF skin property, -tr-stretch-dropdown-table
, for the inputComboboxListOfValues
component. This property determines whether the table in the dropdown list stretches to show the content of the table columns or limits the width of the table to the width of the input field in the inputComboboxListOfValues
component.
The inlineFrame
component displays an image that serves as a loading indicator until the browser determines that the frame's contents have been loaded.
You can implement this functionality in a custom skin that you create. The af|inlineFrame
selector has "busy
" and "flow
" pseudo-classes that enable you to do this. The inlineFrame
component only generates an IFrame element when the parent component does not stretch the inlineFrame
component (the inlineFrame
component is flowing). Use af|inlineFrame:busy:flow
to define a background-image style that references a loading indicator. When the parent component stretches the inlineFrame
component, the generated content is more complex. This complexity allows you define a content image URL using the af|inlineFrame::status-icon
and an optional additional background-image using the af|inlineFrame::status-icon-style
. It also allows you to reuse images that other component selectors use. For example, the carousel
component's af|carousel::status-icon
and af|carousel::status-icon-style
selectors. Use skinning aliases to reuse these images.
The following global selectors have also been introduced that you can use if you implement this functionality in your ADF skin:
.AFBackgroundImageStatus:alias
: use to reference the background image used in af|inlineFrame::busy:flow
.
.AFStatusIcon:alias
use to reference the af|carousel::status-icon
and af|inlineFrame::status-icon
.
.AFStatusIconStyle:alias
use to reference the af|carousel::status-icon-style
and af|inlineFrame::status-icon-style
.
A resource key (af_inlineFrame.LABEL_FETCHING
) defines the string to display for the inlineFrame
component's loading icon.
Projector skins: ADF Faces provides skins that define styles for an application that you want to demonstrate to an audience using a projector. Each projector skin modifies a number of elements in its parent skin so that an application renders appropriately when displayed using table-top projectors (particularly older models of projector). For example, the fusion-projector
skin modifies a number of elements in the fusion
skin. These skins are useful if the audience is present at the same location as the projector. They may not be appropriate for an audience that views an application online through a web conference. ADF Faces provides the projector skins as a download from the Oracle Technology Network (OTN) web site.
Skins allow you to globally change the appearance of ADF Faces components within an application. By default, ADF Faces applications use the fusion
skin. Components in the visual editor, as well as in the web page, are displayed using the settings for this skin. Figure 20-1 shows the default fusion
skin applied to the File Explorer Application index page.
Note:
The syntax in a skin style sheet is based on the CSS 3.0 specification. However, many browsers do not yet adhere to this version. At runtime, ADF Faces converts the CSS to the CSS 2.0 specification.ADF Faces also provides the simple
skin, shown in Figure 20-2 as applied to the File Explorer Application index page.
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. For example, you can customize the skin file using rules and pseudo classes that are supported by the skinning framework. Supported rules and pseudo classes include @platform
, @agent
, @accessibility-profile
, :rtl
, :lang
, and @locale
. For more information, see Section 20.1.2, "Skin Style Selectors".
Style sheet rules include a style selector, which identifies an element, and a set of style properties, which describe the appearance of the components. ADF Faces components include two categories of skin style selectors:
Global selectors determine the style properties for multiple ADF Faces components. If the global selector name ends in the :alias
pseudo-class, then the selector is most likely included in other component-specific selectors and will affect the skin for more than one component. For example, most, if not all, components use the .AFDefaultFontFamily:alias
definition to specify the font family. If your skin overrides this selector with a different font family, that change will affect all the components that have included it in their selector definition. Example 20-1 shows the global selector for the default font family for ADF Faces components in an application.
Component selectors
Component-specific selectors are selectors that can apply a skin to a particular ADF Faces component. Example 20-2 shows the selector set to red as the background color for the content area of the af:inputText
component.
Each category may include one or more of these types of ADF Faces skin selectors:
Standard selectors
Standard selectors are those that directly represent an element that can have styles applied to it. For example, af|body
represents the af:body
component. You can set CSS styles, properties, and icons for this type of element.
Selectors with pseudo-elements
Pseudo-elements are used to denote a specific area of a component that can have styles applied. Pseudo-elements are denoted by a double colon followed by the portion of the component the selector represents. For example, af|chooseDate::days-row
provides the styles and properties for the appearance of the dates within the calendar grid.
Some components render icons (<img>
tags) using a set of base icons. These icons can have skins applied even though no entries appear in the CSS source file for the icons in the way, for example, that entries appear for the background-image
CSS property. Instead, the icons are registered with the Skin
object for use by the renderer. As no entries for an icon selector appear in the CSS source file that a browser interprets, you cannot create containment selector definitions for an icon definition. You can only create a containment selector definition for items that have an entry in the CSS source file.
Icon selectors are denoted by -icon
for component selectors and Icon:alias
for global selectors. For example, the af:inputDate
component has a changed icon that can have a skin using the selector af|inputDate::changed-icon
. The changed icon can also be globally set for all components using that icon with the global selector .AFChangedIcon:alias
. For more information, see Section 20.3.2, "How to Apply Skins to Icons".
The text rendered by ADF Faces components is translatable. The text is abstracted as a resource string that has skins applied. For example, af_dialog.LABEL_OK
is a resource string for the text label of an af:dialog
component when the OK button has been configured. Resource strings do not have skins in the CSS skin file, but in a resource bundle referenced from the skin definition file in the trinidad-skins.xml
file using the <bundle-name>
parameter. You can also use the <translation-source>
parameter for an EL binding to point to a Map
or ResourceBundle
. For more information, see Section 20.3.1, "How to Apply Skins to Text".
Selectors with style properties
Skin style properties allow you to customize the rendering of a component throughout the application. A CSS property is stored with a value in the Skin
object and is available when the component is being rendered. For example, in af|breadCrumbs{-tr-show-last-item: false}
, the skin property -tr-show-last-item
is set to hide the last item in the af:breadCrumbs
navigation path.
The CSS specification defines pseudo-classes such as :hover
and :active
that can apply to almost every component. ADF Faces provides additional pseudo-classes for specialized functions. Pseudo-classes are denoted in the selector by a colon followed by the class definition. The following are common pseudo-classes used by ADF Faces style selectors:
Alias: The :alias
pseudo-class is a special type of class that serves as a syntax aid to organize code in your skin file. You can, for example, use it to set styles for more than one component or more than one portion of a component. You can also create your own alias classes that you can then include on other selectors. For example, you can define an alias pseudo-class (.AFLabel:alias
) where you define label colors for a number of form components. Subsequent changes to the alias pseudo-class impact all components referenced by the alias pseudo-class.
af|inputText::label, af|inputChoice::label, af|selectOneChoice::label {-tr-rule-ref: ".AFLabel:alias"} .AFLabel:alias { color: blue }
The .AFLabel:alias
pseudo-class has color set to blue, but you can change all the component's label color to red by simply changing .AFLabel:alias
:
.AFLabel:alias {color: red}
For more information, see Section 20.3.5, "How to Create a Custom Alias".
Drag and drop: The two pseudo-classes available are :drag-source
applied to the component initiating the drag and removed once the drag is over, and :drop-target
applied to a component willing to accept the drop of the current drag.
Standard: In CSS, pseudo-classes like :hover,
:active
, and :focus
are considered states of the component. This same concept is used in applying skins to components. Components can have states like read-only
or disabled
. When states are combined in the same selector, the selector applies only when all states are satisfied.
Right-to-left: Use this pseudo-class to set a style or icon definition when the browser is in a right-to-left language. Another typical use case is asymmetrical images. You will want the image to be flipped when setting skin selectors that use the image in a right-to-left reading direction. Be sure to append the :rtl
pseudo-class to the very end of the selector and point it to a flipped image file. For example, the end image of the panelBox
component will be the panelBoxStart.png
file when the browser is set to right-to-left. The panelBox
end image in right-to-left is the same as the flipped left-to-right panelBox
start image.
af|panelBox::medium af|panelBox::top-end:rtl { background-image: url(/skins/purple/images/panelBoxStart.png); width:8px; height:8px }
You can also use :rtl
to apply to skin icons. For more information, see Section 20.3.2, "How to Apply Skins to Icons".
Inline editing: This pseudo-class is applied when the application activates a component subtree for editing in the browser. For example, :inline-selected
is a pseudo-class applied to currently selected components in the active inline-editable subtree.
Message: This pseudo-class is used to set component-level message styles using CSS pseudo-classes of :fatal
, :error
, :warning
, :confirmation
, and :info
. For more information, see Section 20.3.3, "How to Apply Skins to Messages".
You may not want your selector's CSS properties to be applied to all browsers, all platforms, all locales, and both reading-directions. For example, you may need to add some padding in Internet Explorer that you do not need on any other browser. You may want the font style to be different on Windows than it is on other platforms. To style a selector for a particular user environment, put that skinning information inside a skinning framework rule or :rtl
pseudo-class. The skinning framework picks the styles based on the HTTP
request information, such as agent and platform, and merges them with the styles without rules. Those CSS properties that match the rules get merged with those outside of any rules. The most specific rules that match a user's environment take precedence. The skinning framework currently supports these rules and pseudo-classes:
@platform
and @agent
Define platform styles using @platform
and browser styles using @agent
.
The supported values to set a platform-specific style are windows
, macos
, linux
, solaris
, and ppc
. For a browser agent-specific style, the supported values are ie
, mozilla
, gecko
, webkit
(maps to safari), ice
, and email
.
In this example, the content area of the af:inputText
component is set to the color pink for versions 7 and 8 of Internet Explorer, and set to version 1.9 of gecko
on Windows and Linux platforms:
@platform window, linux { @agent ie and (version: 7) and (version: 8), gecko and (version: 1.9) { af|inputText::content {background-color:pink } } }
Note that the following syntax examples results in the same behavior:
@agent ie and (version: 7.*) @agent ie and (version: 7)
In order to specify only version 7.0.x of Internet Explorer, use the following syntax:
@agent ie and (version: 7.0)
There is currently no syntax to specify a range of versions.
@accessibility-profile
Define @accessibility-profile,
which defines styles for high-contrast and large-fonts accessibility profile settings from the trinidad-config.xml
file.
The high-contrast value would be for cases where background and foreground colors need to be highly contrasted with each other. The large-fonts value would be for cases where the user must be allowed to increase or decrease the text scaling setting in the web browser. Defining large-fonts does not mean that the fonts are large, but rather that they are scalable fonts or dimensions instead of fixed pixel sizes.
<!-- Enable both high-contrast and large-fonts content --> <accessibility-profile>high-contrast large-fonts</accessibility-profile>
:rtl
Use the :rtl
pseudo-class to create a style or icon definition when the browser is displaying a right-to-left language.
:lang
or @locale
Suppress skin styles with the -tr-inhibit
skin property.
Suppress or reset CSS properties inherited from a base skin with the -tr-inhibit
skin property. For example, the -tr-inhibit:padding
property will remove any inherited padding. Remove (clear) all inherited properties with the -tr-inhibit:all
property. The suppressed property name must be matched exactly with the property name in the base skin.
Merge styles with the -tr-rule-ref
property.
Create your own alias and combine it with other style selectors using the -tr-rule-ref
property. For more information, see Section 20.3.5, "How to Create a Custom Alias".
Alter themes of child components with the -tr-children-theme
property.
For more information, see Section 20.3.4, "How to Apply Themes to Components".
Example 20-3 shows several selectors in the CSS file that will be merged together to provide the final style.
Example 20-3 Merging of Style Selectors
/** For IE and Gecko on Windows, Linux and Solaris, make the color pink. **/ @platform windows, linux, solaris { @agent ie, gecko { af|inputText::content {background-color:pink} } } af|someComponent {color: red; width: 10px; padding: 4px} /* For IE, we need to increase the width, so we override the width. We still want the color and padding; this gets merged in. We want to add height in IE. */ @agent ie { af|someComponent {width: 25px; height: 10px} } /* For IE 7 and 8, we also need some margins.*/ @agent ie (version: 7) and (version: 8) { af|someComponent {margin: 5px;} } /* For Firefox 3 (Gecko 1.9) use a smaller margin.*/ @agent gecko (version: 1.9)\ { af|someComponent {margin: 4px;} } /* The following selectors are for all platforms and all browsers. */ /* rounded corners on the top-start and top-end */ /* shows how to use :rtl mode pseudo-class. The start image in ltr mode is the */ /* same as the end image in the right-to-left mode. */ af|panelBox::medium af|panelBox::top-start, af|panelBox::medium af|panelBox::top-end:rtl { background-image: url(/skins/purple/images/panelBoxStart.png); width:8px; height:8px } af|panelBox::medium af|panelBox::top-end, af|panelBox::medium af|panelBox::top-start:rtl { background-image: url(/skins/purple/images/panelBoxEnd.png); height: 8px; width: 8px; }
The selectors used to apply skins to the ADF Faces components are defined in the "Skin Selectors for Fusion's ADF Faces Components" and "Skin Selectors for Fusion's Data Visualization Tools Components" topics in JDeveloper's online help.
You can also apply themes as a way to implement look and feel at the component level. For information about themes, see Section 20.3.4, "How to Apply Themes to Components".
For information about defining skin style properties, see Section 20.3, "Defining Skin Style Properties".
You can adjust the look and feel of any component at design time by changing the style-related properties, inlineStyle
and styleClass
, both of which render on the root DOM element. Any style-related property you specify at design time overrides the comparable style specified in the application skin or CSS for that particular instance of the component.
The inlineStyle
attribute is a semicolon-delimited string of CSS styles that can set individual attributes, for example, background-color:red; color:blue; font-style:italic; padding:3px
. The styleClass
attribute is a CSS style class selector used to group a set of inline styles. The style classes can be defined using an ADF public style class, for example, .AFInstructionText
, sets all properties for the text displayed in an af:outputText
component.
For information about applying component style properties, see Section 20.4, "Changing the Style Properties of a Component".
Given a specific selector, you can get style properties for a custom component by creating a class for a renderer. For more information, see Section 30.4.7, "How to Create a Class for a Renderer".
Custom skins can change the colors, fonts, and even the location of portions of ADF Faces components to represent your company's preferred look and feel. You build the skin by defining style selectors in a CSS file. After you create your custom style sheet, register it as a valid skin in the application, and then configure the application to use the skin.
By default, ADF Faces components use the fusion
skin. Custom skins can extend to any of the ADF Faces skins, fusion
, blafplus-rich
, blafplus-medium
, or simple
. To create a custom skin, you declare selectors in a style sheet that override or inhibit the selectors in the style sheet being extended. Any selectors that you choose not to override will continue to use the style as defined in that skin.
Extending the simple
skin does not require inhibiting as many properties as you would if you extended the BLAF Plus skins. For example, the BLAF Plus skins use many different colors for style properties, including text, background, and borders. The simple
skin uses the :alias
pseudo-class, as in .AFDarkBackground:alias
, instead of specific colors. Changing a color scheme would require overriding far fewer global skin selectors than component skin selectors that specify multiple colors.
The text used in a skin is defined in a resource bundle. As with the selectors for the blafplus-rich
skin, you can override the text by creating a custom resource bundle and declaring only the text you want to change. After you create your custom resource bundle, register it with the skin.
You can create and apply multiple skins. For example, you might create one skin for the version of an application for the web, and another for when the application runs on a PDA. Or you can change the skin based on the locale set on the current user's browser. Additionally, you can configure a component, for example an af:selectOneChoice
component, to allow a user to switch between skins.
While you can bundle the custom skin resources and configuration files with the application for deployment, you can also store skin definitions in a Java Archive (JAR) file and then add it to the deployed application. The advantages to using a JAR file are that the custom skin can be developed and deployed separately from the application, improving consistency in the look and feel, and that skin definitions and image files can be partitioned into their own JAR files, reducing the number of files that may have to be deployed to an application.
The steps to apply a custom skin to your application are the following:
Add a custom skin to your application. For details, see Section 20.2.1, "How to Add a Custom Skin to an Application".
Register the custom skin. For details, see Section 20.2.2, "How to Register the XML Schema Definition File for a Custom Skin" and Section 20.2.3, "How to Register a Custom Skin".
Configure the application to use the custom skin. For details, see Section 20.2.4, "How to Configure an Application to Use a Custom Skin".
Deploy a custom skin in a JAR file. For details, see Section 20.6, "Deploying a Custom Skin File in a JAR File".
To add a custom skin to your application, create a CSS file within JDeveloper, which places the CSS in a project's source file for deployment with the application.
To add a custom skin to an application:
In JDeveloper, make sure that CSS Level 3 and ADF Faces are selected. From the main toolbar, choose Tools > Preferences > CSS Editor. For Support Level, choose CSS Level 3 from the dropdown menu, and for Supported Components, select ADF Faces Extension.
In the Application Navigator, right-click the project that contains the code for the user interface and choose New from the context menu.
In the New Gallery under Categories, expand Web Tier and select HTML.
Double-click the CSS File option.
In the Create Cascading Style Sheet dialog, enter a name and path for the CSS.
Click OK.
You can now open the CSS in the CSS editor and define styles for your application. For information about setting ADF Faces component style selectors, see Section 20.3, "Defining Skin Style Properties".
You can also create a CSS outside the context of Oracle JDeveloper and package the CSS with the skin resources into a JAR file. For information about this recommended option, see Section 20.6, "Deploying a Custom Skin File in a JAR File".
You need to register the trindidad-skins.xsd
file with JDeveloper if you plan to register a custom skin, as described in Section 20.2.3, "How to Register a Custom Skin". The trindidad-skins.xsd
file defines the valid elements for a custom skin.
To register an XML schema definition file:
In JDeveloper, select Tools > Preferences.
In the Preferences dialog, select XML Schemas in the left pane and click Add.
In the Add Schema dialog, click Browse to navigate to the XML schemas included in your version of JDeveloper.
The directory path to the XML schemas is similar to the following:
JDeveloper_Home
/jdeveloper/modules/oracle.adf.view_11.1.1/trinidad-impl.jar!/org/apache/myfaces/trinidadinternal/ui/laf/xml/schemas/skin/trinidad-skins.xsd
Note:
In the Add Schema dialog, make sure the value in the Extension input field is.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.Click OK.
Registering a skin involves creating a file named trinidad-skins.xml
and populating it with values that identify the skin's ID, family, location, and the custom resource bundle if you are using one.
Register the XML schema definition file that defines valid elements for the trinidad-skins.xml
file. For more information, see Section 20.2.2, "How to Register the XML Schema Definition File for a Custom Skin".
In the Application Navigator, right-click the project and select New.
In the New Gallery, expand General and select XML.
Select XML Document from XML Schema and click OK.
In the Create XML from XML Schema - Step 1 of 2 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.
In the Create XML Schema - Step 2 of 2 dialog:
Target Namespace: Select http://myfaces.apache.org/trinidad/skin
.
Root Element: Select skins
.
Click Finish. The new file automatically opens in the XML Editor.
In the XML editor, enter values for the following elements:
<id>
A skin is required to have a unique ID. You can also use an EL expression to reference the skin ID. For example, if you want to have different skins for different locales, create an EL expression that selects the correct skin based on its ID. The convention is to put a "desktop" or ".pda" or ".portlet" at the end of the ID, such as "fusion.desktop".
<family>
You configure 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.
For example, you can define the blafplus-rich.desktop
skin and the blafplus-rich.pda
skin to be part of the richDemo
family and the system automatically chooses the right skin based on the render-kit-id
.
<skin> <id>richdemo.desktop</id> <family>richDemo</family> <extends>blafplus-rich.desktop</extends> <render-kit-id>org.apache.myfaces.trinidad.desktop</render-kit-id> <style-sheet-name>skins/richdemo/richdemo.css</style-sheet-name> </skin> <skin> <id>richdemo.pda</id> <family>richDemo</family> <extends>blafplus-rich.pda</extends> <render-kit-id>pda</render-kit-id> <style-sheet-name>skins/richdemo/richdemo.css</style-sheet-name> </skin>
<extends>
You extend a custom skin by using this element. The default value for this element is simple.desktop
. However, you can extend any skin by using this element.
For example, you can easily change the font of the entire skin by extending the skin and creating a CSS with the font alias. For example, extend the fusion.desktop
family as follows:
<extends>fusion.desktop</extends> <style-sheet-name>skins/fod_skin.css</style-sheet-name>
In the CSS, set the alias to change the font for the entire skin:
.AFDefaultFontFamily:alias {font-family: Tahoma}.AFDefaultFont:alias {font-size: 16px}
<render-kit-id>
This value 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 the application is rendered on a PDA.
<style-sheet-name>
This is the URL of the custom style sheet. The style sheet name file is retrieved as a URL object using the following methods:
For nonstatic URLs, those that could change after the server has started, the URL is created by calling new java.new.URL(style-sheet-name)
if style-sheet-name
starts with http:
, https:
, file:
, ftp:
, or jar:
. Otherwise, the URL is created by calling <FacesContext>
<ExternalContext>
getResource<style-sheet-name>
. It will add a slash (/
) to delimit the URL parts if it is not already present. For example, the slash is added between skins/bigfont/bigfont.css
.
If still not retrieved, the URL is created using the <ClassLoader
> getResource
in a style-sheet-name format similar to META-INF/purpleSkin/styles/myPurpleSkin.css
. Once the URL is converted to this format, it can be searched for in JAR files that may contain the style sheet.
<bundle-name>
This is the resource bundle created for the skin. If you did not create a custom bundle, then you do not need to declare this element. For more information, see Section 20.3.1, "How to Apply Skins to Text".
Note:
If you have created localized versions of the resource bundle, then you need to register only the base resource bundle.<translation-source>
This is an EL binding that can point to a Map
or a ResourceBundle
. You can use this instead of the bundle name if you would like to be more dynamic in your skin translations at runtime. The <bundle-name>
tag takes precedence.
Example 20-4 shows the entry in the trinidad-skins.xml
file for the mySkin
skin.
Example 20-4 Skin Entry in the trinidad-skins.xml File
<?xml version="1.0" encoding="ISO-8859-1"?> <skins xmlns="http://myfaces.apache.org/trinidad/skin"> <skin> <id> mySkin.desktop </id> <family> mySkin </family> <extends>blafplus-rich.desktop</extends> <render-kit-id> org.apache.myfaces.trinidad.desktop </render-kit-id> <style-sheet-name> skins/mySkin/mySkin.css </style-sheet-name> <bundle-name> myBundle </bundle-name> <translation-source></translation-source> </skin> </skins>
Save the file.
You set an element in the trinidad-config.xml
file that determines which skin to use, and if necessary, under what conditions.
Note:
If you do not see the skin, check to see whether or not theaf:document
tag has been added to the page. The af:document
tag initializes the skin framework to create the CSS and link it to the page.To configure an application to use a skin:
Open the trinidad-config.xml
file.
Replace the <skin-family>
value with the family name for the skin you wish to use.
Example 20-5 shows the configuration to use for the mySkin
skin family.
To conditionally set the value, enter an EL expression that can be evaluated to determine the skin to display.
For example, if you want to use the German skin when the user's browser is set to the German locale, and to use the English skin otherwise, you would have the following entry in the trinidad-config.xml
file:
<skin-family>#{facesContext.viewRoot.locale.language=='de' ? 'german' : 'english'}</skin-family>
Save the file.
During development, after you make changes to the custom skin, you can see your CSS changes without restarting the server by setting the web.xml
file parameter org.apache.myfaces.trinidad.CHECK_FILE_MODIFICATION
to true
, as shown in Example 20-6. However, you must always restart the server to see icon and skin property changes.
The ADF Faces skin style selectors support multiple options for applying skins to a component to create a custom look and feel to your application. The af:goButton
component skin style selectors are described in Table 20-1.
Table 20-1 af:goButton Component Style Selectors
Name | Description |
---|---|
|
Style on the root element of the |
|
Style on the button icon, if the icon attribute is set on the |
|
Style on the text of the button. This includes the |
Figure 20-3 shows the application of the default fusion
skin on the af:goButton
component and the component icon.
Figure 20-4 shows the new appearance of the button and icon by setting the following style properties in a custom skin:
af|goButton::access-key {color: red;} af|goButton::icon-style {border: 1px solid black;}
The ADF Faces skin style selectors used by the default skin are defined in the "Skin Selectors for Fusion's ADF Faces Components" and "Skin Selectors for Fusion's Data Visualization Tools Components" topics in JDeveloper's online help. They are located in All Online Help > Developing Oracle ADF Faces Applications.
JDeveloper provides coding support while editing your CSS files. You can invoke the CSS code editor when editing your file directly or when editing an ADF Faces component in the JSP source editor. Code support is available for the following:
Code insight
Error highlighting
Preview of styles
Refactoring
Finding usages
Quick comment
Formatting
Matching tag highlighting
In addition to using a CSS file to determine styles, skins also use a resource bundle to determine the text within a component. The text that ADF Faces components render can be translated and abstracted as a resource string. For example, af_chooseDate.LABEL_SELECT_YEAR
is the resource string for the label of the field used to select the year using an af:chooseDate
component. All the ADF Faces skins use the same resource bundle.
To apply a skin to the text in ADF Faces components, create a custom resource bundle and override the default resource string values. Then, set the <bundle-name>
property for your custom resource bundle in the trinidad-skins.xml
file.
Note:
ADF Faces components provide automatic translation. The resource bundle used for the components' skin is translated into 28 languages. If a user sets the browser to use the German (Germany) language, any text contained within the components will automatically be displayed in German. For this reason, if you create a resource bundle for a custom skin, you must also create localized versions of that bundle for any other languages the application supports.See Chapter 21, "Internationalizing and Localizing Pages" for more information.
To create and register a custom resource bundle:
In JDeveloper, create a new simple Java class:
In the Application Navigator, right-click where you want the file to be placed and choose New to open the New Gallery.
In the Categories tree, select Java, and in the Items list, select Java Class.
Enter a name and package for the class. The class must extend java.util.ListResourceBundle
.
Add any keys to your bundle that you wish to override and set the text as needed. Example 20-7 shows the SkinBundle
custom resource bundle.
Example 20-7 Resource Strings Set in Custom SkinBundle
public class SkinBundle extends ListResourceBundle { @Override public Object[][] getContents() { return _CONTENTS; } static private final Object[][] _CONTENTS = { {"af_tableSelectMany.SELECT_COLUMN_HEADER", "Select A Lot"}, {"af_tableSelectOne.SELECT_COLUMN_HEADER", "Select Just One"}, {"af_showDetail.DISCLOSED_TIP", "Click to Hide"} }; }
Set the name of your custom resource bundle in the <bundle-name>
parameter of the trinidad-skins.xml
file. Example 20-8 shows the custom SkinBundle
set in the trinidad-skins.xml
file.
Example 20-8 Custom SkinBundle Set in trinidad-skins.xml
<skin> <id> purple.desktop </id> <family> purple </family> <render-kit-id> org.apache.myfaces.trinidad.desktop </render-kit-id> <style-sheet-name> skins/purple/purpleSkin.css </style-sheet-name> <bundle-name> org.apache.myfaces.trinidaddemo.resource.SkinBundle </bundle-name> </skin>
Another option for applying skins to text is to use the <translation-source>
parameter instead of <bundle-name>
. The <translation-source>
parameter is an EL binding that points to a Map
or a ResourceBundle
. The benefit of this option is that you can automatically change the translation value based on any logic that you want at runtime. The <bundle-name>
tag takes precedence if both are set. Example 20-9 shows the code for using an EL expression to set the <translation-source>
parameter in a bundle map.
Example 20-9 Custom Resource Bundle Map
public class SkinTranslationMapDemo { /* Test a skin's translation-source EL pointing to a Map */ public Map<String, String> getContents() { return _CONTENTS; } static private final Map<String, String> _CONTENTS = new HashMap<String, String>(); static { _CONTENTS.put("af_inputDate.LAUNCH_PICKER_TIP", "Launch PickerMap"); _CONTENTS.put("af_showDetail.DISCLOSED_TIP", "Hide Tip Map"); _CONTENTS.put("af_showDetail.DISCLOSED", "Hide Map"); } }
Example 20-10 shows setting the <translation-source>
parameter for the resource map in the trinidad-skins.xml
file.
Example 20-10 Custom Resource Bundle Map Set in trinidad-skins.xml
<skin> <id> purple.desktop </id> <family> purple </family> <render-kit-id> org.apache.myfaces.trinidad.desktop </render-kit-id> <style-sheet-name> skins/purple/purpleSkin.css </style-sheet-name> <translation-source> #{skinTranslationMap.resourceBundle} </translation-source> </skin>
You can apply skins to the default icons associated with ADF Faces components by specifying the URL path to the icon image in the icon style selector.
Note that CSS syntax like pseudo-classes (:hover
, and so forth) and descendant selectors and composite class selectors does not work with icon selectors.
Note:
If you are overriding a selector for an icon, use a context-relative path for the URL to the icon image (that is, start with a leading slash (/
)), and do not use quotation marks.
Also, you must include the width and the height for the icon.
Example 20-11 shows a selector for an icon.
Example 20-11 Selector for an Icon
.AFErrorIcon:alias { content:url(/adf/images/error.png); width:7px; height:18px }
Icons and buttons can both use the rtl
pseudo-class. This defines an icon or button for use when the application displays in right-to-left mode. Example 20-12 shows the rtl
pseudo-class used for an icon.
You can apply style to ADF Faces input components based on whether or not they have certain levels of messages associated with them. When a message of a particular type is added to a component, the styles of that component are automatically modified to reflect the new status. If styles are not defined for the status in question, then the default styles are used.
In order to define styles for your input components based on message levels that are tied to them, you would append a style pseudo-class to your component definition. For example, to define the base style for the content region of the af:inputText
component to a background color of purple, use the style selector af|inputText::content{background-color:purple}
. To define the content region of the component when an error message is present, use the skin style selector af|inputText:error::content
.
The valid message properties are :fatal
, :error
, :warning
, :confirmation
, and :info
.
Themes are a way of implementing a look and feel at a component level. The purpose is to provides a consistent look and feel across multiple components for a portion of a page. A common usage for themes is in a JSF page template where certain areas have a distinct look. For example, a page may have a branding area at the top with a dark background and light text, a navigation component with a lighter background, and a main content area with a light background.
A component that sets a theme exposes that theme to its child components and therefore the theme is inherited. Themes can be set (started or changed) by the following components:
af:document
af:decorativeBox
af:panelStretchLayout
af:panelGroupLayout
The Fusion and BLAF Plus skins (blafplus-rich
and blafplus-medium
) support the following themes:
Dark
Medium
Light
None (default)
In the JSPX page, the theme is started by the af:document
component, as in:
<af:document theme="dark"> <af:panelTabbed>...</af:panelTabbed> </af:document>
To set the theme for a component, specify a theme
attribute in the skin selector in the CSS file. For example, the selector to change the text color under an af:panelTabbed
component to a dark theme is:
af|panelTabbed[theme="dark"] { color: red; }
If you do not want a child component to inherit modifications made to a parent component in a JSPX page, set a value for the -tr-children-theme
property in the CSS file. For example, you do not want the af:panelTabbed
child component to inherit the dark
theme defined for the af:document
parent component in the JSPX page. Set the -tr-children-theme
property in the CSS file as follows:
af|panelTabbed::content { -tr-children-theme: default; }
By default, themes are not set for components or their child components. Because themes are inherited, the following values are supported when a component has a theme
attribute that is not set:
not given - If no theme is given, the theme is inherited, as in <af:decorativeBox>...
#{null}
- The theme is inherited; same as not given.
inherit
- The theme is inherited; same as null.
default
- The theme is removed for the component and its child components.
empty string - If the theme is set to a blank string, it has the same behavior as default
. For example, <af:decorativeBox theme="">
will remove the theme for the component and its child components.
Because the themes are added to every HTML element of a component that supports themes and that has style classes, there is no need for containment-style CSS selectors for themes. With the exception of :ltr
and :rtl
, all theme selectors should always appear on the last element of the selector. For example, the selector to apply a dark theme to each step of an af:breadCrumbs
component would be:
af|breadCrumbs::step:disabled[theme="dark"] { color:#FFFFFF; }
Color incompatibility may occur if a component sets its background color to a color that is not compatible with its encompassing theme color. For example, if a panelHeader
component is placed in a dark theme, the CSS styles inside the panelHeader
component will set its component background to a light color without changing its foreground color accordingly. The result is a component with a light foreground on a light background. Many other components also set their foreground color to a light color when placed in a dark theme.
If color incompatibility occurs, you can resolve color incompatibility between parent and child components by setting a value for the -tr-children-theme
property. For components that do not have a parent-child relationship, you can manually set the component's theme color to a color that is compatible with the surrounding theme color. You do this by inserting the panelGroupLayout
or panelStretchLayout
component inside the component and by setting the panelGroupLayout
or panelStretchLayout
theme to a compatible color.
<af:panelHeader text="Header Level 0"> <af:panelGroupLayout layout="vertical" theme="default"> ... </af:panelGroupLayout> </af:panelHeader>
You can create your own alias that you can then include on other selectors.
Create a selector class for the alias. For example, you can add an alias to set the color of a link when a mouse cursor hovers over it:
.MyLinkHoverColor:alias {color: #CC6633;}
To include the alias in another selector, add a pseudo-element to an existing selector to create a new selector, and then reference the alias using the -tr-rule-ref:selector
property.
For example, you can create a new selector for the af|menuBar::enabled-link
selector to style the hover color, and then reference the custom alias, as shown in Example 20-13.
To configure a component to dynamically change the skin, you must first configure the component on the JSF page to set a scope value that can later be evaluated by the configuration file. You then configure the skin family in the trinidad-config
file to be dynamically set by that value.
To conditionally configure a component to set the skin family:
Open the main JSF page (such as the index.jspx
or a similar file) that contains the component that will be used to set the skin family.
Configure the page to display the skin family by using the sessionScope
component.
Example 20-14 shows an af:selectOneChoice
component that takes its selected value, and sets it as the value for the skinFamily
attribute in the sessionScope
component on the index.jspx
page.
Example 20-14 Using a Component to Set the Skin Family
<af:selectOneChoice label="Choose Skin:" value="#{sessionScope.skinFamily}" autoSubmit="true"> <af:selectItem value="blafplus-rich" label="blafplus-rich"/> <af:selectItem value="blafplus-medium" label="blafplus-medium"/> <af:selectItem value="simple" label="simple"/> <af:selectItem value="richDemo" label="richDemo"/> <af:selectItem value="mySkin" label="mySkin"/> </af:selectOneChoice>
The Refresh button on the page resubmits the page. Every time the page refreshes, the EL expression is evaluated and if there is a change, the page is redrawn with the new skin.
To conditionally configure a component for changing skins at runtime:
In the trinidad-config.xml
file, use an EL expression to dynamically evaluate the skin family:
<skin-family>#{sessionScope.skinFamily}</skin-family>
ADF Faces components use the CSS style properties based on the Cascading Style Sheet (CSS) specification. Cascading style sheets contain rules, composed of selectors and declarations, that define how styles will be applied. These are then interpreted by the browser and override the browser's default settings.
WARNING:
Do not use styles to achieve stretching of components. Using styles to achieve stretching is not declarative and, in many cases, will result in inconsistent behavior across different web browsers. Instead, you can use the geometry management provided by the ADF Faces framework to achieve component stretching. For more information about layouts and stretching, see Section 8.2.1, "Geometry Management and Component Stretching.".
Set an inline style for a component by defining the inlineStyle
attribute. You can use inline style to specify the style of a component for that instance of the component. For more information, see Section 8.3, "Arranging Contents to Stretch Across a Page".
Set the inlineStyle
attribute of the component to the inline style you want to use.
If you use the Property Inspector to set a style, you can select the style features you want from dropdown lists, as shown in Figure 20-5.
JDeveloper adds the corresponding code for the component to the JSF page. Example 20-15 shows the source for an af:outputText
component with an inlineStyle
attribute.
You can use an EL expression for the inlineStyle
attribute itself to conditionally set inline style attributes. For example, if you want the date to be displayed in red when an action has not yet been completed, you could use the code similar to that in Example 20-16.
The ADF Faces component may have other style attributes not available for styling that do not register on the root DOM element. For example, for the af:inputText
component, set the text of the element using the contentStyle
property, as shown in Example 20-17.
You can define the style for a component using a style class. You create a style class to group a set of inline styles.
To set a style using a style class:
Set the styleClass
attribute of the component to the style class you want to use.
Example 20-18 shows an example of a style class being used in the page source.
You can also use EL expressions for the styleClass
attribute to conditionally set style attributes. For example, if you want the date to be displayed in red when an action has not yet been completed, you could use code similar to that in Example 20-16.
You can refer to a URL from a skin's CSS file in a number of different formats. The supported formats are:
Absolute
You specify the complete URL to the resource. For example, a URL in the following format:
http://www.mycompany.com/WebApp/Skin/skin1/img/errorIcon.gif
Relative
You can specify a relative URL if the URL does not start with /
and no protocol is present. A relative URL is based on the location of the skin's CSS file. For example, if the skin's CSS file directory is WebApp/Skin/skin1/
and the specified URL is img/errorIcon.gif
, the final URL is /WebApp/Skin/mySkin/img/errorIcon.gif
Context relative
This format of URL is resolved relative to the context root of your web application. You start a context relative root with /
. For example, if the context relative root of a web application is:
/WebApp
and the specified URL is:
/img/errorIcon.gif
the resulting URL is:
/WebApp/img/errorIcon.gif
Server relative
A server relative URL is resolved relative to the web server. This differs to the context relative URL in that it allows you reference a resource located in another application on the same web server. You specify the start of the URL using //
. For example, write a URL in the following format:
//WebApp/Skin/mySkin/img/errorIcon.gif
You may want to store skin definitions in a Java Archive (JAR) file and then add it to the deployed application. The benefits of packaging skins into a JAR file as compared to bundling them into the application are the following:
A skin can be deployed and developed separately from the application. This also helps to reduce the number of files to be checked in case some changes must be applied to the skin. Foremost is that using a skin definition contained in a JAR file improves consistency in the look and feel of the application.
Skin definitions and images can be separated into their own JAR files. Therefore, you can partition the image base into separate JAR files, so that not all files have to be deployed with all applications.
To deploy a skin into a JAR file, follow these rules:
The trinidad-skins.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 must also be under the META-INF
directory. The images 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, as shown in Example 20-19.
The JAR file must be placed in the WEB-INF/lib
directory of the view layer project of the application to deploy (or use a shared library at the application-server level).
Example 20-19 web.xml File with Paths
<servlet-mapping> <servlet-name>resources</servlet-name> <url-pattern>/adf/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>resources</servlet-name> <url-pattern>/afr/*</url-pattern> </servlet-mapping>
To deploy a skin into a JAR file:
Create a directory structure similar to the following:
c:\temp\META-INF\adf\oracle\skin\images META-INF\skins\fusion.css META-INF\trinidad-skins.xml
Confirm that the directory in the META-INF
directory starts with adf
. The images
directory contains all the images used within the oracleblaf.css
skin. The CSS reference to the images should have a path similar to this:
af|inputColor::launch-icon:rtl { content:url(../adf/oracle/skin/images/cfsortl.png); width: 12; height: 12; left:-7px; position:relative; right:-7px; top:5px; }
Note the two leading periods in front of the image path ../adf/oracle/skin/images/cfsortl.png
. This allows the search for the META-INF
root to start one directory above the META-INF/skin
directory in which the CSS is located.
Check that the trinidad-skins.xml
file is located in the META-INF
directory and that it contains content in a format similar to this:
<?xml version="1.0" encoding="ISO-8859-1"?> <skins xmlns="http://myfaces.apache.org/trinidad/skin"> <skin> <id>richdemo.desktop</id> <family>richDemo</family> <extends>fusion.desktop</extends> <render-kit-id>org.apache.myfaces.trinidad.desktop</render-kit-id> <style-sheet-name>skins/richdemo/richdemo.css</style-sheet-name> </skin> </skins>
This example defines the skin as richdemo.desktop
in the richDemo
family. The trinidad-skins.xml
file can have more than one skin definition. The richdemo.css
file (or your custom CSS file) is referenced from the style-sheet-name
element.
To create the JAR file, issue the following command from the c:\temp
directory:
jar -cvf customSkin.jar META-INF/
Copy the resulting customSkin.jar
file to the WEB-INF/lib
directory of the consuming ADF project. Configure the trinidad-skins.xml
file located on the WEB-INF
directory of the ADF project.
<?xml version="1.0" encoding="windows-1252"?> <trinidad-config xmlns="http://myfaces.apache.org/trinidad/config"> <skin-family>oracleblaf</skin-family> </trinidad-config>
Because the skin can be discovered at runtime, you do not need to code the skin family name.
Note:
The skin definition in the JAR file is not displayed in the JDeveloper visual editor. You may see a message in the log window that the skin family could not be found. You can ignore this message.