There are no files on XDisk. There is one file on XDisk. There are 2 files on XDisk.La forma más rápida de resolver este problema es crear un patrón de MessageFormat como éste:
There are {0,number} file(s) on {1}.
Desafortunadamente, este patrón resulta gramáticamente incorrecto:
There are 1 file(s) on XDisk.Podemos hacer algo mejor que esto utilizando la clase ChoiceFormat. En esta sección, veremos como trarar con plurales en un mensaje, pasando a través de un programa de ejemplo llamado ChoiceFormatDemo.java. Este programa también hace uso de la clase MessageFormat que se describió en la sección anterior, Tratar con Mensajes Concatenados.
There | are no files | on | XDisk | .
There | is one file | on | XDisk | .
There | are 2 files | on | XDisk | .
|______________| |_______|
^ ^
| |
variable variable
Luego, reemplazamos las variables del mensaje con argumentos, creando un patrón que puede aplicarse a un objeto MessageFormat:
There {0} on {1}.
Es muy sencillo trabajar con el argumento para el nombre del disco, que está representado por {1}. Lo trataremos igual que cualquier otra variable String en un patrón MessageFormat. Este argumento corresponde con el elemento 1 del array de valores (Ver paso 7).
Tratar con el argumento {0} es más complejo por un par de razones:
ResourceBundle bundle =
ResourceBundle.getBundle("ChoiceBundle",currentLocale);
Hemos decidido construir nuestro ResourceBundle con ficheros de propiedades. El fichero ChoiceBundle_en_US.properties contiene las siguientes líneas:
pattern = There {0} on {1}.
noFiles = are no files
oneFile = is one file
multipleFiles = are {2} files
El contenido de este fichero de propiedades muestra cómo se construirán y formatearán los mensajes. La primera línea contiene el patrón para MessageFormat, que explicamos en el paso anterior. Las otras líneas contienen frases que reemplazarán el argumento {0} en el patrón. La frase para la clave "multipleFiles" contiene el argumento {2}, que será reemplazado por un número
Aquí podemos ver la versión francesa del fichero de propiedades ChoiceBundle_fr_FR.properties:
pattern = Il {0} sur {1}.
noFiles = n' y a pas des fichiers
oneFile = y a un fichier
multipleFiles = y a {2} fichiers
MessageFormat messageForm = new MessageFormat("");
messageForm.setLocale(currentLocale);
double[] fileLimits = {0,1,2};
String [] fileStrings = {
bundle.getString("noFiles"),
bundle.getString("oneFile"),
bundle.getString("multipleFiles")
};
ChoiceFormat mapea cada elemento del array double con el elemento del array String que tiene el mismo índice. En nuestro código de ejemplo, el 0 mapea el String devuelto por la llamada a bundle.getString("noFiles"). Por coincidencia, en nuestro ejemplo, el índice es el mismo que el valor en el array fileLimits. si hubieramos seleccionado fileLimits[0] a 7, ChoiceFormat mapearía el número 7 con fileStrings[0].
Especificamos los arrays double y String cuando ejemplarizamos ChoiceFormat:
ChoiceFormat choiceForm = new ChoiceFormat(fileLimits, fileStrings);
String pattern = bundle.getString("pattern");
messageForm.applyPattern(pattern);
Format[] formats = {choiceForm, null, NumberFormat.getInstance()};
messageForm.setFormats(formats);
El método setFormats asigna objetos Format a los argumentos del patrón del mensaje. Debemos llamar al método applyPattern antes del llamar al método setFormats. La siguiente tabla muestra cómo el array Format corresponde con los argumentos del patrón del mensaje:
| Elemento del Array | Argumento del Patrón |
|---|---|
| choiceForm | {0} |
| null | {1} |
| NumberFormat.getInstance() | {2} |
Object[] messageArguments = {null, "XDisk", null};
for (int numFiles = 0; numFiles < 4; numFiles++) {
messageArguments[0] = new Integer(numFiles);
messageArguments[2] = new Integer(numFiles);
String result = messageForm.format(messageArguments);
System.out.println(result);
}
% java ChoiceFormatDemo en US currentLocale = en_US There are no files on XDisk. There is one file on XDisk. There are 2 files on XDisk. There are 3 files on XDisk.Compara los mensajes mostrados por el programa con las frases del ResourceBundle del paso 2. Observa que el objeto ChoiceFormat selecciona la frase corecta, que el objeto MessageFormat utiliza para construir el mensaje apropiado.
La versión francesa del mensaje también parece correcta:
% java ChoiceFormatDemo fr FR
currentLocale = fr_FR
Il n' y a pas des fichiers sur XDisk.
Il y a un fichier sur XDisk.
Il y a 2 fichiers sur XDisk.
Il y a 3 fichiers sur XDisk.