单击国际化按钮后如何在Vaadin中重新加载组件?

时间:2019-05-29 08:10:04

标签: java internationalization vaadin

我在Vaadin中使用国际化I18N。我有一个使用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;
    }

我可以从任何地方调用此方法来使用此getText()方法。 我的组件通过调用此方法来获得国际化文本,如下所示: label.setCaption(Internationalization.getText("Willkommen"));

我现在有两个分别用于德语和英语的按钮“ DE”和“ EN”。在此按钮的ClickListener中,我像这样设置新的区域设置:

    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"); 
        });

问题是,如果我单击“按钮”,它们将设置为本地,但没有重新加载页面上的组件。仅当我手动重新加载页面时,它才会更改。 我试图称其为UI.getCurrent().getPage().getLocation();,但没有效果。

如何使用实际的语言环境重新加载组件?

3 个答案:

答案 0 :(得分:3)

有一个documentation about internationlization / localization和vaadin。

首先,您似乎已经实现了自己的逻辑,该如何使用国际化类访问翻译后的标签。
Vaadin已经实现了这一点。您可以让您的国际化类实现I18NProvider(如果使用的是Spring,请使用@Component进行注释。否则,您需要以某种方式注册它(我认为链接的文档会说明如何)),然后从{{ 1}}至getText。每个Vaadin组件(因此,在每个视图中,因为视图类必须扩展一个组件)可以调用getTranslation,在其中提取并使用getTranslation(keyString);
所有这些都是可选的,因为您已经自己进行了类似的实现。但是这样做是最好的做法。


现在是您的实际问题-您需要让每个具有可转换字符串I18NProvider的视图。这会强制视图实现方法implements LocaleChangeObserver,当UI的区域设置更改时,该方法自动 。 在localeChange(LocaleChangeEvent event)方法中,可以重新设置所有已翻译的文本。
无需刷新页面!

localeChange

您可以这样更改UI的区域设置:

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

我在another StackOverflow post中共享了“语言选择”的代码-我想您会发现示例代码相关,因为我的UI.getCurrent().setLocale(myNewLocale); 组件具有一个valueChangeListener,它设置了一个新的Locale-直接触发{ {1}}。

答案 1 :(得分:0)

我确实建议您重新加载页面UI.getCurrent().getPage().reload()

答案 2 :(得分:0)

您应该看一下I18N教程。您可以在这里找到它们:Vaadin Tutorials - I18N

干杯斯文