Skip to content

i18n-swing

i18n-swing provides drop-in replacements for every standard Swing component. Each Resourceful* class extends its standard Swing counterpart and automatically re-applies all localizable properties on the Event Dispatch Thread when the application locale changes.

Artifact: dev.javai18n:i18n-swing · Requires: Java 17+ · View Javadoc →

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

1. Extend a Localizable container

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

2. Define a resource bundle

MyFrameBundle.json:

{
"okButton": {
"type": "dev.javai18n.swing.AbstractButtonPropertyBundle",
"Text": "OK",
"Mnemonic": 79
}
}

MyFrameBundle_fr.json:

{
"okButton": {
"type": "dev.javai18n.swing.AbstractButtonPropertyBundle",
"Text": "D'accord",
"Mnemonic": 68
}
}

3. Create Resourceful components

MyFrame frame = MyFrame.create();
Resource okResource = new Resource(frame, "okButton");
ResourcefulJButton okButton = ResourcefulJButton.create(okResource);
// Switch the entire UI to French — every attached component updates on the EDT
frame.setBundleLocale(Locale.FRANCE);

These classes serve as the locale-event source for all Resourceful components they own.

ClassExtendsNotes
LocalizableJFrameJFrameStandard application frame; bundle key "windowProperties" uses FramePropertyBundle
LocalizableJDialogJDialogModal or non-modal dialog; bundle key "windowProperties" uses FramePropertyBundle
LocalizableJWindowJWindowUndecorated window; bundle key "windowProperties" uses WindowPropertyBundle

The base set of localized properties for every Resourceful component is: name, tooltip, font, accessible name, accessible description (from JComponentPropertyBundle).

Buttons and toggles

ClassExtendsAdditional localized properties
ResourcefulJButtonJButtontext, label, mnemonic, 7 icon types
ResourcefulJCheckBoxJCheckBoxtext, label, mnemonic, 7 icon types
ResourcefulJRadioButtonJRadioButtontext, label, mnemonic, 7 icon types
ResourcefulJToggleButtonJToggleButtontext, label, mnemonic, 7 icon types

Menus

ClassExtendsAdditional localized properties
ResourcefulJMenuJMenutext, label, mnemonic, 7 icon types
ResourcefulJMenuBarJMenuBar
ResourcefulJMenuItemJMenuItemtext, label, mnemonic, 7 icon types
ResourcefulJCheckBoxMenuItemJCheckBoxMenuItemtext, label, mnemonic, 7 icon types
ResourcefulJRadioButtonMenuItemJRadioButtonMenuItemtext, label, mnemonic, 7 icon types
ResourcefulJPopupMenuJPopupMenu
ResourcefulJPopupMenuSeparatorJPopupMenu.Separator

Text components

ClassExtends
ResourcefulJTextFieldJTextField
ResourcefulJTextAreaJTextArea
ResourcefulJEditorPaneJEditorPane
ResourcefulJTextPaneJTextPane
ResourcefulJPasswordFieldJPasswordField
ResourcefulJFormattedTextFieldJFormattedTextField

Data and selection

ClassExtendsAdditional localized properties
ResourcefulJComboBoxJComboBoxitem values (string array)
ResourcefulJListJList
ResourcefulJSpinnerJSpinner
ResourcefulJSliderJSlider
ResourcefulJTreeJTree
ResourcefulJTableJTable
ResourcefulJTableHeaderJTableHeader
ResourcefulJProgressBarJProgressBarprogress string
ResourcefulJScrollBarJScrollBar
ResourcefulJColorChooserJColorChooser
ResourcefulJFileChooserJFileChooserdialog title, approve button text/tooltip

Panes and containers

ClassExtendsAdditional localized properties
ResourcefulJPanelJPanel
ResourcefulJScrollPaneJScrollPane
ResourcefulJSplitPaneJSplitPane
ResourcefulJTabbedPaneJTabbedPaneper-tab title, tooltip, icon
ResourcefulJInternalFrameJInternalFrametitle, frame icon
ResourcefulJLayeredPaneJLayeredPane
ResourcefulJDesktopPaneJDesktopPane
ResourcefulJDesktopIconJDesktopIcon
ResourcefulJRootPaneJRootPane
ResourcefulJViewportJViewport
ResourcefulJOptionPaneJOptionPanedialog title, button option labels

Layout helpers

ClassExtendsAdditional localized properties
ResourcefulBoxBox
ResourcefulBoxFillerBox.Filler
ResourcefulJLabelJLabeltext, mnemonic, icon, disabled icon
ResourcefulJSeparatorJSeparator
ResourcefulJToolBarJToolBar
ResourcefulJToolBarSeparatorJToolBar.Separator
ResourcefulJToolTipJToolTiptip text

Spinner editors

ClassExtends
ResourcefulJSpinnerDefaultEditorJSpinner.DefaultEditor
ResourcefulJSpinnerDateEditorJSpinner.DateEditor
ResourcefulJSpinnerNumberEditorJSpinner.NumberEditor
ResourcefulJSpinnerListEditorJSpinner.ListEditor

Utility menu items

ClassExtendsDescription
LocaleJMenuItemResourcefulJRadioButtonMenuItemDisplays a locale name; sets the application locale when selected; shows a radio-button check mark for the active locale
LookAndFeelJMenuItemResourcefulJMenuItemDisplays a Look and Feel name; applies it when selected

BundleExtendsFields
ComponentPropertyBundlename, font, accessible name, accessible description
JComponentPropertyBundleComponentPropertyBundle+ tooltip
AbstractButtonPropertyBundleJComponentPropertyBundle+ text, label, mnemonic, icon, pressed, selected, disabled, disabled-selected, rollover, rollover-selected icons
JLabelPropertyBundleJComponentPropertyBundle+ text, mnemonic, icon, disabled icon
JComboBoxPropertyBundleJComponentPropertyBundle+ values (string array)
JProgressBarPropertyBundleJComponentPropertyBundle+ progress string
JInternalFramePropertyBundleJComponentPropertyBundle+ title, frame icon
JTabbedPaneTabPropertyBundletab title, tab tooltip, tab icon (one entry per tab)
JOptionPanePropertyBundleJComponentPropertyBundle+ title, options (string array)
JFileChooserPropertyBundleJComponentPropertyBundle+ dialog title, approve button text/tooltip
JToolTipPropertyBundleJComponentPropertyBundle+ tip text
WindowPropertyBundleComponentPropertyBundle+ icon images (list)
FramePropertyBundleWindowPropertyBundle+ title

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 — it is propagated via System.setProperty() after the JVM’s default locale has already been set.

Rule: In any test that asserts specific string values from a bundle, always pin the locale explicitly before constructing the Localizable object:

TestComponentSource source = TestComponentSource.create();
// create() calls setBundleLocale(Locale.ROOT) immediately after construction
ResourceBundle rb = ResourceBundle.getBundle(
"com.example.MyFrameBundle", Locale.ROOT); // always pass explicit locale

See the full guide for the complete explanation.