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