Skip to content

i18n-fx

i18n-fx provides Resourceful wrappers for every standard JavaFX control. Each component automatically re-applies all localizable properties on the JavaFX Application Thread when the application locale changes.

Artifact: dev.javai18n:i18n-fx · Requires: Java 21+ · View Javadoc →

<dependency>
<groupId>dev.javai18n</groupId>
<artifactId>i18n-fx</artifactId>
<version>1.0</version>
</dependency>
module my.module {
requires dev.javai18n.fx;
}

1. Extend LocalizableStage

public class MyStage extends LocalizableStage {
static {
MyModuleRegistrar.ensureRegistered();
}
@Override
public Locale[] getAvailableLocales() {
return new Locale[]{ Locale.ROOT, Locale.FRANCE };
}
}

2. Define a resource bundle

MyStageBundle.json:

{
"okButton": {
"type": "dev.javai18n.fx.ButtonBasePropertyBundle",
"Text": "OK"
}
}

MyStageBundle_fr.json:

{
"okButton": {
"type": "dev.javai18n.fx.ButtonBasePropertyBundle",
"Text": "D'accord"
}
}

3. Create Resourceful components

MyStage stage = MyStage.create();
Resource okResource = new Resource(stage, "okButton");
ResourcefulButton okButton = ResourcefulButton.create(okResource);
// Switch the entire UI to French — every attached component updates on the FX thread
stage.setBundleLocale(Locale.FRANCE);

ClassExtendsNotes
LocalizableStageStageAll top-level windows. Covers standard windows, modal dialogs (initModality()), and undecorated windows (initStyle()). Bundle key "stageProperties" uses StagePropertyBundle.
LocalizablePopupPopupFloating unowned window. updateLocaleSpecificValues() is a no-op in the base class — subclass to add locale-specific popup content.

The base set of localized properties for every Resourceful Node is: name, style (CSS), accessible text, accessible help, accessible role description (from NodePropertyBundle).

Buttons and labels

ClassExtendsAdditional localized properties
ResourcefulButtonButtontext, graphic, tooltip
ResourcefulCheckBoxCheckBoxtext, graphic, tooltip
ResourcefulRadioButtonRadioButtontext, graphic, tooltip
ResourcefulToggleButtonToggleButtontext, graphic, tooltip
ResourcefulHyperlinkHyperlinktext, graphic, tooltip
ResourcefulLabelLabeltext, graphic, tooltip

Text input

ClassExtendsAdditional localized properties
ResourcefulTextFieldTextFieldprompt text, tooltip
ResourcefulPasswordFieldPasswordFieldprompt text, tooltip
ResourcefulTextAreaTextAreaprompt text, tooltip

Data and selection

ClassExtendsAdditional localized properties
ResourcefulComboBoxComboBoxprompt text, item values (string array), tooltip
ResourcefulChoiceBoxChoiceBoxitem values (string array)
ResourcefulListViewListViewtooltip
ResourcefulTableViewTableViewtooltip
ResourcefulTreeViewTreeViewtooltip
ResourcefulTreeTableViewTreeTableViewtooltip
ResourcefulSpinnerSpinnertooltip
ResourcefulSliderSlidertooltip
ResourcefulProgressBarProgressBartooltip
ResourcefulProgressIndicatorProgressIndicatortooltip
ResourcefulScrollBarScrollBartooltip

Panes and containers

ClassExtendsAdditional localized properties
ResourcefulScrollPaneScrollPanetooltip
ResourcefulSplitPaneSplitPanetooltip
ResourcefulTabPaneTabPanetooltip
ResourcefulTitledPaneTitledPanetitle text, graphic, tooltip
ResourcefulAccordionAccordiontooltip
ResourcefulMenuBarMenuBartooltip
ResourcefulToolBarToolBartooltip
ResourcefulSeparatorSeparatortooltip
ResourcefulPaginationPaginationtooltip
ResourcefulHTMLEditorHTMLEditortooltip

Non-Node components (MenuItem, Tab, TableColumn, Tooltip do not extend Node)

ClassExtendsLocalized properties
ResourcefulMenuItemMenuItemtext, graphic
ResourcefulMenuMenutext, graphic
ResourcefulCheckMenuItemCheckMenuItemtext, graphic
ResourcefulRadioMenuItemRadioMenuItemtext, graphic
ResourcefulTabTabtitle text, graphic, tooltip
ResourcefulTableColumnTableColumnheader text, graphic
ResourcefulTooltipTooltiptext


Font is stored as a CSS style string via the Style key and applied via Node.setStyle(). This makes locale-specific fonts — such as CJK typefaces — straightforward to configure:

{
"header": {
"type": "dev.javai18n.fx.LabeledPropertyBundle",
"Text": "ファイルエクスプローラー",
"Style": "-fx-font: bold 14pt 'Hiragino Sans'"
}
}

Graphic is stored as a path or URL string. FXImageResourceLoader resolves it at setAttribute() time and returns a javafx.scene.image.Image; the component wraps it in new ImageView(image) before calling setGraphic().


BundleExtendsFields
NodePropertyBundlename, style (CSS), accessible text, accessible help, accessible role description
ControlPropertyBundleNodePropertyBundle+ tooltip text
LabeledPropertyBundleControlPropertyBundle+ text, graphic
ButtonBasePropertyBundleLabeledPropertyBundle(type marker — no additional keys)
TextInputPropertyBundleControlPropertyBundle+ prompt text
ComboBoxPropertyBundleControlPropertyBundle+ prompt text, values (string array)
ChoiceBoxPropertyBundleNodePropertyBundle+ values (string array)
TitledPanePropertyBundleControlPropertyBundle+ title text, graphic
StagePropertyBundleNodePropertyBundle+ title, icon images (list)
MenuItemPropertyBundletext, graphic
TabPropertyBundletitle text, graphic, tooltip text
TableColumnPropertyBundleheader text, graphic
TooltipPropertyBundletext

LocalizationDelegate initializes its locale from Locale.getDefault() at construction time. Maven Surefire’s -Duser.language flag does not change Locale.getDefault() in the forked JVM.

Rule: Always pin the locale in test factory methods before calling updateLocaleSpecificValues():

public static TestComponentSource create() {
TestComponentSource source = new TestComponentSource();
source.setBundleLocale(Locale.ROOT); // before any locale-dependent work
return source;
}

See the full guide for the complete explanation.