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 ThreadLocal instance =
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 List locales = 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>
Комментариев нет:
Отправить комментарий