FXMLLoader templates

Sebastian Rheinnecker sebastian.rheinnecker at yworks.com
Wed Sep 25 06:25:29 PDT 2013


Hi,

the initial request was due to the poor performance of the FXMLLoader 
when loading the same fxml file over and over again. Consider a case 
where I want to define the appearance of, for example, a ListCell per 
fxml but every cell displays different data. The way to do this would be 
something like this:

FXMLLoader loader = new FXMLLoader(myFXMLResourceLocation);
for (int i = 0; i<100; i++){
   Node cell = loader.load();
   MyController controller = loader.getController();
   controller.setBusinessData(getBusinessData(i));
}

This is really slow if the fxml that is loaded is moderately complex 
right now. In our application it takes around 20 seconds to load the 
fxml 60 times with JavaFX in 7u40.

In our view there is a great potentional hidden here, because the 
loading of the same fxml file over and over again can be sped  up by a 
huge scale, if the FXMLLoader was capable of caching the relevant data 
to construct the root and controller from fxml, like loading the classes 
that are imported only once and such. In fact, we were able to set our 
own classloader into the FXMLLoader that just does that and the time for 
loading the fxml was cut in half. The other thing where the FXMLLoader 
spends a lot of time is in the BeanAdapter#get method, which we cannot 
change from outside.

I'm aware of the inconsitensies that can arise in situations where the 
root is set from outside before load() and such.
So, without breaking your API and consistency of the FXMLLoader I could 
imagine something like a reset-method that is called between load-calls 
and sets the FXMLLoader in a consistent state that is ready to take 
another load() call. Two indepentend load calls or classes also sound 
promising.

Kind regards,
Sebastian Rheinnecker




Am 20.09.2013 14:22, schrieb Martin Sladecek:
> Hi,
> I would like to discuss a 8.0 feature of FXMLLoader - the template flag.
> I was introduced with this issue: 
> https://javafx-jira.kenai.com/browse/RT-23413, but unfortunately, it 
> never worked: https://javafx-jira.kenai.com/browse/RT-28121. I was 
> trying to fix the issue, but the whole concept of a flag for loading 
> templates seems hardly usable and incorrect to me and should be 
> replaced with something more appropriate.
>
> The reason is the handling of root, controller and the namespace 
> before and after the load. Both are treated in 2 different ways. 
> Before the load, they are used to adjust the following load - by 
> setting the root (for <fx:root> tag), setting the namespace and a 
> controller.
> However, after the load, these properties (though not FX-properties) 
> can be used to query what was just loaded. The root of the FXML, the 
> namespace with all "id"s and the controller.
>
> Now that's not very useful when you want to use template loading. My 
> solution for RT-28121 (when keeping the old API) is to save the 
> namespace after setTemplate(true) was called, using this namespace on 
> each load(), clearing it at the begging of load() +  disallow 
> setController() for this mode.
>
> But that doesn't cover all of the relevant use-cases I can think of. 
> Actually, without changing the API, I doubt we can support all such 
> use-cases.
>
> Here's the set I'm working with:
> 1) setup some "template namespace", n times do { adjust namespace 
> (based on template namespace) , load) }
>
> 2) n times do {load, query id from namespace}
>
> 3) n times do {setController(new Controller) load }
>
> 4) n times do {load, query newly created controller}
>
> 5,6) same as 3,4 but with root
>
> So while in 1,3 we would need to clear namespace/controller after each 
> load, in 2,4 we need to clear it before each load. In case 3), 
> forgetting to set a new controller would otherwise result in 2 
> instances with the same controller.
>
> One solution might be to split this to 2 independent calls. 
> setController/getLoadedController, ObservableMap getNamespace() and 
> Map getLoadedNamespace (unmodifiable).
>
> Another might be a completely new class FXMLTemplate.
> It might yield new pre-set FXMLLoaders that can be adjusted and 
> loaded, but it means generating a temporary object for each call.
> Also, FXMLLoader would need to be updated, so that it's only possible 
> to call load() once.
>
> Other ideas / use-cases?
>
> Thanks,
> -Martin


-- 
Sebastian Rheinnecker
phone: +49 7071 9709050
fax: +49 7071 9709051

yWorks GmbH
Vor dem Kreuzberg 28
72070 Tuebingen
Germany
http://www.yworks.com
Managing Directors: Sebastian Müller, Michael Pfahler
Commercial Registry: Stuttgart, Germany, HRB 382340



More information about the openjfx-dev mailing list