Internationalizing programs with JBuilder

This is a feature of JBuilder Professional and Enterprise.

This section examines issues involved in designing your Java applications to meet the needs of a worldwide audience. Why limit the use of your applet or application only to users in a particular country, when with a little extra effort it could be used by people all around the world? Special features in JBuilder make it easy to take advantage of Java's internationalization capabilities, allowing your applications to be customized for any number of countries or languages without requiring cumbersome changes to the code.

Although this chapter is about specific JBuilder features and is not meant to be an in-depth discussion of Java's internationalization features, several links are provided to related Java documentation to help get you started. Finally, before proceeding to the explanation of internationalization features in JBuilder, please review the following section on commonly-used terms that are specific to internationalization.


Internationalization terms and definitions

Internationalization (i18n)
Internationalization is the process of designing or converting an existing program so it is capable of being used in more than one locale. Because internationalization is a long word, it is often abbreviated as 'i18n', where 18 represents the number of letters between the 'i' and 'n.'
Locale
A locale defines a set of culturally-specific conventions for the display, format, and collation (sorting) of data. In Java, a locale is specified by a Locale object, which is simply a container for strings identifying a particular language and country.
Resourcing
Resourcing is the part of the internationalization process that involves isolating the locale-specific resources in the source code into modules so they can be independently added to or removed from the application. Examples of locale-specific resources include text displayed to the user or possibly even business rules or application logic. Java provides a set of ResourceBundle classes for resourcing strings and objects in Java programs.
Localization (l10n)
Localization is the customization of a program's resources for a particular locale. Note that whereas internationalization generalizes a program for any locale, localization specializes it for a single locale. Because localization is a long word, it is often abbreviated as 'l10n', where 10 represents the number of letters between the 'l' and 'n.'
Native encoding
A native encoding, also commonly known as a character set or codepage, defines a mapping of numeric values to symbolic characters within a particular operating system. Because the native encoding varies by operating system (and sometimes even within the same operating system), a file containing characters on one system may appear to have completely different characters on another system using a different native encoding.
Unicode
Unicode is a universal character encoding standard maintained by The Unicode Consortium that defines a character mapping for nearly all the written languages of the world. Any Unicode character can be specified in Java source code by its Unicode escape sequence, \uNNNN, where NNNN is the hexadecimal value of the character in the Unicode character set. Characters and strings are always processed as 16-bit Unicode-encoded values within the Java Virtual Machine.


Internationalization features in JBuilder

JBuilder includes a number of features designed to help you easily internationalize your Java applets and applications. The following sections discuss these features:


A multilingual sample application

JBuilder includes an extensive multilingual sample order entry application demonstrating many of the important internationalization concepts in detail. This sample also illustrates many other important features of JBuilder, such as building applications with JBuilder components, creating internationalized JavaBeans, and using the DataExpress architecture. You can find the "IntlDemo.jpx" project located under the samples/dbswing/MultiLingual directory of your JBuilder installation. Please refer to the IntlDemo.html documentation file and source code in the sample for more detailed information. The IntlDemo sample supports and includes translations for 15 different locales.

The Borland Multilingual International Store's LocaleChooser JavaBean lets you switch the application's locale at runtime. Doing so automatically adapts the UI to the language and conventions for the selected locale.

The ProductFrame lets users see images of Borland Store products and written descriptions in their own language. Note how the buttons and labels adjust their sizes automatically for the different German and Italian translations shown here.

The OrderFrame displays the address of the customer and the cost of the order in the appropriate format for the user's locale. The OrderFrame is shown in German here:


Eliminating hard-coded strings using the Resource Strings wizard

A common design error that prevents your application or applet from being localized easily is the inclusion of hard-coded strings in your source code that are displayed in the UI of your application or applet.

While you can resource hard-coded strings in your user interface after you've completed and tested your source code, it's better to resource visible strings as part of the UI design process.

Resourcing your UI as you write it provides two major advantages:

JBuilder provides two ways to get these benefits with minimal effort: the Resource Strings wizard and the Localizable Property Setting dialog box.

The Resource Strings wizard scans your source code and allows you to quickly and easily move hard-coded strings into Java ResourceBundle classes. This wizard works with any Java file, not just source code generated by JBuilder. To move your strings into a ResourceBundle class,

  1. Select the source code module you want scanned in the project pane.

  2. Choose Wizards|Resource Strings to display the Resource Strings wizard:

  3. In the ResourceBundle Name field, select a ResourceBundle from the drop-down list, which displays all ResourceBundles in your project. To create a new ResourceBundle, click the New button to display a Create ResourceBundle dialog box. It suggests a name for the resource bundle, allowing you to change if you want, and lets you specify the resource bundle as a ListResourceBundle or a PropertyResourceBundle. Once you are through with the Create ResourceBundle dialog box, click OK to put it away.

  4. Select whether you want the keys for the strings to be generated with names based on the string values or on component and property names.

  5. Choose Next to display the second page of the Resource Strings wizard:

  6. Uncheck any string you don't want resourced.

  7. Click Finish.

The Localizable Property Setting dialog box allows you to resource visible strings as you create or customize components in your UI. In the Inspector, simply right-click any text property, such as the label of a ButtonControl, and select the ResourceBundle command to display the Localizable Property Setting dialog box:

This dialog box displays options similar to those in the Resource Strings wizard but includes only those options that affect the single (selected) property. Select the Store Text In ResourceBundle For Localization option and select how the keys are generated if these options aren't already set or if you wish to make changes. Because resourcing from the Inspector is so quick and convenient, you can easily make it an integral part of customizing the components in your application.


dbSwing internationalization features

The dbSwing architecture includes several design decisions that facilitate internationalization of an application or applet:

Most JBuilder dbSwing components include a textWithMnemonic property. This property supports a mnemonic character that is specified in the same string used to display the component's text. The Swing design (which many dbSwing components extend) is to store the text and mnemonic characters into separate properties. This makes localization difficult as translators often have little context on which to base the translating of strings. Allowing dbSwing components to store the mnemonic character embedded in the text itself allows the translator to choose the correct mnemonic. If this feature is used effectively, it can provide some context during translation.

JBuilder's IntlSwingSupport component provides Swing internationalization support for twelve locales. When IntlSwingSupport is instantiated, it automatically updates Swing's internal localizable resources appropriately for the current locale. IntlSwingSupport need be instantiated once only in an application, and it should be instantiated on application startup before any Swing components are displayed.

To initialize IntlSwingSupport for a locale other than the default locale (in a multilingual application, for example), set the locale property of the IntlSwingSupport component to the target locale. For example:

     new IntlSwingSupport();
     int response = JOptionPane.showConfirmDialog(frame, localizedMessageString,
                       localizedTitleString, JOptionPane.OK_CANCEL_OPTION);

As of JDK 1.2, the only Swing components with visible, translatable text strings are the JFileChooser, JColorChooser, and JOptionPane. For more information on locales, see the JavaSoft documentation for the Locale class.


Using JBuilder's locale-sensitive components

In addition to being fully resourced, many of JBuilder's components also provide useful locale-sensitive behavior. For example, string data that is loaded into a Column of a JdbTable using DataExpress DataSet components is automatically sorted according to the default collation order for the user's runtime locale. Similarly, date, time, and numeric values are automatically formatted correctly for the user's locale.

By default, objects inherit the locale of their containers. Therefore the locale setting on a DataSet is used by default by Columns within the DataSet. Alternatively, a locale can be specified explicitly for each Column object within the DataSet. This is useful if, for example, each Column holds data that must be sorted by a different locale. Refer to the JDK's API documentation about the Collator class for more information about locale-sensitive sorting.

For more information about the locale-sensitive formatting of data types in Java, refer to the DateFormat, NumberFormat, and MessageFormat classes in the JDK API documentation.


JBuilder components display any Unicode character

Component architectures which rely solely upon native UI peer controls to display characters can only display the set of characters supported by the native peer. Because JBuilder components use Java to display characters rather than native peers, they can display any Unicode character for which a font has been installed on your system, regardless of whether that character actually exists in your operating system's default character set.

To display Unicode characters for a new font,

  1. Install the desired font on your operating system.
  2. Modify the JDK font.properties file for your locale, specifying that the font for that character is now available.
For instructions on how to do this, refer to Adding Fonts to the Java Runtime in the JDK Internationalization documentation.


Internationalization features in the UI designer

JBuilder's UI designer is a powerful tool for the creation and verification of your internationalized UI design. As you add translatable text elements to your UI, you can instantly put them into resource bundles. The Inspector automatically reads strings from and writes them back to resource bundles for you. In addition, after you've resourced all the text of your UI and have received a localized resource bundle from your translator, you can use the designer to quickly build and verify your internationalized user interface.

The Inspector displays locale-sensitive short description information about a JavaBean's property, as described in the internationalization section of the JavaBeans specification.

The Inspector allows the use of Unicode character escape sequences to denote characters that cannot be entered directly via the keyboard under your operating system locale. When you want to insert a Unicode character into a string property you're editing, simply put the hexadecimal value of the character's Unicode escape sequence within angle brackets. For example, to insert the Japanese character for the word "mountain" into the label of a button, enter "<5C71>". If your system has Japanese fonts installed and the proper settings in your JDK font.properties file, the character will be displayed as the label of the button, and the Unicode escape "\u5C71" will appear in your source code.

The UI designer provides excellent support for dynamic layout managers, a crucial requirement for building internationalized UI designs. Building a single UI capable of supporting multiple languages is a difficult task but one that is made much easier by the UI designer's support for Java's dynamic AWT layout managers. When designing a UI intended to be localized for more than one language, an extremely important rule is always use a dynamic layout manager.

Consider, for example, the following Dialog containing OK, Cancel, and Help buttons:

This displays as expected for English labels, but when the labels are translated into German, the label's text is too long to fit completely within the fixed button size. This is a very common problem that almost always occurs when attempting to localize a non-internationalized UI.

The solution is to use one or more dynamic AWT layout managers to allow the buttons to grow based on their label width. Here are the English and German internationalized versions of the same Dialog, written using a panel with a dynamic GridLayout for the buttons and embedded within a BorderLayout Dialog.

To learn more about creating dynamic layouts using the UI designer, refer to "Using layout managers".

The multilingual international sample application also demonstrates some advanced techniques for updating the layout of Frames in an application at runtime.


Unicode in the IDE debugger

The JBuilder debugger allows you to view and edit Unicode characters, even if your operating system does not support them. When examining values in the debugger's Watch pane, expand the value in the tree you want to inspect until you can see its primitive Java type. By default, the debugger tries to display the Unicode character, assuming that your operating system can display it.

To view the character's Unicode equivalent, right-click the value and select the Show Hex Value option to see the character's Unicode escape sequence. You can also change the value by selecting Modify Value and entering another Unicode escape sequence in the Change Data Value dialog box.


Specifying a native encoding for the compiler

The JBuilder and javac compilers compile source code encoded in native encodings (also known as local codepages), which is the storage format used by most text editors, including the JBuilder editor.

The IDE and compiler support all JDK native encodings. All JBuilder compilers automatically select the appropriate native encoding for your operating system's locale. You can also specify any JDK encoding for compiling source code files which were written in a different native encoding.

You can specify an encoding name to control how the compiler interprets characters beyond the English (ASCII) character set. The specification can be done on a project-wide basis or with the encoding compiler switch from the command line. If no setting is specified for this option, the default native encoding converter for the platform is used.

Setting the encoding option

To set the encoding option from within the IDE,
  1. Choose Project|Project Properties to display the Project Properties dialog box.
  2. Click the General tab.
  3. Select an encoding name from the Encoding drop-down list.
  4. Choose OK.

To set the encoding option at the command line,

  1. Use bcj's -encoding option followed by the encoding name.
  2. Use bmj's -encoding option followed by the encoding name.

Native encodings supported

Two encoding names have special meaning:
null
Specifies that no native-encoding conversion should be done. Each byte in the file is converted to Unicode by setting it to the lower byte of the Unicode character. The upper byte of the Unicode character is set to zero.
default
Equivalent to not specifying an encoding option. This uses the default encoding of the user's environment.

For a description of each encoding, see the JDK Internationalization Specification: Character Set Conversion: Supported Encodings at http://java.sun.com/j2se/1.3/docs/guide/intl/encoding.doc.html. The following descriptions supplement that section:

Unicode
Unicode, with BigEndian or LittleEndian indicated by Byte-Order-Mark.
UnicodeBig
Big-Endian Unicode.
UnicodeLittle
Little-Endian Unicode.

Adding and overriding encodings

To add encodings to the Encoding drop-down list on the Build page of the Project Properties dialog box (Project|Project Properties),
  1. Open the user.properties file in the .jbuilder folder.

  2. Add encodings as in the following example:
  3. Save and close the file.

  4. Restart JBuilder.
To replace encodings in the Encodings drop-down list,
  1. Open the user.properties file in the .jbuilder folder.

  2. Override the encodings as in the following example:
  3. Save and close the file.

  4. Restart JBuilder.

More about native encodings

Non-Unicode environments represent characters using different encoding systems. In the PC world, these are known as codepages; Java refers to them as native encodings. When moving data from one encoding system to another, conversion needs to be done. Because each system can have a different set of extended characters, conversion is required to prevent loss of data.

You can also use the the Java utility, native2ascii, to convert native-encoded characters to Unicode escape sequences (for example, \uNNNN). The converted file(s) can then be readily compiled on any system without the need for more conversion or the specifying of a particular encoding.

Most text editors, including JBuilder's editor, write text in the native encoding. For example, Japanese Windows uses the Shift-JIS format, and US Windows uses Windows Codepage 1252. Starting with JDK 1.1, javac is also able to compile "native-encoded" source code. The encoding can be specified by using the "encoding" switch. When the encoding is not specified, the compiler uses the encoding based on the user's environment.

Unlike Unicode, source code written with native encoding is not directly portable to systems using other encodings. For example, if source code has been encoded in Shift-JIS (a Japanese encoding), and you are running the compiler in a US Windows environment, you must specify the Shift-JIS encoding for the compiler to read the source correctly.


The 16-bit Unicode format

Unicode is a universal system of representing characters using 16-bit numbers. The 16-bit Unicode character set can be supported directly, or can be represented indirectly within the 7-bit ASCII character set, using the \u escape character followed by four hexadecimal digits.

When all major operating environments directly support Unicode, this will replace the established approach, which requires conversion between different native encodings with conflicting character values. Java is one of the first environments to standardize on Unicode; Unicode is the internal character set of the Java environment.

Unicode support using ASCII and '\u'

Currently, most Windows text editors, including JBuilder's editor, store and process text as 7- or 8-bit characters, rather than 16-bit Unicode characters. The ASCII character set uses a 7-bit encoding that contains the 26 letters of the English alphabet and some symbols. Almost all native encodings have ASCII as a subset, and represent it in the same way: the first 127 characters of an encoding are the ASCII character set. The ASCII character set can be considered a subset of Unicode.

To enable users to specify Unicode characters in their source code without a Unicode-enabled editor, the Java specification allows the use of the \u "Unicode escape" in an ASCII file. This usage enables extended characters to be represented by a combination of ASCII characters. This way of representing Unicode uses 6 characters to represent each non-ASCII character. To enter an ordinary ASCII character, you press the character's key on the keyboard, and to enter a non-ASCII character, you type in the Unicode escape sequence representing the character.

In this 7-bit representation of Unicode, each character beyond the ASCII character set is represented in the form \uNNNN, where NNNN are the 4 hex digits of the Unicode character. For example, the Unicode character "Latin Small Letter F with Hook", a cursive 'f' which is represented in Unicode with the hexadecimal number 0192, can be entered by typing "\u0192".

Unicode, in both the 16-bit and 7-bit forms, is in a universal format; source code in Unicode is directly portable to all platforms, in all languages.


JBuilder around the world

JBuilder is available in several languages including English, German, French and Japanese. Localized versions usually include translated printed and online documentation, UI, and components. Localized versions of JBuilder are available for purchase from the Inprise sales office in those countries.


Online internationalization support

Visit the multi-lingual-apps newsgroup on the Inprise web page at news://forums.inprise.com/borland.public.jbuilder.multi-lingual-apps. This newsgroup is dedicated to JBuilder internationalization and multilingual issues and is actively monitored by our support engineers as well as R&D and QA engineers in the JBuilder internationalization group.