Saturday 18 September 2010

How to position nodes using layoutInfo?

Hi guys,
Hope you all are doing ok. Today I’d like to describe another method of positioning nodes within a container. This time we will have a look at the layoutInfo variable and LayoutInfo class. Mentioned variable is accessible in any node in javafx. To be more specific layoutInfo is inherited from the “big daddy” Node class. The information stored in layoutInfo tell the container how to position the particular node within its bounds. Objects of LayoutInfo are used to describe what exactly we want to do with the node to position.

Before reading further it would be a great idea if you checked LayoutInfo class description in javafxdoc:



As always let’s have a look at the example:



From the picture above you can see that the application consists of two red rectangles one positioned in top left corner and the other in bottom right corner. They are exactly half of the width and height of the window. They also connected in the exact middle.  In addition, when we resize the window they keep the proportion:



I hope you more or less understand what the application does. The next step is to have a look at the code for this example:

import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.layout.Stack;
import javafx.geometry.VPos;
import javafx.geometry.HPos;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.scene.layout.LayoutInfo;

var scene: Scene;

Stage {
    title: "Stack and LayoutInfo"
    scene: scene = Scene {
        width: 200
        height: 200
        content: [

            Stack {
                height: bind scene.height;
                width: bind scene.width;
                content: [

                    Rectangle {
                        width: bind scene.width / 2
                        height: bind scene.height / 2
                        fill: Color.RED;

                        layoutInfo: LayoutInfo {
                            vpos: VPos.TOP
                            hpos: HPos.LEFT
                        } // end LayoutInfo
                    } // end Rectangle

                    Rectangle {
                        width: bind scene.width / 2
                        height: bind scene.height / 2
                        fill: Color.RED;

                        layoutInfo: LayoutInfo {
                            vpos: VPos.BOTTOM
                            hpos: HPos.RIGHT
                        } // end LayoutInfo
                    } // end Rectangle
                ] // end Stack content
            } // end Stack
        ] // end Scene content
    } // end Scene
} // end Stage

From the listing above you can see that as a container I used Stack (discussed in previous post). I did it from one reason. Stack centres all of the nodes by default. It gives me perfect opportunity to demonstrate the power of layoutInfo. If we didn’t use this variable the application would look as follows:


I would also like you too notice that the height and width is calculated using bind statement. It assures that the rectangle will have half of the scene's height and width. 

Let’s concentrate on the one of the rectangles (one in top left corner):

Rectangle {
width: bind scene.width / 2
height: bind scene.height / 2
fill: Color.RED;

layoutInfo: LayoutInfo {
vpos: VPos.TOP
hpos: HPos.LEFT
} // end LayoutInfo
} // end Rectangle

In here you can see the variable layoutInfo with object of LayoutInfo class assigned to it. This class consists of many variables, which allow container to manipulate the node. The ones seen above are:

vpos – sets the vertical position of the node (in this example top). Expects constant value from VPos     class.
hpos – sets horizontal position of the node(in this example left). Expects constant value from HPos class.

In order to assign proper values we need to import two library classes:

javafx.geometry.VPos
javafx.geometry.HPos

Possible constant values for HPos ( from JavaFX API documentation ):

CENTER - Indicates centered horizontal position
LEADING - Indicates leading horizontal position, which means left in left-to-right context and right in a right-to-left context.
LEFT - Indicates left horizontal position.
RIGHT - Indicates left horizontal position.
TRAILING - Indicates trailing horizontal position, which means right in left-to-right context and left in a right-to-left context

On the other hand VPos provides following constants:

BASELINE - Indicates baseline vertical position.
BOTTOM - Indicates bottom vertical position.
CENTER - Indicates centered vertical position.
PAGE_END - Indicates vertical position at the end of the page, which means bottom in a top-to-bottom context and top in a bottom-to-top context.
PAGE_START - Indicates vertical position at the start of the page, which means top in a top-to-bottom context and bottom in a bottom-to-top context.
TOP - Indicates top vertical position.

Using these two variables gives us free choice of where to position particular node within container. 

Apart from the vpos and hpos LayoutInfo class consists of the following properties, which will allow further manipulation of the node:

minWidth – sets minimal allowed width of the node
minHeight – sets minimal allowed height of the node
maxWidth – sets maximal allowed width of the node
maxHeight – sets maximal allowed height of the node
height – sets height of the node
width – sets width of the node

There are more variables, but I’ll leave them for you to exploreJ

That would be all from me today. Hope you enjoyed the read.

Cheers

No comments:

Post a Comment