Buttons in GridPane with prefWidth="Infinity" break JavaFX


Question

I am just starting with JavaFX so please excuse if this is a dumb mistake to make.

I have a GridPane which I want to use to have two buttons next to eachother stretch over the whole width of the window. So I created a GridPane with one row and two collumns and added in my two buttons.

Code for that:

<GridPane id="GridPane" alignment="TOP_LEFT" disable="false" gridLinesVisible="false" hgap="5.0">
  <children>
     <Button mnemonicParsing="false"  styleClass="add-button" text="Save" GridPane.columnIndex="0" GridPane.rowIndex="0" />
     <Button mnemonicParsing="false"  text="Discard" GridPane.columnIndex="1" GridPane.rowIndex="0" />
  </children>
  <columnConstraints>
     <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" />
     <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" />
  </columnConstraints>
  <rowConstraints>
     <RowConstraints minHeight="10.0" vgrow="SOMETIMES" />
  </rowConstraints>
</GridPane>

But now the Button only take up their necessary space. So I added prefWidth="Infinity" to both of them. This results in the Secene Builder 1.1 instantly freezing. I heard that the Scene Builders were and probably are buggy so I coded it into the FXML by hand and tried to run the program. The program starts but does not open a window.

Inspection of the running process with jvisualvm tells me that the JavaFX Application Thread is allocating huge amounts of space (for millions of ArrayLists that get instantly garbage collected). It allocates about 1.2 GB/s. The Scene Builder in contrast seems to do about nothing when I try to open the file with it as its used heap is pretty constant at about 16MB (it also does not open a window).

Even if the prefWidth is only added on one Button the error happens. If I use for example prefWidth="100000000" on both buttons I get the desired result but I feel that this is realy bad coding.

So my questions are:

  • Is this an error of JavaFX?
  • How to get my desired result in a nicer way?
1
1
1/14/2014 10:14:59 AM

Accepted Answer

You should use maxWidth and not prefWidth. JavaFX is trying to compute the MAX value as the initial size for your button as it is the preferred size. Max size is only a parameter that is used to compare the actual size to (and in some cases, setting the size to a min (actual size is not big enough: augment it to min size) or max value (actual size is too big: diminish it to max size)), it is probably what you need ; maxWidth / maxHeight with 'infinity' value means you don't limit the growth of your widget.

By default, max size is equal to prefSize, that is why you have to modify it to have a correct HGROW / VGROW. You were correct on some point: you need to modify the max size, but do not change the pref size.

Something like this should work:

<Button fx:id="testButton"
        text="Test"
        maxWidth="Infinity"
        maxHeight="Infinity"
        GridPane.hgrow="ALWAYS"
        GridPane.vgrow="ALWAYS"
        GridPane.rowIndex="0"
        GridPane.columnIndex="0"/>
3
1/14/2014 10:28:11 AM

Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Icon