anlyticsed java internationalization resourcebundle

java - anlyticsed - minecraft splash



En Java, ¿cómo puedo averiguar qué idiomas tengo disponible? Mi paquete de recursos (4)

Tengo algunos paquetes de recursos empaquetados en mi jar principal

widget_en.properties widget_de.properties

Recupero un paquete de recursos basado en mi configuración regional predeterminada como archivos

ResourceBundle.getBundle("widget", Locale.getDefault());

Pero quiero presentar al usuario una lista de idiomas disponibles compatibles para que pueda seleccionar un idioma que puede ser diferente al predeterminado de su computadora

Pero no puedo encontrar un método en ResourceBundle que enumere las configuraciones regionales disponibles, no quiero codificar una lista, ya que puedo olvidar actualizarla cuando se agrega otro paquete de recursos.

EDITAR

Como solo busco paquetes para diferentes idiomas (no tengo refinamientos de país) entonces he generado una lista al recorrer todos los códigos de idioma conocidos y verificar cada uno como un recurso.

String[]langs = Locale.getISOLanguages(); for(String lang:langs) { URL rb = ClassLoader.getSystemResource("widget_"+lang+".properties"); if(rb!=null) { System.out.println("Found:"+rb.toString()); } }


Si puedes hacer dos suposiciones básicas:

1) Tiene un paquete de recursos predeterminado sin configuración regional, o al menos una configuración regional que sabe que existe.

2) Todos sus recursos están en la misma ubicación (es decir, la misma ruta dentro de un único archivo jar)

Luego puede obtener la URL de un solo recurso:

URL url = SomeClass.class.getClassLoader().getResource("widget.properties");

una vez que tenga eso, debería poder analizar la URL.

Si usa commons-vfs, debería poder convertir la URL en un FileObject:

FileSystemManager manager = VFS.getManager(); FileObject resource = manager.resolveFile(url.toExternalForm()); FileObject parent = resource.getParent(); FileObject children[] = parent.getChildren(); // figure out which ones are bundles, and parse the names into a list of locales.

Esto le ahorrará la molestia de lidiar con las complejidades de jar: style url''s y demás, ya que vfs se encargará de eso por usted.


Si realmente empaqueta los archivos de recursos dentro de su JAR, entonces lo haría así:

public static void main(String[] args) { Set<ResourceBundle> resourceBundles = getResourceBundles(A.class.getName()); if (resourceBundles.isEmpty()) // ... } public static Set<ResourceBundle> getResourceBundles(String baseName) { Set<ResourceBundle> resourceBundles = new HashSet<>(); for (Locale locale : Locale.getAvailableLocales()) { try { resourceBundles.add(ResourceBundle.getBundle(baseName, locale)); } catch (MissingResourceException ex) { // ... } } return Collections.unmodifiableSet(resourceBundles); }

Si te importan tus JAR, al menos obtendrás un conjunto que contiene el recurso predeterminado para un baseName dado.

Si solo tiene recursos con nombres como baseName_<country> este método funciona perfectamente, porque solo esos ResourceBundles se agregarán al conjunto que está presente en su JAR. Funcionará incluso si decide que necesita baseName_en_US separados de baseName_en_US y baseName_en_UK , lo cual no es desconocido.

Conector descarado: escribí un ResourceBundle.Control que toma un Charset como argumento, puede que le interese si quiere cargar archivos de recursos codificados en UTF-8. Está disponible en GitHub.


No creo que haya una API para esto porque se pueden crear nuevos objetos de localización válidos sobre la marcha:

Locale locale = new Locale("abcd");

sin la necesidad de registrarlo en alguna parte. Y luego puede usar un paquete de recursos widget_abcd.properties sin restricciones:

ResourceBundle resource= ResourceBundle.getBundle("widget", new Locale("abcd"));

De los documentos de la API java.util.Locale :

Como un objeto Locale es solo un identificador para una región, no se realiza ninguna comprobación de validez cuando se construye una configuración regional. Si desea ver si hay recursos particulares disponibles para la configuración regional que construye, debe consultar esos recursos.

Para resolver el problema, puede iterar sobre todos los archivos llamados "widget_" en el directorio de recursos y descubrir los nuevos paquetes de recursos agregados.

Tenga en cuenta que Locale.getAvailableLocales() no es 100% seguro por la razón anterior: es posible que algún día defina una configuración regional no estándar. Pero si agrega solo algunas configuraciones estándar, puede usar este método estático para recorrer las configuraciones regionales del sistema y obtener los paquetes correspondientes.


A resolverlo enumerando archivos.

public class JavaApplication1 { public static final ArrayList<String> LOCALES = new ArrayList<>(); static { try { File f = new File(JavaApplication1.class.getResource("/l10n").toURI()); final String bundle = "widget_";// Bundle name prefix. for (String s : f.list(new FilenameFilter() { @Override public boolean accept(File dir, String name) { return name.startsWith(bundle); } })) { LOCALES.add(s.substring(bundle.length(), s.indexOf(''.''))); } } catch (URISyntaxException x) { throw new RuntimeException(x); } LOCALES.trimToSize(); } ... }