Дата публикации: 04.11.2013 13:09:45
It is typical to use absolute coordinates to position nodes in a simple JavaFX application. But what if your application becomes more complex? It is quite annoying to change the coordinates of several nodes if one of them changes its size. From Swing and AWT you can recall the mechanism of Layout Managers. Does JavaFX suggest anything similar?
The JavaFX API 1.0 provides two simple subclasses of the Group class: the HBox class lays out nodes in a row, and the VBox class - in a column. Find more details in Building GUI Applications With JavaFX.
Create a simple application that employs HBox and VBox to lay out patterns of all colors supported by JavaFX. Note that the Color class in JavaFX differs from the Color class in Java SE. In particular, the LIGHTGRAY and DARKGRAY constants represent different colors in these classes. Strangely enough, but GRAY is darker than DARKGRAY. It is because JavaFX implements the W3C specification.
content: VBox { translateX: space translateY: space spacing: space content: for (v in [0..height-1]) HBox { spacing: space content: for (h in [0..width-1]) Rectangle { def color = colors[h + v * width]; fill: Color.web(color) width: size height: size onMouseEntered: function(event) { this.color = color } } } }
The HBox and VBox classes make layout easier but their facilities are not enough. However, the Group class provides resources to create a custom group that allows laying out nodes. Hopefully, next JavaFX release will provide more such groups. I would like to show you how to arrange elements within a group. Note, that the following example uses variables that are not in the public JavaFX API. They may be changed later.
Create a new application based on the example above. Replace the HBox and VBox classes with the Group class that uses a custom function to lay out nodes. This function uses an algorithm similar to the FlowLayout in Java. Note that content adding is simpler then before.
content: Group { impl_layout: function(group) { var x = space; var y = space; for (node in group.content) { node.impl_layoutX = x; node.impl_layoutY = y; def width = space + node.boundsInLocal.width; x += width; if (x > node.scene.width - width) { x = space; y += space + node.boundsInLocal.height; } } } content: for (color in colors) Rectangle { fill: Color.web(color) width: size height: size onMouseEntered: function(event) { this.color = color } } }
Try to resize the window and you'll see how the color patterns change their position.
PS. This article was originally posted on the Java.net site.