user2499946
user2499946

Reputation: 689

JavaFx Bindings and Localization

I am localizing my relatively simple JavaFx app. "manually" (i.e. I don't use the SceneBuilder or anything). Now I'd like to add support for dynamic localization, so that the user does not have to restart the application for changes to apply.

The only part in my app that needs to be localized in this manner, are the tooltips. (I'm using lots of ControlsFX dialogs, and they are re-created every time so there is no problem there...)

I have not used the JavaFx binding system before, but I have a hunch that it could make this task very simple.

Currently, I am just setting the tooltips like so:

myButton.setTooltip(new Tooltip(Utils.i8n("mybutton")));

I've read something about the JavaFx bindings, but I'm a bit overwhelmed by the amount of choices I seem to have! How would I go on (ab)using the binding system to help me localize these tooltips "dynamically"?

Thanks.

Upvotes: 0

Views: 1228

Answers (1)

James_D
James_D

Reputation: 209358

public class Utils {
    private static final ObjectProperty<Locale> locale = new SimpleObjectProperty<>(Locale.getDefault());
    public static ObjectProperty<Locale> localeProperty() {
        return locale ;
    }
    public static Locale getLocale() {
        return locale.get();
    }
    public static void setLocale(Locale locale) {
        localeProperty().set(locale);
    }

    public static String i18n(String key) {
        return ResourceBundle.getBundle("bundleName", getLocale()).getString(key);
    }
}

then

myButton.setTooltip(createBoundTooltip("mybutton"));

with

private Tooltip createBoundTooltip(final String key) {
    Tooltip tooltip = new Tooltip();
    tooltip.textProperty().bind(Bindings.createStringBinding( 
         () -> Utils.i18n(key), Utils.localeProperty()));
    return tooltip ;
}

Then Utils.setLocale(...) should automatically update the tooltip text. You can also do fun stuff like

ComboBox<Locale> languages = new ComboBox<>();
languages.getItems().addAll(new Locale("en"), new Locale("fr"), new Locale("fi"), new Locale("ru"));
languages.setConverter(new StringConverter<Locale>() {
    @Override
    public String toString(Locale l) {
        return l.getDisplayLanguage(l);
    }
    @Override
    public Locale fromString(String s) {
        // only really needed if combo box is editable
        return Locale.forLanguageTag(s);
    }
});

Utils.localeProperty().bind(languages.valueProperty());

Upvotes: 4

Related Questions