hi,
here is another retake on the whole issue. Since locale change is a cross cutting concern, its better that locale is set for pages without the page doing anything special for it. Plus the "do both" approach is bit bothersome. If you add a page in future,where you forget to add f:view, then again you will have locale problem for that page. Here is a clean approach to change locale,I did the following:
1)remove all f:view tags from pages(also remove f:loadBundle from pages).
2)change the swapLocale() method to:
public void swapLocale(ActionEvent event) {
System.out.println("[swapLocale] Setting isEnglish to " + !isEnglish);
isEnglish = !isEnglish;
//FacesContext.getCurrentInstance().getViewRoot().setLocale(isEnglish?ENGLISH:SPANISH);
}
notice that i commented out the last statement in the method. So now, its no longer the responsibility of a page to set locale.
3) getLocale() method as before, no changes in it:
public Locale getLocale() {
if (isEnglish) {
return (ENGLISH); // ENGLISH is Locale.ENGLISH
} else {
return (SPANISH);// SPANISH is Locale("es")
}
}
4)Here's the interesting part:
register a listener:
<lifecycle>
<phase-listener>coreservlets.LifeCycleListener</phase-listener>
</lifecycle>
the listener code is:
import java.util.Locale;
import javax.el.ELContext;
import javax.el.ValueExpression;
import javax.faces.application.Application;
import javax.faces.context.FacesContext;
import javax.faces.event.PhaseEvent;
import javax.faces.event.PhaseId;
import javax.faces.event.PhaseListener;
public class LifeCycleListener implements PhaseListener {
public PhaseId getPhaseId() {
return PhaseId.ANY_PHASE;
}
public void beforePhase(PhaseEvent event) {
System.out.println("START PHASE " + event.getPhaseId());
FacesContext context;
if (event.getPhaseId() == PhaseId.RENDER_RESPONSE) {
context = event.getFacesContext();
Application application = context.getApplication();
ValueExpression ve = application.getExpressionFactory().
createValueExpression(context.getELContext(),
"#{person.locale}", Locale.class);
try {
System.out.println("setting locale in phase listener");
Locale localeToSet = (Locale) ve.getValue(context.getELContext());
context.getViewRoot().setLocale(localeToSet);
} catch (Exception e) {
System.out.println("error in getting locale");
}
}
}
public void afterPhase(PhaseEvent event) {
System.out.println("END PHASE " + event.getPhaseId());
}
}
In the above code, the if block is run just before any page is rendered. Here we, take the #{person.locale} value and set it as UIViewRoot locale.
So now, no code in any page to change locale, no worry about forgetting the f:view, plus no dual setting.
Dont know, if you have read this
http://balusc.blogspot.com/2006/09/debug-jsf-lifecycle.html . Its quite a informative article.
ps:am from india
[Message sent by forum member 'nash_era']
http://forums.java.net/jive/thread.jspa?messageID=474362