mirror of
https://https.git.savannah.gnu.org/git/gettext.git
synced 2026-01-26 15:39:11 +00:00
210 lines
6.4 KiB
Plaintext
210 lines
6.4 KiB
Plaintext
@c This file is part of the GNU gettext manual.
|
|
@c Copyright (C) 1995-2025 Free Software Foundation, Inc.
|
|
@c See the file gettext.texi for copying conditions.
|
|
|
|
@node Java
|
|
@subsection Java
|
|
@cindex Java
|
|
|
|
@ignore
|
|
A widespread approach for localization in Java is via .properties files,
|
|
with a programmer-assigned ID as key for each message.
|
|
With this approach, no PO files, and no support from GNU gettext is possible.
|
|
@end ignore
|
|
|
|
@table @asis
|
|
@item RPMs
|
|
java, java2
|
|
|
|
@item Ubuntu packages
|
|
default-jdk
|
|
|
|
@item File extension
|
|
@code{java}
|
|
|
|
@item String syntax
|
|
"abc", """text block"""
|
|
|
|
@item gettext shorthand
|
|
i18n("abc")
|
|
|
|
@item gettext/ngettext functions
|
|
@code{GettextResource.gettext}, @code{GettextResource.ngettext},
|
|
@code{GettextResource.pgettext}, @code{GettextResource.npgettext}
|
|
|
|
@item textdomain
|
|
---, use @code{ResourceBundle.getResource} instead
|
|
|
|
@item bindtextdomain
|
|
---, use CLASSPATH instead
|
|
|
|
@item setlocale
|
|
automatic
|
|
|
|
@item Prerequisite
|
|
---
|
|
|
|
@item Use or emulate GNU gettext
|
|
---, uses a Java specific message catalog format
|
|
|
|
@item Extractor
|
|
@code{xgettext -ki18n}
|
|
|
|
@item Formatting with positions
|
|
@code{MessageFormat.format "@{1,number@} @{0,number@}"}
|
|
or @code{String.format "%2$d %1$d"}
|
|
|
|
@item Portability
|
|
fully portable
|
|
|
|
@item po-mode marking
|
|
---
|
|
@end table
|
|
|
|
Before marking strings as internationalizable, uses of the string
|
|
concatenation operator need to be converted to @code{MessageFormat}
|
|
applications. For example, @code{"file "+filename+" not found"} becomes
|
|
@code{MessageFormat.format("file @{0@} not found", new Object[] @{ filename @})}.
|
|
Only after this is done, can the strings be marked and extracted.
|
|
|
|
GNU gettext uses the native Java internationalization mechanism, namely
|
|
@code{ResourceBundle}s. There are two formats of @code{ResourceBundle}s:
|
|
@code{.properties} files and @code{.class} files. The @code{.properties}
|
|
format is a text file which the translators can directly edit, like PO
|
|
files, but which doesn't support plural forms. Whereas the @code{.class}
|
|
format is compiled from @code{.java} source code and can support plural
|
|
forms (provided it is accessed through an appropriate API, see below).
|
|
|
|
To convert a PO file to a @code{.properties} file, the @code{msgcat}
|
|
program can be used with the option @code{--properties-output}. To convert
|
|
a @code{.properties} file back to a PO file, the @code{msgcat} program
|
|
can be used with the option @code{--properties-input}. All the tools
|
|
that manipulate PO files can work with @code{.properties} files as well,
|
|
if given the @code{--properties-input} and/or @code{--properties-output}
|
|
option.
|
|
|
|
To convert a PO file to a ResourceBundle class, the @code{msgfmt} program
|
|
can be used with the option @code{--java} or @code{--java2}. To convert a
|
|
ResourceBundle back to a PO file, the @code{msgunfmt} program can be used
|
|
with the option @code{--java}.
|
|
|
|
Two different programmatic APIs can be used to access ResourceBundles.
|
|
Note that both APIs work with all kinds of ResourceBundles, whether
|
|
GNU gettext generated classes, or other @code{.class} or @code{.properties}
|
|
files.
|
|
|
|
@enumerate
|
|
@item
|
|
The @code{java.util.ResourceBundle} API.
|
|
|
|
In particular, its @code{getString} function returns a string translation.
|
|
Note that a missing translation yields a @code{MissingResourceException}.
|
|
|
|
This has the advantage of being the standard API. And it does not require
|
|
any additional libraries, only the @code{msgcat} generated @code{.properties}
|
|
files or the @code{msgfmt} generated @code{.class} files. But it cannot do
|
|
plural handling, even if the resource was generated by @code{msgfmt} from
|
|
a PO file with plural handling.
|
|
|
|
@item
|
|
The @code{gnu.gettext.GettextResource} API.
|
|
|
|
Reference documentation in Javadoc 1.1 style format is in the
|
|
@uref{javadoc2/index.html,javadoc2 directory}.
|
|
|
|
Its @code{gettext} function returns a string translation. Note that when
|
|
a translation is missing, the @var{msgid} argument is returned unchanged.
|
|
|
|
This has the advantage of having the @code{ngettext} function for plural
|
|
handling and the @code{pgettext} and @code{npgettext} for strings constraint
|
|
to a particular context.
|
|
|
|
@cindex @code{libintl} for Java
|
|
To use this API, one needs the @code{libintl.jar} file which is part of
|
|
the GNU gettext package and distributed under the LGPL.
|
|
@end enumerate
|
|
|
|
Four examples, using the second API, are available in the @file{examples}
|
|
directory: @code{hello-java}, @code{hello-java-awt}, @code{hello-java-swing},
|
|
@code{hello-java-qtjambi}.
|
|
|
|
Now, to make use of the API and define a shorthand for @samp{getString},
|
|
there are three idioms that you can choose from:
|
|
|
|
@itemize @bullet
|
|
@item
|
|
(This one assumes Java 1.5 or newer.)
|
|
In a unique class of your project, say @samp{Util}, define a static variable
|
|
holding the @code{ResourceBundle} instance and the shorthand:
|
|
|
|
@smallexample
|
|
private static ResourceBundle myResources =
|
|
ResourceBundle.getBundle("domain-name");
|
|
public static String i18n(String s) @{
|
|
return myResources.getString(s);
|
|
@}
|
|
@end smallexample
|
|
|
|
All classes containing internationalized strings then contain
|
|
|
|
@smallexample
|
|
import static Util.i18n;
|
|
@end smallexample
|
|
|
|
@noindent
|
|
and the shorthand is used like this:
|
|
|
|
@smallexample
|
|
System.out.println(i18n("Operation completed."));
|
|
@end smallexample
|
|
|
|
@item
|
|
In a unique class of your project, say @samp{Util}, define a static variable
|
|
holding the @code{ResourceBundle} instance:
|
|
|
|
@smallexample
|
|
public static ResourceBundle myResources =
|
|
ResourceBundle.getBundle("domain-name");
|
|
@end smallexample
|
|
|
|
All classes containing internationalized strings then contain
|
|
|
|
@smallexample
|
|
private static ResourceBundle res = Util.myResources;
|
|
private static String i18n(String s) @{ return res.getString(s); @}
|
|
@end smallexample
|
|
|
|
@noindent
|
|
and the shorthand is used like this:
|
|
|
|
@smallexample
|
|
System.out.println(i18n("Operation completed."));
|
|
@end smallexample
|
|
|
|
@item
|
|
You add a class with a very short name, say @samp{S}, containing just the
|
|
definition of the resource bundle and of the shorthand:
|
|
|
|
@smallexample
|
|
public class S @{
|
|
public static ResourceBundle myResources =
|
|
ResourceBundle.getBundle("domain-name");
|
|
public static String i18n(String s) @{
|
|
return myResources.getString(s);
|
|
@}
|
|
@}
|
|
@end smallexample
|
|
|
|
@noindent
|
|
and the shorthand is used like this:
|
|
|
|
@smallexample
|
|
System.out.println(S.i18n("Operation completed."));
|
|
@end smallexample
|
|
@end itemize
|
|
|
|
Which of the three idioms you choose, will depend on whether your project
|
|
requires portability to Java versions prior to Java 1.5 and, if so, whether
|
|
copying two lines of codes into every class is more acceptable in your project
|
|
than a class with a single-letter name.
|