[REVIEW] Make controller instantiation customizable

Daniel Zwolenski zonski at googlemail.com
Fri Dec 16 16:37:43 PST 2011

Maybe the following provides a concrete example of the namespace stuff to
work with and expand upon (most interesting bits highlighted in red):

<?xml version="1.0" encoding="UTF-8"?>

<?import java.lang.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?param name="presenter"
<?param name="model"
<?param name="helper"

<VBox fx:id="root" spacing="10" xmlns:fx="http://javafx.com/fxml">
<children> <!-- Search Bar --> <HBox spacing="10"> <children> <Label
text="Search"/> <TextField text="${+model.searchPhrase}"
onAction="${presenter.doSearch}"/> <Button text="Search" onAction="
${presenter.doSearch}"/> </children> </HBox> <!-- Search Results -->
<ListView items="${+model.searchResultsList}" VBox.vgrow="ALWAYS">
<cellFactory fx:value="${helper.createCellFactory}"/>
</ListView> </children> </VBox>

Some additional comments:

   - The fx:controller attribute has been avoided altogether (i.e. the
   specialness of the controller has been downgraded - it's just another
   variable in the namespace like 'model' and 'helper' and can be called
   whatever, in the case above 'presenter'). This makes the FXML less
   pattern-specific, MVP, PV, SC, MVC, MVVC, MVWTF - the developer has more

   - For my money the 'param' declarations would be optional. If they are
   specified then tooling support can be provided, but if not the tool just
   doesn't try to help out with the expressions further down. e.g. with the
   'param' declarations, the tool could tell me if 'createCellFactory' exists
   and is the right type, without the param the tool would just ignore it (as
   it must be doing currently with namespace variables).

   - I've added a ifNotInNamespace variable (the name of this need works)
   as an idea to explore. This could let you specify 'error|ignore|create' -
   if create it works much as the current fx:controller does (i.e. the
   FXMLLoader tries to new the instance), if 'error' the FXMLLoader fails with
   exception, if 'ignore' the FXMLLoader does nothing special and carries on
   with the rest of the loading (which might throw an exception further down
   depending on how the variable is used).

   - To handle fx:include I would suggest a pass-through mechanism, where
   the outer FXML effectively populates the inner FXML's namespace with
   variables from its own namespace (or from other controls in the outer
   FXML). Probably an optional flag on the fx:include  to just pass through
   the whole outer namespace verbatim. So something like:

<fx:include source="inner-fxml" passNamespaceVars="true|false">
    <param name="presenter" value="${presenter}"/>
    <param name="someProperty1" value="${model.someValue}"/>
    <!-- following assumes 'outerTextField' is an fx:id on a textfield in
this FXML -->
    <param name="someProperty2" value="${outerTextField.text}"/>

As I said, just a starting point to think upon and to give us a concrete
example to pull apart and reference.

On Sat, Dec 17, 2011 at 11:00 AM, Greg Brown <greg.x.brown at oracle.com>wrote:

> > I think we're crossing wires. I'm talking about the:
> >
> > <param fx:id="someParameterInTheNamedParametersMap" />
> >
> > not passing the String to the controller factory.
> OK, thanks for clarifying. So what would be the use case for this feature?
> Where would I apply a <param> tag, and why?
> >> A developer will have to look a lot more closely at the Javadoc for
> setControllerFactory() to understand what a "callback" is in this context,
> and what call() will actually do. A dedicated interface is clearer, yet
> will be equally applicable to lambdas in Java 8.
> >
> > I know the argument well. The same question has come up in multiple
> places in the platform. If we went with one-off interfaces, the interface
> names and method names would be much clearer and more specific. On the
> other hand, there would be more class files.
> I'm not sure how much of an issue that really is in practice. As I recall,
> we use a lot of anonymous inner classes, which also add to the total class
> count. JavaFX is a framework, so in my opinion API clarity is much a more
> important consideration.
> > In the end, I think we need to use a Callback here. We've already faced
> and made this decision for the other parts of the platform, so it makes
> sense to be consistent here.
> It would be consistent with other unrelated parts of the platform, but not
> with the BuilderFactory interface, which is used by FXMLLoader and is
> already defined similarly to ControllerFactory.
> G

More information about the openjfx-dev mailing list