In JavaFX-8, can a controller be dynamically added to a node not created using FXML/FXMLLoader? -
this may case of newb-swimming-upstream, but...
in fxml file, 1 of attributes identifies controller. assuming controller , identified methods bound node during load (i.e., controller instance instantiated , methods bound listeners identified in fxml).
is there way programmatically associate controller instance javafx node (e.g., tableview) created procedurally vice via fxmlloader?
if understand correctly, want define controller instance in java code, instead of letting fxmlloader
instantiate it.
you can calling setcontroller
on fxmlloader
before call load()
. note means must create fxmlloader
instance , invoke instance load()
method, , must not call static load(url)
method:
mycontroller controller = new mycontroller(); fxmlloader loader = new fxmlloader(getclass().getresource("path/to/fxml")); loader.setcontroller(controller); parent root = loader.load();
if use technique, must not use fx:controller
attribute in root element of fxml file.
note gives ability instantiate controller way - e.g. if have controller classes have constructors take parameters can use them here (controllers used default mechanism must have zero-arg constructor).
more advanced related information:
a related technique, perhaps more specialized use cases, set controller factory on fxmlloader
. controller factory function maps class<?>
(the 1 defined fx:controller
attribute) object (the controller). gives programmatic control on way controllers instantiated (typically using reflection). 1 use of if have model class:
public class model { /* ... */ }
and several different controller classes take model reference constructor parameter. typically want use same model instance , pass controllers. define controller factory follows:
model model = new model(); callback<class<?>, object> controllerfactory = type -> { try { // constructor single parameter of type model: (constructor<?> c : type.getconstructors) { if (c.getparametercount() == 1 && c.getparametertypes()[0] == model.class) { return c.newinstance(model); } } // no constructor found, invoke no-arg constructor in default: return type.newinstance(); } catch (exception e) { throw new runtimeexception(e); } };
then can set controller factory on fxmlloader
(s):
fxmlloader loader = new fxmlloader(getclass().getresource("path/to/fxml")); loader.setcontrollerfactory(controllerfactory); parent root = loader.load();
another use of technique in conjunction dependency-injection frameworks such spring , guice. if configure di framework instantiate controllers you, , perhaps inject model instances them, can use controller factory allow fxmlloader
retrieve controller instances framework. e.g. spring:
applicationcontext context = ... ; fxmlloader loader = new fxmlloader(getclass().getresource("path/to/fxml")); loader.setcontrollerfactory(context::getbean); parent root = loader.load();
or guice:
injector injector = guice.createinjector(...); fxmlloader loader = new fxmlloader(getclass().getresource("path/to/fxml")); loader.setcontrollerfactory(injector::getinstance); parent root = loader.load();
Comments
Post a Comment