Domanda

Quale sarebbe la migliore pratica per la condivisione di oggetti di localizzazione (in questo caso ResourceBundle, dove faccio salvare tutte le traduzioni) in molti oggetti GUI in app? Ho alcune idee, ma entrambi hanno svantaggi:

1) passando ResourceBundle via ogni costruttore della classe GUI, ma poi ho bisogno di salvarlo all'interno di ogni classe (per un uso successivo) - significa avere lo stesso codice in ogni classe più e più volte

2) dichiarare ResourceBundle come public static (ma non definitiva, perché posso avere bisogno di cambiarlo - ad esempio la lingua cambiato) in classe GUI principale (per esempio "pubblico ResourceBundle msg statica"), poi accedervi sempre tramite esso (ad esempio, chiamando MainGuiClass.msg.getString ( "qualcosa")), ma poi può anche essere modificato / distrutto da qualsiasi altra classe GUI nella stessa confezione ...

Forse c'è una certa pratica di meglio da fare la condivisione?

Grazie.

È stato utile?

Soluzione

L'oggetto ResourceBundle globale non può essere definitiva ma invece dovrebbe essere memorizzati nella cache in una mappa. La modifica della lingua non richiede di cambiare questo riferimento:

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);
    }

}

Con questo codice è possibile sia testi di accesso a specifiche lingue / locali o semplicemente usare l'impostazione internazionale predefinita. Se si desidera passare proprio locale, è sufficiente impostare l'impostazione internazionale predefinita. L'interfaccia utente ha bisogno di conoscere le modifiche delle impostazioni internazionali, quindi potrebbe essere necessario introdurre un po 'l'interfaccia listener per tutti i componenti dell'interfaccia utente ( PropertyChangeListener , PropertyChangeSupport ) e non modificare direttamente le impostazioni internazionali.

Altri suggerimenti

Si potrebbe implementare una fabbrica di caching, che restituisce il ResourceBundle in base al valore di un parametro di ingresso locale. Alla prima chiamata ResourceBundle sarà costruito e poi memorizzato nella cache in un riferimento statico, che può successivamente essere restituito e riutilizzato in chiamate successive alla fabbrica.

Se siete preoccupati per le altre classi di fare le cose che non si desidera a un oggetto, ne fanno un protetto / campo privato di una classe che ha i metodi che si desidera eseguire su di esso.

Globali sono il male, ma a volte la loro convenienza è maggiore della loro malvagità.

Il ResourceBundle classe implementa già una cache, quindi non c'è necessità di implementare la memorizzazione nella cache da soli. La vostra classe di accesso può essere implementato come Singleton. Per cambiare la lingua che uso un ThreadLocal per le impostazioni internazionali:

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

    private ThreadLocale () 
    {
        super ();
    }

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

Nel metodo della classe di accesso, che ottiene il testo dal pacchetto di risorse che uso il locale thread corrente:

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 ());
}

Così si può impostare un locale per ogni thread e non a livello globale.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top