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