Extending Builders: Layout Builders

Tom Schindl tom.schindl at bestsolution.at
Thu Nov 29 04:43:58 PST 2012


Hi,

Coming back to this I think the easiest solution would be to:
a) have constraint objects (HBoxConstraint, ....)
b) haveing $layoutPane$.add(Node,Constraint)
c) having Node#setLayoutConstraint(Constraint)

This makes b) simply a convenience method for c).

Why do we need c) well I don't see how we can provide all the different
list operations (e.g. bulk operation) with the API Tom E is proposing
(List.addAll, List.set, List.add).

It would have the advantage that FXML does not have to be changed
because it is still the serialized object graph.

Drawback: we'd have to have this layoutConstraint-Property in an area of
the framework that doesn't really know about layouts but is dealing
generic scenegraph/graphic stuff which might the original reason why
static stuff got introduced because at its heart JavaFX is not a widget
libary but a graphics framework.

Tom


Am 24.11.12 08:18, schrieb Tom Eugelink:
> Ah, yes. We can start by agreeing that it will not be easy, or even
> possible, to always create a good Java API that also is easy mappable
> and readable onto FXML by simple serialization. So then you come into a
> conflict of priorities, what is more important: a good Java API or a
> readable FXML?
> 
> We had similar issues with MigPane which also has a constaint class:
> 
> <TextFieldfx:id="firstNameField"text=""MigPane.cc="growx, wrap"/>
> 
> Here we decided to use the string notation for the controls. But in
> order to process this, we also needed a few static methods on MigPane.
> Since I really feel uncomfortable with polluting the Java API with
> things that basically are required by the layer above, I decided (to the
> dismay of some others) to create a separate MigPane class in a fxml
> subpackage which contains these methods.
> 
> http://code.google.com/p/miglayout/source/browse/javafx/src/main/java/org/tbee/javafx/scene/layout/fxml/MigPane.java
> 
> 
> A similar approach for the alternative HBox would basically result in
> the same API as HBox currently has:
> 
> <HBox>
>      <Label  fx:id="arrow"  alignment="center"   text=""
> maxWidth="Infinity" HBox.vgrow="ALWAYS" HBox.valignment="LEFT"/>
> </HBox>
> 
> With one important difference in that there still is a formal constraint
> class being set instead of an obscure internal map. And, like MigPane, I
> would not place these methods in the HBox class directly, but a special
> FXML version. Keep the Java API clean.
> 
> But I'd rather use a different approach: provide (de)serializers that
> help map the FXML onto the objects. I see FXML as a layer on top of the
> API and good software development teachings say that lower layers should
> not have any knowledge of higher layers, so I feel really really bad
> about polluting the Java API to support FXML. Providing glue might be a
> better approach. Java has standard plugin-style solutions in place, like
> META-INF/services, so it should be easily possible to provide plugins
> together with the components that help in those places where simple
> serialization does not cut it.
> 
> http://docs.oracle.com/javase/6/docs/technotes/guides/jar/jar.html#Service%20Provider
> 
> 
> In this way both Java API and FXML can be optimal. The plugin can also
> be extended to help the scene builder, by providing meta data for when
> it can't rely on reflection alone. I suspect the future will only
> introduce more of such conflict areas and rolling in a good solution
> instead of patching it would be IMHO the right way (tm).
> 
> Tom
> 
> 
> 
> On 2012-11-23 11:08, Tom Schindl wrote:
>> Hi,
>>
>> Let me retry - I hope this doesn't get too long.
>>
>> FXML is simply a serialization definition to serialize ANY given
>> java-object graph.
>>
>> Let's take your example:
>>
>> <HBox>
>>    <Label
>>      fx:id="arrow"
>>      alignment="center"
>>      text=""
>>      maxWidth="Infinity">
>>      <HBox.C vgrow="ALWAYS"  hgrow="ALWAYS"/>
>>    <Label>
>> </HBox>
>>
>> which means in full blown FXML without default-attributes
>>
>> <HBox>
>>    <children>
>>    <Label
>>      fx:id="arrow"
>>      alignment="center"
>>      text=""
>>      maxWidth="Infinity">
>>      <constraint>
>>        <HBox.C vgrow="ALWAYS"  hgrow="ALWAYS"/>
>>      </constraint>
>>    <Label>
>>    </children>
>> </HBox>
>>
>> So written in Java-Code it means
>>
>> HBox box = new HBox();
>> Label l = new Label();
>> l.set...
>> HBox.C c = new HBox.C();
>> c.set...
>> l.setConstraint(c);
>> box.getChildren().add(l);
>>
>> Definately not what you want because your layout-containers code looks
>> like this:
>>
>> HBox box = new HBox();
>> Label l = new Label();
>> l.set...
>> HBox.C c = new HBox.C();
>> c.set...
>> box.add(l,c);
>>
>> Which clearly violates the generic serialisation which says sub-elements
>> are always added (if it is a list) / set (single attribute) on the
>> attribute they are the child of.
>>
>> So if we take your proposed FXML as shown above we have a problem
>> because when we follow the general serialization/deserialization
>> strategy we'd have to have a layoutConstraint-Property on the *Node*
>> although things like layouts only make sense when you add the node
>> inside a layout-container but not if it is e.g. a child of a Group, ...
>>
>> To summerize: My point - I fully agree with you that when coding the UI
>> in Java your layout-container additions make a whole lot of sense but
>> they break the serialization infrastructure because the addition is not
>> done on the attribute itself (children) but through the owner of the
>> attribute (HBox).
>>
>> Tom
>>
>> Am 22.11.12 19:51, schrieb Tom Eugelink:
>>> Not sure I understand what you are trying to say here. Each layout has
>>> different and much deviating constraints, so they cannot be unified into
>>> one model.
>>>
>>> I think I summarized it well in my blogpost: "All information about the
>>> layout of a single node should be stored in one place." This means
>>> absolute layout can suffice with the X,Y,W,H information available in
>>> the nodes (and thus allow binding), but all more advanced layouts
>>> require a separate constraint class.
>>>
>>> Tom
>>>
>>>
>>>
>>>
>>> On 2012-11-21 22:42, Tom Schindl wrote:
>>>> the nice thing about the current expression with static calls is that
>>>> the semantics for adding children are always the same whether your
>>>> target is a Layout-Container or e.g. a Group.
>>>>
>>>> You always call add on the target your specified. Your way of layout
>>>> containers expects two different things to happen:
>>>> * for layout container you want to call add on the owner because you
>>>>     want to pass the constraint object
>>>> * you can add on the list itself for stuff like Group but also Tables
>>>>
>>>> Not to forget how would you like set the constraint when you not add to
>>>> a list e.g. when using a borderpane?
>>>>
>>>> Tom
>>>>
>>>> Am 21.11.12 19:02, schrieb Tom Eugelink:
>>>>> I suspect the constraints were already "out" before FXML, but this
>>>>> would
>>>>> be a fairly acceptable notation:
>>>>>
>>>>> |<HBox>
>>>>>       <Label  fx:id="arrow"  alignment="center"   text=""
>>>>> maxWidth="Infinity">        |
>>>>> ||        <HBox.Cvgrow="ALWAYS"  hgrow="ALWAYS"|/>
>>>>>       <Label>
>>>>> </HBox>
>>>>> |
>>>>>
>>>>>
>>>>> Or:
>>>>>
>>>>> |<HBox>
>>>>>       <Label  fx:id="arrow"  alignment="center"   text=""
>>>>> maxWidth="Infinity"|||HBox.C.vgrow="ALWAYS"  HBox.C.hgrow="ALWAYS"|/>
>>>>> </HBox>
>>>>> |
>>>>>
>>>>>
>>>>>
>>>>> On 2012-11-21 17:46, Tom Schindl wrote:
>>>>>> Am 21.11.12 09:46, schrieb Richard Bair:
>>>>>>> I wanted constraint classes from the start. There was a problem
>>>>>>> there, which I don't accurately remember now, but I do want to see
>>>>>>> some discussion around deprecating (or at least no longer depending
>>>>>>> on) the static methods and having some constraint classes again.
>>>>>> They've probably been harder to implement in FXML?
>>>>>>
>>>>>> Tom
>>>>>>
>>>>>>
>>
> 


-- 
B e s t S o l u t i o n . a t                        EDV Systemhaus GmbH
------------------------------------------------------------------------
tom schindl                 geschäftsführer/CEO
------------------------------------------------------------------------
eduard-bodem-gasse 5-7/1   A-6020 innsbruck     fax      ++43 512 935833
http://www.BestSolution.at                      phone    ++43 512 935834


More information about the openjfx-dev mailing list