# Localizer > **Relevant source files** > * [src/io/github/samera2022/mouse_macros/Localizer.java](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/Localizer.java) > * [src/io/github/samera2022/mouse_macros/listener/GlobalMouseListener.java](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/listener/GlobalMouseListener.java) > * [src/io/github/samera2022/mouse_macros/manager/ConfigManager.java](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/manager/ConfigManager.java) > * [src/io/github/samera2022/mouse_macros/util/FileUtil.java](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/util/FileUtil.java) ## Purpose and Scope The `Localizer` utility class provides internationalization (i18n) functionality for the MouseMacros application. It manages loading, caching, and retrieval of localized strings from JSON language files. This system supports seven languages (English, Chinese, Japanese, Korean, Russian, Spanish, and French) and provides automatic system language detection with English fallback. For information about the language file structure and supported translation keys, see [Language Files and Translation Keys](Language-Files-and-Translation-Keys). For details on how appearance settings control language selection, see [Configuration Files and Settings](Configuration-Files-and-Settings). **Sources:** [src/io/github/samera2022/mouse_macros/Localizer.java L1-L98](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/Localizer.java#L1-L98) --- ## Architecture Overview The `Localizer` operates as a singleton utility with static methods, loading translations at application startup and providing runtime access to localized strings throughout the UI layer. ### System Context Diagram ```mermaid flowchart TD StaticInit["Localizer static block"] EnvDetect["Environment Detection"] SysLangDetect["System Language Detection"] DevFiles["Development Mode
lang/*.json files"] JarFiles["Production Mode
JAR resources"] LocalizerClass["Localizer"] TranslationMap["translations Map"] CurrentLang["currentLang String"] DevModeFlag["isDevMode boolean"] RuntimeSwitchFlag["runtimeSwitch boolean"] LoadMethod["load(String lang)"] GetMethod["get(String key)"] IsDevMode["isDevMode()"] GetCurrentLang["getCurrentLang()"] SetRuntimeSwitch["setRuntimeSwitch(boolean)"] ConfigManager["ConfigManager.getAvailableLangs()"] UIComponents["MainFrame, Dialogs, Listeners"] SettingsDialog["SettingsDialog
language selection"] PrimaryLookup["Primary Language Lookup"] EnglishFallback["English Fallback
en_us.json"] KeyReturn["Return key if not found"] EnvDetect --> DevModeFlag SysLangDetect --> LoadMethod DevModeFlag --> DevFiles DevModeFlag --> JarFiles DevFiles --> LoadMethod JarFiles --> LoadMethod LoadMethod --> TranslationMap LoadMethod --> CurrentLang GetMethod --> PrimaryLookup LocalizerClass --> LoadMethod LocalizerClass --> GetMethod LocalizerClass --> IsDevMode LocalizerClass --> GetCurrentLang LocalizerClass --> SetRuntimeSwitch ConfigManager --> IsDevMode ConfigManager --> JarFiles UIComponents --> GetMethod SettingsDialog --> LoadMethod TranslationMap --> GetMethod CurrentLang --> GetMethod subgraph subGraph5 ["Fallback Mechanism"] PrimaryLookup EnglishFallback KeyReturn PrimaryLookup --> EnglishFallback EnglishFallback --> KeyReturn end subgraph subGraph4 ["Integration Points"] ConfigManager UIComponents SettingsDialog end subgraph subGraph3 ["API Methods"] LoadMethod GetMethod IsDevMode GetCurrentLang SetRuntimeSwitch end subgraph subGraph2 ["Localizer Core"] LocalizerClass TranslationMap CurrentLang DevModeFlag RuntimeSwitchFlag end subgraph subGraph1 ["Language File Sources"] DevFiles JarFiles end subgraph subGraph0 ["Application Initialization"] StaticInit EnvDetect SysLangDetect StaticInit --> EnvDetect StaticInit --> SysLangDetect end ``` **Sources:** [src/io/github/samera2022/mouse_macros/Localizer.java L1-L98](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/Localizer.java#L1-L98), [src/io/github/samera2022/mouse_macros/manager/ConfigManager.java L79-L132](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/manager/ConfigManager.java#L79-L132) --- ## Environment Detection The `Localizer` determines its operational mode (development or production) during static initialization by checking for the presence of language files in the file system. ### Development vs Production Mode | Mode | Detection Method | Language File Source | Use Case | | --- | --- | --- | --- | | **Development** | Checks if `lang/zh_cn.json` file exists | Reads from `lang/` directory in project | IDE/development environment | | **Production** | File check fails | Reads from JAR resources `lang/*.json` | Packaged application | ### Environment Detection Logic ```mermaid flowchart TD Start["Static Initialization"] CheckFile["Check File:
new File('lang/zh_cn.json').exists()"] SetDevMode["isDevMode = true"] SetProdMode["isDevMode = false"] DetectSysLang["Detect System Language
Locale.getDefault()"] NormalizeLang["Normalize language code
replace '-' with '_'"] CheckLangFile["Language file
exists?"] UseSysLang["Use system language"] FallbackEnglish["Fallback to en_us"] LoadLang["load(currentLang)"] Start --> CheckFile CheckFile --> SetDevMode CheckFile --> SetProdMode SetDevMode --> DetectSysLang SetProdMode --> DetectSysLang DetectSysLang --> NormalizeLang NormalizeLang --> CheckLangFile CheckLangFile --> UseSysLang CheckLangFile --> FallbackEnglish UseSysLang --> LoadLang FallbackEnglish --> LoadLang ``` **Code Implementation:** * **Environment detection**: [src/io/github/samera2022/mouse_macros/Localizer.java L15-L18](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/Localizer.java#L15-L18) * **System language detection**: [src/io/github/samera2022/mouse_macros/Localizer.java L20-L32](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/Localizer.java#L20-L32) **Sources:** [src/io/github/samera2022/mouse_macros/Localizer.java L15-L33](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/Localizer.java#L15-L33) --- ## Language Loading Process The `load(String lang)` method is the core mechanism for loading translation files into memory. It handles both development and production environments differently. ### Loading Flow ```mermaid sequenceDiagram participant Caller participant load(lang) participant isDevMode check participant File System participant ClassLoader participant Gson Parser participant translations Map Caller->>load(lang): load("zh_cn") load(lang)->>isDevMode check: Check isDevMode loop [Development Mode] isDevMode check->>File System: new File("lang/zh_cn.json") File System->>File System: Check existence File System-->>load(lang): FileReader load(lang)->>Gson Parser: fromJson(reader, Map.class) isDevMode check->>ClassLoader: getResourceAsStream("lang/zh_cn.json") ClassLoader-->>load(lang): InputStream load(lang)->>Gson Parser: fromJson(InputStreamReader, Map.class) end Gson Parser-->>load(lang): Map load(lang)->>translations Map: Update translations load(lang)->>load(lang): currentLang = "zh_cn" load(lang)-->>Caller: Success note over load(lang): On exception: translations = empty HashMap ``` ### Path Resolution | Environment | File Path | Access Method | | --- | --- | --- | | Development | `/lang/{lang}.json` or `lang/{lang}.json` | `new FileReader(file)` | | Production | `lang/{lang}.json` (JAR resource) | `ClassLoader.getResourceAsStream(path)` | **Code Implementation:** * **Load method signature**: [src/io/github/samera2022/mouse_macros/Localizer.java L47](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/Localizer.java#L47-L47) * **Development mode loading**: [src/io/github/samera2022/mouse_macros/Localizer.java L49-L52](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/Localizer.java#L49-L52) * **Production mode loading**: [src/io/github/samera2022/mouse_macros/Localizer.java L53-L59](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/Localizer.java#L53-L59) * **Error handling**: [src/io/github/samera2022/mouse_macros/Localizer.java L62-L64](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/Localizer.java#L62-L64) **Sources:** [src/io/github/samera2022/mouse_macros/Localizer.java L47-L65](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/Localizer.java#L47-L65) --- ## Translation Retrieval and Fallback Mechanism The `get(String key)` method implements a two-tier fallback strategy to ensure that UI text is always available, even when translations are incomplete. ### Retrieval Logic Flow ```mermaid flowchart TD GetCall["get(key)"] PrimaryLookup["translations.get(key)"] CheckValue["value != null?"] ReturnValue["Return value"] CheckCurrent["currentLang == 'en_us'?"] LoadEnglish["Load en_us.json"] EnglishLookup["enMap.get(key)"] CheckEnValue["enValue != null?"] ReturnEnValue["Return enValue"] ReturnKey["Return key
(untranslated)"] GetCall --> PrimaryLookup PrimaryLookup --> CheckValue CheckValue --> ReturnValue CheckValue --> CheckCurrent CheckCurrent --> ReturnKey CheckCurrent --> LoadEnglish LoadEnglish --> EnglishLookup EnglishLookup --> CheckEnValue CheckEnValue --> ReturnEnValue CheckEnValue --> ReturnKey ``` ### Fallback Behavior Table | Scenario | Primary Lookup | English Fallback | Final Result | | --- | --- | --- | --- | | Key exists in current language | ✓ Found | Not attempted | Localized string | | Key missing, current is English | ✗ Not found | Not applicable | Key string | | Key missing, current is not English | ✗ Not found | Attempted | English string or key | | All lookups fail | ✗ Not found | ✗ Not found | Key string | **Code Implementation:** * **Primary lookup**: [src/io/github/samera2022/mouse_macros/Localizer.java L67-L69](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/Localizer.java#L67-L69) * **English fallback check**: [src/io/github/samera2022/mouse_macros/Localizer.java L71](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/Localizer.java#L71-L71) * **Development mode fallback**: [src/io/github/samera2022/mouse_macros/Localizer.java L73-L79](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/Localizer.java#L73-L79) * **Production mode fallback**: [src/io/github/samera2022/mouse_macros/Localizer.java L80-L89](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/Localizer.java#L80-L89) * **Final fallback**: [src/io/github/samera2022/mouse_macros/Localizer.java L92](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/Localizer.java#L92-L92) **Sources:** [src/io/github/samera2022/mouse_macros/Localizer.java L67-L93](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/Localizer.java#L67-L93) --- ## Runtime Language Switching The `Localizer` supports runtime language switching through a control flag and manual reload mechanism. ### Runtime Switch Mechanism ```mermaid flowchart TD RuntimeSwitch["runtimeSwitch boolean"] SetMethod["setRuntimeSwitch(boolean)"] IsMethod["isRuntimeSwitch()"] UserAction["User selects new language"] ConfigUpdate["ConfigManager updates config.lang"] LoadCall["Localizer.load(newLang)"] MapUpdate["translations Map updated"] CurrentLangUpdate["currentLang updated"] ComponentUtil["ComponentUtil triggers resize"] FrameAdjust["Frame adjustments based on
readjustFrameMode"] TextRefresh["UI components re-fetch strings"] MapUpdate --> ComponentUtil subgraph subGraph2 ["UI Update"] ComponentUtil FrameAdjust TextRefresh ComponentUtil --> FrameAdjust FrameAdjust --> TextRefresh end subgraph subGraph1 ["Language Change Process"] UserAction ConfigUpdate LoadCall MapUpdate CurrentLangUpdate UserAction --> ConfigUpdate ConfigUpdate --> LoadCall LoadCall --> MapUpdate LoadCall --> CurrentLangUpdate end subgraph subGraph0 ["Control Flag"] RuntimeSwitch SetMethod IsMethod SetMethod --> RuntimeSwitch RuntimeSwitch --> IsMethod end ``` ### Runtime Switch API | Method | Purpose | Usage | | --- | --- | --- | | `setRuntimeSwitch(boolean enable)` | Enable/disable runtime switching flag | Called by settings dialog before language change | | `isRuntimeSwitch()` | Check if runtime switch is active | Used by `ComponentUtil` to determine resize behavior | | `load(String lang)` | Reload translations for new language | Called after config update | | `getCurrentLang()` | Get active language code | Used to check current state | **Code Implementation:** * **Runtime switch setter**: [src/io/github/samera2022/mouse_macros/Localizer.java L35-L37](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/Localizer.java#L35-L37) * **Runtime switch getter**: [src/io/github/samera2022/mouse_macros/Localizer.java L39-L41](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/Localizer.java#L39-L41) * **Current language getter**: [src/io/github/samera2022/mouse_macros/Localizer.java L95-L97](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/Localizer.java#L95-L97) **Sources:** [src/io/github/samera2022/mouse_macros/Localizer.java L35-L41](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/Localizer.java#L35-L41), [src/io/github/samera2022/mouse_macros/Localizer.java L95-L97](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/Localizer.java#L95-L97) --- ## Integration with Configuration System The `ConfigManager` works with `Localizer` to discover available languages and manage language selection preferences. ### Available Languages Detection The `ConfigManager.getAvailableLangs()` method enumerates language files using the same environment detection logic as `Localizer`. ```mermaid flowchart TD GetLangs["getAvailableLangs()"] CheckMode["isDevMode()?"] ListFiles["FileUtil.listFileNames('lang')"] StripExt1["Strip .json extension"] GetResURL["getResource('lang/')"] CheckProtocol["protocol == 'jar'?"] ParsePath["Parse JAR path"] OpenJar["new JarFile(jarPath)"] EnumEntries["Enumerate entries"] FilterLang["Filter 'lang/*.json'"] ExtractName["Extract filename"] ListDir["List directory files"] FilterJson["Filter .json files"] StripExt2["Strip extension"] BuildArray["Build String[] array"] ReturnLangs["Return available languages"] GetLangs --> CheckMode CheckMode --> ListFiles CheckMode --> GetResURL StripExt1 --> BuildArray ExtractName --> BuildArray StripExt2 --> BuildArray BuildArray --> ReturnLangs subgraph subGraph3 ["Production Mode"] GetResURL CheckProtocol GetResURL --> CheckProtocol CheckProtocol --> ParsePath CheckProtocol --> ListDir subgraph subGraph2 ["File Protocol"] ListDir FilterJson StripExt2 ListDir --> FilterJson FilterJson --> StripExt2 end subgraph subGraph1 ["JAR Processing"] ParsePath OpenJar EnumEntries FilterLang ExtractName ParsePath --> OpenJar OpenJar --> EnumEntries EnumEntries --> FilterLang FilterLang --> ExtractName end end subgraph subGraph0 ["Development Mode"] ListFiles StripExt1 ListFiles --> StripExt1 end ``` ### Language Discovery Table | Environment | Discovery Method | File Pattern | | --- | --- | --- | | Development | `FileUtil.listFileNames("lang")` | `lang/*.json` in filesystem | | Production (JAR) | JAR entry enumeration | Entries matching `lang/*.json` | | Production (File) | Directory listing | `.json` files in `lang/` directory | **Code Implementation:** * **getAvailableLangs() method**: [src/io/github/samera2022/mouse_macros/manager/ConfigManager.java L79-L132](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/manager/ConfigManager.java#L79-L132) * **isDevMode() check**: [src/io/github/samera2022/mouse_macros/manager/ConfigManager.java L81](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/manager/ConfigManager.java#L81-L81) * **Development mode listing**: [src/io/github/samera2022/mouse_macros/manager/ConfigManager.java L82-L91](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/manager/ConfigManager.java#L82-L91) * **JAR entry enumeration**: [src/io/github/samera2022/mouse_macros/manager/ConfigManager.java L94-L113](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/manager/ConfigManager.java#L94-L113) * **File protocol handling**: [src/io/github/samera2022/mouse_macros/manager/ConfigManager.java L114-L126](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/manager/ConfigManager.java#L114-L126) **Sources:** [src/io/github/samera2022/mouse_macros/manager/ConfigManager.java L79-L132](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/manager/ConfigManager.java#L79-L132), [src/io/github/samera2022/mouse_macros/Localizer.java L43-L45](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/Localizer.java#L43-L45) --- ## Usage Examples Throughout the Codebase The `Localizer.get(key)` method is called extensively throughout the UI layer to retrieve localized strings. ### Common Usage Patterns ```mermaid flowchart TD MainFrame["MainFrame"] Dialogs["Various Dialogs"] Listeners["Event Listeners"] GetButton["Localizer.get('button.record')"] GetLog["Localizer.get('log.recording_mouse_pressed')"] GetTooltip["Localizer.get('tooltip.enable_quick_mode')"] GetLabel["Localizer.get('label.language')"] UIKeys["UI Element Labels"] LogKeys["Log Messages"] TooltipKeys["Tooltip Text"] DialogKeys["Dialog Messages"] MainFrame --> GetButton MainFrame --> GetLabel Dialogs --> GetTooltip Listeners --> GetLog GetButton --> UIKeys GetLog --> LogKeys GetTooltip --> TooltipKeys GetLabel --> DialogKeys subgraph subGraph2 ["Translation Keys"] UIKeys LogKeys TooltipKeys DialogKeys end subgraph subGraph1 ["Localizer Usage"] GetButton GetLog GetTooltip GetLabel end subgraph subGraph0 ["UI Components"] MainFrame Dialogs Listeners end ``` ### Example Call Sites | Component | Key Example | Purpose | | --- | --- | --- | | `GlobalMouseListener` | `"recording_key_pressed"` | Log recording events | | `GlobalMouseListener` | `"log.mouse_left"` | Button name display | | `GlobalMouseListener` | `"log.recording_scroll_msg1"` | Scroll event logging | | `MainFrame` | Button labels, menu items | UI text | | Dialogs | Dialog titles, labels | Settings interface | **Code Examples:** * **Key press recording**: [src/io/github/samera2022/mouse_macros/listener/GlobalMouseListener.java L47](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/listener/GlobalMouseListener.java#L47-L47) * **Mouse button names**: [src/io/github/samera2022/mouse_macros/listener/GlobalMouseListener.java L73](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/listener/GlobalMouseListener.java#L73-L73) * **Scroll event logging**: [src/io/github/samera2022/mouse_macros/listener/GlobalMouseListener.java L125](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/listener/GlobalMouseListener.java#L125-L125) **Sources:** [src/io/github/samera2022/mouse_macros/listener/GlobalMouseListener.java L9](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/listener/GlobalMouseListener.java#L9-L9), [src/io/github/samera2022/mouse_macros/listener/GlobalMouseListener.java L47-L48](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/listener/GlobalMouseListener.java#L47-L48), [src/io/github/samera2022/mouse_macros/listener/GlobalMouseListener.java L73](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/listener/GlobalMouseListener.java#L73-L73), [src/io/github/samera2022/mouse_macros/listener/GlobalMouseListener.java L87](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/listener/GlobalMouseListener.java#L87-L87), [src/io/github/samera2022/mouse_macros/listener/GlobalMouseListener.java L125](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/listener/GlobalMouseListener.java#L125-L125) --- ## API Reference ### Static Fields | Field | Type | Purpose | Access | | --- | --- | --- | --- | | `translations` | `Map` | Stores current language key-value pairs | Private | | `currentLang` | `String` | Currently loaded language code | Private | | `runtimeSwitch` | `boolean` | Flag for runtime language switching | Private | | `isDevMode` | `boolean` | Environment detection flag | Private | ### Public Methods | Method Signature | Return Type | Description | | --- | --- | --- | | `load(String lang)` | `void` | Loads translations for specified language | | `get(String key)` | `String` | Retrieves translation for key with fallback | | `getCurrentLang()` | `String` | Returns current language code | | `isDevMode()` | `boolean` | Returns true if in development mode | | `setRuntimeSwitch(boolean enable)` | `void` | Sets runtime switching flag | | `isRuntimeSwitch()` | `boolean` | Returns runtime switching flag state | ### Method Details #### load(String lang) Loads a language file and populates the `translations` map. * **Parameters:** * `lang` - Language code (e.g., "en_us", "zh_cn") * **Behavior:** * In dev mode: reads from `lang/{lang}.json` file * In production: reads from JAR resource `lang/{lang}.json` * Updates `currentLang` on success * Sets `translations` to empty map on error * **Thread Safety:** Not thread-safe; typically called during initialization or from UI thread #### get(String key) Retrieves a localized string for the given key. * **Parameters:** * `key` - Translation key (e.g., "button.record") * **Returns:** * Localized string if found in current language * English translation if current language missing key * Key itself if no translation found * **Thread Safety:** Thread-safe for reading (map is replaced atomically on load) #### isDevMode() Checks if running in development environment. * **Returns:** `true` if `lang/zh_cn.json` file exists, `false` otherwise * **Usage:** Primarily by `ConfigManager` for language discovery * **Initialized:** During static initialization **Sources:** [src/io/github/samera2022/mouse_macros/Localizer.java L1-L98](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/Localizer.java#L1-L98) --- ## Design Considerations ### Static Initialization The `Localizer` uses static initialization to ensure translations are available before any UI components are created. The static block: 1. Detects environment (dev vs production) 2. Auto-detects system language via `Locale.getDefault()` 3. Normalizes language codes (replacing `-` with `_`) 4. Checks for language file existence 5. Loads the appropriate language file This ensures that even early initialization code can safely call `Localizer.get()`. ### Fallback Strategy The two-tier fallback (current language → English → key) ensures: * **Graceful degradation**: Missing translations don't break UI * **Developer visibility**: Untranslated keys appear as-is for easy identification * **English baseline**: English (`en_us`) serves as complete reference ### Environment Abstraction The dual-mode (dev/production) design allows: * **Easy development**: Work with editable JSON files in IDE * **Proper packaging**: Read from JAR resources in production * **Consistent API**: Same method calls work in both modes **Sources:** [src/io/github/samera2022/mouse_macros/Localizer.java L15-L33](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/Localizer.java#L15-L33), [src/io/github/samera2022/mouse_macros/Localizer.java L47-L65](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/Localizer.java#L47-L65), [src/io/github/samera2022/mouse_macros/Localizer.java L67-L93](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/Localizer.java#L67-L93)