• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1@c This file is part of the GNU gettext manual.
2@c Copyright (C) 1995-2020 Free Software Foundation, Inc.
3@c See the file gettext.texi for copying conditions.
4
5@node Java
6@subsection Java
7@cindex Java
8
9@table @asis
10@item RPMs
11java, java2
12
13@item Ubuntu packages
14default-jdk
15
16@item File extension
17@code{java}
18
19@item String syntax
20"abc", """text block"""
21
22@item gettext shorthand
23i18n("abc")
24
25@item gettext/ngettext functions
26@code{GettextResource.gettext}, @code{GettextResource.ngettext},
27@code{GettextResource.pgettext}, @code{GettextResource.npgettext}
28
29@item textdomain
30---, use @code{ResourceBundle.getResource} instead
31
32@item bindtextdomain
33---, use CLASSPATH instead
34
35@item setlocale
36automatic
37
38@item Prerequisite
39---
40
41@item Use or emulate GNU gettext
42---, uses a Java specific message catalog format
43
44@item Extractor
45@code{xgettext -ki18n}
46
47@item Formatting with positions
48@code{MessageFormat.format "@{1,number@} @{0,number@}"}
49or @code{String.format "%2$d %1$d"}
50
51@item Portability
52fully portable
53
54@item po-mode marking
55---
56@end table
57
58Before marking strings as internationalizable, uses of the string
59concatenation operator need to be converted to @code{MessageFormat}
60applications.  For example, @code{"file "+filename+" not found"} becomes
61@code{MessageFormat.format("file @{0@} not found", new Object[] @{ filename @})}.
62Only after this is done, can the strings be marked and extracted.
63
64GNU gettext uses the native Java internationalization mechanism, namely
65@code{ResourceBundle}s.  There are two formats of @code{ResourceBundle}s:
66@code{.properties} files and @code{.class} files.  The @code{.properties}
67format is a text file which the translators can directly edit, like PO
68files, but which doesn't support plural forms.  Whereas the @code{.class}
69format is compiled from @code{.java} source code and can support plural
70forms (provided it is accessed through an appropriate API, see below).
71
72To convert a PO file to a @code{.properties} file, the @code{msgcat}
73program can be used with the option @code{--properties-output}.  To convert
74a @code{.properties} file back to a PO file, the @code{msgcat} program
75can be used with the option @code{--properties-input}.  All the tools
76that manipulate PO files can work with @code{.properties} files as well,
77if given the @code{--properties-input} and/or @code{--properties-output}
78option.
79
80To convert a PO file to a ResourceBundle class, the @code{msgfmt} program
81can be used with the option @code{--java} or @code{--java2}.  To convert a
82ResourceBundle back to a PO file, the @code{msgunfmt} program can be used
83with the option @code{--java}.
84
85Two different programmatic APIs can be used to access ResourceBundles.
86Note that both APIs work with all kinds of ResourceBundles, whether
87GNU gettext generated classes, or other @code{.class} or @code{.properties}
88files.
89
90@enumerate
91@item
92The @code{java.util.ResourceBundle} API.
93
94In particular, its @code{getString} function returns a string translation.
95Note that a missing translation yields a @code{MissingResourceException}.
96
97This has the advantage of being the standard API.  And it does not require
98any additional libraries, only the @code{msgcat} generated @code{.properties}
99files or the @code{msgfmt} generated @code{.class} files.  But it cannot do
100plural handling, even if the resource was generated by @code{msgfmt} from
101a PO file with plural handling.
102
103@item
104The @code{gnu.gettext.GettextResource} API.
105
106Reference documentation in Javadoc 1.1 style format is in the
107@uref{javadoc2/index.html,javadoc2 directory}.
108
109Its @code{gettext} function returns a string translation.  Note that when
110a translation is missing, the @var{msgid} argument is returned unchanged.
111
112This has the advantage of having the @code{ngettext} function for plural
113handling and the @code{pgettext} and @code{npgettext} for strings constraint
114to a particular context.
115
116@cindex @code{libintl} for Java
117To use this API, one needs the @code{libintl.jar} file which is part of
118the GNU gettext package and distributed under the LGPL.
119@end enumerate
120
121Four examples, using the second API, are available in the @file{examples}
122directory: @code{hello-java}, @code{hello-java-awt}, @code{hello-java-swing},
123@code{hello-java-qtjambi}.
124
125Now, to make use of the API and define a shorthand for @samp{getString},
126there are three idioms that you can choose from:
127
128@itemize @bullet
129@item
130(This one assumes Java 1.5 or newer.)
131In a unique class of your project, say @samp{Util}, define a static variable
132holding the @code{ResourceBundle} instance and the shorthand:
133
134@smallexample
135private static ResourceBundle myResources =
136  ResourceBundle.getBundle("domain-name");
137public static String i18n(String s) @{
138  return myResources.getString(s);
139@}
140@end smallexample
141
142All classes containing internationalized strings then contain
143
144@smallexample
145import static Util.i18n;
146@end smallexample
147
148@noindent
149and the shorthand is used like this:
150
151@smallexample
152System.out.println(i18n("Operation completed."));
153@end smallexample
154
155@item
156In a unique class of your project, say @samp{Util}, define a static variable
157holding the @code{ResourceBundle} instance:
158
159@smallexample
160public static ResourceBundle myResources =
161  ResourceBundle.getBundle("domain-name");
162@end smallexample
163
164All classes containing internationalized strings then contain
165
166@smallexample
167private static ResourceBundle res = Util.myResources;
168private static String i18n(String s) @{ return res.getString(s); @}
169@end smallexample
170
171@noindent
172and the shorthand is used like this:
173
174@smallexample
175System.out.println(i18n("Operation completed."));
176@end smallexample
177
178@item
179You add a class with a very short name, say @samp{S}, containing just the
180definition of the resource bundle and of the shorthand:
181
182@smallexample
183public class S @{
184  public static ResourceBundle myResources =
185    ResourceBundle.getBundle("domain-name");
186  public static String i18n(String s) @{
187    return myResources.getString(s);
188  @}
189@}
190@end smallexample
191
192@noindent
193and the shorthand is used like this:
194
195@smallexample
196System.out.println(S.i18n("Operation completed."));
197@end smallexample
198@end itemize
199
200Which of the three idioms you choose, will depend on whether your project
201requires portability to Java versions prior to Java 1.5 and, if so, whether
202copying two lines of codes into every class is more acceptable in your project
203than a class with a single-letter name.
204