title: JavaFX GridPane resizing of pane children
body: <p>This <i>may</i> be a duplicate question, but I haven't found a solution that suits my needs.</p>
  
  <p>Inspired from <a href="https://stackoverflow.com/users/1155209/jewelsea">jewelsea</a>'s <a href="https://gist.github.com/jewelsea/2030464" rel="nofollow noreferrer">ColorChooserSample</a>, half-way through my implementation I realised that manual size can only be set on <code>Control</code>s, and not on <code>Pane</code>s. These panes should be smart enough to resize themselves automatically depending on their parent.</p>
  
  <p>Is there a way for the <code>GridPane</code>s children to grab vertical and horizontal space at the same time? Much like a <code>VBox</code> and <code>HBox</code> combined. I bet the solution involves <code>AnchorPane</code>.</p>
  
  <p>Keep in my the children are <b>panes</b> and <b>not controls</b>.</p>
  
  <hr>
  
  <p><b>SSCCE with buttons</b> (copy - paste - run - resize window)</p>
  
  <pre><code>import javafx.application.Application;
  import javafx.beans.property.DoubleProperty;
  import javafx.beans.property.SimpleDoubleProperty;
  import javafx.beans.value.ChangeListener;
  import javafx.beans.value.ObservableValue;
  import javafx.geometry.Bounds;
  import javafx.geometry.Insets;
  import javafx.scene.Node;
  import javafx.scene.Scene;
  import javafx.scene.control.Button;
  import javafx.scene.control.Control;
  import javafx.scene.layout.GridPane;
  import javafx.stage.Stage;
  
  /**
   * 
   * @author ggrec
   *
   */
  public class DashboardFXGrid extends Application
  {
  
      // ==================== 1. Static Fields ========================
  
      private final static double GOLDEN_RATIO = 1.618;
  
      private final static double MIN_TILE_SIZE = 5;
      private final static double MAX_TILE_SIZE = Double.MAX_VALUE;
  
  
      // ====================== 2. Instance Fields =============================
  
      private DoubleProperty prefTileSize = new SimpleDoubleProperty(MIN_TILE_SIZE);
  
      private double nColumns;
      private double nRows;
  
      private GridPane gridPane;
  
  
      // ==================== 3. Static Methods ====================
  
      public static void main(final String[] args)
      {
          Application.launch(args);
      }
  
  
      // ==================== 4. Constructors ====================
  
      @Override
      public void start(final Stage primaryStage) throws Exception
      {
          gridPane = new GridPane();
  
          gridPane.setPadding(new Insets(20));
          gridPane.setHgap(10);
          gridPane.setVgap(10);
  
          nColumns = Math.floor(Math.sqrt(dummyButtons().length) * 2 / GOLDEN_RATIO);
          nRows    = Math.ceil(dummyButtons().length / nColumns);
  
          createContents();
  
          addResizeListeners();
  
          primaryStage.setScene(new Scene(gridPane));
          primaryStage.show();
      }
  
  
      // ==================== 5. Creators ====================
  
      private void createContents()
      {
          int i = 0;
  
          for (final Button button : dummyButtons())
          {
              GridPane.setRowIndex(button,       i / (int) nColumns);
              GridPane.setColumnIndex(button, i % (int) nColumns);
  
              button.setMinSize(MIN_TILE_SIZE, MIN_TILE_SIZE);
              button.setMaxSize(MAX_TILE_SIZE, MAX_TILE_SIZE);
  
              gridPane.getChildren().add(button);
  
              i++;
          }
      }
  
      private void addResizeListeners()
      {
          gridPane.layoutBoundsProperty().addListener(new ChangeListener&lt;Bounds&gt;() {
  
              @Override public void changed(final ObservableValue&lt;? extends Bounds&gt; observableValue, final Bounds oldBounds, final Bounds newBounds)
              {
                  prefTileSize.set(Math.max(MIN_TILE_SIZE, Math.min(newBounds.getWidth() / nColumns, newBounds.getHeight() / nRows)));
  
                  for (final Node child : gridPane.getChildrenUnmodifiable())
                  {
                      final Control tile = (Control) child;
                      tile.setPrefSize(prefTileSize.get(), prefTileSize.get());
                  }
              }
          });
      }
  
  
      // ==================== 15. Other ====================
  
      private static final Button[] dummyButtons()
      {
          final Button[] buttons = new Button[5];
  
          for(int i = 0; i &lt; buttons.length; i++)
          {
              buttons[i] = new Button(String.valueOf(i));
          }
  
          return buttons;
      }
  
  }
  </code></pre>