Extending Builders: Layout Builders (original) (raw)

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 layoutPanelayoutPanelayoutPane.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: <Label fx:id="arrow" alignment="center" text=""_ _maxWidth="Infinity" HBox.vgrow="ALWAYS" HBox.valignment="LEFT"/> 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: <Label_ _fx:id="arrow"_ _alignment="center"_ _text=""_ _maxWidth="Infinity"> <HBox.C vgrow="ALWAYS" hgrow="ALWAYS"/> which means in full blown FXML without default-attributes <Label_ _fx:id="arrow"_ _alignment="center"_ _text=""_ _maxWidth="Infinity"> <HBox.C vgrow="ALWAYS" hgrow="ALWAYS"/> 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: | <Label fx:id="arrow" alignment="center" text=""_ _maxWidth="Infinity"> | || <HBox.Cvgrow="ALWAYS" hgrow="ALWAYS"|/> | Or: | <Label fx:id="arrow" alignment="center" text=""_ _maxWidth="Infinity"|||HBox.C.vgrow="ALWAYS" HBox.C.hgrow="ALWAYS"|/> |

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