Skip to main content

I18n How-to: Just get started!

Posted by joconner on April 19, 2004 at 11:31 PM PDT

Developers and project managers make lots of excuses for not internationalizing an application. But it's easier to get started than you might imagine. Don't worry too much about all your difficult questions...you'll never begin. Just get started!

Although there are several steps to creating a fully internationalized application, you can start by separating localizable text from your core business logic. You should place that text in a separate file, either a PropertyResourceBundle or a ListResourceBundle. Since a PropertyResourceBundle is so much more simple, I'll start with that. Let's pretend you're creating a simple application with a single button and a text field. When the user presses the button, the application will display a simple greeting. Your application might start like this:

package com.joconner.demo;

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

public class Greeting extends JFrame {
    JButton btnGreeting = new JButton();
    JTextField tfGreeting = new JTextField();
    ResourceBundle res =  GridBagLayout layout = new GridBagLayout();

    public Greeting() {
        try {
            btnGreeting.setText("Show Greeting");
            this.setTitle("I18n Demo");
            btnGreeting.addActionListener(new ActionListener() {
   
                public void actionPerformed(ActionEvent event) {
                    tfGreeting.setText("Hello, world!");
                }
   
            });
            this.getContentPane().setLayout(layout);
            this.getContentPane().add(btnGreeting,    new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0
                ,GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
            this.getContentPane().add(tfGreeting,     new GridBagConstraints(0, 1, 1, 1, 1.0, 1.0
                ,GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
            this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        }
        catch(Exception ex) {
            ex.printStackTrace();
        }
    }

    public static void main(String[] args) {
        Greeting app = new Greeting();
        app.pack();
        app.show();
    }
}

To get started with internationalization, you first need to pull all the localizable text from the source code. For this app, it's simple; you just have 3 strings:

  • Show Greeting!
  • Hello, world!
  • I18n Demo

Put these strings in a PropertyResourceBundle. A PropertyResourceBundle is a simple text file with key/value pairs. Let's name our bundle "GreetingResources.properties" and we'll place it in the same package as our application's .java file. Proving 3 keys for each string, the property bundle will look like this:

BTN_TEXT=Show Greeting!
GREETING=Hello, world!
TITLE=I18n Demo

Now we have to touch up the original source code to use our new ResourceBundle. The modified code is below:

package com.joconner.demo;

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

public class Greeting extends JFrame {
    JButton btnGreeting = new JButton();
    JTextField tfGreeting = new JTextField();
    ResourceBundle res = ResourceBundle.getBundle("com.joconner.demo.GreetingResources");
    GridBagLayout layout = new GridBagLayout();

    public Greeting() {
        try {
            String btnGreetingText = res.getString("BTN_TEXT");
            btnGreeting.setText(btnGreetingText);
            String title = res.getString("TITLE");
            this.setTitle(title);
            btnGreeting.addActionListener(new ActionListener() {
   
                public void actionPerformed(ActionEvent event) {
                    String tfGreetingText = res.getString("GREETING");
                    tfGreeting.setText(tfGreetingText);
                }
   
            });
            this.getContentPane().setLayout(layout);
            this.getContentPane().add(btnGreeting,    new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0
                ,GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
            this.getContentPane().add(tfGreeting,     new GridBagConstraints(0, 1, 1, 1, 1.0, 1.0
                ,GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
            this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        }
        catch(Exception ex) {
            ex.printStackTrace();
        }
    }

    public static void main(String[] args) {
        Greeting app = new Greeting();
        app.pack();
        app.show();
    }
}

You'll notice that we've done 3 new things:

  1. load a PropertyResourceBundle containing key/value pairs for each piece of localizable text
  2. retrieve each piece of text by its key using the getString(String key) method of the bundle
  3. use the retrieved String to set the text of the appropriate GUI component.

Now believe it or not, you've started to internationalize your application with these easy steps! You can now localize the PropertyResourceBundle file into multiple languages, and the Java platform will find the localized bundle for you. In my next blog tip, I'll discuss how to name your bundles for multiple localizations of the same resources.

Want more information about resource bundles? Check this out:

Java Internationalization: Localization with ResourceBundles

Related Topics >>