如何通过p:commandLinks更改视图区域设置?

时间:2011-12-05 11:01:43

标签: jsf jsf-2 internationalization primefaces

我正在尝试在JSF 2中实现国际化。我尝试了很多解决方案,但是我无法让它改变视图语言环境。这是faces-config.xml文件的代码:

<application>
    <locale-config>
        <default-locale>es</default-locale>
        <supported-locale>en_GB</supported-locale>
        <supported-locale>fr</supported-locale>
    </locale-config>
    <resource-bundle>
        <base-name>malagaAcoge.configuracion.Messages</base-name>
        <var>msg</var>
    </resource-bundle>
</application>

我正在使用位于我的源包中的3个属性。

这是我的观点:

<f:view locale="#{idiomaBean.locale}">
    <div id="contenedor">
        <div id="cabecera"
            style="background: url('../images/logo/fondoCabecera.png') no-repeat">
        </div>
        <div id="cuerpo">
            <div id="center">
                <h:form prependId="false" id="form_login">
                    <h:selectOneMenu value="#{idiomaBean.locale}"
                        onchange="submit()"
                        valueChangeListener="#{idiomaBean.changeLanguage}">
                        <f:selectItems value="#{idiomaBean.countriesInMap}" />
                    </h:selectOneMenu>

                    <h:panelGrid columns="3">
                        <p:commandLink title="SP" action="#{idiomaBean.changeLanguage}">
                            <p:graphicImage value="../images/paises/sp.png"></p:graphicImage>
                        </p:commandLink>
                        <p:commandLink title="EN" action="#{idiomaBean.changeLanguage}">
                            <p:graphicImage value="../images/paises/en.png">
                            </p:graphicImage>
                        </p:commandLink>
                        <p:commandLink title="FR" action="#{idiomaBean.changeLanguage}">
                            <p:graphicImage value="../images/paises/fr.png">
                            </p:graphicImage>
                            <f:setPropertyActionListener target="#{idiomaBean.locale}"
                                value="fr"></f:setPropertyActionListener>
                        </p:commandLink>
                    </h:panelGrid>

这是我用来执行更改的IdiomaBean

private static final long serialVersionUID = 1L;
private static String locale = FacesContext.getCurrentInstance()
        .getViewRoot().getLocale().getLanguage();
private static Map<String, Object> countries;
static {
    countries = new LinkedHashMap<String, Object>();
    countries.put("Español", new Locale("es")); // label, value
    countries.put("English", Locale.ENGLISH);
    countries.put("Français", Locale.FRENCH);
}

public Map<String, Object> getCountriesInMap() {
    return countries;
}

public String getLocale() {
    return locale;
}

@SuppressWarnings("static-access")
public void setLocale(String locale) {
    this.locale = locale;
    FacesContext.getCurrentInstance().getViewRoot().setLocale(new Locale(locale));
}

public void changeLanguage(ValueChangeEvent e) {
    String newLocaleValue = e.getNewValue().toString();

    // loop country map to compare the locale code
    for (Map.Entry<String, Object> entry : countries.entrySet()) {

        if (entry.getValue().toString().equals(newLocaleValue)) {

            FacesContext.getCurrentInstance().getViewRoot()
                    .setLocale((Locale) entry.getValue());

        }
    }

我在Tomcat服务器上使用PrimeFaces 3.0。

1 个答案:

答案 0 :(得分:4)

您的问题描述中并不清楚。该下拉列表看起来像它将起作用(尽管值更改侦听器完全是多余的),但这些链接确实根本不起作用。我假设您实际上正在询问如何正确实现链接。

首先,在下拉列表和图像链接中删除值更改侦听器方法。您对旧值不感兴趣,您只对新值感兴趣,因此您根本不需要它。当你使用PrimeFaces 3.0时,它又需要Servlet 3.0,后者又与EL 2.2一起出现,你应该能够在EL中传递方法参数。您只需要将Locale参数更改为String类型,以便它也可以用作链接方法参数。

此外,您绝对不应该使用户选择的区域设置static。它将在同一个应用程序中的所有用户之间共享。因此,如果一个用户更改了区域设置,那么每个其他访问者都会看到最后一个用户选择的区域设置!使它成为会话范围bean的非静态属性。

所以,这应该做

<f:view locale="#{idiomaBean.locale}">
    <h:form>
        <h:selectOneMenu value="#{idiomaBean.language}" onchange="submit()">
            <f:selectItems value="#{idiomaBean.availableLanguages}" />
        </h:selectOneMenu>

        <h:panelGrid columns="3">
            <p:commandLink title="SP" action="#{idiomaBean.setLanguage('sp')}" update="@all">
                <p:graphicImage value="../images/paises/sp.png" />
            </p:commandLink>
            <p:commandLink title="EN" action="#{idiomaBean.setLanguage('en')}" update="@all">
                <p:graphicImage value="../images/paises/en.png" />
            </p:commandLink>
            <p:commandLink title="FR" action="#{idiomaBean.setLanguage('fr')}" update="@all">
                <p:graphicImage value="../images/paises/fr.png" />
            </p:commandLink>
        </h:panelGrid>
    </h:form>
</f:view>

@ManagedBean
@SessionScoped
public class IdiomaBean implements Serializable {

    private Locale locale = FacesContext.getCurrentInstance().getViewRoot().getLocale();

    private static Map<String, String> availableLanguages;

    static {
        availableLanguages = new LinkedHashMap<String, String>();
        availableLanguages.put("Español", "es");
        availableLanguages.put("English", "en");
        availableLanguages.put("Français", "fr");
    }

    public Map<String, String> getAvailableLanguages() {
        return availableLanguages;
    }

    public Locale getLocale() {
        return locale;
    }

    public String getLanguage() {
        return locale.getLanguage();
    }

    public void setLanguage(String language) {
        locale = new Locale(language);
        FacesContext.getCurrentInstance().getViewRoot().setLocale(locale);
    }

}