Load resources based upon client environment at startupTag(s): Internationalization


There are two ways to include resources based on the current Locale. One way is to use Properties files and the other are classes extending the ListResourceBundle base class. You need to follow a naming standard so that the JVM retrieves the right resources bundle.

Note that if a resource is missing for the current locale then the default definition is used.

[International.java (main program)]

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.text.*;

public class International extends JFrame
    implements ActionListener
{
  JLabel aLabel;
  JLabel vLabel;
  JCheckBox aCheckbox;
  JButton aButton;
  JButton vButton;
  JTextField aTextField;
  NumberFormat nf;

  public void initGUI(){
    setLayout(new FlowLayout());

    // String
    aLabel = new JLabel
      (MyResources.rb.getString("aLabel"));
    add(aLabel);

    // Object
    aCheckbox =
      (JCheckBox)MyResources.rb.getObject("aCheckbox");
    add(aCheckbox);

    // String concatenation with MessageFormat
    Date d = new Date();
    MessageFormat mf = new MessageFormat
       (MyResources.rb.getString("aButton"));
    aButton = new JButton
      (mf.format(new Object [] { d }));
    add(aButton);

    // Number format output
    double dn = 3.1416;
    nf = (NumberFormat)
      (MyResources.rb.getObject("aNumber"));
    aTextField = new JTextField(6);
    add(aTextField);
    aTextField.setText(nf.format(dn));

    // Number input validation
    vButton =
      (JButton)MyResources.rb.getObject("vButton");
    add(vButton);
    vButton.addActionListener(this);

    vLabel = new JLabel("validation message ...");
    add(vLabel);

    setSize(400,400);
  }

  public void actionPerformed(ActionEvent ae) {
    if (ae.getSource() == vButton) {
       try {
         nf.parse(aTextField.getText());
         vLabel.setText(MyResources.rb.getString("numOK"));
         vLabel.invalidate();
         this.validate();
       }
       catch (ParseException pe) {
         pe.printStackTrace();
         vLabel.setText(MyResources.rb.getString("numERR"));
         vLabel.invalidate();
         this.validate();
       }
    }
  }

  public static void  main(String args[]) {
      System.out.println("Current Local : " + Locale.getDefault());
      Thread t = new Thread () {
          public void run() {
              International frame = new International();
              frame.initGUI();
              frame.setVisible(true);
          }
      };

      SwingUtilities.invokeLater(t);
  }
}
[MyResources.java (default resources)]
import java.util.*;
import javax.swing.*;
import java.text.*;

public class MyResources extends ListResourceBundle {
  public static ResourceBundle rb =
    ResourceBundle.getBundle("MyResources");

  public Object [][] getContents() {
    return contents;
  }

  static final Object[][] contents =  {
       { "myLabel" , "A Label" } ,
       { "aCheckbox", new JCheckBox("Yes") } ,
       { "aButton"  , "Today {0,date,long}"},
       { "aNumber"  , new DecimalFormat("0.####")},
       { "vButton"  , new JButton("Validate number")},
       { "numOK"       , "Valid!" },
       { "numERR"      , "Invalid"}
  };
}
[MyResources_en.java (english language resources)]
The classname format is [name][language ID][country code].java.
You can retrieve a list of language IDs and country codes at the Unicode organization Web site

import java.util.*;

public class MyResources_en extends ListResourceBundle {
  public Object [][] getContents() {
    return contents;
  }
  static final Object[][] contents =  {
    { "aLabel"     , "a Label (en)" }
  };
}
[MyResources_fr.java (french language resources)]
import java.util.*;
import javax.swing.*;

public class MyResources_fr extends ListResourceBundle {
  public Object [][] getContents() {
    return contents;
  }

  static final Object[][] contents =  {
    { "aLabel"     , "une étiquette (fr)" } ,
    { "aCheckbox", new JCheckBox("Oui (fr)")} ,
    { "vButton" , new JButton("Validation du nombre")},
    { "numOK" , "Valide!"},
    { "numERR", "Invalide"}
  };
}
[MyResources_fr_CA.java (french language (for Canada) resources)]
import java.util.*;

public class myResources_fr_CA extends ListResourceBundle {
  public Object [][] getContents() {
    return contents;
  }

  static final Object[][] contents =  {
    { "aLabel"     , "une étiquette (fr CA)" } ,
  };
}
This example uses ListResourceBundle classes to store the required resources. It is possible to substitute them for Properties files without any change to the code. The properties files must have the .properties extension.

See this How-to.


blog comments powered by Disqus