[REVIEW] Make controller instantiation customizable

Gaja Sutra gajasutra at gmail.com
Sat Dec 17 07:22:56 PST 2011


>> I think for what it does the current design is very nice. But we've had Roman, Adam Bien, Dan and myself all make reference to wanting to use other patterns and for those, the fx:controller and "code behind" concepts are just not what we're looking for, even with a ControllerFactory (although that does certainly help!). Do you remember before 2.0 when Eamonn and I both wanted to invert the control and have the Controller create the FXML file rather than the other way around as we do now? We were thwarted due to the fx:include problem. But with<param>  we might have a more powerful, and I think more elegant, way to address that issue without having the FXMLLoader to create the controller.
+1 for <?param name="..." type="..."?>

> But maybe this whole thing comes down to a terminology issue. What we're currently calling the "controller" could be viewed simply as the implementation of the view. Imagine that we called it "view manager" instead of "controller".  The "real" controller could be an external entity that simply communicates with the view via view manager. That way, we'd avoid the tight coupling between the actual controller and the view - and the view manager (what we're currently calling the controller) would provide a typed abstraction layer that the controller could use to talk to the view.

The view manager is useful, but I think it will be simple code mostly 
delegating to the controller or to the view. Being simple, I think a 
view manager can be better by being declarative (for avoiding bugs and 
allowing automatic persistency). Depending of direction and type of 
communication, I see two parts:

As many others have requested, I think <?param?> will be very useful. 
Half of exchange can be made with <?param ?>:

  * Data send from controller to view with <?param name="..."
    value="..."?> and ${myParam.myProperty}
  * Action send from view to controller: #{myParam.doSomething}

The other half (of the the view manager) can be made with a state 
machine (like SCXML)[1,2], to be independent of UI controls used and 
allow simple persistence of current state of view (when user close 
application), even if relaunched on slightly different UI (by example if 
user go from phone to computer and a TabPane is replaced by an Accordion 
on the bigger screen). In this communication, we have the following two 
exchange types.

  * Data send from view to controller: divider position of SplitPane
    (for saving in user preferences of this view), save the state of
    view, save time of video playing, etc.
  * Action send from controller to view: go to a specific tab, restore
    state of view, start video at given time, etc.

The SCXML model (declarative view manager) can be mapped to annotated 
FXML, by example like that SCXML:
|<state id="content">
<datamodel>
<dividerPositions>0.4</dividerPositions>
</datamodel>
<state id="first"/>
<state id="second"/>
</state>|

will be usable in one FXML with a code like that (and in another using 
an Accordion or some other control):
|<SplitPane id="content" 
dividerPositions="${+controller.content.dividerPositions}>
<children>
<TreeView>...</TreeView>
<TabPane selectionModel="${+controller.content.target}">
<tabs>
<Tab id="first">...</Tab>
<Tab id="second">...</Tab>
</tabs>
</TabPane>
</children>
</SplitPane>|

My two (crazy) cents.

 1. http://www.w3.org/TR/scxml/
 2. http://commons.apache.org/scxml/guide/datamodel.html



More information about the openjfx-dev mailing list