Once upon a time, there was a method in FXMLLoader called setStaticLoad.
It can be used to load a FXML document with relaxed constraints.
For reference, the following behavior is changed or relaxed:
- fx:controller is not loaded/instantiated
- fx:root does not require that setRoot(..) is called before on the
FXMLLoader
- Methods like onAction="#method" are not resolved against the controller
Usages in the wild:
- SceneBuilder uses it as FXML from users could use fx:root or
fx:controller and SceneBuilder has no way to resolve that. As it only
opens the FXML and nothing else.
See: [0]
- JabRef uses it to extract i18n Strings from all FXMLs and checks if
they are also defined.
See: [1]
This is actually an interesting usecase.
- I used it on a project to just check that all FXMLs are fine, so can
be loaded.
That is really helpful to catch when e.g. an enum was written wrong or a
property is set that does not exist.
Below is an example how such a test could look like: [2]
I wonder if we could bring it back, so make it public API. All examples
above will call the private "setStaticLoad" method with reflection.
I do think "setStaticLoad" is a bad name, maybe something like
"setResolveReferences" or even "setResolveExternalReferences" would fit
much better.
-- Marius
[0]
https://github.com/gluonhq/scenebuilder/blob/f3194d6f8089789549c105f112f3bc6836eec55a/kit/src/main/java/com/oracle/javafx/scenebuilder/kit/util/ReflectionUtils.java#L53
[1]
https://github.com/JabRef/jabref/blob/3aa263ea14af3c34d148e742376c8d99350720c2/jablib/src/test/java/org/jabref/logic/l10n/LocalizationParser.java#L202-L217
[2] FXML Test (Headless Platform must be initialized before):
@ParameterizedTest(name = "{0}")
@MethodSource("allFxml")
void isLoadable(URL fxml) {
Throwable failure = runOnFxThread(() -> {
FXMLLoader loader = new FXMLLoader(fxml);
enableStaticLoad(loader);
try {
loader.load();
return null;
} catch (Throwable t) {
return t;
}
});
if (failure != null) {
fail(fxml + " does not load", failure);
}
}