Skip to main content

How to lay out FX nodes?

Posted by malenkov on December 19, 2008 at 12:00 AM PST

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 1.0 API provides two simple subclasses of the Group class: HBox and VBox. 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.

Related Topics >>

Comments

I wouldn't worry. I'm sure nice layout managers (like yours Mikael) will be included in JavaFX when they release their amazing UI Components (remember Swing 2). I know...the next question is when. Olivier Allouch

I am glad that the latest release of JavaFX didpenses with the GroupLayout that was a part of a pre-release distribution. There is no need to start a java layout manager war here, but I obviously think that the campaign for miglayout is somewhat more intense than the degree to which it recommends itself as a software component for inclusion in the JDK. There are better candidates out there.

Layout Managers is a very big thing and something that should be included from day 0 in any GUI framework. Swing failed miserably in this regard and that has been pointed out again and again. The heart was there but not the understanding on how people really use layout managers.

Sometimes, in my most negative moments (hungry and low on coffee) I wonder if Sun engineers read RFE comments like in this RFE: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6530906

Cheers,
Mikael Grev

This is what I don't get about JavaFX. We've come full circle back to pixel positioning. Didn't we learn anything from VB and the old null layout days of Swing? So now we have Node equivalents of BoxLayout and FlowLayout. That's at least a start, but what is the vision here? Will there be GridBox? GridBagBox? SpringBox? Should we all be looking at Group as the way to package up reusable positioning code? Is there a way to give positioning hints, like layout parameters?

Is it at all possible that JavaFX Script declarative syntax works relativity well for simple stacking groups. But moving beyond that something like a LayoutManager might be necessary after all? ref: http://blogs.sun.com/geertjan/entry/it_s_super_crazy_nesting Was also wondering should we expect CSS support for JavaFX positioning? feed sure it'd be popular with designers (if the CSS support was really CSS). Wondered about the crossovers with http://www.thinkvitamin.com/features/css/tables-the-next-evolution-in-cs... ((x)html5 becoming more declarative in nature). ..off topic but related above css markup also serves the semantic, seo & accessibility responsibilities. JavaFX in the browser seems to break these, or at least delegate to their own impls that differ from the browser/searchengine/screenreader in an unexpected way.