There is a JSF application using Primefaces . The application must support a language change at any time. To do this, a combo box with a list of languages ​​in which the user selects the desired language. When selecting, the handler is called, changing the locale with the following code:
FacesContext.getCurrentInstance().getViewRoot().setLocale(locale); Everything works fine except for one detail. There is a menu that is not created in XHTML files, but dynamically, programmatically. In simplified form, it looks like this:
@ManagedBean @SessionScoped public class MenuView implements Serializable { private MenuModel model; public MenuModel getModel() { return model; } @PostConstruct public void init() { model = new DefaultMenuModel(); ResourceBundle messages = ResourceBundle.getBundle("i18n.messages", (Locale) getSession().getAttribute("locale")); DefaultSubMenu submenu = new DefaultSubMenu(messages.getString("Menu 1")); DefaultMenuItem item = new DefaultMenuItem(messages.getString("Item 1")); submenu.addElement(item); model.addElement(submenu); } } XHTML contains the following string:
<p:menu model="#{menuView.model}"> So, this menu ignores the language change and remains in the language that was at the time of its creation, which, of course, the user does not like.
How to intercept the locale change event and make the menu appear in the correct language? You can even recreate it, if necessary.
Now done as follows. When changing the language in the combo-box, a handler is called, which, in addition to changing the locale, also calls the static method
MenuView.localeChanged(); The MenuView class acquires additional fields and methods:
private MenuView instance; @PostConstruct public void init() { // ... instance = this; } public static void localeChanged() { if (instance != null) instance.init(); } But I don’t like this approach, because the class managing the locale acquires completely unnecessary knowledge about menu classes, i.e. there is an extra dependence of classes.
Is there any way to do without this dependence?
SessionScopedtoViewScopedfor a menu bean. But also not the best solutions. - Pavel Parshin@ViewScopedtried - not recreated. - user194374javax.faces.bean.ViewScoped, but it was necessaryjavax.faces.view.ViewScoped. It has become re-created. But now it is being recreated with every sneeze, which is also not good. - user194374SessionScopedbins and recreate them when the language isSessionScoped. Because, perhaps, not only the menu will be cached. - Pavel Parshin