Skip to content

Sort the GUI language selector by display name#703

Open
lhaeger wants to merge 1 commit into
Evolveum:masterfrom
IS4IT:fix/locale-sort-by-name-master
Open

Sort the GUI language selector by display name#703
lhaeger wants to merge 1 commit into
Evolveum:masterfrom
IS4IT:fix/locale-sort-by-name-master

Conversation

@lhaeger

@lhaeger lhaeger commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Sort the GUI language selector by display name

Summary

The GUI language selector lists locales in an unusual order. This pull
request changes the order to sort by the configured display name, which
is what users typically would expect. The change affects only the visual
presentation; locale resolution is not touched.

Problem

The comparator in AvailableLocale.LocaleDescriptor sorts by country code
first, then by language, then by variant. Locale.getCountry() returns an
empty string for language-only locales such as en or de, and an empty
string sorts before any real country code. As a result, every locale with a
country code (for example en_US, pt_BR, zh_CN) appears below every
language-only entry, regardless of how the entries read in the selector.
Adding en_US and en_GB to ${midpoint.home}/localization/locale.properties
places both at the bottom of the list. There is no separate sort property in
locale.properties, so the comparator is the only place this can be fixed.

Change

The comparator now sorts by the configured display name (.name in
locale.properties) using java.text.Collator with the JVM default locale.
The country code, language code, and variant no longer affect the order. With
this change, "English (UK)" appears between "Deutsch" and "Español"; the
familiar pt_BR and zh_CN defaults move to the alphabetical position of
their display names ("Português (Brasil)", "中文").

Using Collator rather than plain string comparison handles accents and
non-Latin scripts as users would expect.

grafik grafik

(Before vs. After)

Compatibility

AvailableLocale.AVAILABLE_LOCALES is read only by code that presents the
list to a user. Locale resolution compares Locale objects directly and
does not depend on the descriptor order. Existing locale.properties files
keep working unchanged.

Tests

A new AvailableLocaleTest in infra/common adds three cases: the sorted
list is in non-decreasing collation order; a country-coded locale "Chinese"
(zh_CN) sorts before a language-only locale "Deutsch" (de); two locales
with identical display names compare as equal.

The old sort key was country -> language -> variant on the Locale
identifier. Because Locale.getCountry() returns "" (empty string, not
null) for a language-only locale and compareStrings only short-circuits
on null, every country-coded entry (en_US, pt_BR, zh_CN, en_GB)
silently sorted after every language-only entry (de, fr, ...) in the
GUI language selector - regardless of how its display name read.

This made a typical "add en_GB and en_US for clearer English variants"
configuration land at the bottom of the picker, dependent on country
code rather than on visible name. There is no separate sort or order
property in locale.properties; the comparator IS the only knob.

Switch the comparator to sort by the configured .name field (the
display name users actually see) using java.text.Collator with the
JVM default locale. Country code, language code and variant no longer
participate in the order; a country-coded locale is interleaved with
the rest by its display name.

A small TestNG suite in infra/common covers three cases: monotonicity
of the sorted list under the default Collator, the specific scenario
where a country-coded "Chinese" (zh_CN) precedes a language-only
"Deutsch" (de) because "C" collates before "D", and the edge case of
two locales with identical display names compareTo()-equal.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant