Java
ResourceBundle localization for Java applications.
Translate the .properties files of your application, also inside a JAR, reuse earlier translations, check placeholders, and write App_de.properties for each language. Your Java project keeps the code, the build, and runtime loading.
- Input
.propertiesfiles, or a.jarthat contains them- Output
App_de.propertiesfor each language, or a JAR with all of them- Runtime
ResourceBundlepicks the file by its name- Preview
- None: strings are translated in the table
On this page
Tutorial
Localize Java resource bundles with Lingobit, step by step.
Four steps from App.properties to a translated file for each language.
Your code reads bundles, Lingobit translates them, your build packs them.
Your code loads text with ResourceBundle.getBundle("App"), and the English text lives in App.properties. Lingobit translates it and writes App_de.properties, App_fr.properties, and so on. Your build puts them on the classpath or into the JAR, as before. Lingobit can also open the JAR and write a new one with every language inside.
Lingobit does
- Translates the values of your
.propertiesfiles; keys, separators, and comments stay as they are. - Reuses earlier translations and the translation memory.
- Checks
{0}placeholders, apostrophes in MessageFormat strings, numbers, and more. - Writes
App_de.propertiesfor each language, or a new JAR with all languages inside.
Your Java project keeps
- Keeping text in bundles and loading it with
ResourceBundle. - The build, the JAR, and the installer.
- Choosing the language at runtime.
- Swing, JavaFX, or SWT, and the final test in the running application.
Reference
At startup, ResourceBundle picks the file by its name.
Your code asks for the bundle App in the user's locale. For German (Germany) Java tries App_de_DE, then App_de, and takes any key that is missing there from App.properties. Lingobit writes App_de.properties, so one file serves every German-speaking country.
- A missing key shows the English text from the base bundle; it does not break the application.
- A missing language falls back to the default locale first, then to the base bundle. An application that asks for Spanish, which is not shipped, on a computer set to French gets French.
ResourceBundle texts = ResourceBundle.getBundle("App", Locale.getDefault());
setTitle(texts.getString("order.title"));
Choose the language in your app.
Java takes the default locale from the Windows settings. To let users pick the language, keep their choice and use it instead:
- List the languages you ship from the bundles in your JAR or folder.
- Read the saved choice or a command-line switch; otherwise use
Locale.getDefault(). - Load the bundle with that locale before the first window is created.
- Switch while running by loading the bundle again and setting the texts of the open windows, or restart.
Preferences prefs = Preferences.userNodeForPackage(App.class);
Locale locale = Locale.forLanguageTag(prefs.get("language", Locale.getDefault().toLanguageTag()));
ResourceBundle texts = ResourceBundle.getBundle("App", locale);
What Lingobit reads in a .properties file.
Lingobit reads a .properties file the way java.util.Properties does and writes the translated file in the same layout.
It reads .properties files in UTF-8, as Java 9 and later do, and falls back to ISO-8859-1 with \uXXXX escapes, as Java 8 does. It writes non-ASCII text as \uXXXX, which every Java version reads.
| In the file | In Lingobit | In the translated file |
|---|---|---|
| Key | The string's ID; translations are matched by it | Unchanged, with the same =, :, or spacing |
| Value | The text that is translated; a value continued with \ is read as one string | The translation, on one line |
\u00e9, \t, \n | Shown as the characters they stand for | Non-ASCII text as \uXXXX, which every Java version reads |
Comments #, ! | Not shown | Unchanged |
| Blank lines | — | Kept |
| JAR | Each .properties file inside is translated | Localized\App.jar with App_de.properties and the other languages added; classes and other files copied unchanged |
Do and don't.
Do
- Keep the English text in the base bundle,
App.properties, and add it to the project. - Use
MessageFormatwith{0},{1}, so translators can change the order. - Write an apostrophe as
''in strings with placeholders. - Keep keys stable between releases.
- Move hard-coded text from
.javafiles into bundles with Lingobit Extractor.
Don't
- Translate
.javasource files as the normal workflow. - Edit
App_de.propertiesby hand: the next Create overwrites it. - Build sentences in code from translated pieces.
- Rename keys after translation has started without a reason.
- Send Java code or class files to translators.
Troubleshooting.
| Symptom | Likely cause | What to do |
|---|---|---|
| The application stays in English | App_de.properties is not on the classpath or in the JAR, its name differs from the bundle name, or the locale is not German | Put the translated files next to App.properties, or use the JAR that Lingobit writes, and check the locale your code passes |
| Users see another language than expected | Their language is not shipped, and Java fell back to the default locale before the base bundle | Ship the language, or load bundles with ResourceBundle.Control.getNoFallbackControl |
A placeholder shows as {0}, or an apostrophe is missing | A single apostrophe in a MessageFormat string starts a quote | Run Validation: it reports the apostrophe and offers to write it as '' |
| The application fails with one language | A translation changes a placeholder that MessageFormat expects | Run Validation: it reports {0} placeholders that do not match the source |
| German text is cut off in the application | .properties files have no preview, so long text shows only in the running application | Set a maximum length for the strings in Lingobit; Validation reports translations that exceed it |
The Java samples.
Localizer installs two Java samples with their projects, so you can try the steps above without your own application.
- Java ResourceBundle:
LabelsBundle.propertieswith comments, continued lines, and escapes, in German and French. Create Localized Files writesLabelsBundle_de.properties. - JAR Localization:
Jar_Sample.jarin German, Spanish, Dutch, Russian, and Chinese. Create Localized Files writesLocalized\Jar_Sample.jarwith every language inside.
More about Java localization.
A ResourceBundle family in one project
Java ResourceBundles keep locale-specific text outside application code. Lingobit treats the bundle family as one project, so translators work in one structured editor instead of opening locale files by hand; keys stay stable, translators see only the values, and later updates reuse the existing translations.
Messages.properties
Messages_de.properties
Messages_de_DE.properties
Messages_fr.properties
The Java runtime still decides which bundle to load and how locale fallback works.
UTF-8 and ISO-8859-1 .properties files
Lingobit reads .properties files in UTF-8, as Java 9 and later do, and falls back to ISO-8859-1 with \uXXXX escapes, as Java 8 does, so translated files from earlier tools import either way. It writes non-ASCII text as \uXXXX escapes, which every Java version reads.
Java source files: preparation only
Translating .java source directly is fragile: it mixes localization with development and exposes implementation details to translators. When user-facing text is still hardcoded, use Lingobit Extractor as a developer-side step to find the strings and move them into ResourceBundle files, then localize the bundles. Compiled .class files are not a translation source.
Clear boundaries
- Lingobit does not decompile Java applications or change
.classfiles; JAR support is for the resources inside. - There is no visual preview for Swing, JavaFX, SWT, or other Java UI frameworks.
- Loading the locale at runtime, ResourceBundle fallback, packaging the final JAR, and refreshing the UI on a language switch stay with the application.
Related paths
- Localization QA — Validation, placeholder checks, and Crash Finder.
- Lingobit Extractor — Move hard-coded text from Java code into bundles.
- Release workflow — Scan for Changes and translated files for every release.
- Migration — Bring translations from earlier tools.