Layouts with constraint classes
Tom Schindl
tom.schindl at bestsolution.at
Sat Dec 1 03:58:17 PST 2012
I agree predefining the constraint for a node that might get added
somewhere feels wrong (=> your 2nd sample looks good!). That's why I
think it makes no sense to store to constraint on the container but it
should be stored on the node itself and when you move the Node you
update the constraint.
BTW: I think the samples would be more interesting if the source and
target container are of different type. e.g. HBox => VBox
Tom
Am 01.12.12 11:57, schrieb Daniel Zwolenski:
> I've slapped up two examples for you - they are pretty rough and could be
> cleaned up, but it's just to demonstrate.
>
>
> *Example 1* is basically how you requested it.
>
> The FXML looks like this:
>
>
> <HBox fx:id="hbox1">
> <constraints>
> <HBoxConstraints forNode="myLabel" hgrow="ALWAYS"/>
> </constraints>
> <Label fx:id="myLabel" text="I'm a Label"
> style="-fx-background-color:green" maxWidth="10000"/>
> </HBox>
>
> <HBox fx:id="hbox2">
> <constraints>
> <HBoxConstraints forNode="myLabel" hgrow="NEVER"/>
> </constraints>
> <!-- label will get moved here -->
> </HBox>
>
>
> For the full FXML see:
> http://code.google.com/p/zenjava-playtime/source/browse/trunk/layouts/src/main/resources/fxml/example1.fxml
> (Note
> that I defined the Animation in the FXML, but this is totally optional, you
> could define it in the controller).
>
> This needed a fair few support classes because you have to create new
> builders for the layout manager. If this was a common use case then you
> could put all the customised builders and constraint classes in something
> like JFXtras for shared reuse.
>
> Main support class is the HBoxBuilder:
> http://code.google.com/p/zenjava-playtime/source/browse/trunk/layouts/src/main/java/com/playtime/layouts/example1/CustomHBoxBuilder.java
>
> (strangely extending the default HBoxBuilder didn't work with FXML - not
> sure if I was just doing something dumb, I didn't look into it deeper)
>
> Other support classes are all in the same package:
> http://code.google.com/p/zenjava-playtime/source/browse/trunk/layouts/src/main/java/com/playtime/layouts/example1/
>
>
> *Example 2* is where the animation itself defines the constraints (as per
> my suggestion). This one feels more natural to me as the animation knows
> context and could decide to use a different layout depending on what action
> was picked. In the animation dance there is the source parent, the target
> parent and the node being moved. All of these are 'passive' and only the
> animation does the "action" and really knows that there is a move happening
> and why it is happening so in my book it is the one that should make
> decisions about how the node looks when it is moved. That's a subjective
> opinion though and you have both options to choose from.
>
> The FXML looks like this
>
> <HBox fx:id="hbox1">
> <Label fx:id="myLabel" text="I'm a Label"
> style="-fx-background-color:green" HBox.hgrow="ALWAYS" maxWidth="10000"/>
> </HBox>
>
> <HBox fx:id="hbox2">
> <!-- label will get moved here -->
> </HBox>
>
> <fx:define>
> <MoveAnimation fx:id="moveForwardAnimation" node="$myLabel"
> newParent="$hbox2">
> <HBoxConstraints hgrow="NEVER"/>
> </MoveAnimation>
> <MoveAnimation fx:id="moveBackAnimation" node="$myLabel"
> newParent="$hbox1">
> <HBoxConstraints hgrow="ALWAYS"/>
> </MoveAnimation>
> </fx:define>
>
> There are considerably fewer/simpler support classes for this. The only
> really interesting one is this:
>
> http://code.google.com/p/zenjava-playtime/source/browse/trunk/layouts/src/main/java/com/playtime/layouts/example2/MoveAnimation.java
>
> As a side note, the JFX animation/transition classes being final make the
> code a little messier. This is one area where I would vote for relaxing the
> use of 'final' - extending transitions makes as much sense as extending
> Nodes in my book. We can already extend Transition so I don't see why we
> can't extend SequentialTransition for example.
>
> I hope this time I got it right and that solves your use case. My main
> point though is that pretty much all of this sort of stuff *should* be
> possible through the use of builders and support classes. The glue may not
> always be the nicest but the driving force should be to keep the FXML and
> Java clean without compromising each other - the mess should be in the glue
> because only the glue author sees that, not the end user of the API, that's
> why the glue exists in the first place.
>
>
>
>
>
> On Sat, Dec 1, 2012 at 6:47 PM, Tom Eugelink <tbee at tbee.org> wrote:
>
>> Yes, correct :-)
>>
>> The approach where the constraint is set in the animation feels procedural
>> and not declarative to me. Like you say yourself, I think it should be
>> define like: when node X is part of this layout, use these constraints. In
>> this way it is not relevant where the animation is defined or how the node
>> got there.
>>
>> Tom
>>
>>
>>
>> On 2012-12-01 08:38, Daniel Zwolenski wrote:
>>
>>> Ah ok, so in the first hbox you are saying when the "arrow" node is moved
>>> into here use these new constraints. I think I've got you now.
>>>
>>> That should be do-able using some more helper classes. I can knock some
>>> up but my first thought would be to do it as part of the animation since
>>> its the thing that has the most knowledge about what's going on and why.
>>>
>>> How/where do you define and trigger your animation - are you specifying
>>> it in the FXML? If so the constraints could be part of that eg. (made up
>>> pseudo FXML):
>>>
>>> <MoveAnimation nodeToMove="arrow" moveTo="hbox1">
>>> <NewConstraints>
>>>
>>>> <HBox.C vgrow="NEVER" valignment="RIGHT"/>
>>>>
>>> </NewConstraints>
>>> </MoveAnimation>
>>>
>>> (also slightly confusing is that the constraints you are using aren't
>>> applicable to HBox)
>>>
>>> If you don't like that approach I can knock up the alternative?
>>>
>>>
>>>
>>> On 01/12/2012, at 6:17 PM, Tom Eugelink <tbee at tbee.org> wrote:
>>>
>>> Because of animation the label may move from one HBox to the other. This
>>>> is the reason why the current approach stores constraints inside the node,
>>>> so that when it moves from layout A to B, the constraints also move. My
>>>> approach allows to specify different constraints for the same node in each
>>>> layout.
>>>>
>>>> You are right that there should be a parent layout, I left it out to not
>>>> confuse things, but apparently that is confusing :-)
>>>>
>>>> <VBox>
>>>> <HBox>
>>>> <HBox.C for="arrow" vgrow="NEVER" valignment="RIGHT"/>
>>>> </HBox>
>>>>
>>>> <HBox>
>>>> <Label fx:id="arrow" alignment="center" text="">
>>>> <HBox.C vgrow="ALWAYS" valignment="LEFT"
>>>> maxWidth="Infinity"/>
>>>> <Label>
>>>> </HBox>
>>>> </VBox>
>>>>
>>>>
>>>>
>>>> On 2012-12-01 08:01, Daniel Zwolenski wrote:
>>>>
>>>>> You've lost me. What are you expecting the actual view to look like
>>>>> with this FXML?
>>>>>
>>>>> If I interpret it literally you've defined two HBox's one after the
>>>>> other. The first one has no children and an unused constraint, the second
>>>>> one has a Label in it with a constraint on it. I'm guessing you are trying
>>>>> to do something more but it's not real clear what that more is?
>>>>>
>>>>>
>>>>>
>>>>> On 01/12/2012, at 5:28 PM, Tom Eugelink <tbee at tbee.org> wrote:
>>>>>
>>>>> Not variables, but references. There are constraints specified for
>>>>>> nodes that are not yet part of a layout (or even exist at that time,
>>>>>> because they are declared further down). Note the absense of a label in the
>>>>>> first HBox.C.
>>>>>>
>>>>>> <HBox>
>>>>>> <HBox.C for="arrow" vgrow="NEVER" valignment="RIGHT"/>
>>>>>> </HBox>
>>>>>>
>>>>>> <HBox>
>>>>>> <Label fx:id="arrow" alignment="center" text="">
>>>>>> <HBox.C vgrow="ALWAYS" valignment="LEFT" maxWidth="Infinity"/>
>>>>>> <Label>
>>>>>> </HBox>
>>>>>>
>>>>>>
>>>>>> Tom
>>>>>>
>>>>>>
>>>>>> On 2012-11-30 14:11, Daniel Zwolenski wrote:
>>>>>>
>>>>>>> Ah ok, from your example code it looks like you want to use variables
>>>>>>> in FXML to define your constraints - getting into that territory of
>>>>>>> CSS-like style definitions that Richard was talking about?
>>>>>>>
>>>>>>> Assuming this is what you want, this can be done in the current setup
>>>>>>> using the ridiculously under-documented <fx:define> thing.
>>>>>>>
>>>>>>> I knocked up a very rough sample for you quickly. The FXML looks like
>>>>>>> this:
>>>>>>>
>>>>>>> <BorderPane xmlns:fx="http://javafx.com/**fxml<http://javafx.com/fxml>
>>>>>>> ">
>>>>>>>
>>>>>>> <fx:define>
>>>>>>> <HBoxConstraints fx:id="noGrow" hgrow="NEVER"/>
>>>>>>> <HBoxConstraints fx:id="growLots" hgrow="ALWAYS"/>
>>>>>>> </fx:define>
>>>>>>>
>>>>>>> <center>
>>>>>>> <HBox>
>>>>>>> <Label text="I don't grow" style="-fx-background-color:**green"
>>>>>>> Constraints.constraints="$**noGrow"/>
>>>>>>> <Label text="I grow big" style="-fx-background-color:**yellow"
>>>>>>> Constraints.constraints="$**growLots"/>
>>>>>>> </HBox>
>>>>>>> </center>
>>>>>>>
>>>>>>> </BorderPane>
>>>>>>>
>>>>>>> (see https://code.google.com/p/**zenjava-playtime/source/**
>>>>>>> browse/trunk/layouts/src/main/**resources/fxml/example.fxml<https://code.google.com/p/zenjava-playtime/source/browse/trunk/layouts/src/main/resources/fxml/example.fxml>
>>>>>>> )
>>>>>>>
>>>>>>> I made a base Constraints class with a static helper method on it
>>>>>>> (called via "Constraints.constraints" in the FXML above):
>>>>>>> https://code.google.com/p/**zenjava-playtime/source/**
>>>>>>> browse/trunk/layouts/src/main/**java/com/playtime/layouts/**
>>>>>>> Constraints.java<https://code.google.com/p/zenjava-playtime/source/browse/trunk/layouts/src/main/java/com/playtime/layouts/Constraints.java>
>>>>>>>
>>>>>>> And then a specific instance of HBoxConstraints:
>>>>>>> https://code.google.com/p/**zenjava-playtime/source/**
>>>>>>> browse/trunk/layouts/src/main/**java/com/playtime/layouts/**
>>>>>>> HBoxConstraints.java<https://code.google.com/p/zenjava-playtime/source/browse/trunk/layouts/src/main/java/com/playtime/layouts/HBoxConstraints.java>
>>>>>>>
>>>>>>> Obviously you would add others, like VBoxConstraints,
>>>>>>> GridPaneConstraints, etc. All pretty trivial. These helper classes could
>>>>>>> easily be included in something like JFXtras.
>>>>>>>
>>>>>>> So I stick with the stance that FXML is more or less OK here (not to
>>>>>>> say I wouldn't improve it lots in other areas), and really your
>>>>>>> conversation is about the Java API which is nicely decoupled to what
>>>>>>> can/can't be done in FXML. Kudos to Richard and the JFX team for designing
>>>>>>> the builders right.
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> On Fri, Nov 30, 2012 at 9:20 PM, Tom Eugelink <tbee at tbee.org <mailto:
>>>>>>> tbee at tbee.org>> wrote:
>>>>>>>
>>>>>>> On 2012-11-30 10:59, Daniel Zwolenski wrote:
>>>>>>>
>>>>>>> It just doesn't do it the exact way you suggest where you
>>>>>>> specify multiple possibilities directly in the child in case it ends up in
>>>>>>> a different parent - not an approach I agree with anyway (see my previous
>>>>>>> comments), but that's just my opinion.
>>>>>>>
>>>>>>>
>>>>>>> Just to make sure my suggestion is not misunderstood, it does not
>>>>>>> specify multiple possibilities in the child, but in the layout.
>>>>>>>
>>>>>>> <HBox>
>>>>>>> <HBox.C for="arrow" vgrow="NEVER" valignment="RIGHT"/>
>>>>>>> </HBox>
>>>>>>>
>>>>>>> <HBox>
>>>>>>> <Label fx:id="arrow" alignment="center" text="">
>>>>>>> <HBox.C vgrow="ALWAYS" valignment="LEFT"
>>>>>>> maxWidth="Infinity"/>
>>>>>>> <Label>
>>>>>>> </HBox>
>>>>>>>
>>>>>>>
>>>>>>>
>>
--
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