Java Tutorial/I18N/ResourceBundle

Материал из Java эксперт
Перейти к: навигация, поиск

An Internationalized Swing Application

File: MyResources_en_US.properties
userName=User Name
password=Password
login=Login
File: MyResources_fr_CA.properties
userName=Compte
password=Mot de passe
login=Ouvrir session
File: MyResources.properties (the default)
userName=User Name
password=Password
login=Login

These files are placed in the directory specified in the class path.



   <source lang="java">

import java.awt.GridLayout; import java.util.Locale; import java.util.ResourceBundle; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPasswordField; import javax.swing.JTextField; public class MainClass {

 public static void main(String[] args) {
   Locale locale = Locale.getDefault();
   ResourceBundle rb = ResourceBundle.getBundle("MyResources", locale);
   JFrame.setDefaultLookAndFeelDecorated(true);
   JFrame frame = new JFrame("I18N Test");
   frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   frame.setLayout(new GridLayout(3, 2));
   frame.add(new JLabel(rb.getString("userName")));
   frame.add(new JTextField());
   frame.add(new JLabel(rb.getString("password")));
   frame.add(new JPasswordField());
   frame.add(new JButton(rb.getString("login")));
   frame.pack();
   frame.setVisible(true);
 }

}</source>





Convert ResourceBundle to Map

   <source lang="java">

import java.util.Enumeration; import java.util.HashMap; import java.util.Iterator; import java.util.Locale; import java.util.Map; import java.util.ResourceBundle; public class Main {

 public static void main(String[] args) {
   ResourceBundle resource = ResourceBundle.getBundle("Messages", Locale.UK);
   Map<String, String> map = convertResourceBundleToMap(resource);
   Iterator iterator = map.keySet().iterator();
   while (iterator.hasNext()) {
     String key = (String) iterator.next();
     String value = map.get(key);
     System.out.println(key + " = " + value);
   }
 }
 static Map<String, String> convertResourceBundleToMap(ResourceBundle resource) {
   Map<String, String> map = new HashMap<String, String>();
   Enumeration<String> keys = resource.getKeys();
   while (keys.hasMoreElements()) {
     String key = keys.nextElement();
     map.put(key, resource.getString(key));
   }
   return map;
 }

}</source>





Convert ResourceBundle to Properties

   <source lang="java">

import java.util.Enumeration; import java.util.Locale; import java.util.Properties; import java.util.ResourceBundle; public class Main {

 public static void main(String[] args) {
   ResourceBundle resource = ResourceBundle.getBundle("Messages", Locale.UK);
   Properties properties = convertResourceBundleToProperties(resource);
   Enumeration keys = properties.keys();
   while (keys.hasMoreElements()) {
     String key = (String) keys.nextElement();
     String value = (String) properties.get(key);
     System.out.println(key + " = " + value);
   }
 }
 static Properties convertResourceBundleToProperties(ResourceBundle resource) {
   Properties properties = new Properties();
   Enumeration<String> keys = resource.getKeys();
   while (keys.hasMoreElements()) {
     String key = keys.nextElement();
     properties.put(key, resource.getString(key));
   }
   return properties;
 }

}</source>





Customizing Resource Bundle Loading

   <source lang="java">

import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.net.URLConnection; import java.util.Collections; import java.util.Enumeration; import java.util.List; import java.util.Locale; import java.util.Properties; import java.util.ResourceBundle; import java.util.Set; public class XMLResourceBundleControl extends ResourceBundle.Control {

 private static String XML = "xml";
 public List<String> getFormats(String baseName) {
   return Collections.singletonList(XML);
 }
 public ResourceBundle newBundle(String baseName, Locale locale, String format,
     ClassLoader loader, boolean reload) throws IllegalAccessException, InstantiationException,
     IOException {
   if ((baseName == null) || (locale == null) || (format == null) || (loader == null)) {
     throw new NullPointerException();
   }
   ResourceBundle bundle = null;
   if (!format.equals(XML)) {
     return null;
   }
   String bundleName = toBundleName(baseName, locale);
   String resourceName = toResourceName(bundleName, format);
   URL url = loader.getResource(resourceName);
   if (url == null) {
     return null;
   }
   URLConnection connection = url.openConnection();
   if (connection == null) {
     return null;
   }
   if (reload) {
     connection.setUseCaches(false);
   }
   InputStream stream = connection.getInputStream();
   if (stream == null) {
     return null;
   }
   BufferedInputStream bis = new BufferedInputStream(stream);
   bundle = new XMLResourceBundle(bis);
   bis.close();
   return bundle;
 }
 public static void main(String args[]) {
   ResourceBundle bundle = ResourceBundle.getBundle("Strings", new XMLResourceBundleControl());
   String string = bundle.getString("Key");
   System.out.println("Key: " + string);
 }

} class XMLResourceBundle extends ResourceBundle {

 private Properties props;
 XMLResourceBundle(InputStream stream) throws IOException {
   props = new Properties();
   props.loadFromXML(stream);
 }
 protected Object handleGetObject(String key) {
   return props.getProperty(key);
 }
 public Enumeration<String> getKeys() {
   Set<String> handleKeys = props.stringPropertyNames();
   return Collections.enumeration(handleKeys);
 }

}</source>





Displaying Calendar Names

MyResources.properties file



   <source lang="java">

okKey = OK cancelKey = Cancel submitKey = Submit</source>





File name for java.util.ResourceBundle

java.util.ResourceBundle class enables you to choose and read the properties file specific to the user"s locale and look up the values.

A ResourceBundle object has a base name. In order for a ResourceBundle object to pick up a properties file, the filename must be composed of the ResourceBundle base name, followed by an underscore, followed by the language code, and optionally followed by another underscore and the country code.

The format for the properties file name is as follows:



   <source lang="java">

basename_languageCode_countryCode</source>





Get resource bundle for a certain locale

   <source lang="java">

import java.util.Locale; import java.util.ResourceBundle; import java.util.MissingResourceException; public class Animals {

 public static void main(String [] argv) {
   ResourceBundle animalResources;
   try {
     animalResources = ResourceBundle.getBundle("AnimalResources", Locale.getDefault());
     System.out.println(animalResources.getString("Animals"));
   } catch (MissingResourceException mre) {
     mre.printStackTrace();
   }
 }

}

  1. Sample properties file with keys whose values span more than one line

Animals=Cat, Dog, Giraffe, \

   Bear, Moose</source>
   
  
 
  



Java file based resource bundle

   <source lang="java">

import java.util.Enumeration; import java.util.Locale; import java.util.ResourceBundle; import java.util.MissingResourceException; public class HelloResourceBundleExample {

 public static void main(String [] argv) {
   try {
     Locale frenchLocale = new Locale("fr", "FR");
     ResourceBundle rb = ResourceBundle.getBundle("HelloResourceBundle", frenchLocale);
     System.out.println(rb.getString("Hello"));
     System.out.println(rb.getString("Goodbye"));
   } catch (MissingResourceException mre) {
     mre.printStackTrace();
   }
 }

} import java.util.Enumeration; import java.util.ResourceBundle; import java.util.StringTokenizer; public class HelloResourceBundle extends ResourceBundle {

 private String keys = "Hello Goodbye";
   public Object handleGetObject(String key) {
     if (key.equals("Hello")) return "Hello";
     if (key.equals("Goodbye")) return "Goodbye";
     return null;
   }
   public Enumeration getKeys() {
     StringTokenizer keyTokenizer = new StringTokenizer(keys);
     return keyTokenizer;
   }

} import java.util.Enumeration; import java.util.ResourceBundle; import java.util.StringTokenizer; public class HelloResourceBundle_fr extends HelloResourceBundle {

 public Object handleGetObject(String key) {
   if (key.equals("Hello")) return "Bonjour";
   return null;
 }

} import java.util.Enumeration; import java.util.ResourceBundle; import java.util.StringTokenizer; public class HelloResourceBundle_fr_FR extends HelloResourceBundle_fr {

 public Object handleGetObject(String key) {
   if (key.equals("Goodbye")) return "Au Revoir";
   return null;
 }

}</source>





JOptionPane Resources

   <source lang="java">

import java.awt.Font; import java.awt.GraphicsEnvironment; import java.util.Locale; import java.util.ResourceBundle; import javax.swing.JDialog; import javax.swing.JOptionPane; public class JOptionPaneDemonstrationLocalized {

 public static void main(String[] argv) {
   GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
   Font unicodeFont = new Font("LucidaSans", Font.PLAIN, 12);
   ResourceBundle bundle = ResourceBundle.getBundle("JOptionPaneResources",
       Locale.getDefault());
   String[] textMessages = new String[3];
   textMessages[0] = bundle.getString("Yes");
   textMessages[1] = bundle.getString("No");
   textMessages[2] = bundle.getString("Cancel");
   JOptionPane jop = new JOptionPane(bundle.getString("MessageText"),
       JOptionPane.ERROR_MESSAGE, JOptionPane.YES_NO_CANCEL_OPTION, null,
       textMessages);
   JDialog jopDialog = jop.createDialog(null, bundle.getString("TitleText"));
   jop.setFont(unicodeFont);
   jopDialog.setVisible(true);
   Object userSelection = jop.getValue();
 }

}

  1. JOptionPane text resources in Hebrew

Yes=\u05db\u05df No=\u05dc\u05d0 OK=\u05d0\u05d9\u05e9\u05d5\u05e8 Cancel=\u05d1\u05d9\u05d8\u05d5\u05dc MessageText=\u05d6\u05d0\u05ea \u05d4\u05d5\u05d3\u05e2\u05d4 TitleText=\u05d6\u05d0\u05ea \u05db\u05d5\u05ea\u05e8\u05ea</source>





Load resources via a resources file

   <source lang="java">

import java.util.Locale; import java.util.ResourceBundle; public class Main {

 public static void main(String[] argv) throws Exception {
   ResourceBundle rb = ResourceBundle.getBundle("res.ResourcesDynamic", Locale.getDefault());
   System.out.println(rb.getString("title"));
 }

} [RresourcesDynamic.properties] title=Example [RresourcesDynamic_en.properties] title=Example [ResourcesDynamic_fr.properties] title=Exemple [ResourcesDynamic_de.properties] title=Beispiel</source>





Reading Properties Files using ResourceBundle

You can obtain an instance of ResourceBundle by calling its static getBundle method.



   <source lang="java">

public static ResourceBundle getBundle(java.lang.String baseName) public static ResourceBundle getBundle(java.lang.String baseName, Locale locale)</source>



If the entry with the specified key is not found, a java.util.MissingResourceException will be thrown.


ResourceBundle: avoid a performance penalty by superfluous resource (and classes loaded by Class.forName) lookups on web server in applets.

   <source lang="java">

/*

* JFreeChart : a free chart library for the Java(tm) platform
* 
*
* (C) Copyright 2000-2008, by Object Refinery Limited and Contributors.
*
* Project Info:  http://www.jfree.org/jfreechart/index.html
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
* USA.
*
* [Java is a trademark or registered trademark of Sun Microsystems, Inc.
* in the United States and other countries.]
*
* --------------------------
* ResourceBundleWrapper.java
* --------------------------
* (C)opyright 2008, by Jess Thrysoee and Contributors.
*
* Original Author:  Jess Thrysoee;
* Contributor(s):   David Gilbert (for Object Refinery Limited);
*
* Changes
* -------
* 18-Dec-2008 : Version 1 (JT);
*
*/

import java.net.URL; import java.net.URLClassLoader; import java.util.ArrayList; import java.util.List; import java.util.Locale; import java.util.ResourceBundle; /**

* Wrapper of ResourceBundle.getBundle() methods. This wrapper is introduced to
* avoid a dramatic performance penalty by superfluous resource (and classes
* loaded by Class.forName) lookups on web server in applets.
*
*
 * public class AppletC extends javax.swing.JApplet {
 *    public void init() {
 *       ResourceBundleWrapper.removeCodeBase(getCodeBase(),
 *               (URLClassLoader) getClass().getClassLoader());
 *    ...
 * 
*
* @see 
*
* @since 1.0.12
*/

public class ResourceBundleWrapper {

   /**
    * A special class loader with no code base lookup.  This field may be
    * null (the field is only initialised if removeCodeBase() is
    * called from an applet.
    */
   private static URLClassLoader noCodeBaseClassLoader;
   /**
    * Private constructor.
    */
   private ResourceBundleWrapper() {
       // all methods are static, no need to instantiate
   }
   /**
    * Instantiate a {@link URLClassLoader} for resource lookups where the
    * codeBase URL is removed.  This method is typically called from an
    * applet"s init() method.  If this method is never called, the
    * getBundle() methods map to the standard
    * {@link ResourceBundle} lookup methods.
    *
    * @param codeBase  the codeBase URL.
    * @param urlClassLoader  the class loader.
    */
   public static void removeCodeBase(URL codeBase,
           URLClassLoader urlClassLoader) {
       List urlsNoBase = new ArrayList();
       URL[] urls = urlClassLoader.getURLs();
       for (int i = 0; i < urls.length; i++) {
           if (! urls[i].sameFile(codeBase)) {
               urlsNoBase.add(urls[i]);
           }
       }
       // substitute the filtered URL list
       URL[] urlsNoBaseArray = (URL[]) urlsNoBase.toArray(new URL[0]);
       noCodeBaseClassLoader = URLClassLoader.newInstance(urlsNoBaseArray);
   }
   /**
    * Finds and returns the specified resource bundle.
    *
    * @param baseName  the base name.
    *
    * @return The resource bundle.
    */
   public static final ResourceBundle getBundle(String baseName) {
       // the noCodeBaseClassLoader is configured by a call to the
       // removeCodeBase() method, typically in the init() method of an
       // applet...
       if (noCodeBaseClassLoader != null) {
           return ResourceBundle.getBundle(baseName, Locale.getDefault(),
                   noCodeBaseClassLoader);
       }
       else {
           // standard ResourceBundle behaviour
           return ResourceBundle.getBundle(baseName);
       }
   }
   /**
    * Finds and returns the specified resource bundle.
    *
    * @param baseName  the base name.
    * @param locale  the locale.
    *
    * @return The resource bundle.
    */
   public static final ResourceBundle getBundle(String baseName,
           Locale locale) {
       // the noCodeBaseClassLoader is configured by a call to the
       // removeCodeBase() method, typically in the init() method of an
       // applet...
       if (noCodeBaseClassLoader != null) {
           return ResourceBundle.getBundle(baseName, locale,
                   noCodeBaseClassLoader);
       }
       else {
           // standard ResourceBundle behaviour
           return ResourceBundle.getBundle(baseName, locale);
       }
   }
   /**
    * Maps directly to ResourceBundle.getBundle(baseName, locale,
    * loader).
    *
    * @param baseName  the base name.
    * @param locale  the locale.
    * @param loader  the class loader.
    *
    * @return The resource bundle.
    */
   public static ResourceBundle getBundle(String baseName, Locale locale,
           ClassLoader loader) {
       return ResourceBundle.getBundle(baseName, locale, loader);
   }

}</source>





Using the JDK 6 ResourceBundle class

   <source lang="java">

import java.util.Locale; import java.util.ResourceBundle; import java.util.Set; public class RBPropDemo {

 public static void main(String[] args) {
   ResourceBundle.clearCache();
   String bundleName = "myproj.MyResources";
   ResourceBundle myResources = ResourceBundle.getBundle(bundleName, Locale.GERMAN);
   System.out.println("Key"s values:");
   System.out.println(myResources.getString("okKey"));
   System.out.println(myResources.getString("cancelKey"));
   System.out.println(myResources.getString("submitKey"));
   System.out.println("\nChecking okKey in resource bundle:");
   if (myResources.containsKey("okKey")) {
     System.out.println("okKey exists! " + " Value = " + myResources.getString("okKey"));
   } else {
     System.out.println("The key Doesn"t Exist");
   }
   System.out.println("\nGet a set of keys:");
   Set<String> keySet = myResources.keySet();
   Object[] keys = keySet.toArray();
   for (int i = 0; i < keys.length; i++) {
     System.out.println("Key " + (i + 1) + " = " + keys[i]);
   }
 }

}</source>





XML resource bundle

The Strings.xml Resource Bundle



   <source lang="java">

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE properties SYSTEM "http://java.sun.ru/dtd/properties.dtd"> <properties> <entry key="Key">Value</entry> </properties>

</code>

       <![CDATA[ 

import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.net.URLConnection; import java.util.Collections; import java.util.Enumeration; import java.util.List; import java.util.Locale; import java.util.Properties; import java.util.ResourceBundle; import java.util.Set; public class XMLResourceBundleControl extends ResourceBundle.Control {

 private static String XML = "xml";
 public List<String> getFormats(String baseName) {
   return Collections.singletonList(XML);
 }
 public ResourceBundle newBundle(String baseName, Locale locale, String format,
     ClassLoader loader, boolean reload) throws IllegalAccessException, InstantiationException,
     IOException {
   if ((baseName == null) || (locale == null) || (format == null) || (loader == null)) {
     throw new NullPointerException();
   }
   ResourceBundle bundle = null;
   if (!format.equals(XML)) {
     return null;
   }
   String bundleName = toBundleName(baseName, locale);
   String resourceName = toResourceName(bundleName, format);
   URL url = loader.getResource(resourceName);
   if (url == null) {
     return null;
   }
   URLConnection connection = url.openConnection();
   if (connection == null) {
     return null;
   }
   if (reload) {
     connection.setUseCaches(false);
   }
   InputStream stream = connection.getInputStream();
   if (stream == null) {
     return null;
   }
   BufferedInputStream bis = new BufferedInputStream(stream);
   bundle = new XMLResourceBundle(bis);
   bis.close();
   return bundle;
 }
 public static void main(String args[]) {
   ResourceBundle bundle = ResourceBundle.getBundle("Strings", new XMLResourceBundleControl());
   String string = bundle.getString("Key");
   System.out.println("Key: " + string);
 }

} class XMLResourceBundle extends ResourceBundle {

 private Properties props;
 XMLResourceBundle(InputStream stream) throws IOException {
   props = new Properties();
   props.loadFromXML(stream);
 }
 protected Object handleGetObject(String key) {
   return props.getProperty(key);
 }
 public Enumeration<String> getKeys() {
   Set<String> handleKeys = props.stringPropertyNames();
   return Collections.enumeration(handleKeys);
 }

}</source>