webtier@glassfish.java.net

Re: Changing Locale Dynamically

From: <webtier_at_javadesktop.org>
Date: Mon, 31 May 2010 21:09:45 PDT

Hi,
I was able to solve your problem using 2 steps:
1)change swapLocale(), added one line
public void swapLocale(ActionEvent event) {
        System.out.println("[swapLocale] Setting isEnglish to " + !isEnglish);
        isEnglish = !isEnglish;

     FacesContext.getCurrentInstance().getViewRoot().setLocale(isEnglish?ENGLISH:SPANISH);
    }

2)use <resource-bundle> in faces-config.xml instead of <f:loadBundle> as
    <application>
        <resource-bundle>
            <base-name>messages</base-name>
            <var>msgs</var>
        </resource-bundle>
    </application>

It seems <resource-bundle> is required for changing locales.

the solution even works if you remove f:view completely, or it works even if you keep the <f:loadbundle> tag in the page. however <resource-bundle> is required.

========
getLocale() is called in first phase i.e RESTORE_VIEW. It happens seemingly due to this part mentioned in JSF 2.0 specs
2.2.1 Restore View
■ Examine the FacesContext instance for the current request. If it already contains a UIViewRoot:
      ■ Set the locale on this UIViewRoot to the value returned by the getRequestLocale() method on the ExternalContext for this request.
========

Better remove the <f:view> tag completely. it is not mandatory in JSF 2.0. As such the locale change happens due to FacesContext.getCurrentInstance().getViewRoot().setLocale() method. If you remove it, you will see getLocale() called after swapLocale() in RENDER_RESPONSE phase.


========

To check in which phase my System.out.println() statements where executed i added a PhaseListener as:

package coreservlets;

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());
    }

    public void afterPhase(PhaseEvent event) {
        System.out.println("END PHASE " + event.getPhaseId());
    }
}

and registered it in faces-config:

    <lifecycle>
        <phase-listener>coreservlets.LifeCycleListener</phase-listener>
    </lifecycle>
[Message sent by forum member 'nash_era']

http://forums.java.net/jive/thread.jspa?messageID=472193