3 Replies Latest reply: Nov 6, 2012 1:45 PM by teabeeoh_ RSS

    i18n a FXML based form: changing the language without restarting the app


      is it possible to reapply a new ResourceBundle after the initialization of a FXML-based GUI? The use case would be changing the GUI language of an application and applying that change during runtime without a restart.

      Let's say I have a FXML-based form called AboutDialog. Following the patterns mentioned here http://docs.oracle.com/javafx/2/fxml_get_started/custom_control.htm I have a controller class AboutDialog.java (which extends AnchorPane) with the following constructor:
           public AboutDialog() {
                FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("AboutDialog.fxml"));
                try {
                } catch (IOException exception) {
                     throw new RuntimeException(exception);
      This is how the ResourceBundle is applied during initialization.

      If I now change the default Locale to another Locale that is supported
      returns the ResourceBundle with new language.
      Calling the FXMLLoader-code after super() again at a later point in time leads to a reload of the whole FXML form with all its children doubled. Calling getChildren().clear() before fxmlLoader.load() would solve this, but leads to another problem: All ChangeListeners that I apply to the children somewhere else are lost (because the form's children are new instances).
      Is it possible to just reapply the new ResourceBundle to the existing set of child nodes of the form without having to reinstatiate the whole form?

      Maybe I am completely on the wrong way with the approach I have taken. In that case: What is the proposed approach to achieve the goal of allowing the user to change the GUI language during runtime without having to restart the application?


        • 1. Re: i18n a FXML based form: changing the language without restarting the app
          The short answer is - no you can't.

          The longer answer is - you should organize your code in such a way that you
          can re-initialize your UI more than once. If your model is strictly decoupled
          from your UI, this should not be a problem.
          • 2. Re: i18n a FXML based form: changing the language without restarting the app

            Another solution would be to declare a property containing the internationalized string in your controller, and bind your UI to that.
            When you change your resource bundle, update the properties in your controller and your UI will reflect the change.

            I'm not sure if I'd do it that way though. If you have only a couple of internationalized strings in your FXML that might be workable.
            If you have a lot of them, it might get much more difficult to maintain.
            As MiPa says - it might be easier to throw away the old nodes and simply reload & reinitialize the FXML.


            -- daniel
            • 3. Re: i18n a FXML based form: changing the language without restarting the app
              Hi MiPa, Daniel,

              thanks for clarification I filed a request on jira describing this functionality as I think that it makes sense to have it in the API for several reasons (http://javafx-jira.kenai.com/browse/RT-26065)
              @Daniel: I took a similar approach as workaround, where reloading the whole view (with all Nodes) was not possible and just to heavy. I have a ResouceBundle-Property and directly reset the texts of the controls when the ResourceBundle changes, that is one indirection less. Anyway: I generally like the i18n part of FXML and the tool support in ScenceBuilder, but it still feels odd to have to do this workaround in order to achieve what I think is nothing exotic but a common use case in the i18n context.