2009年9月19日星期六

ADF_026:使用ADF Faces 之六:使用CSS为应用动态换肤

本文最后一次修改时间:2012-03-09。
开发环境:JDevloper 11.1.2.1.0+ Oracle Database 10g Express Edition 10.2.0.1。

完成《Changing an Application's Look and Feel by Using Skins》。

1. 创建ADF Skin:MyNewSkin.css

新建的ADF Skin继承fusion的皮肤,包括所有组件的外观定义。

可以在默认皮肤的基础上定制你的皮肤,修改后会把变化的部分保存到CSS文件中。


2. 使用Firefox Debug查看当前页面使用的是哪个CSS?


3. 定制皮肤
(1)定制af:document:Faces Component Selectors > Document > af|document

(2)定制默认字体:Global Selector Aliases | Font > .AFDefaultFontFamily

(3)定制默认别名字体:Global Selector Aliases | Font > .AFDefaultFont:alias.

(4)定制Panel Header:Faces Component Selectors,Panel Header | Pseudo-Elements

(5)定制Column Header:Faces Component Selectors,Column | Pseudo-Elements node,column-header-table

(6)定制Panel List的Link:Panel List > Pseudo-Elements,link

(7)定制Tab形状:Global Selector Aliases > node Component Group Tabs

运行效果如下:使用登录用户 sking/Welcome1234


4. 运行时动态切换皮肤
(1)trinidad-config.xml
该文件决定运行时使用哪个皮肤,可以静态指定,也可以使用EL表达式实现动态选择。
你甚至可以根据用户的本地语言来决定使用哪个皮肤,比如德语皮肤或英语皮肤。

<?xml version="1.0" encoding="windows-1252"?>
<trinidad-config xmlns="http://myfaces.apache.org/trinidad/config">
<skin-family>#{sessionScope.skinFamily!=null?sessionScope.skinFamily : 'fusion'}</skin-family>
<!--
<skin-family>MyNewSkin</skin-family>
<skin-family>#{facesContext.viewRoot.locale.language=='de' ? 'german' : 'english'}</skin-family>
-->
</trinidad-config>


(2)trinidad-skins.xml
该文件注册了所有自定义皮肤,运行时可以选择这些皮肤或者系统自带的皮肤。

<?xml version="1.0" encoding="windows-1252" ?>
<skins xmlns="http://myfaces.apache.org/trinidad/skin">
<skin>
<id>completedSkinSample.desktop</id>
<family>completedSkinSample</family>
<extends>fusion.desktop</extends>
<render-kit-id>org.apache.myfaces.trinidad.desktop</render-kit-id>
<style-sheet-name>skins/completedSkinSample/completedSkinSample.css</style-sheet-name>
</skin>
<skin>
<id>princess-skin.desktop</id>
<family>princess-skin</family>
<render-kit-id>org.apache.myfaces.trinidad.desktop</render-kit-id>
<extends>simple.desktop</extends>
<style-sheet-name>skins/princess/princess.css</style-sheet-name>
</skin>
<skin>
<id>MyNewSkin.desktop</id>
<family>MyNewSkin</family>
<extends>fusionFx-simple-v2.desktop</extends>
<render-kit-id>org.apache.myfaces.trinidad.desktop</render-kit-id>
<style-sheet-name>skins/MyNewSkin/MyNewSkin.css</style-sheet-name>
<bundle-name>adf/sample/view.skinBundle</bundle-name>
</skin>
</skins>


(3)trinidad-skins.xml
<af:selectOneChoice label="Choose a Skin" value="#{sessionScope.skinFamily}" id="soc1" autoSubmit="true" valueChangeListener="#SkinManager.onNewSkinSelection}">
<f:selectItems value="#{SkinManager.skinChoices}" id="si1"/>
</af:selectOneChoice>

(4)SkinManager.java

package adf.sample.view.beans;

import java.io.IOException;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.event.ValueChangeEvent;
import javax.faces.model.SelectItem;

import oracle.adf.controller.ControllerContext;
import oracle.adf.share.ADFContext;

import org.apache.myfaces.trinidad.skin.Skin;
import org.apache.myfaces.trinidad.skin.SkinFactory;


public class SkinManager {
public SkinManager() {
ADFContext adfctx = ADFContext.getCurrent();
Map sessionScope = adfctx.getSessionScope();
Object skinFamily = sessionScope.get("skinFamily");
if (skinFamily == null) {
sessionScope.put("skinFamily", "fusion");
}
}

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

public void onNewSkinSelection(ValueChangeEvent valueChangeEvent) {
ADFContext adfctx = ADFContext.getCurrent();
Map sessionScope = adfctx.getSessionScope();
sessionScope.put("skinFamily", (String)valueChangeEvent.getNewValue());
redirectToSelf();
}

private void redirectToSelf() {
FacesContext fctx = FacesContext.getCurrentInstance();
ExternalContext ectx = fctx.getExternalContext();
String viewId = fctx.getViewRoot().getViewId();
ControllerContext controllerCtx = null;
controllerCtx = ControllerContext.getInstance();
String activityURL = controllerCtx.getGlobalViewActivityURL(viewId);
try {
ectx.redirect(activityURL);
fctx.responseComplete();
} catch (IOException e) {
//Can't redirect
e.printStackTrace();
fctx.renderResponse();
}
}
}

(5)运行时下拉列表显示的ADF Skins:


Project 下载:ADFSkinSample.7z

没有评论: