jsfinternationalizationmyfaces

Apache MyFaces 2.3-next-M6 | change of language don't work | it shows not the selected language


How can I fix the following error? The start language is German. If I select english it stays with the german text. However, if I then select German, I get English and if I then select English, I get German language. However, when the English text appears instead of the German text, "de" is displayed correctly next to language (Language de:) in the index.xhtml. To show which language is selected I use #{language.localeCode} in the index.xhtml. I use Apache MyFaces 2.3-next-M6 with Quarkus. What am I doing wrong?

index.xhtml

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core"
    xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:p="http://primefaces.org/ui">

<f:view contentType="text/html" encoding="UTF-8" locale="#{language.localeCode}">
    <f:loadBundle basename="messages" var="msg" />

    <h:head>
        <h:outputStylesheet name="primeflex/primeflex.css" />
    </h:head>

    <h:body>
        <p:growl>
            <p:autoUpdate />
        </p:growl>

        <h:form id="formlanguagechanger">
            <h:panelGrid columns="2">


                Language #{language.localeCode}:
                <h:selectOneMenu value="#{language.localeCode}" onchange="submit()"
                    valueChangeListener="#{language.countryLocaleCodeChanged}">
                    <f:selectItems value="#{language.countriesInMap}" />
                </h:selectOneMenu>
            </h:panelGrid>
        </h:form>

        <h:outputText value="#{msg.title}" />
    </h:body>
</f:view>

</html>

LanguageBean.java

@Named("language")
@SessionScoped
public class LanguageBean implements Serializable {
    private static final long serialVersionUID = 1L;

        private String localeCode;
        
        @PostConstruct
        public void init() {
            localeCode = "de";
        }

        private static Map<String, Locale> countries;
        static {
            countries = new LinkedHashMap<String, Locale>();
            countries.put("Deutsch", new Locale("de"));
            countries.put("English", new Locale("en"));
        }

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

        public String getLocaleCode() {
            return localeCode;
        }

        public void setLocaleCode(String localeCode) {
            this.localeCode = localeCode;
        }

        // value change event listener
        public void countryLocaleCodeChanged(ValueChangeEvent e) {

            String newLocaleValue = e.getNewValue().toString();

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

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

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

                }
            }
        }
}

Solution

  • This code works fine for me in Mojarra 2.3.17.

    In Myfaces 2.3.9, however, I could reproduce the described issue.

    The root cause is that the <f:loadBundle> is not (re)initialized during view render time but during view build time only. This might be a bug in MyFaces.

    I could work around the issue by replacing the <f:loadBundle> tag by this entry in faces-config.xml.

    <application>
        ...
        <resource-bundle>
            <base-name>messages</base-name>
            <var>msg</var>
        </resource-bundle>
    </application>
    

    It's at least not a Quarkus related problem. So I've fixed your question.

    See also: