Search code examples
javajavafxinternationalizationresourcebundlecontrolsfx

Howto use SimpleLocalizedStringProperty (controlsfx-plugin) with ResourceBundle in JavaFX


I am working with the controlsfx plugin and I came across an implementation for the StringProperty which is of type: SimpleLocalizedStringProperty and is imported from:
import impl.org.controlsfx.i18n.SimpleLocalizedStringProperty; Has anyone worked with this property; according to its name it should ease the usage with a ResourceBundle I assume. But there are no tutorials nor detailed info about how to bind it with locale-based ResourceBundles.

It would be greatly appreciated if someone here would be able to share with us his/her experience with this property.


Solution

  • This class is supposed to load stings with a specific pattern from a ResourceBundle and keep other strings as they are. If a string starts with @@, the rest of the string is used as a key to the controlsfx.properties properties file.

    Example:

    @Override
    public void start(Stage primaryStage) {
        SimpleLocalizedStringProperty prop = new SimpleLocalizedStringProperty("Hello World");
        Button btn = new Button();
        btn.textProperty().bind(prop);
        btn.setOnAction((ActionEvent event) -> {
            prop.set("@@font.dlg.title");
        });
    
        StackPane root = new StackPane();
        root.getChildren().add(btn);
    
        Scene scene = new Scene(root, 500, 300);
    
        primaryStage.setScene(scene);
        primaryStage.show();
    }
    

    My recommendation however: Do not use the class at this time!!! (July 2016)

    It contains some fundamental flaws:

    • The getValue method is overwritten to return the localized result. Many methods, including getValue, use the get method however, which can lead to unexpected behaviour. Just replace

      btn.textProperty().bind(prop);
      

      with

      btn.textProperty().bind(Bindings.when(new SimpleBooleanProperty(true)).then(prop).otherwise((String) null))
      

      in the above example and the key of the property us used instead of the localized value.

      get() and getValue() are supposed to return the same value, which this class doesn't do and therefore violates the Liskov Substitution Principle.

    • The value can change without an update being triggered. By changing the Locale using e.g. impl.org.controlsfx.i18n.Localization.setLocale(Locale.FRANCE); (assuming a Locale other than FRANCE before the change) will change the value returned by getValue() without notifying listeners.