Vaadin Internationlization localization.
Впервые познакомившись с Vaadin я был в восторге от него, но со временем интерес к нему прошел, из-за ряда вещей но кое-какие наработки остались.Вот одна из наработок - это как наиболле просто локализовать программу, точнее где правильно хранить локаль пользователя. Правильно хранить локаль и другие данные нужно в глобальной сессии пользователя, для этого нужно создать ThreadLocal сингильтон который будет содержать объекты ResourceBundle bundle, Locale locale, Application app и сингильтон при этом должен наследовать interface ApplicationContext.TransactionListener - у этого интерфейса есть 2 метода:
public void transactionStart(Application application, Object transactionData) { if (this.app == application) instance.set(this); }
который связывает данные пользователя с текушим потоком во ThreadLocal и
public void transactionEnd(Application application, Object transactionData) { // Clear the reference to avoid potential problems if (this.app == application) instance.set(null); }
который разрывает эту связь. Коротко что мы здесь сделали - ThreadLocal позволяет нам хранить
разные данные для каждого пользователя, т.е. для каждого потока(сессии пользователя) будут разные
значения объектов ResourceBundle bundle, Locale locale.
package com.vit; import com.vaadin.Application; import com.vaadin.service.ApplicationContext; import java.io.Serializable; import java.util.Locale; import java.util.ResourceBundle; /** Holds data for one user session. */ public class AppData implements ApplicationContext.TransactionListener, Serializable { private ResourceBundle bundle; private Locale locale; // Current locale private Application app; // For distinguishing between apps private static ThreadLocalinstance = new ThreadLocal (); public AppData(Application app) { this.app = app; // It's usable from now on in the current request instance.set(this); } @Override public void transactionStart(Application application, Object transactionData) { // Set this data instance of this application // as the one active in the current thread. if (this.app == application) instance.set(this); } @Override public void transactionEnd(Application application, Object transactionData) { // Clear the reference to avoid potential problems if (this.app == application) instance.set(null); } public static void initLocale(Locale locale, String bundleName) { instance.get().locale = locale; instance.get().bundle = ResourceBundle.getBundle(bundleName, locale); } public static Locale getLocale() { return instance.get().locale; } public static String getMessage(String msgId) { return instance.get().bundle.getString(msgId); } }
Дальше создаем ComboBox который позволяет нам менять текушую локаль и
соответственно настроить под неё ResourceBundle.
package com.vit; import com.vaadin.ui.ComboBox; import java.util.Arrays; import java.util.List; import java.util.Locale; public class ComboBoxLocale extends ComboBox{ private final Listlocales = Arrays.asList( new Locale("ru", "RU"), Locale.US, Locale.ENGLISH, AppData.getLocale()); public ComboBoxLocale(String caption) { super(caption); for (Locale l:locales) { addItem(l); setItemCaption(l,l.getDisplayName()); } setNullSelectionAllowed(false); setImmediate(true); setVisible(true); } @Override public void attach() { super.attach(); setValue(AppData.getLocale()); } }
Далее создаем файл ресурсов для английского языка MyVaadinApplication_en.properties:
Button.text=Click me English Label.text=Thank you for clicking Еnglish
и для русского MyVaadinApplication_ru_RU.properties:
Button.text=Click me Russian Label.text=Thank you for clicking Russian
И наконец все встраиваем в наше веб приложение.
package com.vit; import com.vaadin.Application; import com.vaadin.data.Property; import com.vaadin.ui.Button.ClickEvent; import com.vaadin.ui.*; import com.vaadin.ui.themes.Runo; import java.util.Locale; public class MyVaadinApplication extends Application { private Window window; public ComboBoxLocale comboBoxLocale; public Button button; @Override public void init() { setTheme("runo"); window = new Window("Hello Vaadin!"); setMainWindow(window); window.setImmediate(true); // Create the application data instance AppData sessionData = new AppData(this); // Register it as a listener in the application context getContext().addTransactionListener(sessionData); // Initialize the session-global data AppData.initLocale(getLocale(), MyVaadinApplication.class.getSimpleName()); comboBoxLocale = new ComboBoxLocale("Change Locale:"); comboBoxLocale.setWidth("150px"); comboBoxLocale.setValue(getLocale()); Property.ValueChangeListener listener = new Property.ValueChangeListener() { public void valueChange(Property.ValueChangeEvent event) { AppData.initLocale((Locale) comboBoxLocale.getValue(), MyVaadinApplication.class.getSimpleName()); setLocale((Locale) comboBoxLocale.getValue()); window.showNotification( ((Locale) comboBoxLocale.getValue()).getDisplayName() + " : " + AppData.getLocale().getLanguage() ); button.setLocale((Locale) comboBoxLocale.getValue()); button.setCaption(AppData.getMessage("Button.text")); } }; comboBoxLocale.addListener(listener); window.addComponent(comboBoxLocale); button = new Button(AppData.getMessage("Button.text")); button.addListener(new Button.ClickListener() { public void buttonClick(ClickEvent event) { window.addComponent(new Label(AppData.getMessage("Label.text"))); } }); button.addStyleName(Runo.BUTTON_SMALL); window.addComponent(button); } }
Опишу пару строк важных строк
создаем наш сингильтон - AppData sessionData = new AppData(this);
регистрируем наш обработчик - getContext().addTransactionListener(sessionData); устанвливаем текушую локаль и связываем с ним ResourceBundle - AppData.initLocale(getLocale(),MyVaadinApplication.class.getSimpleName());
создаем кнопку и выдергиваем строчку Button.text из ResourceBundle - button = new Button(AppData.getMessage("Button.text"));
Вот и все на последок привожу файл pom.xml с зависимостями:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.vit</groupId> <artifactId>VaadinTest11</artifactId> <packaging>war</packaging> <version>1.0-SNAPSHOT</version> <name>Vaadin Web Application</name> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <vaadin.version>6.6.6</vaadin.version> <gwt.version>2.3.0</gwt.version> <gwt.plugin.version>2.2.0</gwt.plugin.version> </properties> <build> <finalName>test</finalName> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.5</source> <target>1.5</target> <encoding>UTF-8</encoding> </configuration> </plugin> <!-- A simple Jetty test server at http://localhost:8080/VaadinTest11 can be launched with the Maven goal jetty:run and stopped with jetty:stop --> <plugin> <groupId>org.mortbay.jetty</groupId> <artifactId>maven-jetty-plugin</artifactId> <version>6.1.24</version> <configuration> <stopPort>9966</stopPort> <stopKey>VaadinTest11</stopKey> <!-- Redeploy every x seconds if changes are detected, 0 for no automatic redeployment --> <scanIntervalSeconds>0</scanIntervalSeconds> <!-- make sure Jetty also finds the widgetset --> <webAppConfig> <contextPath>/VaadinTest11</contextPath> <baseResource implementation="org.mortbay.resource.ResourceCollection"> <!-- Workaround for Maven/Jetty issue http://jira.codehaus.org/browse/JETTY-680 --> <!-- <resources>src/main/webapp,${project.build.directory}/${project.build.finalName}</resources> --> <resourcesAsCSV>src/main/webapp,${project.build.directory}/${project.build.finalName}</resourcesAsCSV> </baseResource> </webAppConfig> </configuration> </plugin> </plugins> </build> <repositories> <repository> <id>vaadin-snapshots</id> <url>http://oss.sonatype.org/content/repositories/vaadin-snapshots/</url> <releases> <enabled>false</enabled> </releases> <snapshots> <enabled>true</enabled> </snapshots> </repository> <repository> <id>vaadin-addons</id> <url>http://maven.vaadin.com/vaadin-addons</url> </repository> </repositories> <dependencies> <dependency> <groupId>com.vaadin</groupId> <artifactId>vaadin</artifactId> <version>${vaadin.version}</version> </dependency> </dependencies> </project>
Комментариев нет:
Отправить комментарий