Skip to content

#1936: Improve localization of gui#1979

Open
KarimALotfy wants to merge 71 commits into
devonfw:mainfrom
KarimALotfy:feature/1936-improve-localization-of-gui
Open

#1936: Improve localization of gui#1979
KarimALotfy wants to merge 71 commits into
devonfw:mainfrom
KarimALotfy:feature/1936-improve-localization-of-gui

Conversation

@KarimALotfy

@KarimALotfy KarimALotfy commented May 27, 2026

Copy link
Copy Markdown
Contributor

This PR fixes #1936

Implemented changes:

Added localization support to the JavaFX GUI — users can select a display language, and the preference is persisted across restarts.

How it works

Locale resolution — on startup, LocalizationService resolves the active locale in order of priority: persisted user preference → system default → eg: English. The persisted value is stored as IDE_LOCALE in ~/.ide/ide.properties.

Bundle loading — resource bundles live under src/main/resources/localization/ as UTF-8 .properties files (messages.properties for English, messages_<tag>.properties for other languages). Bundles are loaded with a custom UTF8Control to correctly handle non-ASCII characters.

Locale discovery — available locales are detected dynamically at runtime by scanning the classpath for localization/messages_*.properties files, covering both exploded directories and JARs — dropping a new bundle file with CurrentLanguage property is enough to make a language appear.

UI integration — the language combo box is populated from the discovered locales. Each entry is labelled using the CurrentLanguage property from that locale's bundle, with a fallback to a generated display name. Selecting a language applies it immediately across the UI by calling setLocale and persists it to ~/.ide/ide.properties.

Adding a new language

Add src/main/resources/localization/messages_<tag>.properties with the full key set matching messages.properties. The language will appear in the combo box automatically on the next build.


Testing instructions

  1. Launch the app through AppLauncher.java — the language combo box should list all bundled languages
  2. Switch to a non-English language — all UI labels should update immediately
  3. Close and reopen the app — the selected language should be restored
  4. Add a new messages_<tag>.properties file with a CurrentLanguage property (ex: CurrentLanguage=French (fr)), rebuild, and launch — the new language should appear in the combo box without any code change.

Checklist for this PR

Make sure everything is checked before merging this PR. For further info please also see
our DoD.

  • When running mvn clean test locally all tests pass and build is successful
  • PR title is of the form #«issue-id»: «brief summary» (e.g. #921: fixed setup.bat). If no issue ID exists, title only.
  • PR top-level comment summarizes what has been done and contains link to addressed issue(s)
  • PR and issue(s) have suitable labels
  • Issue is set to In Progress and assigned to you or there is no issue (might happen for very small PRs)
  • You followed all coding conventions
  • You have added the issue implemented by your PR in CHANGELOG.adoc unless issue is labeled
    with internal
  • You have formulated clear instructions on how to test your contribution under "Testing instructions"

laim2003 added 30 commits March 27, 2026 17:52
- Added logging to IdeGuiStateManager.
- Added functionality, that selecting a different project now switches the IdeContext to the new project.
- Added logging to IdeGuiStateManager.
- Added functionality, that selecting a different project now switches the IdeContext to the new project.
- Added functionality, that selecting a different project now switches the IdeContext to the new project.
- added DI for IdeGuiStateManager.switchContext
…reading the list of workspaces/projects instead of reading those from the UI
…nager, when switchContext(Path rootDirectory, ...) is called.
…tateManager is now set when calling getInstance(), allowing us to provide a getInstance() method with a DI parameter
@laim2003 laim2003 self-assigned this Jun 16, 2026
@laim2003 laim2003 self-requested a review June 16, 2026 13:20
@KarimALotfy KarimALotfy moved this from 🏗 In progress to Team Review in IDEasy board Jun 16, 2026

@laim2003 laim2003 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good! just left some thoughts😊

Comment thread gui/src/main/java/com/devonfw/ide/gui/i18n/I18nService.java Outdated
Comment thread gui/src/main/java/com/devonfw/ide/gui/i18n/I18nService.java Outdated
Comment thread gui/src/main/java/com/devonfw/ide/gui/i18n/I18nService.java Outdated
Comment thread gui/src/main/java/com/devonfw/ide/gui/i18n/I18nService.java Outdated
Comment thread gui/src/main/java/com/devonfw/ide/gui/localization/LocalizationService.java Outdated
@hohwille hohwille moved this from Team Review to 👀 In review in IDEasy board Jun 22, 2026
@hohwille hohwille added this to the release:2026.07.001 milestone Jun 22, 2026
@@ -0,0 +1,17 @@
# IDEasy GUI - English (default) Translation File

@hohwille hohwille Jun 22, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In cli we named the folder nls for "Native Language Support".
For homogeneity, it would be nice to have both folder named the same.
If the team better understands localization we can also change nls but it is short and maybe more speaking than l10n what other projects use as shortcut for localization.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So should localization be changed to nls , and accordingly the usage of the service also to nls ?

Comment thread gui/src/main/resources/localization/messages.properties Outdated
Comment thread gui/src/test/java/com/devonfw/ide/gui/localization/LocalizationServiceTest.java Outdated
Comment thread gui/src/main/java/com/devonfw/ide/gui/MainController.java Outdated
Comment thread gui/src/main/java/com/devonfw/ide/gui/MainController.java Outdated

@hohwille hohwille left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@KarimALotfy thanks for your PR.
Very nice that you figured out how to do NLS (i18n and l10n) with JavaFx (using Locale, ResourceBundle and the % syntax in fxml files). Great that you also added a proper JUnit test and some advanced features. 👍
I left quite some comments for rework.
In some cases you may decide to go for more KISS and keep some advanced features out of this first PR and introduce in a later improving PR after this one is merged or you should go for the full solution if you already start it.

- Generalize localization keys in the `.properties` files
- Detect available resource bundles automatically instead of hardcoding languages
- Persist the selected language in `~/.ide/ide.properties` using `IDE_LOCALE`
- Load and apply the persisted locale during GUI initialization
- Remove `updateTexts()` from `MainController`
- Reload the app after each language selection to apply localization changes
 - Refactor tests to match the updated localization flow
…le discovery

 -Scan localization/messages_*.properties across classpath entries (directories and JARs) at runtime instead of checking against a fixed language array.
 - Add tests covering directory scan, JAR scan, and content-agnostic detection.

@hohwille hohwille left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@KarimALotfy thanks for your rework. Great that you figured the proper solution to find the locales from the classpath and reload the GUI elegantly after language change, etc. Great work 👍
Still I left some comments for improvement. Please have a look. When resolved, we can finally merge.

Comment thread gui/src/main/java/com/devonfw/ide/gui/localization/LocalizationService.java Outdated
Comment thread gui/src/main/java/com/devonfw/ide/gui/localization/LocalizationService.java Outdated
Comment thread gui/src/main/java/com/devonfw/ide/gui/localization/LocalizationService.java Outdated
Comment thread cli/src/main/java/com/devonfw/tools/ide/variable/IdeVariables.java Outdated
Comment thread gui/src/main/java/com/devonfw/ide/gui/localization/LocalizationService.java Outdated
Comment thread gui/src/main/java/com/devonfw/ide/gui/localization/LocalizationService.java Outdated
Comment thread gui/src/main/java/com/devonfw/ide/gui/MainController.java Outdated
      -Persistence to use existing variable IDE_OPTIONS (-Duser.lang=) instead of the new unneeded variable IDE_LOCALE
      -Removed unneccessary UTF8Control
…njection

      Remove static getInstance/resetInstance methods; LocalizationService is now
      instantiated in App and passed to MainController via constructor. Tests create
      instances directly — no reset seam needed.
@KarimALotfy

Copy link
Copy Markdown
Contributor Author

@KarimALotfy thanks for your rework. Great that you figured the proper solution to find the locales from the classpath and reload the GUI elegantly after language change, etc. Great work 👍 Still I left some comments for improvement. Please have a look. When resolved, we can finally merge.

@hohwille

Thanks for the review feedback, what's recently changed:

  • Replaced IDE_LOCALE with -Duser.lang= inside the existing IDE_OPTIONS
  • Removed the UTF8Control inner class
  • Replaced the LocalizationService singleton with constructor injection via App → MainController
  • Updated existing tests and added three new ones for the IDE_OPTIONS persistence logic
  • Implemented the other suggested changes

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

GUI Graphical User Interface of IDEasy (aka dashboard) build with JavaFx

Projects

Status: 👀 In review

Development

Successfully merging this pull request may close these issues.

Improve localization of the GUI

4 participants