جافا: أفضل الممارسات لمشاركة كائن التوطين عبر العديد من كائنات واجهة المستخدم الرسومية؟

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

سؤال

ما هي أفضل الممارسات لمشاركة كائن التوطين (في هذه الحالة ResourceBundle ، حيث أقوم بحفظ جميع الترجمات) عبر العديد من كائنات واجهة المستخدم الرسومية في التطبيق؟ لدي القليل من الأفكار ، لكن كلاهما لديه عيوب:

1) تمرير ResourceBundle عبر كل مُنشئ فئة واجهة المستخدم الرسومية ، ولكن بعد ذلك أحتاج إلى حفظه داخل كل فئة (للاستخدام لاحقًا) - يعني وجود نفس الرمز في كل فئة مرارًا وتكرارًا

2) إعلان ResourceBundle باعتباره ثابتًا عامًا (ولكن ليس نهائيًا ، لأنني قد أحتاج إلى تغييره - على سبيل المثال ، تم تغيير اللغة) في فئة واجهة المستخدم الرسومية الرئيسية (على سبيل المثال ، "ResourceBundle MSG العامة") ، ثم الوصول إليها لاحقًا دائمًا عبر (على سبيل المثال استدعاء Mainguiclass. msg.getString ("شيء ما")) ، ولكن بعد ذلك يمكن أيضًا تعديلها/تدميرها من قبل أي فئة أخرى واجهة المستخدم الرسومية في نفس الحزمة ...

ربما هناك بعض الممارسات الأفضل للقيام بالمشاركة؟

شكرًا.

هل كانت مفيدة؟

المحلول

لا يمكن أن يكون كائن ResourceBundle العالمي نهائيًا ولكن بدلاً من ذلك يجب أن يتم تخزينه مؤقتًا في الخريطة. تغيير اللغة لا يتطلب تغيير هذا المرجع:

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

}

باستخدام هذا الرمز ، يمكنك إما الوصول إلى النصوص بلغات/لغات محددة أو مجرد استخدام اللغة الافتراضية. إذا كنت تريد تبديل موقعك ، فما عليك سوى تعيين اللغة الافتراضية. يجب أن تعرف واجهة المستخدم الخاصة بك عن التغييرات المحلية ، لذلك قد تضطر إلى تقديم بعض واجهة المستمع لجميع مكونات واجهة المستخدم الخاصة بك (PropertyChangelistener, PropertyChangesupport) وعدم تغيير اللغة مباشرة.

نصائح أخرى

يمكنك تنفيذ مصنع للتخزين المؤقت ، والذي يقوم بإرجاع ResourceBundle استنادًا إلى قيمة معلمة لغة الإدخال. عند المكالمة الأولى ، سيتم بناء ResourceBundle ثم يتم تخزينها مؤقتًا في مرجع ثابت ، والتي يمكن إرجاعها وإعادة استخدامها لاحقًا في المكالمات اللاحقة إلى المصنع.

إذا كنت تشعر بالقلق إزاء الفصول الأخرى التي تقوم بأشياء لا تريد أن تهدف إلى كائن ، اجعلها حقلًا محميًا/خاصًا لفصل يحتوي على الأساليب التي تريد تنفيذها عليها.

الكرباليات شريرة ، ولكن في بعض الأحيان تكون راحتها أكبر من شرهم.

ينفذ ResourceBundle Class بالفعل ذاكرة التخزين المؤقت ، لذلك ليست هناك حاجة لتنفيذ التخزين المؤقت لنفسك. يمكن تنفيذ فئة الوصول الخاصة بك كـ Singleton. لتبديل اللغة ، أستخدم threadlocal للموقع:

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

    private ThreadLocale () 
    {
        super ();
    }

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

في طريقة فئة الوصول ، التي تحصل على النص من حزمة الموارد ، أستخدم لغة الخيط الحالية:

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

حتى تتمكن من ضبط لغة لكل موضوع وليس على مستوى العالم.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top