(Difference between revisions)
Line 1: Line 1:
==NetBeans specific I18N Requirements, Guidelines and information  for developers and writers who work on NetBeans modules or product itself.==
==NetBeans specific I18N Requirements, Guidelines and information  for developers and writers who work on NetBeans modules or product itself.==

Current revision as of 18:24, 6 November 2009

NetBeans specific I18N Requirements, Guidelines and information for developers and writers who work on NetBeans modules or product itself.

Information provided by Ken Frank, Tools I18N Quality and Testing Team (some parts are extracted from a document in the NetBeans javadoc api set) Contact kfrank@netbeans.org for more information or with comments or questions about these pages.

This is not meant to be a tutorial or guidelines or functionality about i18n implementation for Java language or api itself, but calls out various specific i18n readiness practices and guidelines specifically needed and important for Netbeans developers and writers.

For more detailed information onNetbeans specific requirements and implementation of those requirements related to I18N, please contact (kfrank@netbeans.org) or NetBeans developers or writers via the netbeans-dev and netbeans-users aliases on netbeans.org.

This document also is not about the process of translation (localization) but relates to i18n only (including that part of i18n that might be called i18n readiness, which is preparing material to be translated to be provided to translation team or to building localized product based on translated material provided back by translation team.

Naming and location of localized files

   * Make sure the policy on naming and location of localized files in a product is clear and has been implemented by dev team, for example:
   * names of localized message or html files ie ie Bundle_ja.properties, somefile_ja.jar
   * where localized files live in a product
   * for localized jar files, how the localized separate files in them are to be named and where they live within the jar, relative to where they live in english jar
   * do localized jars have only localized files in them ? (for netbeans based products answer is yes)
   * do english jars do not have localized files or not ? (for netbeans based products answer is no)

l10n kits and l10n.list

NOTE - as of nb6.1, there is different approach to how l10n kits are built and l10n.lists for each module is not needed anymore - see the section on this in the longer document and also see http://jupiter.czech.sun.com/wiki/view/Netbeans/Nb61-l10nkit-how-to-fix especially part about modifying patterns in nbbuild/l10n.patterns if needed if you have files to be translated in your module whose names don't match an existing pattern - if there is not a match, then the file will not be in the l10n kit.

pattern file is at http://hg.netbeans.org/main/file/tip/nbbuild/l10n.patterns

l10n kits are the files that translators get from us that will be translated - they are delivered in a special zip file and are part of each trunk build once they have been started for a given release.

l10n kits are now built from product nbms, not from source repository.

It's developer's responsibilty to make sure the kits are accurate for the modules they are responsible for and the way to do this is to get a kit and review it.

Background on where localized files reside in netbeans installed product

  • they live in separate jars under a given netbeans directory ie

ide10/modules/somefile.jar ide10/modules/locale/somefile_<localename>.jar

in the localized jar are placed localized message and html files, and for localized javahelp jar files are placed localized html and other javahelp configuration files

ie in english somefile.jar is org/netbeans/somedir/Bundle.properties in localized jar is org/netbeans/somedir/Bundle_<localename>.properties

Procedure and api to use for handling messages and labels to user in java code (these are the messages and labels that are in Bundle.properties files)

use the NbBundle api


In the code, use the NbBundle class for finding and reading messages or labels.

All message strings should be contained in a Bundle.properties file (containing default message strings - i.e. in US English). This resource bundle is conventionally in the same directory (package) as the source files which use it; other source packages should have their own bundles. Localized (non-US-English) message strings should be inserted into a Bundle_LOCALE.properties file - this file must be placed in the same directory as the default bundle. For example, Bundle.properties might have:

# A simple bundle key:

LBL_some_text=Text in English for a button.

#A nicely formatted one:
# {0} - number of missing files

EXC_missing_files=There {0,choice,1#is one file|1#are {0,number,integer} files} missing.

In Bundle_cs.properties, however, there may be:

LBL_some_text=Text v \u010De\u0161tin\u011B na tla\u010D\u00EDtko.

EXC_missing_files=Chyb\u00ED {0,choice,1#jeden soubor|2#dva soubory|3#t\u0159i \

       soubory|4#\u010Dty\u0159i soubory|4#{0,number,integer} soubor\u016F}.

Remember that all non-ASCII characters present in bundle files should be escaped in Unicode format (\uXXXX). The native2ascii utility present in the JDK can help with this. Translators of netbeans do run the native2ascii before they return files that have been translated.

Message strings are identified by keys and these are entered in source files. These keys are non-localized strings. The recommended way to use these in a source file is like this:

import org.openide.util.NbBundle; // Looks in Bundle.properties for LBL_some_text key: String localized = NbBundle.getMessage(ThisClass.class, "LBL_some_text"); // Same, but formats the text as well: throw new IOException(NbBundle.getMessage(ThisClass.class, "EXC_missing_files",

                                         new Integer(missingFiles)));

In general you have a string literal in code which you know should never be localized, then end that line of source code with a comment like //NOI18N.

How to write good *.properties files - part 1

There are some rules for how to write good *.properties files for easy localization, starting with the most important.

1. Localizable messages should be stored in files named Bundle.properties by convention.

2. If it is necessary to mix localizable and nonlocalizable messages in one Bundle.properties (to create groups of messages, where some of these messages are localizable and part not, and it is unreasonable to split off the unlocalizable ones): notate each nonlocalizable message with the preceding line #NOI18N. For example:


var.POSSIBLE_FILE_STATUSES.value="Up-to-date", "Locally Modified", "Locally Added" var.POSSIBLE_FILE_STATUSES_LOCALIZED.value="Up-to-date", "Locally Modified", \

       "Locally Added"
     In some cases it would be preferable to hardcode the unlocalizable messages in source to begin with.

3. If there is *.properties file which must have a name different from the default and there are some localizable strings in it, the strings should be individually notated with #I18N. For example:

var.POSSIBLE_FILE_STATUSES.value="Up-to-date", "Locally Modified", "Locally Added"


var.POSSIBLE_FILE_STATUSES_LOCALIZED.value="Up-to-date", "Locally Modified", \

       "Locally Added"

4. If (by the previous two cases) one message must be partially localized, the message should be annotated as #PARTI18N or #PARTNOI18N (above the message) indicating the exceptional part of the message. For example, in a properties file not named Bundle.properties:

# PARTI18N The module name


     ${USER_PARAM(-N -R)} ${PROMPT_FOR SELECTOR_MODULES](The module name)} ${NUR}
     Where there is more than one exceptional part, indicate them separated by commas, for example:
#PARTI18N Directory to export into, Date, The module name

EXEC_EXPORT_MODULE_DATE=${RUN} ${CD} ${PROMPT_FOR_DIR(Directory to export into)}&& \

     ${USER_PARAM} ${PROMPT_FOR SELECTOR_MODULES](The module name)} ${NUR}
     Analogously, for files named Bundle.properties with some nonlocalizable bits in some messages, use #PARTNOI18N.

How to write and construct accurate properties files and how to review them - part 2

# Do not use 2 or more key/values to build one message to user.

Or don't get a string from a bundle and add a calculated value to it unless Java API message formatting is used. This is because word order may vary in other languages, and by having 2 or more separate pieces of a message, it can make it difficult for proper translation.

     For example
     KEY_1="This is the"
     KEY_2="first part"
     KEY_3="second part"
     KEY_4="of the message"
     then instead of building a message using KEY_1+KEY_2++KEY_VAL+KEY_4, it would be better to have separate messages as
     KEY_FIRST="This is the first part {%0} of the message"
     KEY_SECOND="This is the second part {%0} of the message"
 * Make sure that the key/value separator is an "=". There have been some cases where a ":" was used, but this will not be recognized and thus the localized value will not be seen.
   *  Make sure all information meant to be seen by user are in Bundle.properties files and adjust any xml files or other internal code so that information from Bundle.properties is used. (This doesn't apply to help files or template descriptor html files).
   *   Make sure no duplicate keys are in any given bundle file.
* make sure that certain information from manifest files are in bundle files - see the section in this doc on OpenIDE* values to be placed into bundle files.
  *  avoid partial/fragmented msgs

each line in a bundle file should have a complete message - there should not be partial messages which are later combined in code into one message

having these partial or fragmented messages makes it difficult for accurate translations.

     In general, if a line in a bundle file should not be translated and it might not be obvious that it should not be, then add a commented line before the line in question with words #NOI18N on it (and other comments that might be helpful)


 *     If on some given line in a bundle file, if just some word(s) should not be translated, then place a commented line before the line in question with words #PARTI18N on it and with other instructions about the word(s) not to be translated. 

* review Bundle.properties and source code to make sure that all messages/labels will indeed come from the localized bundle file

a combination of checking source code for strings that don't have nb i18n api that need them plus reviewing bundle files can be helpful.

netbeans source has scripts that can do this at some level, but post processing of results is needed.

(note that lines that have NOI18N comment will be skipped by the scripts, but sometimes this comment is put by mistake, so there could be strings that dont show in the report that are still missing from bundle files.)

      	 The actual script that checks for the strings can be found in the nbbuild cvs.
  	 * the  nbbuild/monitor.xml script has a check-bundle-usage target which checks to see if  any unused keys are in bundle files, so they can be removed.

   * review bundle files to make sure that no duplicate keys are used in a given file (especially if there is a different message for each of these)

A duplicate key with different messages for each key means that both will be translated, but its unknown which message the user would see when using localized product.

This analysis should make sure that there are no duplicate mnemonic key words with different assigned keys that apply to the same window.

* Make sure no unused keys are in bundle files

Several tools that are part of netbeans source can be helpful in analyzing for these issues. "nbbuild" module has a target named "checkBundles" for this purpose. Target Class = org.netbeans.nbbuild.CheckBundles this scans the properties files and java files and prints unused keys to the console. it won't delete those keys, it just prints them to console.

    *  Make sure no labels or messages in a bundle file are also used as some variable or value to be in used in code or as an argument to some code routine sincewhen that label or message is translated, it may not be what is expected and exceptions can and do happen as a result.
         o  If it really is needed to have something needed by the code from a bundle that is not to be translated, use a separate key/value and place the #NOI18N comment on the line above it. This is VERY important as there have been instances where if some string in a bundle file was translated when it should not be (because of lack of NOI18N comment), then certain modules features did not work.

   * Mnemonics should only use the '&' method, not the 2key/value one.  There are now tasks in all nb areas that involve changing existing use of 2 key/value to the '&' approach. See the Mnemonics class of NetBeans API.
   * review bundle files to make sure that if mnemonics defined there still use the 2 key/value method, that is, they define a specific key (vs using the '&' way), that there is a separate key for the label and one for the key definition itself.  As part of this, please plan to convert these existing usages to the '&' approach.
   * review bundle files  by developers and/or writers for correct wording and syntax

here are 2 links about writing for messages or docs that will be translated http://knowledge.central/Ops/local/documentation/english_quality.html http://knowledge.central/Ops/local/documentation/standards/L10n_standards.html

* review bundle files to make sure that any key/value not to be translated is marked on line before it with a #NOI18N comment. Sometimes its not clear that a certain item is not to be translated without such a comment, and if the item is translated, product functionality may not work. This is really important.

   * if there are items in bundle files that are not to be translated, or not to be localized (like urls) and that will never be needed to be modified in other ways by third parties, perhaps these items could be placed in the code rather than property file, since in these cases that item will never be modified and thus not need to be in property file.
But if there is any doubt that some item might need to be modified by third party, even if not    translated or localized, then it should definitely stay in the bundle file, making sure that its marked with #NOI18N

   * review bundle files to make sure some value is not used programatically so that, when translated, the functionality of that area might not work; this has happened before in other products.

to clarify more about this:

  	1. if an item in bundle is used programatically and thus should not be translated BUT if that item is also a label or message to user, then
         * the item not to be translated should be marked with #NOI18N
         * there should be a new key/value of this item that can be safely translated
  2. if an item in bundle should not be translated and is not something that might be localized (like a url), perhaps it could just be removed from bundle and handled in code since noone will be modifying that bundle file besides l10n (who are only concerned with translations) but if its not removed, then should be marked with #NOI18N

3. if an item in a bundle file that will be translated will be parsed for length as part of process of allocating space for it to be displayed in the UI, make sure not to assume that there will be any space characters in that string; some languages do not use spaces between words. Java's BreakIterator class might be used in these cases.

   * review bundle files to make sure that any items not to be actually translated but need to be changed/customized by transators  have a clear instructional comment on the line before it that has the word #NOI18N on it.  But this should really never need to happen unless in very exceptional cases.
* Do NOT reuse the I18N label names or keys in bundle files (with mnemonics) as dialog titles, descriptions, tool-tip-texts and other texts that don't require mnemonics. That is, have a unique key for each, even if the value is the same.

General assumption about types of files that will be localized

     Messages, labels, menu items and other items to be translated or localized should be placed either in

         o Bundle.properties files
         o html files only if they are template descriptors or javahelp information (our products use javahelp system for their help)

o No localizable information should be placed into xml or other files. This would not apply to comments in .java or other source code files.

         o   Items that should not be translated or otherwise localized (like urls), should not be placed in bundle files, but rather should be handled in the code, if at all possible; sometimes it cannot be avoided however. 

If any of these items do need to be placed in bundle files, make sure they are clearly marked with the #NOI18N comment on line before that item and/or explain what does need to be localized in such a given bundle key.

Other localizable kinds of files

Non javahelp product html files need to be found per locale; in most if not all cases, these are for template descriptors and there is a policy for this - that the localized ones are in same location path as english ones but named with locale suffix (and in separate localized jars) . See section below on Template Descriptor files.

If other non template descriptor html files are meant to be translated, please make sure such a similar policy is implemented that will find the html files in the localized jar per locale; this is not implememted automatically.

* .url files

These are files that are used to point to urls when user chooses certain items in the help window menu; the localized .url file will have the address of the url for that language if there is a translation for it.

* Do NOT make .xml or .txt files or other kinds of files have content that would be translated, besides .properties and .html and .url files discussed here.

* text files

If a file to be translated is a text file, change it to be an html file, so the correct encoding can be inserted into the meta charset by translators; some locales have multiple sub locales, each with a different encoding, so that a text file would not be seen correctly by users in those locales, but if its an html file, it can be because there is one meta charset tag that works for all those sub locales.

Provide a meta charset statement inside the html file for a default; usually its UTF-8; translators can change it as needed.

xml files should not be used as files for anything that will be translated - only Bundle.properties files for messages/labels and html files for template descriptors and help files, and .url files as mentioned above.

Template Descriptor files seen in new project/file wizards

These are translated and the descriptions found in html files.

The simplest way to localize template content is to use the nbresloc URL protocol in the location of the content when specifying the template in the module's XML layer.
These are small blocks of HTML to be displayed to a user in the New wizard giving an overview of what the template is for. Descriptions should be HTML resources within the main module JAR; the API Support module provides a convenient way of associating the description to the template before packing the template JAR.

All templates should have localized description files, and the template file attributes in the localized JAR should point to the localized descriptions; by convention, such descriptions should be named e.g. SomeTemplateDescription_LOCALE.html. (It is not necessary to localize the template's contents just to localize its description.) The URL used may be for example:


where this URL loads the appropriate locale variant at runtime. When doing this, the naming scheme for localized template descriptions becomes a requirement rather than a convention.


Images which are localized should be saved as imageName_LOCALE.gif or imageName_LOCALE.png. As usual, the localized image should be stored alongside that in the default locale.

The filenames of images should not be stored in Bundle.properties files, because such files should be used for translatable text only.
To access localized images, you may use Utilities.loadImage(path, true); or use URLs with the nbresloc protocol, which accesses a resource by path (searching all enabled modules) considering also localized variants.
Note that automatic localization will not change the extension of the image file, so it is preferable to use PNG format consistently in place of GIF, and name the base resource with the .png extension.

Do NOT place text that will need to be localized as part of images. Have the text be separate and coming from a bundle file; if this absolutely cannot be done, see guidelines below, since if an image does need to be localized, the tasks to do that should be done by dev teams or writers who would have the tools to do that.

BUT images still need to go into the l10n kit, since if they are not, then the l10n kit will not have them, which means the localized jar will not have them, which means that references to them in localized html files will not find them, and the images will not be seen.

 By default, netbeans code general factilities does not allow localized images to be found in the case where -- if a gif file is localized and renamed to be <filename>_ja.gif, and placed in a localized jar file, the localized image may not come from this jar file unless specific code has been added to the processing of that particular image. (The procedure described above however is the correct one to use when it does work)

thus that is why all images cango into the l10n kits, they will not be localized in most cases but to be in the localized jars.

NetBeans Online Help I18N - for developers and writers

NetBeans online help uses javahelp api and viewer.

NetBeans Online Help is localized and the localized help reside in separate jar files ie


The layout inside the localized help jar mirrors the base/English one except that the files live inside a subdirectory named for the locale, except for the localized .hs file, which lives above that.

Consult the javahelp documentation and also NetBeans developers for more information, as well as layout of actual localized and base help jar files in NetBeans.

   *  make sure that index and other help  search works when multibyte might be used as a search string

   *   make sure that that no cultural references or assumptions are used in help docs

   *   make sure that images should have no text in them if possible since it means that if so, the image would need to be localized and this is a time consuming process. Usual practice for netbeans is that very few if any images are required to be localized.
     BUT images still need to go into the l10n kit, since if they are not,  the localized jar will not have them, which means that references to them in localized html files will not find them, and the images will not be seen.

Documentation and bundle file writing - other guidelines

http://knowledge.central/Ops/local/documentation/english_quality.html http://knowledge.central/Ops/local/documentation/standards/L10n_standards.html

Module names in Bundle files

Modules have several attributes which contain localizable text. They must be placed in a bundle file in the module, and this bundle must be referred to from the manifest, e.g. in the manifest file:

OpenIDE-Module-Localizing-Bundle: org/foo/mymodule/Bundle.properties

The bundle file should contain the keys and english values; remember that delimiter in bundle files is '=' while in manifest files it is ":" so if copy/paste from manifest to bundle, change the delimiter

OpenIDE-Module-Name= some name

OpenIDE-Module-Display-Category=some category

OpenIDE-Module-Short-Description=short description

OpenIDE-Module-Long-Description=long description

Don't save information that will be localized to the user directory

   * Make sure no data that is used as a label or message will be obtained from the userdir; for example, don't copy some bundle or other file to it and then use the values in them. This is because the user might use the same userdir but be in a different locale when they run again, and the values of labels or messages should always come from the bundle files in the installed product. 

Encoding handling and use of multibyte

NOTE - there is a new project encoding property and more enhanced handling of file encoding in netbeans 6.0. The overall name for these features is file encoding query (FEQ)

see nb api javadoc on these for more information at implementation level



These faq documents tells more details about this; it is a collection of information from various developers who implemented it for projects and various file types. http://wiki.netbeans.org/wiki/view/FaqI18nProjectEncoding http://wiki.netbeans.org/wiki/view/FaqI18nChangeProjectEncodingImpact http://wiki.netbeans.org/wiki/view/FaqI18nFileEncodingQueryObject http://wiki.netbeans.org/DevFaqI18nFileEncodingQueryObject

These documents tell more about encoding handling and testing for it.




Information about handling encoding - see other documents noted above for more information

   * not using the correct encoding to process internal data as as well as for reading or writing data from user generated or other files is a common cause of many i18n issues.
   * the 2 ways to handle encoding are either using utf8 or the encoding of the locale the user is in; each of these is appropriate for different kinds of data processing, reading and writing - other developers can provide you more lower level information about this.
   *   Sometimes, not using UTF-8 encoding for processing internal information has been a cause for some i18n issues.

   * Sometimes, its not using the encoding of the locale the user is in for processing file or other data that is the cause of these issues.

   *  users should be able to use multibyte in file names, paths, contents as well as in other data input or provided to the module, as long as that use is legal in terms of java language or other specs like jsp or j2ee. Thus, handling of encoding of these items is important.
  • This means that if user uses multibyte in some name that will be the base name of some other files, that its legal in ide that these files can have filenames with multibyte. Often these files might be control or other informational files about a project or application user is working on, and it may be that user has no occasion to modify or look directly at those files, but they should still work correctly if named with multibyte.
   * sometimes, multibyte data that appears ok in a running ide may not appear ok on restart, if encoding handling of file saving or reading is not done properly.
   * make sure multibyte can be used in file names and contents (where legal in java and other specs) or note restrictions and provide ui warnings to the user.
   * make sure multibyte can be viewed properly in all parts
   * make sure multibyte can be input via locale specific input tools or via copy/paste in all parts

  • sometimes the user can chose what encoding is used for certain kinds of files like html, jsp, or xml files, so modules need to take into account that the encoding in a file may not be the system or UTF-8 encoding

* Now in netbeans from 6.0 onwared,  newly created jsp, html or xml files are seeded with the current project encoding, but user can change those values, however the user needs to ensure that the characaters in the file are correct for the encoding they have chosen; netbeans does not do automatic encoding detection. 

But even if there is not an encoding choice for a file type, or if user does not use the choice, the module should not necessarily assume that the default encoding is that of the locale the user is in when running the ide.

         o Be careful when using java.io.Reader and java.io.Writer classes for data conversion or manipulation, because they do not convert all bytes to characters and characters to bytes correctly when some encodings are being used. This may lead to data loss or incorrect data.
           Instead, use the java.nio.* package and APIs for these conversions.
         o Don't assume that the encoding used in the file or other data being converted may not be in the system encoding in which the user started the product - since project encoding can be any encoding - again see the FEQ information and pointers mentioned in this doc.

See the FileEncodingQuery api in netbeans javadoc as well as information in documents pointed to in this section, for more on these topics

Other i18n considerations

   * make sure time/date will be shown as per the locale
   * don't use text files - they don't have an encoding attribute and there is no one encoding they can be changed to that will work for all Japanese or Chinese sublocales on unix and windows. Use html files instead.

Fontsize considerations

   * make sure that all windows dynamically resize as needed for those who use fontsize option or for case of longer strings due to translated messages being longer in some locales.  This includes items in dropdown lists.
   * don't hardcode font names that are not jdk font names. If a font name is used, it should be one that is named in the jdk font properties files as a standard java font; since in this case it can be mapped to a "real system font" when multibyte is used. That is, do NOT use a OS font not so named; it can cause serious issues of fonts not being found when user runs product.
   * don't hardcode font sizes, but use global font size as baseline. Since localized chinese release on unix still needs 14 point font for visiblity issues, its best not to reduce global font size for some item due to this situation.

         o If there is a need to use a fontsize different than the product's global fontsize then an offset from the global font size should be used for that font size, not an absolute fontsize number.
         o Don't make fontsizes smaller than the global font size - this is because, for some Chinese locales, the quality of fonts <14 point (which is the global font size set by localized Chinese), the quality of the fonts on some platforms might not be as viewable at smaller font sizes/

Sizing and resizing of windows, dialogs and parts of windows/dialogs - i18n considerations

Main guideline for i18n is: The UI objects shown in most NetBeans windows or dialogs or part of a window should show completely to user in most cases (see below) AND User should not need to resize the window to see this information.

This document explains in detail about this requirement and how to test for it

Mnemonics and I18N

* Mnemonics - UPDATE - as of 3/2006, all mnemonics need to be implemented using the '&' approach, not the 2 key/value approach. There are other important requirements for mnemonics to enable l10n work, such as organizing them in bundle file together, and telling what window/dialog they are for.

See this document for more information

Use the org.openide.awt.Mnemonics helper method to do this.

When changing the format of a bundle value - for example, adding a {0}-style parameter or removing one, or changing a pair of label and mnemonic to just a label to be set with org.openide.awt.Mnemonics - always create a fresh key.

All usages of the 2 key/value approach should be changed to use the '&' approach.
See this document for more information

Apostrophes - when to use double apostrophes in bundle files ?

All bundle messages/labels that use code of java MessageFormat, if there are single apostrophes/single quotes in the message, there needs to be 2 apostrophes/single quotes instead ( however, substituting a double quote for 2 single quotes is not allowed)


This first group of other documents elaborate on what other documents related to i18n guidelines and requirements for developers are here on this wiki.

Information and scenarios for developers on handling use of multibyte and encodings for i18n

High level i18n encoding handling programming guidelines

Additional encoding handling questions to developers that helps QE plan for encoding i18n testing

How to setup english windows to run in other locales

Requirements related to creating mnemonics related to i18n and l10n

Information related to requirements of windows needing to dynamically resize and not using hardcoded font names or font sizes

Other java i18n references

Other java i18n references

Other i18n related references from NetBeans Wiki FAQ



Not logged in. Log in, Register

By use of this website, you agree to the NetBeans Policies and Terms of Use. © 2012, Oracle Corporation and/or its affiliates. Sponsored by Oracle logo