1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203
|
@c This file is part of the GNU gettext manual.
@c Copyright (C) 1995-2020 Free Software Foundation, Inc.
@c See the file gettext.texi for copying conditions.
@node Java
@subsection Java
@cindex Java
@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.
|