Bounds in JavaFX

Bounds in JavaFX:
Bounds refers to the node’s size and position in JavaFx. A nodes rectangular bounds are represented by the Bounds class which provides init-only minX (minimum x value), minY (minimum y value), maxX (maximum x value), maxY (maximum y value) , width , height variables. The X/Y values can also be negative. When a node is created there are three different ways we can access the size and position of the nodes. i.e., boundsInLocal, boundsInParents, and layoutBounds.

boundsInLocal – physical bounds in the node’s local coordinate grid (not the parent’s coordinate grid.), untransformed coordinate space, including shape geometry, space required for a non-zero strokeWidth that may fall outside the shape’s position/size geometry, the effect and the clip.

boundsinParent – physical bounds of the node after ALL transform have been applied to the node’s coordinate space, including transforms[], scaleX/scaleY, rotate, translateX/translateY, and layoutX/layoutY. The rectangle will be defined in terms of the parent node’s coordinate system.

layoutBounds – logical bounds used as basis for layout calculations; by default only includes a node’s shape geometry, however its definition may be overridden in subclasses. It does not necessarily correspond to the node’s physical bounds.

It is important to understand that each node when created have its own coordinate grid systems that is different from its parents coordinate grid. For example, if we create a rectangle node and put it in the scene. The boundsInLocal references to the bounds of the rectangle within the coordinate grid of the rectangle node (includes the bound differences applied by the effect on the node), boundsInParent refers to the bounds of the rectangle within the coordinate grid of the scene (includes the bound differences applied by the effect on the node ), and the layoutBounds refers to the bounds within the coordinate grid of the rectangle node (doesn’t include bound differences applied by the effect and gives the actual shape geometry of the node).

For example: for the following rectangle:

var rect:Rectangle = Rectangle
{
  translateX:10,
  translateY:10,
  x:130,
  y: 0;
  width: 120,
  height: 120
  fill: Color.BLACK
}

Rectangle Bounds In Local bounds:
width: 120.0
height: 120.0
minX: 130.0 (x value specified)
minY: 0.0 (y value specified)
maxX: 250.0 (minX + width)
maxY:120.0 (minY + height)

Rectangle Bounds in Parent bounds:
width: 120.0
height: 120.0
minX: 140.0 (x value + translateX. remember this refrences to the scene coordinate grid)
minY: 10.0 (y value + translateY)
maxX: 260.0 (minX + width)
maxY: 130.0 (minY + height)

Rectangle layout bounds:
width: 120.0
height: 120.0
minX: 130.0
minY: 0.0
maxX: 250.0
maxY: 120.0

The layoutBounds bounds in this case is the same as the boundsInLocal bounds because no effect is applied to the rectangle. Now lets apply a drop shadow effect to the rectangle and see how the bounds change.

var rect:Rectangle = Rectangle
{
  translateX:10,
  translateY:10,
  x:130,
  y: 0;

  width: 120,
  height: 120
  fill: Color.BLACK

  effect: DropShadow
  {
    offsetX: 10
    offsetY:10

    color:Color.GREEN
    radius:20

  }
}

Rectangle Bounds In Local bounds:
width: 160.0 (considers the difference due to the drop shadow effect)
height: 160.0 (considers the difference due to the drop shadow effect)
minX: 120.0 (considers the difference due to the drop shadow effect)
minY: -10.0 (considers the difference due to the drop shadow effect. remember that bound values can be negative)
maxX: 280.0 (minX + width)
maxY: 150.0 (minY + height)

Rectangle Bounds in Parent bounds:
width: 160.0 (considers the difference due to the drop shadow effect)
height: 160.0 (considers the difference due to the drop shadow effect)
minX: 130.0 (considers the difference due to the drop shadow effect and is 130 here instead of 120 as in above because it adds the translateX value. This is because, it is in scene coordinate grid)
minY:  0.0 (considers the difference due to the drop shadow effect and is 0 here instead of -10 as in above because it adds the translateY value. This is because, it is in scene coordinate grid)
maxX:  290.0 (minX + width)
maxY: 160.0 (minY + height)

Rectangle layout bounds:
width: 120.0  (actual width specified )
height: 120.0 (actual height specified)
minX: 130.0 (actual x specified)
minY: 0.0 (actual y specified)
maxX: 250.0 (minX + width)
maxY: 120.0 (minY + height)

Imortant points:
Bounds minX/minY and maxX/maxY can be negative. ex: circle is centered on (0,0).
layout bounds is a logical concept. ex: spin an icon without disturbing the layout of its neighbors
Always use layoutBounds when measuring the current size and position of nodes for the purpose of the layout.
All containers in javafx.scene.layout reference the node’s layoutBounds.
if you want layoutBounds to match a node’s physical bounds(including effects, clip, and transform) then wrap it in a Group. ex: if you want a node to scale up on mouse-over and you want its neighbor to scoot over to make room for the magnified node.

References made from:

http://weblogs.java.net/blog/2009/07/09/javafx12-understanding-bounds#chase

Advertisements