1

I am making a JavaFX application where the content is loaded from JXML. I am now at the point where I am trying to change the language of the components dynamically without reloading the entire scene. I have seen this answer which created an observable ResourceFactory, which is exactly what I'm looking for, however it relies on having the keys for the controls available to look up the internationalised text from the resource bundle.

How can I get the raw key from say a Button or a Label that is loaded from an FXML file using FXMLLoader.load(...? When I look at the attributes of the controls I can see the text attribute which gives me the text visible on screen, but what I'm after is the key used to look this text up - e.g. the '%homepage.enterbuttonlabel' rather than 'Enter'

I've traced thorough the FXMLLoader.load method and found this in FXMLLoader$element:235

public void processInstancePropertyAttributes() throws IOException {
    if (instancePropertyAttributes.size() > 0) {
        for (Attribute attribute : instancePropertyAttributes) {
            processPropertyAttribute(attribute);
        }
    }
}

At this point the instancePropertyAttributes contain the element 'text' which has the '%homepage.enterbuttonlabel' that I'm after, but it would appear processing this value replaces it with the internationalised text.

FXMLLoader$element is a private inner class of FXMLLoader, so I can't see how to override anything that could store this value in a new attribute before processing erases it. Short of Copying / Reimplementing the FXMLLoader class is there any way I can get access to that value?

jcuk
  • 191
  • 7
  • 1
    Your ```FXMLLoader``` has a method called ```getController``` witch returns your Controller as a Generic Type (so you'll have to cast it to your exact Controller class). ```getController``` must be called after ```fxmlLoader.load()``` (meaning before won't work). Then you can access the controller and the controller can access the FXML fields. But you should not even need this just do it in your controller in the ```public void initialize()```-method should work – Max Jul 20 '18 at 10:54
  • 1
    hmm .. interesting. No solution (not using fxml much), just a couple of comments (all ugly): if you have access to the current you know all its keys, so you could loop through the controls, look at the text, then find the key to that text in the bundle, then lookup the text in the new .. dooh. Or if you have access to the creation of the fxml, maybe store the raw text (== key) in its properties – kleopatra Jul 20 '18 at 11:14
  • 1
    @kleopatra I thought about the reverse lookup, but as soon as you have duplicate label text that breaks. Storing the raw key in the properties might be the way to go though. I might look at performing an XSLT transformation on the FXML before loading to do this automagically. For now I did actually copy, paste and hack of the FXMLLoader class to do this which just feels wrong, but its working (for now). – jcuk Jul 30 '18 at 08:51

0 Answers0