Tuesday, January 19, 2010

Dynamic Internationalization in Java (Multilingual Support)




Getting Started
Dynamic Internationalization in Java (Multilingual Support)


Dynamic internationalization is the process of setting up your program so that the locale can be changed “on-the-fly” with the program running. Otherwise, with static internationalization, the locale will load once (at program start-up) based on the settings of your operating system. To change the language you will have to reboot the OS or, at the least, restart the application.

Dynamic internationalization is useful if you will have multiple users from different language backgrounds accessing the same application session. Dynamic Internationalization will allow each to choose their preferred language while they are using the program.

Dynamic internationalization deals not only with language, but also locale-sensitive formats such as calendars, dates, times, numbers, currency, etc.

The following example is one way to accomplish dynamic internationalization. There are many other possible ways to achieve the same desired result.

1) Download softsmithy.jar and add it to your library in Netbeans:
http://sourceforge.net/projects/softsmithy/files/

2) Create a ‘New Project’ in Netbeans. Choose ‘Java Application’ and name the project ‘dynamicinternationalization’. Uncheck the ‘Create Main Class’.

3) Right-click on your package and add a new ‘Java Class’ and name it ‘DIExample’.

4) Right-click on your project and add a new ‘Java Package’ and name it ‘dynamicinternationalization.resources’

5) Right-click on this new ‘dynamicinternationalization.resources’ bundle and add a new ‘Properties File’ and name it ‘DIExample’.

6) Repeat step 5 again for each language you are adding. For our example please create the following property files: ‘DIExample_en’, ‘DIExample_fr’, ‘DIExample_ja’

7) Open the ‘DIExample.properties’ file and enter the following code:
langLabel = to eat
8) Right-click on the ‘DIExample.properties’ and choose open and fill in each language translation.

Finally open the ‘DIExample.java’ file and enter the following code:
package dynamicinternationalization;

import java.util.Locale;
import java.util.ResourceBundle;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JComponent;
import javax.swing.SwingUtilities;
import org.softsmithy.lib.swing.LocaleCellRenderer;
import org.softsmithy.lib.swing.XDefaultListCellRenderer;
import org.softsmithy.lib.util.LocaleDisplay;
import org.softsmithy.lib.util.Locales;


public class DIExample extends javax.swing.JDialog {

private javax.swing.JLabel langLabel;
private javax.swing.JComboBox langList;
private Locale[] locales;
private Locale currentLocale = Locale.ENGLISH;

public DIExample(java.awt.Frame parent, boolean modal) {
super(parent, modal);
initComponents();

locales = new Locale[] {Locale.ENGLISH,
Locale.JAPANESE,
Locale.FRENCH,
new Locale("ja", "JP"),
new Locale("fr", "CH"),};

langList.setRenderer(new XDefaultListCellRenderer(new LocaleCellRenderer()));
updateLocale();
updateModel();

}

private void updateModel() {
Locale[] l = Locales.sort(locales, LocaleDisplay.NAME, currentLocale);
DefaultComboBoxModel model = new DefaultComboBoxModel(l);
model.setSelectedItem(currentLocale);
langList.setModel(model);
}
private void updateLocale() {
Locale.setDefault(currentLocale);
JComponent.setDefaultLocale(currentLocale);
SwingUtilities.updateComponentTreeUI(langList);
}

private void langListActionPerformed(java.awt.event.ActionEvent evt)
{
currentLocale = (Locale) langList.getSelectedItem();
updateLocale();
updateModel();

if(currentLocale.getLanguage().equals("en")){
Locale localizacion = Locale.US;
ResourceBundle bundle = ResourceBundle.getBundle("dynamicinternationalization.resources.DIExample",localizacion);
langLabel.setText(bundle.getString("langLabel")); // NOI18N

}

else if(currentLocale.getLanguage().equals("ja")){
Locale localizacion2;
localizacion2 = new Locale("ja");
ResourceBundle bundle = ResourceBundle.getBundle("dynamicinternationalization.resources.DIExample",localizacion2);
langLabel.setText(bundle.getString("langLabel")); // NOI18N
}

else if(currentLocale.getLanguage().equals("fr")){
Locale localizacion3;
localizacion3 = new Locale("fr");
ResourceBundle bundle = ResourceBundle.getBundle("dynamicinternationalization.resources.DIExample",localizacion3);
langLabel.setText(bundle.getString("langLabel")); // NOI18N
}

}

private void initComponents() {

langList = new javax.swing.JComboBox();
langLabel = new javax.swing.JLabel();

setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);

langList.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
langListActionPerformed(evt);
}
});

java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("dynamicinternationalization.resources.DIExample"); // NOI18N
langLabel.setText(bundle.getString("langLabel"));

org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(layout.createSequentialGroup()
.addContainerGap()
.add(langList, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 146, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED)
.add(langLabel, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 102, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
.addContainerGap(124, Short.MAX_VALUE))
);
layout.setVerticalGroup(
layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(layout.createSequentialGroup()
.addContainerGap()
.add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
.add(langList, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
.add(langLabel))
.addContainerGap(257, Short.MAX_VALUE))
);

pack();
}

public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
DIExample dialog = new DIExample(new javax.swing.JFrame(), true);
dialog.addWindowListener(new java.awt.event.WindowAdapter() {
public void windowClosing(java.awt.event.WindowEvent e) {
System.exit(0);
}
});
dialog.setVisible(true);
}
});
}

}
Internationalization links:
http://joconner.com/javai18n/articles/Multilingual.html
http://joconner.com/
http://netbeans.org/kb/docs/java/gui-automatic-i18n.html
http://www.progdoc.de/papers/intSwing/intSwing.html
http://www.multilingual.com/articleDetail.php?id=685

2 comments:

  1. Here is a very good online tool that works perfectly with gettext: https://poeditor.com/. You just need to create an account and upload your po, pot or other type of file you might have and the translation interface will help you through your work.

    ReplyDelete