TL;DR
- Implements #766 -- translators can now load an external
.propertiesfile from disk and have its entries override the embedded translation bundle, with no rebuild. Settings -> Advanced now exposes a new "External translation file:" row (path field + Browse + Clear) right under the Language combo. Changes take effect on restart, exactly like the existing language switch. - i18n: 5 new bundle keys (
browse_dots,clear,external_translation_file,external_translation_file_tooltip,select_translation_file) in every locale. EN/ES/IT are hand-authored; DE/HU/TR/VI/ZH are translation-tool seeds, refinable via #397. - Includes bovirus' Italian bundle polish from PR #761 (rebased on top, no conflicts in the user-facing strings).
New in 8.47
#766 -- External translation file override
-
I18n.setExternalLanguageFile(Path)adds a secondResourceBundleabove the locale bundle. When an override is loaded,I18n.tr(key)consults it first; missing keys cascade to the active locale bundle, then to the English root, then return the key itself. The override survivessetLocale()calls -- a translator can switch UI languages without dropping their work-in-progress override.null, a non-existing path, or anyIOExceptioncollapse to "no override" with a WARNING log so the app never breaks on a typo'd path. Volatile field + synchronized setter; safe to call from any thread. -
MainPanel.loadUserSettingsreadsexternal_language_filefrom the SQLite settings store at startup. Empty / whitespace-only values are treated as "no override". The file is reloaded on every restart, so editing the.propertiesfile -> restarting is the iteration loop. -
SettingsDialog.jPanel2gets a new control row under the Language combo. Label + read-onlyJTextFieldshowing the absolute path, "Browse..." button (opens aJFileChooserfiltered to*.properties, pre-selects the current value if the file still exists), and "Clear" to drop the override entirely. Hooked into the same restart-required check that already covers font/language/zoom/dark-mode, so saving with a changed override path shows the existing "MegaBasterd will restart" dialog. -
How a translator uses it. Edit
messages_<locale>.properties(e.g.messages_it.properties) in a local checkout or download a single.propertiesfile from the repo, point the Settings field at it, restart MegaBasterd. Whatever's in the file replaces the same key inside the embedded bundle of the currently-selected UI language. Entries can be a full bundle copy or just the handful of keys being iterated on -- everything else falls through to the embedded translation. The file is UTF-8 (no\uXXXXescaping needed). -
LabelTranslatorSingleton.translate("English literal")keeps working transparently. The legacy shim already inverts the English bundle to map "English literal" -> key and then callsI18n.tr(key), so the form-walker (MiscTools.translateLabels) and ~2,140 historical call sites pick up the override "for free" -- no edits required at the NetBeans form level.
i18n
Five new keys in every bundle: browse_dots, clear, external_translation_file, external_translation_file_tooltip, select_translation_file. EN/ES/IT are hand-authored; DE/HU/TR/VI/ZH are translation-tool seeds in the same style as the v8.37 refactor (intended as a working baseline for native-speaker refinement via #397).