lunes, 15 de abril de 2019

15. Vaadin i18n (2). Locale session attributes and Locale flag icons. A combo with flags!

updated on April 16, 2019

0. Introduction

We need to store Locale information in the session, and for selecting the locales, it is nice seeing the flags. So it can be interesting saving the Locale information in the session-scoped bean SessionData. The flags icons can be stored in the folder :

  • Deployed Resources/webapp/frontend/icon/flags


1. Updating the previous SessionData class to get Locales

Remember that the SessionData class was an example of a session scoped class that was annotated by @VaadinSessionScoped and the injected into other classes (in this case into the "LoginForm" class

Now 2 attributes are added:
  1. Locale 
  2. LangEnum
And they are initialised in the method "init()" that is annotated by @PostConstruct. Note the removing of the CURRENT_USER attribute from the session to avoid unwanted access to the application. Here is the code


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
package openadmin.session;

import java.util.Locale;

import javax.annotation.PostConstruct;
//import javax.enterprise.context.SessionScoped;
//import javax.inject.Named;

import com.vaadin.cdi.annotation.VaadinSessionScoped;
import com.vaadin.flow.server.VaadinService;

import openadmin.i18n.LangEnum;
import openadmin.utils.VaadinUtils;

import lombok.Getter;
import lombok.Setter;

//@Named @SessionScoped
@VaadinSessionScoped
public class SessionData {
 
 private Locale loc=null;
 @Getter @Setter
 private LangEnum langEnum=null;
 
 
 @PostConstruct
 private void init() {
  loc=VaadinService.getCurrentRequest().getLocale();
  langEnum=LangEnum.getFromLocale(loc);
  
  System.out.println("SessionData.init() called.");
  // Remove the session attribute that informs the user, if exists
  VaadinUtils.getWrappedSession().removeAttribute("CONNECTED_USER");
 }
}

2. Adding the flag icons


There are plenty of free flag icons on the web. I have downloaded some 64 x 64 pixels flags.

Remember to place them in this folder
  • Deployed Resources/webapp/frontend/icon/flags
And create the folder route from "webapp" folder if not exists.

If not exists these folders in the webapp you should create them


3. A Combo with flags icons.

Important things to take into account:

  1. To display the flags in the combo items, we need a template that manages HTML code
  2. In this case, the combo wraps a LangEnum type (ComboBox<LangEnum>) as it is the source of the items.
  3. When the combo changes its values, it should set the session locale to the new value and it should also change all the labels in the parent form that are affected by i18n.
For changing all the labels affected by i18n in the parent form, the parent form should implement an interface (II18nChange that defines a method for changing the labels called changeI18nLabels())


Let's see the code of this interface


1
2
3
4
5
package openadmin.ui;

public interface II18nChange {
 public void changeI18nLabels();
}

Now the code of our customized combo, note the template code, the change of the session locale and how the event can change the parent form's labels.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
package openadmin.ui;

import java.util.ArrayList;
import java.util.Arrays;

import com.vaadin.flow.component.combobox.ComboBox;
import com.vaadin.flow.data.renderer.TemplateRenderer;

import openadmin.i18n.LangEnum;
import openadmin.session.SessionData;

@SuppressWarnings("serial")
public class LocaleCombo extends ComboBox<LangEnum> {

 // Template to show in each choice of the combo
 private static String HMLTemplate=
  "<p> " + 
   " <img src=\"frontend/icon/flags/[[item.lang]].png\" " + 
     " width=\"40\" " + 
        " height=\"40\" " + 
     " style=\"vertical-align:middle\"" + 
   " > " + 
   " [[item.def]] " + 
  "</p>";
 
 // Constructor
 public LocaleCombo(SessionData sesData, II18nChange parentForm) {
  // Sets the item label generator that is used to produce the strings shown in the combo box for each item. By default, String.valueOf(Object) is used.
  this.setItemLabelGenerator(LangEnum::getDefinition);
  
  // Sets the data items of this component provided as a collection.
  this.setItems(new ArrayList<>(Arrays.asList(LangEnum.values())));
  
  // Sets the TemplateRenderer responsible to render the individual items in the list of possible choices of the ComboBox
  this.setRenderer(
   TemplateRenderer
    .<LangEnum>of(HMLTemplate)
    .withProperty("lang", LangEnum::name).withProperty("def", LangEnum::getDefinition));
  
  // Set the initial value of the combo
  this.setValue(sesData.getLangEnum());
  
  // Add the behaviour of the change value event that afectsd the parent form
  this.setListener(sesData, parentForm);
  
 }
 
 // Define the event for changing the value and modify all the labels affected by the i18n changes
 private void setListener(SessionData sesData, II18nChange parentForm) {
  this.addValueChangeListener(
   event -> {
    if (this.getValue()!=null) {
     
     // Update the session locale
     sesData.setLangEnum(this.getValue());
     
     // Change all labels afected by i18n changes
     parentForm.changeI18nLabels(); 
    } 
  });
 }
 
} 


No hay comentarios:

Publicar un comentario