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;}Quick start
Section titled “Quick start”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 threadstage.setBundleLocale(Locale.FRANCE);Localizable containers
Section titled “Localizable containers”| Class | Extends | Notes |
|---|---|---|
LocalizableStage | Stage | All top-level windows. Covers standard windows, modal dialogs (initModality()), and undecorated windows (initStyle()). Bundle key "stageProperties" uses StagePropertyBundle. |
LocalizablePopup | Popup | Floating unowned window. updateLocaleSpecificValues() is a no-op in the base class — subclass to add locale-specific popup content. |
Resourceful components
Section titled “Resourceful components”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
| Class | Extends | Additional localized properties |
|---|---|---|
ResourcefulButton | Button | text, graphic, tooltip |
ResourcefulCheckBox | CheckBox | text, graphic, tooltip |
ResourcefulRadioButton | RadioButton | text, graphic, tooltip |
ResourcefulToggleButton | ToggleButton | text, graphic, tooltip |
ResourcefulHyperlink | Hyperlink | text, graphic, tooltip |
ResourcefulLabel | Label | text, graphic, tooltip |
Text input
| Class | Extends | Additional localized properties |
|---|---|---|
ResourcefulTextField | TextField | prompt text, tooltip |
ResourcefulPasswordField | PasswordField | prompt text, tooltip |
ResourcefulTextArea | TextArea | prompt text, tooltip |
Data and selection
| Class | Extends | Additional localized properties |
|---|---|---|
ResourcefulComboBox | ComboBox | prompt text, item values (string array), tooltip |
ResourcefulChoiceBox | ChoiceBox | item values (string array) |
ResourcefulListView | ListView | tooltip |
ResourcefulTableView | TableView | tooltip |
ResourcefulTreeView | TreeView | tooltip |
ResourcefulTreeTableView | TreeTableView | tooltip |
ResourcefulSpinner | Spinner | tooltip |
ResourcefulSlider | Slider | tooltip |
ResourcefulProgressBar | ProgressBar | tooltip |
ResourcefulProgressIndicator | ProgressIndicator | tooltip |
ResourcefulScrollBar | ScrollBar | tooltip |
Panes and containers
| Class | Extends | Additional localized properties |
|---|---|---|
ResourcefulScrollPane | ScrollPane | tooltip |
ResourcefulSplitPane | SplitPane | tooltip |
ResourcefulTabPane | TabPane | tooltip |
ResourcefulTitledPane | TitledPane | title text, graphic, tooltip |
ResourcefulAccordion | Accordion | tooltip |
ResourcefulMenuBar | MenuBar | tooltip |
ResourcefulToolBar | ToolBar | tooltip |
ResourcefulSeparator | Separator | tooltip |
ResourcefulPagination | Pagination | tooltip |
ResourcefulHTMLEditor | HTMLEditor | tooltip |
Non-Node components (MenuItem, Tab, TableColumn, Tooltip do not extend Node)
| Class | Extends | Localized properties |
|---|---|---|
ResourcefulMenuItem | MenuItem | text, graphic |
ResourcefulMenu | Menu | text, graphic |
ResourcefulCheckMenuItem | CheckMenuItem | text, graphic |
ResourcefulRadioMenuItem | RadioMenuItem | text, graphic |
ResourcefulTab | Tab | title text, graphic, tooltip |
ResourcefulTableColumn | TableColumn | header text, graphic |
ResourcefulTooltip | Tooltip | text |
Omitted components
Section titled “Omitted components”Fonts and graphics in bundles
Section titled “Fonts and graphics in bundles”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().
Property bundles
Section titled “Property bundles”| Bundle | Extends | Fields |
|---|---|---|
NodePropertyBundle | — | name, style (CSS), accessible text, accessible help, accessible role description |
ControlPropertyBundle | NodePropertyBundle | + tooltip text |
LabeledPropertyBundle | ControlPropertyBundle | + text, graphic |
ButtonBasePropertyBundle | LabeledPropertyBundle | (type marker — no additional keys) |
TextInputPropertyBundle | ControlPropertyBundle | + prompt text |
ComboBoxPropertyBundle | ControlPropertyBundle | + prompt text, values (string array) |
ChoiceBoxPropertyBundle | NodePropertyBundle | + values (string array) |
TitledPanePropertyBundle | ControlPropertyBundle | + title text, graphic |
StagePropertyBundle | NodePropertyBundle | + title, icon images (list) |
MenuItemPropertyBundle | — | text, graphic |
TabPropertyBundle | — | title text, graphic, tooltip text |
TableColumnPropertyBundle | — | header text, graphic |
TooltipPropertyBundle | — | text |
Testing notes
Section titled “Testing notes”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.