Class I18nString
String at the point of use.
A component stores one of these where it would otherwise store a
String, and reads get() when it measures or paints. Holding the
value is what makes keeping it correct: a lookup call whose result must never be
kept in a field fails silently, leaving one widget in yesterday's language.
private static final I18nString PLACEHOLDER =
new I18nString("limn.searchField.placeholder", "Search…");
...
canvas.drawText(PLACEHOLDER.get(), x, baseline, font, colour);
English is not a translation. The second argument is both the default text and the fallback for every key a bundle does not answer, so an application that registers nothing behaves exactly as it did before this type existed, and a missing translation degrades to English rather than to a key name on screen.
The cache lives here. get() memoises its resolution against
I18n.epoch(), so nothing subscribes and nothing leaks: the re-resolution
rides the relayout a language change already causes.
Declare them static final, so the cache is one slot per key for the whole
process rather than one per widget; a list showing five hundred rows of the same
label resolves once per language change, not five hundred times.
Immutable in every respect a caller can observe; the memo is mutated on the UI thread like the rest of the toolkit's state.
-
Field Summary
FieldsModifier and TypeFieldDescriptionstatic final I18nStringThe empty literal: a text field's placeholder before anyone sets one. -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionenglish()The default-language text: also the fallback, and nevernull.booleanValue equality on key and English: two literals of the same text are the same string, and a component's "did this actually change" check keeps working when its field stops being aString.The text with{0}-style arguments substituted, formatted byMessageFormatunder the current locale.get()The text in the locale in effect here, or the English when nothing translates it.inthashCode()booleanWhether this is a literal, which no bundle can ever change.key()The lookup key, ornullfor a literal.static I18nStringText that is not localizable and resolves to itself: whatsetText(String)wraps a caller's literal in, so a component can hold one field instead of two and never has to decide which of them wins.toString()The resolved text, so logging and debugging read as the user sees it.
-
Field Details
-
EMPTY
The empty literal: a text field's placeholder before anyone sets one.
-
-
Constructor Details
-
I18nString
Declares a localizable string.- Parameters:
key- the lookup key, dotted and globally unique; prefix it with the screen or component that owns it (settings.title, nottitle), because bundles share one namespaceenglish- the text in the default language, used whenever no registered bundle answers the key- Throws:
IllegalStateException- if the key was already declared with different English: one key with two meanings is a bug that would otherwise surface as a mistranslation
-
-
Method Details
-
literal
Text that is not localizable and resolves to itself: whatsetText(String)wraps a caller's literal in, so a component can hold one field instead of two and never has to decide which of them wins. -
get
The text in the locale in effect here, or the English when nothing translates it. Inside a widget's measure, layout, paint or event dispatch that locale is the widget's own effective one, so the same declaration reads correctly from every subtree without the caller doing anything. -
format
The text with{0}-style arguments substituted, formatted byMessageFormatunder the current locale. Never cached: the arguments vary per call, and caching them would be caching the wrong thing.Only parameterized keys pay MessageFormat's rules, which is why
get()does not route through it: an apostrophe in an ordinary string needs no escaping. In a parameterized one it does (double it), and so does a stray brace; a pattern a translator got wrong falls back to the English rather than throwing in the middle of a paint.Numbers are formatted for the locale, so pass
Integer.toString(n)where ASCII digits are required; digits the text pipeline cannot draw are worse than an unlocalised number. -
key
The lookup key, ornullfor a literal. -
english
The default-language text: also the fallback, and nevernull. -
isLiteral
public boolean isLiteral()Whether this is a literal, which no bundle can ever change. -
toString
The resolved text, so logging and debugging read as the user sees it. -
equals
Value equality on key and English: two literals of the same text are the same string, and a component's "did this actually change" check keeps working when its field stops being aString. -
hashCode
public int hashCode()
-