Java: Les meilleures pratiques pour le partage des objets de localisation à travers de nombreux objets de l'interface graphique?

StackOverflow https://stackoverflow.com/questions/2350735

Question

Quelle serait la meilleure pratique pour le partage de localisation objet (dans ce cas ResourceBundle, où je fais enregistrer toutes les traductions) à travers de nombreux objets de l'interface graphique dans l'application? J'ai quelques idées, mais les deux ont des inconvénients:

1) passant ResourceBundle par chaque constructeur de la classe GUI, mais je dois l'enregistrer à l'intérieur de chaque classe (pour une utilisation ultérieure) - des moyens ayant le même code dans chaque classe encore et encore

2) déclarer ResourceBundle comme statique public (mais pas définitive, parce que je peux avoir besoin de le changer - par exemple la langue changé) dans la classe principale de l'interface graphique (par exemple, « msg ResourceBundle public static »), puis accéder plus tard toujours par elle (par exemple appelant MainGuiClass.msg.getString ( « quelque chose »)), mais il peut aussi être modifiée / détruite par une autre classe de GUI dans le même paquet ...

Peut-être qu'il ya une meilleure pratique pour faire le partage?

Merci.

Était-ce utile?

La solution

L'objet global ResourceBundle ne peut pas être à la place finale, mais devrait être mis en cache dans une carte. Changer la langue ne nécessite pas de changer cette référence:

import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.ResourceBundle;

public class UIBundle {
    private static final Map<Locale, ResourceBundle> allUIResources = new HashMap<Locale, ResourceBundle>();

    public static String getString(final String key) {
        return getString(key, Locale.getDefault());
    }

    public static String getString(final String key, final Locale locale) {
        ResourceBundle rb = allUIResources.get(locale);
        if (rb == null) {
            rb = ResourceBundle.getBundle("my-ui-resource", locale);
            allUIResources.put(locale, rb);
        }
        return rb.getString(key);
    }

}

Avec ce code, vous pouvez soit les textes d'accès dans des langues spécifiques / locales ou simplement utiliser les paramètres régionaux par défaut. Si vous voulez changer vos paramètres régionaux, juste définir les paramètres régionaux par défaut. Votre interface utilisateur a besoin de savoir sur les changements de paramètres régionaux, de sorte que vous pouvez avoir à introduire une interface écouteur pour tous vos composants de l'interface utilisateur ( PropertyChangeListener , PropertyChangeSupport ) et ne pas modifier les paramètres régionaux directement.

Autres conseils

Vous pouvez mettre en place une usine de mise en cache, qui retourne la ResourceBundle en fonction de la valeur d'un paramètre de paramètres régionaux d'entrée. Dès le premier appel ResourceBundle sera construit puis mis en cache dans une référence statique, qui peut ensuite être retourné et réutilisé dans les appels plus tard à l'usine.

Si vous êtes préoccupé par d'autres classes qui font des choses que vous ne voulez pas un objet, en font un champ de protection / privé d'une classe qui a les méthodes que vous souhaitez effectuer sur elle.

Globals sont mauvais, mais parfois leur convenance est supérieure à leur méchancetés.

La ResourceBundle classe implémente déjà un cache, donc il n'y a pas besoin de mettre en œuvre vous cache. Votre classe d'accès peut être mis en œuvre singleton. Pour changer la langue que j'utilise un ThreadLocal pour les paramètres régionaux:

public final class ThreadLocale extends ThreadLocal<Locale>
{
    public static final ThreadLocale theInstance = new ThreadLocale ();

    private ThreadLocale () 
    {
        super ();
    }

    protected Locale initialValue()
    {
        return Locale.getDefault ();
    }
}

Dans la méthode de la classe d'accès, qui obtient le texte du groupe de ressources que j'utilise les paramètres régionaux de thread courant:

public synchronized String getMessage (Object messageKey, Locale locale) throws MissingResourceException
{
    ResourceBundle resourceBundle = null;
    resourceBundle = ResourceBundle.getBundle (filename, ThreadLocale.theInstance.get ());
    return resourceBundle.getString (messageKey.toString ());
}

Vous pouvez définir un lieu pour chaque thread et non à l'échelle mondiale.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top