How to reload the components in Vaadin after click internationalization Button?

sulox32 :

I use Internationalization I18N in Vaadin. I have a Internationalization class with the method getText.

public static String getText(String key) {
        String returnValue = "";
        String value = "";
        String space = " ";
        Locale locale = new Locale("de", "DE");
        try {
            // session specific locale stored in attribute "locale"
            // if you want add a new language then add a new else if with the
            // new Locale like ("fr", "FR").
            if (VaadinServletService.getCurrentRequest() != null) {
                if ((Locale) VaadinServletService.getCurrentServletRequest().getSession().getAttribute("locale") != null) {
                    if (VaadinServletService.getCurrentServletRequest().getSession().getAttribute("locale").toString().equals("en_EN")) {
                        locale = new Locale("en", "US");
                    } else if (VaadinServletService.getCurrentServletRequest().getSession().getAttribute("locale").toString().equals("de_DE")) {
                        locale = new Locale("de", "DE");
                    }
                }
            }
            ResourceBundle bundle = ResourceBundle.getBundle(baseName, locale);
            value = bundle.getString(key);
            returnValue = new String(value.getBytes("ISO-8859-1"), "UTF-8");
        } catch (MissingResourceException e) {
            // Missing key
            try {
                // return the Key
                String keyString = key.replace("_", space);
                returnValue = new String(keyString.getBytes("ISO-8859-1"), "UTF-8");
            } catch (UnsupportedEncodingException e1) {
                e1.printStackTrace();
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return returnValue + space;
    }

I can call this Method from everywhere to use this getText() method. My Components they get a internationalization text by call this method like this: label.setCaption(Internationalization.getText("Willkommen"));

I have now two Buttons "DE" and "EN" for the languages german and english. In the ClickListener of this Buttons i set the new Locale like this:

    btnLanguageDE.addClickListener(e -> {
VaadinServletService.getCurrentServletRequest().getSession().setAttribute("locale", new Locale("de", "DE"));
        });
btnLanguageEN.addClickListener(e -> {
VaadinServletService.getCurrentServletRequest().getSession().setAttribute("locale", new Locale("en", "EN"));
logger.debug("Internationalization change to: EN"); 
        });

The Problem is, if i click on the Button they set the local but didn't reload the components on the page. It changes only if i reload the page manually. I tried to call this UI.getCurrent().getPage().getLocation(); but no effects.

How can i reload the components with the actual locale ?

kscherrer :

There is a good documentation about internationlization / localization with vaadin.

First up, you seem to have implemented your own logic how you can access translated labels with your Internationalization class.
Vaadin has already implemented this; you can let your Internationalization class implement I18NProvider (and annotate it with @Component if you're using Spring. If not, you need to register it somehow I think the linked docs explain how) and change your methodname from getText to getTranslation. Every Vaadin Component (therefore in every view, since view classes must extend a component) can call getTranslation(keyString); where the I18NProvider is fetched and used.
All this is optional since you already made similar implementations yourself. But doing it like this would be best practice.


Now to your actual question - You need to let every view that has a translateable string implements LocaleChangeObserver. This forces the view to implement the method localeChange(LocaleChangeEvent event) which is called automatically when the locale of the UI is changed. in the localeChange method, you can set all the texts anew that are translated.
There is no need for refreshing the page!

public void localeChange(LocaleChangeEvent event){
    label.setCaption(getTranslation("Willkommen"));
}

You can change the Locale of the UI like this:

UI.getCurrent().setLocale(myNewLocale);

I have shared the code for my Language Selection in another StackOverflow post - I think you will find the example code relevant, as my Select component has a valueChangeListener that sets a new Locale - which directly triggers localeChange.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326187&siteId=1